@fmsim/machine 3.0.0-beta.3 → 3.0.0-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/dist/agv-line.js +2 -2
  2. package/dist/agv-line.js.map +1 -1
  3. package/dist/agv.js +6 -2
  4. package/dist/agv.js.map +1 -1
  5. package/dist/buffer.js +2 -2
  6. package/dist/buffer.js.map +1 -1
  7. package/dist/conveyor-join.js +2 -2
  8. package/dist/conveyor-join.js.map +1 -1
  9. package/dist/conveyor.js +2 -2
  10. package/dist/conveyor.js.map +1 -1
  11. package/dist/crane.js +2 -2
  12. package/dist/crane.js.map +1 -1
  13. package/dist/equipment.js +2 -2
  14. package/dist/equipment.js.map +1 -1
  15. package/dist/factories/conveyor-3d.js +2 -2
  16. package/dist/factories/conveyor-3d.js.map +1 -1
  17. package/dist/factories/machine-3d.js +12 -12
  18. package/dist/factories/machine-3d.js.map +1 -1
  19. package/dist/factories/oht-3d.js +3 -4
  20. package/dist/factories/oht-3d.js.map +1 -1
  21. package/dist/features/legend-panel.js +29 -0
  22. package/dist/features/legend-panel.js.map +1 -0
  23. package/dist/features/legend-rows.js +88 -0
  24. package/dist/features/legend-rows.js.map +1 -0
  25. package/dist/features/lv-figures.js +137 -0
  26. package/dist/features/lv-figures.js.map +1 -0
  27. package/dist/features/lv-heights.js +20 -0
  28. package/dist/features/lv-heights.js.map +1 -0
  29. package/dist/features/mcs-status-default.js +3 -49
  30. package/dist/features/mcs-status-default.js.map +1 -1
  31. package/dist/features/oht-rail.js +32 -0
  32. package/dist/features/oht-rail.js.map +1 -0
  33. package/dist/features/vehicle-travel.js +90 -0
  34. package/dist/features/vehicle-travel.js.map +1 -0
  35. package/dist/index.js +4 -0
  36. package/dist/index.js.map +1 -1
  37. package/dist/mcs-carrier-holder.js +19 -25
  38. package/dist/mcs-carrier-holder.js.map +1 -1
  39. package/dist/mcs-machine.js +10 -1
  40. package/dist/mcs-machine.js.map +1 -1
  41. package/dist/mcs-unit.js +10 -1
  42. package/dist/mcs-unit.js.map +1 -1
  43. package/dist/mcs-vehicle.js +2 -60
  44. package/dist/mcs-vehicle.js.map +1 -1
  45. package/dist/oht-line.js +7 -3
  46. package/dist/oht-line.js.map +1 -1
  47. package/dist/oht.js +2 -2
  48. package/dist/oht.js.map +1 -1
  49. package/dist/port.js +2 -2
  50. package/dist/port.js.map +1 -1
  51. package/dist/scene/root-container-override.js +15 -210
  52. package/dist/scene/root-container-override.js.map +1 -1
  53. package/dist/shelf.js +2 -2
  54. package/dist/shelf.js.map +1 -1
  55. package/dist/shuttle.js +2 -2
  56. package/dist/shuttle.js.map +1 -1
  57. package/dist/stocker.js +2 -2
  58. package/dist/stocker.js.map +1 -1
  59. package/dist/tsconfig.tsbuildinfo +1 -1
  60. package/package.json +5 -4
  61. package/src/agv-line.ts +2 -2
  62. package/src/agv.ts +7 -2
  63. package/src/buffer.ts +2 -2
  64. package/src/conveyor-join.ts +2 -2
  65. package/src/conveyor.ts +2 -2
  66. package/src/crane.ts +2 -2
  67. package/src/equipment.ts +2 -2
  68. package/src/factories/conveyor-3d.ts +2 -2
  69. package/src/factories/machine-3d.ts +11 -12
  70. package/src/factories/oht-3d.ts +3 -5
  71. package/src/features/legend-panel.ts +31 -0
  72. package/src/features/legend-rows.ts +86 -0
  73. package/src/features/lv-figures.ts +144 -0
  74. package/src/features/lv-heights.ts +22 -0
  75. package/src/features/mcs-status-default.ts +3 -53
  76. package/src/features/oht-rail.ts +31 -0
  77. package/src/features/vehicle-travel.ts +97 -0
  78. package/src/index.ts +4 -0
  79. package/src/mcs-carrier-holder.ts +17 -26
  80. package/src/mcs-machine.ts +12 -1
  81. package/src/mcs-unit.ts +12 -1
  82. package/src/mcs-vehicle.ts +3 -71
  83. package/src/oht-line.ts +7 -3
  84. package/src/oht.ts +2 -2
  85. package/src/port.ts +2 -2
  86. package/src/scene/root-container-override.ts +15 -207
  87. package/src/shelf.ts +2 -2
  88. package/src/shuttle.ts +2 -2
  89. package/src/stocker.ts +2 -2
  90. package/translations/en.json +7 -1
  91. package/translations/ja.json +7 -1
  92. package/translations/ko.json +7 -1
  93. package/translations/ms.json +7 -1
  94. package/translations/zh.json +7 -1
@@ -1,8 +1,9 @@
1
1
  import { themesColorMap, themesAnimationMap } from '@fmsim/api';
2
2
  import JSON5 from 'json5';
3
- import { Capacity, Holdable, ItemsDataBinding, Model, TRANSFER_SLOT_KEY, figureLegendSourcesChanged, itemTypeEntryOf, itemTypeTableOf, registerFigureCapability, registerFigureLegendResolver } from '@hatiolab/things-scene';
3
+ import { Capacity, Holdable, ItemsDataBinding, Model, TRANSFER_SLOT_KEY, figureLegendSourcesChanged, itemTypeEntryOf, itemTypeTableOf, registerFigureLegendResolver } from '@hatiolab/things-scene';
4
+ import { colourAndEffect } from './features/legend-rows';
4
5
  import { HOLDER_ANCHOR } from '@hatiolab/figure-model';
5
- import { CARRIER_HOLDER, carrierHolderProperties } from '@fmsim/figure-capabilities';
6
+ import { carrierHolderProperties } from '@fmsim/figure-capabilities';
6
7
  import MCSUnit from './mcs-unit.js';
7
8
  import { incomingFromV2 } from './utils/load-address';
8
9
  /**
@@ -31,6 +32,11 @@ export function CarrierHolder(Base) {
31
32
  get isCarrierHolder() {
32
33
  return true;
33
34
  }
35
+ /** The board legend rows its carriers follow, with whatever else it follows (ADR-0167 decision 20) */
36
+ get legendRowsUsed() {
37
+ var _a;
38
+ return [...((_a = super.legendRowsUsed) !== null && _a !== void 0 ? _a : []), 'carrier', 'carrier-animation'];
39
+ }
34
40
  get showOverflow() {
35
41
  return true;
36
42
  }
@@ -183,12 +189,15 @@ export function CarrierHolder(Base) {
183
189
  }
184
190
  // ── where carriers stand ──────────────────────────────────────────────────
185
191
  /**
186
- * Where a holder's carriers rest, in coordinates above the holder's bottom, and whether they stand on it or hang from
187
- * it: on the transport surface by default (fmsim v2). A Port, Shelf or Shuttle holds them at its bottom; an OHT hangs
188
- * them below.
192
+ * Where a figure holder's carriers rest, in coordinates above the holder's bottom, and whether they stand on it or
193
+ * hang from it, as its `carrierMount` says (ADR-0167 decision 18): on top of its body, or below it. fmsim's own
194
+ * holders say their own (MCSCarrierHolder and those over it).
189
195
  */
190
196
  get carrierRest() {
191
- return { height: 30, mount: 'ON' };
197
+ var _a, _b;
198
+ if (((_a = this.state) === null || _a === void 0 ? void 0 : _a.carrierMount) === 'HANG')
199
+ return { height: 0, mount: 'HANG' };
200
+ return { height: Number((_b = this._realObject) === null || _b === void 0 ? void 0 : _b.effectiveDepth) || 0, mount: 'ON' };
192
201
  }
193
202
  /** The pile, and the exception area beside the holder's +X edge. Frames in mm on the holder's own anchor (its bottom) */
194
203
  outsideSlots() {
@@ -243,6 +252,10 @@ class MCSCarrierHolder extends CarrierHolder(ItemsDataBinding(Holdable(Capacity(
243
252
  static get properties() {
244
253
  return [...MCSUnit.properties, ...CARRIER_HOLDER_PROPERTIES];
245
254
  }
255
+ /** On the transport surface by default (fmsim v2). A Port, Shelf or Shuttle holds them at its bottom; an OHT hangs them below. */
256
+ get carrierRest() {
257
+ return { height: 30, mount: 'ON' };
258
+ }
246
259
  }
247
260
  export default MCSCarrierHolder;
248
261
  /*
@@ -278,24 +291,5 @@ export function carrierHolderLegend({ component, role }) {
278
291
  }
279
292
  return legend && typeof legend === 'object' ? colourAndEffect(legend) : undefined;
280
293
  }
281
- /** A legend as a figure takes it from fmsim: each entry's colour and effect; a colour alone stays the colour; an entry's JSON5 text read. */
282
- function colourAndEffect(legend) {
283
- return Object.fromEntries(Object.entries(legend).map(([code, raw]) => {
284
- let entry = raw;
285
- if (typeof entry === 'string' && entry.trim().startsWith('{')) {
286
- try {
287
- entry = JSON5.parse(entry);
288
- }
289
- catch (_a) {
290
- return [code, raw];
291
- }
292
- }
293
- if (!entry || typeof entry !== 'object')
294
- return [code, entry];
295
- const { color, effect } = entry;
296
- return [code, Object.assign(Object.assign({}, (color !== undefined ? { color } : {})), (effect !== undefined ? { effect } : {}))];
297
- }));
298
- }
299
294
  registerFigureLegendResolver(carrierHolderLegend);
300
- registerFigureCapability(Object.assign(Object.assign({}, CARRIER_HOLDER), { properties: CARRIER_HOLDER_PROPERTIES }), base => CarrierHolder(base));
301
295
  //# sourceMappingURL=mcs-carrier-holder.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcs-carrier-holder.js","sourceRoot":"","sources":["../src/mcs-carrier-holder.ts"],"names":[],"mappings":"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","sourcesContent":["import { themesColorMap, themesAnimationMap } from '@fmsim/api'\nimport JSON5 from 'json5'\nimport {\n Capacity,\n Holdable,\n ItemsDataBinding,\n Model,\n TRANSFER_SLOT_KEY,\n figureLegendSourcesChanged,\n itemTypeEntryOf,\n itemTypeTableOf,\n registerFigureCapability,\n registerFigureLegendResolver,\n type ItemType\n} from '@hatiolab/things-scene'\nimport { HOLDER_ANCHOR, type ItemDims, type ResolvedSlot } from '@hatiolab/figure-model'\nimport { CARRIER_HOLDER, carrierHolderProperties } from '@fmsim/figure-capabilities'\nimport MCSUnit from './mcs-unit.js'\nimport { incomingFromV2 } from './utils/load-address'\n\n/**\n * A holder's slots outside its layout (common item contract 3.4): every carrier of a holder without a layout stands in\n * one pile, and a carrier whose address is unknown or wrong stands in the exception area beside the holder.\n */\nexport const PILE_SLOT = 'pile'\nexport const EXCEPTION_SLOT = 'exception'\n\n/** Where the exception area starts, past the holder's +X edge: a gap of this much of the holder's width */\nconst EXCEPTION_GAP_RATIO = 0.1\n\n/** A carrier shown in a pile is this much of its holder's plan, and half its smaller side high (fmsim v2) */\nconst PILE_PLAN_RATIO = 0.8\nconst PILE_HEIGHT_RATIO = 0.5\n\n/** The record of one carrier the holder's data names: its id, the slot it stands in, what it is told */\nexport interface CarrierRecord {\n slotId: string\n itemId: string\n itemState: { data: Record<string, any>; showText: boolean }\n}\n\n/** The properties a carrier holder adds, offering the legends this board has (ADR-0167 decision 11, 미결 1) */\nexport const CARRIER_HOLDER_PROPERTIES = carrierHolderProperties({ legends: themesColorMap, animations: themesAnimationMap })\n\n/**\n * A holder of MCS carriers, as a mixin over what holds things (`fmsim.CarrierHolder`). What it holds is the common item\n * contract's: carriers are its items (`_items`), found by their CARRIERNAME in the root (itemById), made, moved between\n * holders and let go by the one reconcile by id. MCS's part is here: reading the holder data into one record per\n * carrier, looking its CARRIERTYPE up in the domain's carrier type table (ADR-0155, theme carrier-types), and how a\n * carrier -- whose size MCS does not say -- is shown.\n */\nexport function CarrierHolder<T extends new (...args: any[]) => any>(Base: T) {\n return class extends Base {\n /** Whatever wears this is a carrier holder: the legend resolver finds it up a carrier's parents. */\n get isCarrierHolder(): true {\n return true\n }\n\n /** The records the reconcile took last, as JSON: the same again is not reconciled */\n _carrierRecordsTaken?: string\n\n get showOverflow() {\n return true\n }\n\n get hierarchy() {\n return {\n ...super.hierarchy,\n components: []\n }\n }\n\n // ── items: the holder data is the holder's, the records are worked out from it ─────────────\n\n _itemsFromData(): boolean {\n return false\n }\n\n _keyedById(): boolean {\n return true\n }\n\n /** A carrier the data moves here from another holder travels for two seconds */\n itemMoveAnimation() {\n return { duration: 2000, ease: 'inout' }\n }\n\n _createItemFromRecord(record: CarrierRecord): any {\n const { width, height } = (this as any).state\n return Model.compile(\n { id: record.itemId, type: 'Carrier', left: 0, top: 0, width, height, ...record.itemState },\n (this as any).root?.app\n )\n }\n\n /**\n * One record per carrier the data names, bottom first: MULTICARRIERS in order, then the representative. Without a\n * layout they all stand in the pile. A carrier is told its own keys and whether to show its text.\n */\n carrierRecords(data: Record<string, any> | undefined): CarrierRecord[] {\n return incomingFromV2(data).map(c => ({\n slotId: PILE_SLOT,\n itemId: c.name,\n itemState: this.carrierStateOf(c.record, c.record === data)\n }))\n }\n\n /** What a carrier is told: its own keys (the representative's are picked out of the holder data), and its text */\n carrierStateOf(record: Record<string, any>, representative: boolean): CarrierRecord['itemState'] {\n let data: Record<string, any> = { ...record }\n if (representative) {\n data = { CARRIERNAME: record.CARRIERNAME }\n for (const k of ['CARRIERTYPE', 'EMPTYTYPE', 'CARRIERSTATUS']) if (k in record) data[k] = record[k]\n }\n return { data, showText: !!(this as any).getState('showCarrierText') }\n }\n\n /**\n * The carrier 2D draws (fmsim v2, a rule of position): the top of the data's stack -- MULTICARRIERS bottom first, the\n * holder's own CARRIERNAME last -- when the holder holds it, else the last it holds.\n */\n get topCarrier(): any {\n const items: any[] = (this as any)._items\n const names = incomingFromV2((this as any).data).map(c => c.name)\n for (let i = names.length - 1; i >= 0; i--) {\n const held = items.find(c => c.state.id === names[i])\n if (held) return held\n }\n return items[items.length - 1]\n }\n\n /** The holder's carriers made to be what its data says now. Records the same as last time change nothing */\n syncCarriers(data: Record<string, any> | undefined) {\n const records = this.carrierRecords(data)\n const taken = JSON.stringify(records)\n if (taken === this._carrierRecordsTaken) return\n this._carrierRecordsTaken = taken\n ;(this as any)._reconcileItems(records)\n }\n\n async ready() {\n await super.ready()\n this.syncCarriers((this as any).data)\n }\n\n onchange(after: Record<string, any>, before: Record<string, any>): void {\n super.onchange(after, before)\n /* Its size moves its bottom and changes the size a pile shows carriers at: they take its plan, made and seated again. */\n if ('width' in after || 'height' in after || 'depth' in after) {\n const { width, height } = (this as any).state\n for (const carrier of (this as any)._items) if (width && height) carrier.set({ width, height })\n this._carriersSeatedAgain()\n }\n /* 이 홀더의 Carrier 들이 물려받는 범례가 바뀌었다: 그 피규어들이 범례를 다시 고른다 (ADR-0166 결정 12) */\n if ('carrierLegendName' in after || 'carrierAnimationName' in after) figureLegendSourcesChanged(this)\n if ('showCarrierText' in after || 'slotLayout' in after) {\n this._carrierRecordsTaken = undefined\n this.syncCarriers((this as any).data)\n if ('slotLayout' in after) this._carriersSeatedAgain()\n }\n }\n\n onchangeData(after: Record<string, any>, before: Record<string, any>): void {\n this.syncCarriers(after.data || {})\n super.onchangeData(after, before)\n }\n\n // ── the domain's item types ────────────────────────────────────────────────\n\n /**\n * A carrier's type (ADR-0155): the code it says (its CARRIERTYPE, trimmed and upper-cased -- doc 01, 6.8), in the\n * domain's carrier type table the scene was given when it opened. None when the table does not have it, or the scene\n * was given none.\n */\n carrierItemType(carrier: any): ItemType | null {\n const table = itemTypeTableOf(this)\n return (table && itemTypeEntryOf(table, carrier)) || null\n }\n\n /** A carrier's item type: its code, when the domain's table has it; else null */\n itemTypeOf(carrier: any): string | null {\n return this.carrierItemType(carrier)?.code ?? null\n }\n\n /**\n * A carrier's size in mm, as judged: none. MCS data does not say a carrier's size and a carrier type has none\n * (ADR-0155 amendment 1 C); a carrier is shown at the size of the place it stands in (itemShownDimsOf).\n */\n itemDimsOf(_carrier: any): ItemDims | null {\n return null\n }\n\n /**\n * The size a carrier of unknown size is shown at, in mm (for showing only, never judged). In the pile, most of the\n * holder's plan and half its smaller side high; elsewhere the box filling its slot, its height shared by the stack.\n */\n itemShownDimsOf(_carrier: any, slot: ResolvedSlot, slotId: string): ItemDims | null {\n /* Elsewhere outside the layout, a holder that keeps carriers there says (the exception area: LoadLayoutHolder). */\n if (slotId === PILE_SLOT) {\n const k = (this as any).mmPerSceneUnit\n const { width = 0, height = 0 } = (this as any).state\n const w = Math.abs(width) * PILE_PLAN_RATIO\n const d = Math.abs(height) * PILE_PLAN_RATIO\n return w > 0 && d > 0 ? { width: w * k, depth: d * k, height: Math.min(w, d) * PILE_HEIGHT_RATIO * k } : null\n }\n const layers = Number.isFinite(slot.stackLimit) && slot.stackLimit > 0 ? slot.stackLimit : 1\n return Number.isFinite(slot.allowed.width)\n ? { width: slot.allowed.width, depth: slot.allowed.depth, height: slot.allowed.height / layers }\n : null\n }\n\n /** A carrier's size as it is shown, in mm: its own, or the size its slot shows an unknown one at (its seat's) */\n carrierShownDimsOf(carrier: any): ItemDims | null {\n return (this as any).itemSeatOf(carrier)?.dims ?? null\n }\n\n /** Every carrier made again at the size it is shown at, and every slot seated again */\n _carriersSeatedAgain() {\n const items: any[] = (this as any)._items\n for (const carrier of items) carrier._realObject?.update?.()\n const slots = new Set(items.map(c => c[TRANSFER_SLOT_KEY]))\n for (const slotId of slots) (this as any)._reseatSlot(slotId)\n }\n\n // ── where carriers stand ──────────────────────────────────────────────────\n\n /**\n * Where a holder's carriers rest, in coordinates above the holder's bottom, and whether they stand on it or hang from\n * it: on the transport surface by default (fmsim v2). A Port, Shelf or Shuttle holds them at its bottom; an OHT hangs\n * them below.\n */\n get carrierRest(): { height: number; mount: 'ON' | 'HANG' } {\n return { height: 30, mount: 'ON' }\n }\n\n /** The pile, and the exception area beside the holder's +X edge. Frames in mm on the holder's own anchor (its bottom) */\n outsideSlots() {\n const k = (this as any).mmPerSceneUnit\n const { width = 0 } = (this as any).state\n const w = Math.abs(width)\n const rest = this.carrierRest\n return [\n {\n id: PILE_SLOT,\n anchorId: HOLDER_ANCHOR,\n frame: { position: { x: 0, y: rest.height * k, z: 0 }, rotation: 0 },\n mount: rest.mount\n },\n {\n id: EXCEPTION_SLOT,\n anchorId: HOLDER_ANCHOR,\n frame: {\n position: { x: (w / 2 + w * EXCEPTION_GAP_RATIO) * k + this.exceptionHalfWidth, y: 0, z: 0 },\n rotation: 0\n }\n }\n ]\n }\n\n /** Half the width of a carrier in the exception area, in mm: its edge stands past the gap */\n get exceptionHalfWidth(): number {\n return 0\n }\n\n /**\n * The holder's own anchor is its bottom's centre: a node on the frame at its 3D's origin (the box centre), half its\n * 3D's depth down, turned and moved with it. Others by the layer below.\n */\n anchorObject3D(anchorId: string): any {\n const frame = super.anchorObject3D(anchorId)\n if (anchorId !== HOLDER_ANCHOR || !frame) return frame\n let node = frame.userData.carrierAnchor\n if (!node || node.parent !== frame) {\n node = new frame.constructor()\n node.name = 'carrier-anchor'\n frame.add(node)\n frame.userData.carrierAnchor = node\n }\n node.position.set(0, -(Number((this as any)._realObject?.effectiveDepth) || 0) / 2, 0)\n return node\n }\n }\n}\n\n/* The mixins of things-scene are typed loosely: the holder is still an MCSUnit. */\ninterface MCSCarrierHolder extends MCSUnit {}\n\n/** fmsim's own carrier holder: an MCS unit that holds things, wearing `fmsim.CarrierHolder`. */\nclass MCSCarrierHolder extends CarrierHolder(ItemsDataBinding(Holdable(Capacity(MCSUnit as any)))) {\n static get properties(): any {\n return [...MCSUnit.properties, ...CARRIER_HOLDER_PROPERTIES]\n }\n}\n\nexport default MCSCarrierHolder\n\n/*\n The legend a carrier figure shows its tables by (ADR-0166 7, 12; ADR-0167 11): the nearest carrier holder up its\n parents that chose one for the role -- carrier-legend its carrier legend, carrier-animation its carrier animation --\n then the board root's same choice; none chosen, no answer (the figure's own table, fmsim's default). Colour and effect\n only: a carrier figure's thickness is its own fixed table (ADR-0167 12).\n*/\nconst ROLE_PROPERTY: Record<string, string> = {\n 'carrier-legend': 'carrierLegendName',\n 'carrier-animation': 'carrierAnimationName'\n}\n\nexport function carrierHolderLegend({ component, role }: { component: any; role: string }): unknown {\n const property = ROLE_PROPERTY[role]\n if (!property) return undefined\n let name: unknown\n for (let at = component?.parent; at && !name; at = at.parent) if (at.isCarrierHolder) name = at.state?.[property]\n name ||= component?.root?.rootModel?.state?.[property]\n if (typeof name !== 'string' || !name) return undefined\n let legend = component?.root?.style?.[name]\n if (typeof legend === 'string') {\n try {\n legend = JSON5.parse(legend)\n } catch {\n return undefined\n }\n }\n return legend && typeof legend === 'object' ? colourAndEffect(legend) : undefined\n}\n\n/** A legend as a figure takes it from fmsim: each entry's colour and effect; a colour alone stays the colour; an entry's JSON5 text read. */\nfunction colourAndEffect(legend: Record<string, unknown>): Record<string, unknown> {\n return Object.fromEntries(\n Object.entries(legend).map(([code, raw]) => {\n let entry = raw\n if (typeof entry === 'string' && entry.trim().startsWith('{')) {\n try {\n entry = JSON5.parse(entry)\n } catch {\n return [code, raw]\n }\n }\n if (!entry || typeof entry !== 'object') return [code, entry]\n const { color, effect } = entry as { color?: unknown; effect?: unknown }\n return [code, { ...(color !== undefined ? { color } : {}), ...(effect !== undefined ? { effect } : {}) }]\n })\n )\n}\n\nregisterFigureLegendResolver(carrierHolderLegend)\nregisterFigureCapability({ ...CARRIER_HOLDER, properties: CARRIER_HOLDER_PROPERTIES as never }, base => CarrierHolder(base) as never)\n"]}
1
+ {"version":3,"file":"mcs-carrier-holder.js","sourceRoot":"","sources":["../src/mcs-carrier-holder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAC/D,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,gBAAgB,EAChB,KAAK,EACL,iBAAiB,EACjB,0BAA0B,EAC1B,eAAe,EACf,eAAe,EACf,4BAA4B,EAE7B,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,aAAa,EAAoC,MAAM,wBAAwB,CAAA;AACxF,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAA;AACpE,OAAO,OAAO,MAAM,eAAe,CAAA;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAErD;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAA;AAC/B,MAAM,CAAC,MAAM,cAAc,GAAG,WAAW,CAAA;AAEzC,2GAA2G;AAC3G,MAAM,mBAAmB,GAAG,GAAG,CAAA;AAE/B,6GAA6G;AAC7G,MAAM,eAAe,GAAG,GAAG,CAAA;AAC3B,MAAM,iBAAiB,GAAG,GAAG,CAAA;AAS7B,6GAA6G;AAC7G,MAAM,CAAC,MAAM,yBAAyB,GAAG,uBAAuB,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,kBAAkB,EAAE,CAAC,CAAA;AAE7H;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAwC,IAAO;IAC1E,OAAO,KAAM,SAAQ,IAAI;QACvB,oGAAoG;QACpG,IAAI,eAAe;YACjB,OAAO,IAAI,CAAA;QACb,CAAC;QAED,sGAAsG;QACtG,IAAI,cAAc;;YAChB,OAAO,CAAC,GAAG,CAAC,MAAC,KAAK,CAAC,cAAuC,mCAAI,EAAE,CAAC,EAAE,SAAS,EAAE,mBAAmB,CAAC,CAAA;QACpG,CAAC;QAKD,IAAI,YAAY;YACd,OAAO,IAAI,CAAA;QACb,CAAC;QAED,IAAI,SAAS;YACX,uCACK,KAAK,CAAC,SAAS,KAClB,UAAU,EAAE,EAAE,IACf;QACH,CAAC;QAED,8FAA8F;QAE9F,cAAc;YACZ,OAAO,KAAK,CAAA;QACd,CAAC;QAED,UAAU;YACR,OAAO,IAAI,CAAA;QACb,CAAC;QAED,gFAAgF;QAChF,iBAAiB;YACf,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;QAC1C,CAAC;QAED,qBAAqB,CAAC,MAAqB;;YACzC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAI,IAAY,CAAC,KAAK,CAAA;YAC7C,OAAO,KAAK,CAAC,OAAO,iBAChB,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,IAAK,MAAM,CAAC,SAAS,GACzF,MAAC,IAAY,CAAC,IAAI,0CAAE,GAAG,CACxB,CAAA;QACH,CAAC;QAED;;;WAGG;QACH,cAAc,CAAC,IAAqC;YAClD,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACpC,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,CAAC,CAAC,IAAI;gBACd,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC;aAC5D,CAAC,CAAC,CAAA;QACL,CAAC;QAED,kHAAkH;QAClH,cAAc,CAAC,MAA2B,EAAE,cAAuB;YACjE,IAAI,IAAI,qBAA6B,MAAM,CAAE,CAAA;YAC7C,IAAI,cAAc,EAAE,CAAC;gBACnB,IAAI,GAAG,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAA;gBAC1C,KAAK,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,EAAE,eAAe,CAAC;oBAAE,IAAI,CAAC,IAAI,MAAM;wBAAE,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;YACrG,CAAC;YACD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAE,IAAY,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAA;QACxE,CAAC;QAED;;;WAGG;QACH,IAAI,UAAU;YACZ,MAAM,KAAK,GAAW,IAAY,CAAC,MAAM,CAAA;YACzC,MAAM,KAAK,GAAG,cAAc,CAAE,IAAY,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;YACjE,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;gBACrD,IAAI,IAAI;oBAAE,OAAO,IAAI,CAAA;YACvB,CAAC;YACD,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QAChC,CAAC;QAED,4GAA4G;QAC5G,YAAY,CAAC,IAAqC;YAChD,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;YACzC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;YACrC,IAAI,KAAK,KAAK,IAAI,CAAC,oBAAoB;gBAAE,OAAM;YAC/C,IAAI,CAAC,oBAAoB,GAAG,KAAK,CAChC;YAAC,IAAY,CAAC,eAAe,CAAC,OAAO,CAAC,CAAA;QACzC,CAAC;QAED,KAAK,CAAC,KAAK;YACT,MAAM,KAAK,CAAC,KAAK,EAAE,CAAA;YACnB,IAAI,CAAC,YAAY,CAAE,IAAY,CAAC,IAAI,CAAC,CAAA;QACvC,CAAC;QAED,QAAQ,CAAC,KAA0B,EAAE,MAA2B;YAC9D,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;YAC7B,yHAAyH;YACzH,IAAI,OAAO,IAAI,KAAK,IAAI,QAAQ,IAAI,KAAK,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;gBAC9D,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAI,IAAY,CAAC,KAAK,CAAA;gBAC7C,KAAK,MAAM,OAAO,IAAK,IAAY,CAAC,MAAM;oBAAE,IAAI,KAAK,IAAI,MAAM;wBAAE,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;gBAC/F,IAAI,CAAC,oBAAoB,EAAE,CAAA;YAC7B,CAAC;YACD,yEAAyE;YACzE,IAAI,mBAAmB,IAAI,KAAK,IAAI,sBAAsB,IAAI,KAAK;gBAAE,0BAA0B,CAAC,IAAI,CAAC,CAAA;YACrG,IAAI,iBAAiB,IAAI,KAAK,IAAI,YAAY,IAAI,KAAK,EAAE,CAAC;gBACxD,IAAI,CAAC,oBAAoB,GAAG,SAAS,CAAA;gBACrC,IAAI,CAAC,YAAY,CAAE,IAAY,CAAC,IAAI,CAAC,CAAA;gBACrC,IAAI,YAAY,IAAI,KAAK;oBAAE,IAAI,CAAC,oBAAoB,EAAE,CAAA;YACxD,CAAC;QACH,CAAC;QAED,YAAY,CAAC,KAA0B,EAAE,MAA2B;YAClE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAA;YACnC,KAAK,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QACnC,CAAC;QAED,8EAA8E;QAE9E;;;;WAIG;QACH,eAAe,CAAC,OAAY;YAC1B,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,CAAA;YACnC,OAAO,CAAC,KAAK,IAAI,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,IAAI,CAAA;QAC3D,CAAC;QAED,iFAAiF;QACjF,UAAU,CAAC,OAAY;;YACrB,OAAO,MAAA,MAAA,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,0CAAE,IAAI,mCAAI,IAAI,CAAA;QACpD,CAAC;QAED;;;WAGG;QACH,UAAU,CAAC,QAAa;YACtB,OAAO,IAAI,CAAA;QACb,CAAC;QAED;;;WAGG;QACH,eAAe,CAAC,QAAa,EAAE,IAAkB,EAAE,MAAc;YAC/D,mHAAmH;YACnH,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,MAAM,CAAC,GAAI,IAAY,CAAC,cAAc,CAAA;gBACtC,MAAM,EAAE,KAAK,GAAG,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,GAAI,IAAY,CAAC,KAAK,CAAA;gBACrD,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,eAAe,CAAA;gBAC3C,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,eAAe,CAAA;gBAC5C,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,iBAAiB,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;YAC/G,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAA;YAC5F,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;gBACxC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,MAAM,EAAE;gBAChG,CAAC,CAAC,IAAI,CAAA;QACV,CAAC;QAED,iHAAiH;QACjH,kBAAkB,CAAC,OAAY;;YAC7B,OAAO,MAAA,MAAC,IAAY,CAAC,UAAU,CAAC,OAAO,CAAC,0CAAE,IAAI,mCAAI,IAAI,CAAA;QACxD,CAAC;QAED,uFAAuF;QACvF,oBAAoB;;YAClB,MAAM,KAAK,GAAW,IAAY,CAAC,MAAM,CAAA;YACzC,KAAK,MAAM,OAAO,IAAI,KAAK;gBAAE,MAAA,MAAA,OAAO,CAAC,WAAW,0CAAE,MAAM,kDAAI,CAAA;YAC5D,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAA;YAC3D,KAAK,MAAM,MAAM,IAAI,KAAK;gBAAG,IAAY,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;QAC/D,CAAC;QAED,6EAA6E;QAE7E;;;;WAIG;QACH,IAAI,WAAW;;YACb,IAAI,CAAA,MAAC,IAAY,CAAC,KAAK,0CAAE,YAAY,MAAK,MAAM;gBAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;YACrF,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAC,IAAY,CAAC,WAAW,0CAAE,cAAc,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;QACxF,CAAC;QAED,yHAAyH;QACzH,YAAY;YACV,MAAM,CAAC,GAAI,IAAY,CAAC,cAAc,CAAA;YACtC,MAAM,EAAE,KAAK,GAAG,CAAC,EAAE,GAAI,IAAY,CAAC,KAAK,CAAA;YACzC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;YACzB,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAA;YAC7B,OAAO;gBACL;oBACE,EAAE,EAAE,SAAS;oBACb,QAAQ,EAAE,aAAa;oBACvB,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE;oBACpE,KAAK,EAAE,IAAI,CAAC,KAAK;iBAClB;gBACD;oBACE,EAAE,EAAE,cAAc;oBAClB,QAAQ,EAAE,aAAa;oBACvB,KAAK,EAAE;wBACL,QAAQ,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,mBAAmB,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;wBAC5F,QAAQ,EAAE,CAAC;qBACZ;iBACF;aACF,CAAA;QACH,CAAC;QAED,6FAA6F;QAC7F,IAAI,kBAAkB;YACpB,OAAO,CAAC,CAAA;QACV,CAAC;QAED;;;WAGG;QACH,cAAc,CAAC,QAAgB;;YAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAA;YAC5C,IAAI,QAAQ,KAAK,aAAa,IAAI,CAAC,KAAK;gBAAE,OAAO,KAAK,CAAA;YACtD,IAAI,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAA;YACvC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;gBACnC,IAAI,GAAG,IAAI,KAAK,CAAC,WAAW,EAAE,CAAA;gBAC9B,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAA;gBAC5B,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;gBACf,KAAK,CAAC,QAAQ,CAAC,aAAa,GAAG,IAAI,CAAA;YACrC,CAAC;YACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,MAAC,IAAY,CAAC,WAAW,0CAAE,cAAc,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;YACtF,OAAO,IAAI,CAAA;QACb,CAAC;KACF,CAAA;AACH,CAAC;AAKD,gGAAgG;AAChG,MAAM,gBAAiB,SAAQ,aAAa,CAAC,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAc,CAAC,CAAC,CAAC,CAAC;IAChG,MAAM,KAAK,UAAU;QACnB,OAAO,CAAC,GAAG,OAAO,CAAC,UAAU,EAAE,GAAG,yBAAyB,CAAC,CAAA;IAC9D,CAAC;IAED,kIAAkI;IAClI,IAAI,WAAW;QACb,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;IACpC,CAAC;CACF;AAED,eAAe,gBAAgB,CAAA;AAE/B;;;;;EAKE;AACF,MAAM,aAAa,GAA2B;IAC5C,gBAAgB,EAAE,mBAAmB;IACrC,mBAAmB,EAAE,sBAAsB;CAC5C,CAAA;AAED,MAAM,UAAU,mBAAmB,CAAC,EAAE,SAAS,EAAE,IAAI,EAAoC;;IACvF,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,CAAA;IACpC,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAA;IAC/B,IAAI,IAAa,CAAA;IACjB,KAAK,IAAI,EAAE,GAAG,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,MAAM,EAAE,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM;QAAE,IAAI,EAAE,CAAC,eAAe;YAAE,IAAI,GAAG,MAAA,EAAE,CAAC,KAAK,0CAAG,QAAQ,CAAC,CAAA;IACjH,IAAI,KAAJ,IAAI,GAAK,MAAA,MAAA,MAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,0CAAE,SAAS,0CAAE,KAAK,0CAAG,QAAQ,CAAC,EAAA;IACtD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAA;IACvD,IAAI,MAAM,GAAG,MAAA,MAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,0CAAE,KAAK,0CAAG,IAAI,CAAC,CAAA;IAC3C,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QAC9B,CAAC;QAAC,WAAM,CAAC;YACP,OAAO,SAAS,CAAA;QAClB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AACnF,CAAC;AAED,4BAA4B,CAAC,mBAAmB,CAAC,CAAA","sourcesContent":["import { themesColorMap, themesAnimationMap } from '@fmsim/api'\nimport JSON5 from 'json5'\nimport {\n Capacity,\n Holdable,\n ItemsDataBinding,\n Model,\n TRANSFER_SLOT_KEY,\n figureLegendSourcesChanged,\n itemTypeEntryOf,\n itemTypeTableOf,\n registerFigureLegendResolver,\n type ItemType\n} from '@hatiolab/things-scene'\nimport { colourAndEffect } from './features/legend-rows'\nimport { HOLDER_ANCHOR, type ItemDims, type ResolvedSlot } from '@hatiolab/figure-model'\nimport { carrierHolderProperties } from '@fmsim/figure-capabilities'\nimport MCSUnit from './mcs-unit.js'\nimport { incomingFromV2 } from './utils/load-address'\n\n/**\n * A holder's slots outside its layout (common item contract 3.4): every carrier of a holder without a layout stands in\n * one pile, and a carrier whose address is unknown or wrong stands in the exception area beside the holder.\n */\nexport const PILE_SLOT = 'pile'\nexport const EXCEPTION_SLOT = 'exception'\n\n/** Where the exception area starts, past the holder's +X edge: a gap of this much of the holder's width */\nconst EXCEPTION_GAP_RATIO = 0.1\n\n/** A carrier shown in a pile is this much of its holder's plan, and half its smaller side high (fmsim v2) */\nconst PILE_PLAN_RATIO = 0.8\nconst PILE_HEIGHT_RATIO = 0.5\n\n/** The record of one carrier the holder's data names: its id, the slot it stands in, what it is told */\nexport interface CarrierRecord {\n slotId: string\n itemId: string\n itemState: { data: Record<string, any>; showText: boolean }\n}\n\n/** The properties a carrier holder adds, offering the legends this board has (ADR-0167 decision 11, 미결 1) */\nexport const CARRIER_HOLDER_PROPERTIES = carrierHolderProperties({ legends: themesColorMap, animations: themesAnimationMap })\n\n/**\n * A holder of MCS carriers, as a mixin over what holds things (`fmsim.CarrierHolder`). What it holds is the common item\n * contract's: carriers are its items (`_items`), found by their CARRIERNAME in the root (itemById), made, moved between\n * holders and let go by the one reconcile by id. MCS's part is here: reading the holder data into one record per\n * carrier, looking its CARRIERTYPE up in the domain's carrier type table (ADR-0155, theme carrier-types), and how a\n * carrier -- whose size MCS does not say -- is shown.\n */\nexport function CarrierHolder<T extends new (...args: any[]) => any>(Base: T) {\n return class extends Base {\n /** Whatever wears this is a carrier holder: the legend resolver finds it up a carrier's parents. */\n get isCarrierHolder(): true {\n return true\n }\n\n /** The board legend rows its carriers follow, with whatever else it follows (ADR-0167 decision 20) */\n get legendRowsUsed(): string[] {\n return [...((super.legendRowsUsed as string[] | undefined) ?? []), 'carrier', 'carrier-animation']\n }\n\n /** The records the reconcile took last, as JSON: the same again is not reconciled */\n _carrierRecordsTaken?: string\n\n get showOverflow() {\n return true\n }\n\n get hierarchy() {\n return {\n ...super.hierarchy,\n components: []\n }\n }\n\n // ── items: the holder data is the holder's, the records are worked out from it ─────────────\n\n _itemsFromData(): boolean {\n return false\n }\n\n _keyedById(): boolean {\n return true\n }\n\n /** A carrier the data moves here from another holder travels for two seconds */\n itemMoveAnimation() {\n return { duration: 2000, ease: 'inout' }\n }\n\n _createItemFromRecord(record: CarrierRecord): any {\n const { width, height } = (this as any).state\n return Model.compile(\n { id: record.itemId, type: 'Carrier', left: 0, top: 0, width, height, ...record.itemState },\n (this as any).root?.app\n )\n }\n\n /**\n * One record per carrier the data names, bottom first: MULTICARRIERS in order, then the representative. Without a\n * layout they all stand in the pile. A carrier is told its own keys and whether to show its text.\n */\n carrierRecords(data: Record<string, any> | undefined): CarrierRecord[] {\n return incomingFromV2(data).map(c => ({\n slotId: PILE_SLOT,\n itemId: c.name,\n itemState: this.carrierStateOf(c.record, c.record === data)\n }))\n }\n\n /** What a carrier is told: its own keys (the representative's are picked out of the holder data), and its text */\n carrierStateOf(record: Record<string, any>, representative: boolean): CarrierRecord['itemState'] {\n let data: Record<string, any> = { ...record }\n if (representative) {\n data = { CARRIERNAME: record.CARRIERNAME }\n for (const k of ['CARRIERTYPE', 'EMPTYTYPE', 'CARRIERSTATUS']) if (k in record) data[k] = record[k]\n }\n return { data, showText: !!(this as any).getState('showCarrierText') }\n }\n\n /**\n * The carrier 2D draws (fmsim v2, a rule of position): the top of the data's stack -- MULTICARRIERS bottom first, the\n * holder's own CARRIERNAME last -- when the holder holds it, else the last it holds.\n */\n get topCarrier(): any {\n const items: any[] = (this as any)._items\n const names = incomingFromV2((this as any).data).map(c => c.name)\n for (let i = names.length - 1; i >= 0; i--) {\n const held = items.find(c => c.state.id === names[i])\n if (held) return held\n }\n return items[items.length - 1]\n }\n\n /** The holder's carriers made to be what its data says now. Records the same as last time change nothing */\n syncCarriers(data: Record<string, any> | undefined) {\n const records = this.carrierRecords(data)\n const taken = JSON.stringify(records)\n if (taken === this._carrierRecordsTaken) return\n this._carrierRecordsTaken = taken\n ;(this as any)._reconcileItems(records)\n }\n\n async ready() {\n await super.ready()\n this.syncCarriers((this as any).data)\n }\n\n onchange(after: Record<string, any>, before: Record<string, any>): void {\n super.onchange(after, before)\n /* Its size moves its bottom and changes the size a pile shows carriers at: they take its plan, made and seated again. */\n if ('width' in after || 'height' in after || 'depth' in after) {\n const { width, height } = (this as any).state\n for (const carrier of (this as any)._items) if (width && height) carrier.set({ width, height })\n this._carriersSeatedAgain()\n }\n /* 이 홀더의 Carrier 들이 물려받는 범례가 바뀌었다: 그 피규어들이 범례를 다시 고른다 (ADR-0166 결정 12) */\n if ('carrierLegendName' in after || 'carrierAnimationName' in after) figureLegendSourcesChanged(this)\n if ('showCarrierText' in after || 'slotLayout' in after) {\n this._carrierRecordsTaken = undefined\n this.syncCarriers((this as any).data)\n if ('slotLayout' in after) this._carriersSeatedAgain()\n }\n }\n\n onchangeData(after: Record<string, any>, before: Record<string, any>): void {\n this.syncCarriers(after.data || {})\n super.onchangeData(after, before)\n }\n\n // ── the domain's item types ────────────────────────────────────────────────\n\n /**\n * A carrier's type (ADR-0155): the code it says (its CARRIERTYPE, trimmed and upper-cased -- doc 01, 6.8), in the\n * domain's carrier type table the scene was given when it opened. None when the table does not have it, or the scene\n * was given none.\n */\n carrierItemType(carrier: any): ItemType | null {\n const table = itemTypeTableOf(this)\n return (table && itemTypeEntryOf(table, carrier)) || null\n }\n\n /** A carrier's item type: its code, when the domain's table has it; else null */\n itemTypeOf(carrier: any): string | null {\n return this.carrierItemType(carrier)?.code ?? null\n }\n\n /**\n * A carrier's size in mm, as judged: none. MCS data does not say a carrier's size and a carrier type has none\n * (ADR-0155 amendment 1 C); a carrier is shown at the size of the place it stands in (itemShownDimsOf).\n */\n itemDimsOf(_carrier: any): ItemDims | null {\n return null\n }\n\n /**\n * The size a carrier of unknown size is shown at, in mm (for showing only, never judged). In the pile, most of the\n * holder's plan and half its smaller side high; elsewhere the box filling its slot, its height shared by the stack.\n */\n itemShownDimsOf(_carrier: any, slot: ResolvedSlot, slotId: string): ItemDims | null {\n /* Elsewhere outside the layout, a holder that keeps carriers there says (the exception area: LoadLayoutHolder). */\n if (slotId === PILE_SLOT) {\n const k = (this as any).mmPerSceneUnit\n const { width = 0, height = 0 } = (this as any).state\n const w = Math.abs(width) * PILE_PLAN_RATIO\n const d = Math.abs(height) * PILE_PLAN_RATIO\n return w > 0 && d > 0 ? { width: w * k, depth: d * k, height: Math.min(w, d) * PILE_HEIGHT_RATIO * k } : null\n }\n const layers = Number.isFinite(slot.stackLimit) && slot.stackLimit > 0 ? slot.stackLimit : 1\n return Number.isFinite(slot.allowed.width)\n ? { width: slot.allowed.width, depth: slot.allowed.depth, height: slot.allowed.height / layers }\n : null\n }\n\n /** A carrier's size as it is shown, in mm: its own, or the size its slot shows an unknown one at (its seat's) */\n carrierShownDimsOf(carrier: any): ItemDims | null {\n return (this as any).itemSeatOf(carrier)?.dims ?? null\n }\n\n /** Every carrier made again at the size it is shown at, and every slot seated again */\n _carriersSeatedAgain() {\n const items: any[] = (this as any)._items\n for (const carrier of items) carrier._realObject?.update?.()\n const slots = new Set(items.map(c => c[TRANSFER_SLOT_KEY]))\n for (const slotId of slots) (this as any)._reseatSlot(slotId)\n }\n\n // ── where carriers stand ──────────────────────────────────────────────────\n\n /**\n * Where a figure holder's carriers rest, in coordinates above the holder's bottom, and whether they stand on it or\n * hang from it, as its `carrierMount` says (ADR-0167 decision 18): on top of its body, or below it. fmsim's own\n * holders say their own (MCSCarrierHolder and those over it).\n */\n get carrierRest(): { height: number; mount: 'ON' | 'HANG' } {\n if ((this as any).state?.carrierMount === 'HANG') return { height: 0, mount: 'HANG' }\n return { height: Number((this as any)._realObject?.effectiveDepth) || 0, mount: 'ON' }\n }\n\n /** The pile, and the exception area beside the holder's +X edge. Frames in mm on the holder's own anchor (its bottom) */\n outsideSlots() {\n const k = (this as any).mmPerSceneUnit\n const { width = 0 } = (this as any).state\n const w = Math.abs(width)\n const rest = this.carrierRest\n return [\n {\n id: PILE_SLOT,\n anchorId: HOLDER_ANCHOR,\n frame: { position: { x: 0, y: rest.height * k, z: 0 }, rotation: 0 },\n mount: rest.mount\n },\n {\n id: EXCEPTION_SLOT,\n anchorId: HOLDER_ANCHOR,\n frame: {\n position: { x: (w / 2 + w * EXCEPTION_GAP_RATIO) * k + this.exceptionHalfWidth, y: 0, z: 0 },\n rotation: 0\n }\n }\n ]\n }\n\n /** Half the width of a carrier in the exception area, in mm: its edge stands past the gap */\n get exceptionHalfWidth(): number {\n return 0\n }\n\n /**\n * The holder's own anchor is its bottom's centre: a node on the frame at its 3D's origin (the box centre), half its\n * 3D's depth down, turned and moved with it. Others by the layer below.\n */\n anchorObject3D(anchorId: string): any {\n const frame = super.anchorObject3D(anchorId)\n if (anchorId !== HOLDER_ANCHOR || !frame) return frame\n let node = frame.userData.carrierAnchor\n if (!node || node.parent !== frame) {\n node = new frame.constructor()\n node.name = 'carrier-anchor'\n frame.add(node)\n frame.userData.carrierAnchor = node\n }\n node.position.set(0, -(Number((this as any)._realObject?.effectiveDepth) || 0) / 2, 0)\n return node\n }\n }\n}\n\n/* The mixins of things-scene are typed loosely: the holder is still an MCSUnit. */\ninterface MCSCarrierHolder extends MCSUnit {}\n\n/** fmsim's own carrier holder: an MCS unit that holds things, wearing `fmsim.CarrierHolder`. */\nclass MCSCarrierHolder extends CarrierHolder(ItemsDataBinding(Holdable(Capacity(MCSUnit as any)))) {\n static get properties(): any {\n return [...MCSUnit.properties, ...CARRIER_HOLDER_PROPERTIES]\n }\n\n /** On the transport surface by default (fmsim v2). A Port, Shelf or Shuttle holds them at its bottom; an OHT hangs them below. */\n get carrierRest(): { height: number; mount: 'ON' | 'HANG' } {\n return { height: 30, mount: 'ON' }\n }\n}\n\nexport default MCSCarrierHolder\n\n/*\n The legend a carrier figure shows its tables by (ADR-0166 7, 12; ADR-0167 11): the nearest carrier holder up its\n parents that chose one for the role -- carrier-legend its carrier legend, carrier-animation its carrier animation --\n then the board root's same choice; none chosen, no answer (the figure's own table, fmsim's default). Colour and effect\n only: a carrier figure's thickness is its own fixed table (ADR-0167 12).\n*/\nconst ROLE_PROPERTY: Record<string, string> = {\n 'carrier-legend': 'carrierLegendName',\n 'carrier-animation': 'carrierAnimationName'\n}\n\nexport function carrierHolderLegend({ component, role }: { component: any; role: string }): unknown {\n const property = ROLE_PROPERTY[role]\n if (!property) return undefined\n let name: unknown\n for (let at = component?.parent; at && !name; at = at.parent) if (at.isCarrierHolder) name = at.state?.[property]\n name ||= component?.root?.rootModel?.state?.[property]\n if (typeof name !== 'string' || !name) return undefined\n let legend = component?.root?.style?.[name]\n if (typeof legend === 'string') {\n try {\n legend = JSON5.parse(legend)\n } catch {\n return undefined\n }\n }\n return legend && typeof legend === 'object' ? colourAndEffect(legend) : undefined\n}\n\nregisterFigureLegendResolver(carrierHolderLegend)\n"]}
@@ -2,6 +2,7 @@ import { ContainerAbstract } from '@hatiolab/things-scene';
2
2
  import { getPopupData } from '@fmsim/api';
3
3
  import { MCSStatusMixin, MCSStatusMixinProperties } from './features/mcs-status-mixin';
4
4
  import { LEGEND_MACHINE } from './features/mcs-status-default';
5
+ import { boardLegendOfRow } from './features/legend-rows';
5
6
  /**
6
7
  * MCS Machine의 공통 속성을 정의한 최상위 오브젝트
7
8
  * - Container
@@ -57,7 +58,15 @@ export default class MCSMachine extends MCSStatusMixin(ContainerAbstract) {
57
58
  return (_a = this.data) === null || _a === void 0 ? void 0 : _a.STATUS;
58
59
  }
59
60
  get legend() {
60
- return this.getTheme() || this.getLegendFallback();
61
+ return this.getTheme() || boardLegendOfRow(this, this.statusLegendRow) || this.getLegendFallback();
62
+ }
63
+ /** The board legend row its STATUS colour follows when it chose no legend of its own (ADR-0167 decision 20); none here */
64
+ get statusLegendRow() {
65
+ return undefined;
66
+ }
67
+ /** The board legend rows it follows: what the board's LEGENDS panel shows first */
68
+ get legendRowsUsed() {
69
+ return this.statusLegendRow ? [this.statusLegendRow] : [];
61
70
  }
62
71
  get auxLegend() {
63
72
  return LEGEND_MACHINE;
@@ -1 +1 @@
1
- {"version":3,"file":"mcs-machine.js","sourceRoot":"","sources":["../src/mcs-machine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEzC,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAA;AAEtF,OAAO,EAAE,cAAc,EAAU,MAAM,+BAA+B,CAAA;AAEtE;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,cAAc,CAAC,iBAAiB,CAAC;IACvE,MAAM,KAAK,UAAU;QACnB,OAAO;YACL,GAAG,wBAAwB;YAC3B;gBACE,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,OAAO;aACf;SACF,CAAA;IACH,CAAC;IAED,IAAI,cAAc;QAChB,OAAO,KAAK,CAAA;IACd,CAAC;IAED;;;OAGG;IACH,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAA;IACxB,CAAC;IAED,oDAAoD;IACpD,IAAI,YAAY;QACd,OAAO,IAAI,CAAA;IACb,CAAC;IAED,WAAW,CAAC,SAAoB;QAC9B,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC3D,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,CAAC,SAAS,CAAC,CAAA;IACpB,CAAC;IAED,QAAQ;;QACN,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,KAAK,CAAA;QAEjC,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,MAAA,MAAC,IAAI,CAAC,IAAY,0CAAE,KAAK,0CAAG,UAAU,CAAC,CAAA;QAChD,CAAC;IACH,CAAC;IAED,IAAI,eAAe;QACjB,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,MAAM;;QACR,OAAO,MAAA,IAAI,CAAC,IAAI,0CAAE,MAAM,CAAA;IAC1B,CAAC;IAED,IAAI,SAAS;;QACX,OAAO,MAAA,IAAI,CAAC,IAAI,0CAAE,MAAM,CAAA;IAC1B,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,QAAQ,EAAE,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAA;IACpD,CAAC;IAED,IAAI,SAAS;QACX,OAAO,cAAc,CAAA;IACvB,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAA;IAC/B,CAAC;IAED,iBAAiB;QACf,OAAO,cAAc,CAAA;IACvB,CAAC;IAED;;;;OAIG;IACH,SAAS,CAAC,GAAQ;QAChB,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QACpB,GAAG,CAAC,WAAW,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAA;IACxC,CAAC;IAED,MAAM,CAAC,GAAG;QACR,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,KAAK,CAAA;QACzC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAA;QAE9C,GAAG,CAAC,SAAS,EAAE,CAAA;QAEf,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAA;QAC/B,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,WAAY,CAAA;QACjC,GAAG,CAAC,SAAS,GAAG,SAAS,IAAI,CAAC,CAAA;QAC9B,GAAG,CAAC,OAAO,GAAG,OAAO,CAAA;QACrB,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;QAEnB,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;QAChD,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;QACpC,CAAC;QAED,GAAG,CAAC,IAAI,EAAE,CAAA;QACV,GAAG,CAAC,MAAM,EAAE,CAAA;IACd,CAAC;IAED,eAAe;IACf,iCAAiC;IACjC,oDAAoD;IACpD,mEAAmE;IACnE,MAAM;IAEN,sBAAsB;IACtB,IAAI;IAEJ,mBAAmB;IACnB,sBAAsB;IACtB,IAAI;IAEJ,KAAK,CAAC,UAAU;QACd,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC,KAAK,CAAA;QAE/B,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,OAAM;QACR,CAAC;QAED,OAAO,MAAM,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;IACrC,CAAC;CACF","sourcesContent":["import { Component, ContainerAbstract } from '@hatiolab/things-scene'\nimport { getPopupData } from '@fmsim/api'\n\nimport { MCSStatusMixin, MCSStatusMixinProperties } from './features/mcs-status-mixin'\n\nimport { LEGEND_MACHINE, Legend } from './features/mcs-status-default'\n\n/**\n * MCS Machine의 공통 속성을 정의한 최상위 오브젝트\n * - Container\n * -\n */\nexport default class MCSMachine extends MCSStatusMixin(ContainerAbstract) {\n static get properties(): any {\n return [\n ...MCSStatusMixinProperties,\n {\n type: 'number',\n name: 'round',\n label: 'round'\n }\n ]\n }\n\n get showMoveHandle() {\n return false\n }\n\n /**\n * id 후보를 조회할 때 백엔드에 보낼 타입명. 값이 있으면 검색(lookup) 대상.\n * 기본은 자기 타입. 자기 타입과 다른 타입으로 조회해야 하는 특수 케이스는 override.\n */\n get idLookupType(): string | undefined {\n return this.state.type\n }\n\n /** MCS 머신 — parentObject(부모 머신) 후보 수집 시 머신으로 식별. */\n get isMcsMachine(): boolean {\n return true\n }\n\n containable(component: Component) {\n return ['rect', 'ellipse'].includes(component.state.type)\n }\n\n get decorators() {\n return ['decotag']\n }\n\n getTheme() {\n const { legendName } = this.state\n\n if (legendName) {\n return (this.root as any)?.style?.[legendName]\n }\n }\n\n get hasTextProperty() {\n return true\n }\n\n get status() {\n return this.data?.STATUS\n }\n\n get auxStatus() {\n return this.data?.STATUS\n }\n\n get legend(): Legend {\n return this.getTheme() || this.getLegendFallback()\n }\n\n get auxLegend() {\n return LEGEND_MACHINE\n }\n\n get auxColor() {\n return this.state.strokeStyle\n }\n\n getLegendFallback() {\n return LEGEND_MACHINE\n }\n\n /**\n * 2D 에서는 `state.alpha`(3D material 전용)를 무시한다. hidden/모델링 dim 흐림은 **코어(draw)가\n * 일괄 처리**하므로 여기서 손대지 않는다 (component-drawing.ts draw 가 prerender 직후 faint 적용).\n * fade 애니메이션은 보존. 3D 는 factory `updateAlpha()` 가 state.alpha 를 별도로 존중.\n */\n prerender(ctx: any) {\n super.prerender(ctx)\n ctx.globalAlpha = 1 - this._delta.fade\n }\n\n render(ctx) {\n var { round = 0, lineWidth } = this.state\n var { left, top, width, height } = this.bounds\n\n ctx.beginPath()\n\n ctx.strokeStyle = this.auxColor\n ctx.fillStyle = this.statusColor!\n ctx.lineWidth = lineWidth || 1\n ctx.lineCap = 'round'\n ctx.setLineDash([])\n\n if (round > 0) {\n ctx.roundRect(left, top, width, height, round)\n } else {\n ctx.rect(left, top, width, height)\n }\n\n ctx.fill()\n ctx.stroke()\n }\n\n // get text() {\n // if (this.data?.LOCALENAME) {\n // // TODO 왜 LOCALENAME 데이타는 문자열인가 ? 오브젝트로 보내달라.\n // return JSON.parse(this.data.LOCALENAME)[getLocaleLanguage()]\n // }\n\n // return super.text\n // }\n\n // set text(text) {\n // super.text = text\n // }\n\n async detailInfo() {\n const { type, id } = this.state\n\n if (!id) {\n return\n }\n\n return await getPopupData(type, id)\n }\n}\n"]}
1
+ {"version":3,"file":"mcs-machine.js","sourceRoot":"","sources":["../src/mcs-machine.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ContainerAbstract } from '@hatiolab/things-scene'\nimport { getPopupData } from '@fmsim/api'\n\nimport { MCSStatusMixin, MCSStatusMixinProperties } from './features/mcs-status-mixin'\n\nimport { LEGEND_MACHINE, Legend } from './features/mcs-status-default'\nimport { boardLegendOfRow } from './features/legend-rows'\n\n/**\n * MCS Machine의 공통 속성을 정의한 최상위 오브젝트\n * - Container\n * -\n */\nexport default class MCSMachine extends MCSStatusMixin(ContainerAbstract) {\n static get properties(): any {\n return [\n ...MCSStatusMixinProperties,\n {\n type: 'number',\n name: 'round',\n label: 'round'\n }\n ]\n }\n\n get showMoveHandle() {\n return false\n }\n\n /**\n * id 후보를 조회할 때 백엔드에 보낼 타입명. 값이 있으면 검색(lookup) 대상.\n * 기본은 자기 타입. 자기 타입과 다른 타입으로 조회해야 하는 특수 케이스는 override.\n */\n get idLookupType(): string | undefined {\n return this.state.type\n }\n\n /** MCS 머신 — parentObject(부모 머신) 후보 수집 시 머신으로 식별. */\n get isMcsMachine(): boolean {\n return true\n }\n\n containable(component: Component) {\n return ['rect', 'ellipse'].includes(component.state.type)\n }\n\n get decorators() {\n return ['decotag']\n }\n\n getTheme() {\n const { legendName } = this.state\n\n if (legendName) {\n return (this.root as any)?.style?.[legendName]\n }\n }\n\n get hasTextProperty() {\n return true\n }\n\n get status() {\n return this.data?.STATUS\n }\n\n get auxStatus() {\n return this.data?.STATUS\n }\n\n get legend(): Legend {\n return this.getTheme() || boardLegendOfRow(this, this.statusLegendRow) || this.getLegendFallback()\n }\n\n /** The board legend row its STATUS colour follows when it chose no legend of its own (ADR-0167 decision 20); none here */\n get statusLegendRow(): string | undefined {\n return undefined\n }\n\n /** The board legend rows it follows: what the board's LEGENDS panel shows first */\n get legendRowsUsed(): string[] {\n return this.statusLegendRow ? [this.statusLegendRow] : []\n }\n\n get auxLegend() {\n return LEGEND_MACHINE\n }\n\n get auxColor() {\n return this.state.strokeStyle\n }\n\n getLegendFallback() {\n return LEGEND_MACHINE\n }\n\n /**\n * 2D 에서는 `state.alpha`(3D material 전용)를 무시한다. hidden/모델링 dim 흐림은 **코어(draw)가\n * 일괄 처리**하므로 여기서 손대지 않는다 (component-drawing.ts draw 가 prerender 직후 faint 적용).\n * fade 애니메이션은 보존. 3D 는 factory `updateAlpha()` 가 state.alpha 를 별도로 존중.\n */\n prerender(ctx: any) {\n super.prerender(ctx)\n ctx.globalAlpha = 1 - this._delta.fade\n }\n\n render(ctx) {\n var { round = 0, lineWidth } = this.state\n var { left, top, width, height } = this.bounds\n\n ctx.beginPath()\n\n ctx.strokeStyle = this.auxColor\n ctx.fillStyle = this.statusColor!\n ctx.lineWidth = lineWidth || 1\n ctx.lineCap = 'round'\n ctx.setLineDash([])\n\n if (round > 0) {\n ctx.roundRect(left, top, width, height, round)\n } else {\n ctx.rect(left, top, width, height)\n }\n\n ctx.fill()\n ctx.stroke()\n }\n\n // get text() {\n // if (this.data?.LOCALENAME) {\n // // TODO 왜 LOCALENAME 데이타는 문자열인가 ? 오브젝트로 보내달라.\n // return JSON.parse(this.data.LOCALENAME)[getLocaleLanguage()]\n // }\n\n // return super.text\n // }\n\n // set text(text) {\n // super.text = text\n // }\n\n async detailInfo() {\n const { type, id } = this.state\n\n if (!id) {\n return\n }\n\n return await getPopupData(type, id)\n }\n}\n"]}
package/dist/mcs-unit.js CHANGED
@@ -2,6 +2,7 @@ import { ContainerAbstract } from '@hatiolab/things-scene';
2
2
  import { getPopupData } from '@fmsim/api';
3
3
  import { MCSStatusMixin, MCSStatusMixinProperties } from './features/mcs-status-mixin';
4
4
  import { LEGEND_UNIT } from './features/mcs-status-default';
5
+ import { boardLegendOfRow } from './features/legend-rows';
5
6
  import { ParentObjectMixin, ParentObjectMixinProperties } from './features/parent-object-mixin';
6
7
  /**
7
8
  * MCS용 Unit들의 공통 속성을 정의한 오브젝트
@@ -42,7 +43,15 @@ export default class MCSUnit extends MCSStatusMixin(ParentObjectMixin(ContainerA
42
43
  return (_a = this.data) === null || _a === void 0 ? void 0 : _a.STATUS;
43
44
  }
44
45
  get legend() {
45
- return this.getTheme() || this.getLegendFallback();
46
+ return this.getTheme() || boardLegendOfRow(this, this.statusLegendRow) || this.getLegendFallback();
47
+ }
48
+ /** The board legend row its STATUS colour follows when it chose no legend of its own (ADR-0167 decision 20); none here */
49
+ get statusLegendRow() {
50
+ return undefined;
51
+ }
52
+ /** The board legend rows it follows: what the board's LEGENDS panel shows first */
53
+ get legendRowsUsed() {
54
+ return this.statusLegendRow ? [this.statusLegendRow] : [];
46
55
  }
47
56
  get auxLegend() {
48
57
  return this.legend;
@@ -1 +1 @@
1
- {"version":3,"file":"mcs-unit.js","sourceRoot":"","sources":["../src/mcs-unit.ts"],"names":[],"mappings":"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","sourcesContent":["import { ContainerAbstract } from '@hatiolab/things-scene'\nimport { getPopupData } from '@fmsim/api'\n\nimport { MCSStatusMixin, MCSStatusMixinProperties } from './features/mcs-status-mixin'\nimport { LEGEND_UNIT, Legend } from './features/mcs-status-default'\nimport { ParentObjectMixin, ParentObjectMixinProperties } from './features/parent-object-mixin'\n\n/**\n * MCS용 Unit들의 공통 속성을 정의한 오브젝트\n */\nexport default class MCSUnit extends MCSStatusMixin(ParentObjectMixin(ContainerAbstract)) {\n static get properties(): any {\n return [...MCSStatusMixinProperties, ...ParentObjectMixinProperties]\n }\n\n get showMoveHandle() {\n return false\n }\n\n /**\n * id 후보를 조회할 때 백엔드에 보낼 타입명. 값이 있으면 검색(lookup) 대상.\n * 기본은 자기 타입. 특수 케이스는 override.\n */\n get idLookupType(): string | undefined {\n return this.state.type\n }\n\n get hasTextProperty() {\n return true\n }\n\n get decorators() {\n return ['decotag']\n }\n\n getTheme() {\n const { legendName } = this.state\n\n if (legendName) {\n return (this.root as any)?.style?.[legendName]\n }\n }\n\n get status() {\n return this.data?.STATUS\n }\n\n get auxStatus() {\n return this.data?.STATUS\n }\n\n get legend(): Legend {\n return this.getTheme() || this.getLegendFallback()\n }\n\n get auxLegend() {\n return this.legend\n }\n\n getLegendFallback() {\n return LEGEND_UNIT\n }\n\n /**\n * 2D 에서는 state.alpha 무시. hidden/모델링 dim 흐림은 코어(draw)가 일괄 처리 (MCSMachine 동일).\n */\n prerender(ctx: any) {\n super.prerender(ctx)\n ctx.globalAlpha = 1 - this._delta.fade\n }\n\n contains(x, y) {\n var { left, top, width, height, lineWidth = 0 } = this.state\n var extend = lineWidth / 2\n\n return (\n x < Math.max(left + width, left) + extend &&\n x > Math.min(left + width, left) - extend &&\n y < Math.max(top + height, top) + extend &&\n y > Math.min(top + height, top) - extend\n )\n }\n\n set path(path) {\n var left_top = path[0]\n var right_bottom = path[2]\n\n this.set({\n left: left_top.x,\n top: left_top.y,\n width: right_bottom.x - left_top.x,\n height: right_bottom.y - left_top.y\n })\n }\n\n get path() {\n var { left = 0, top = 0, width = 0, height = 0 } = this.state\n\n return [\n {\n x: left,\n y: top\n },\n {\n x: left + width,\n y: top\n },\n {\n x: left + width,\n y: top + height\n },\n {\n x: left,\n y: top + height\n }\n ]\n }\n\n async detailInfo() {\n const { type, id } = this.state\n\n if (!id) {\n return\n }\n\n return await getPopupData(type, id)\n }\n}\n"]}
1
+ {"version":3,"file":"mcs-unit.js","sourceRoot":"","sources":["../src/mcs-unit.ts"],"names":[],"mappings":"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","sourcesContent":["import { ContainerAbstract } from '@hatiolab/things-scene'\nimport { getPopupData } from '@fmsim/api'\n\nimport { MCSStatusMixin, MCSStatusMixinProperties } from './features/mcs-status-mixin'\nimport { LEGEND_UNIT, Legend } from './features/mcs-status-default'\nimport { boardLegendOfRow } from './features/legend-rows'\nimport { ParentObjectMixin, ParentObjectMixinProperties } from './features/parent-object-mixin'\n\n/**\n * MCS용 Unit들의 공통 속성을 정의한 오브젝트\n */\nexport default class MCSUnit extends MCSStatusMixin(ParentObjectMixin(ContainerAbstract)) {\n static get properties(): any {\n return [...MCSStatusMixinProperties, ...ParentObjectMixinProperties]\n }\n\n get showMoveHandle() {\n return false\n }\n\n /**\n * id 후보를 조회할 때 백엔드에 보낼 타입명. 값이 있으면 검색(lookup) 대상.\n * 기본은 자기 타입. 특수 케이스는 override.\n */\n get idLookupType(): string | undefined {\n return this.state.type\n }\n\n get hasTextProperty() {\n return true\n }\n\n get decorators() {\n return ['decotag']\n }\n\n getTheme() {\n const { legendName } = this.state\n\n if (legendName) {\n return (this.root as any)?.style?.[legendName]\n }\n }\n\n get status() {\n return this.data?.STATUS\n }\n\n get auxStatus() {\n return this.data?.STATUS\n }\n\n get legend(): Legend {\n return this.getTheme() || boardLegendOfRow(this, this.statusLegendRow) || this.getLegendFallback()\n }\n\n /** The board legend row its STATUS colour follows when it chose no legend of its own (ADR-0167 decision 20); none here */\n get statusLegendRow(): string | undefined {\n return undefined\n }\n\n /** The board legend rows it follows: what the board's LEGENDS panel shows first */\n get legendRowsUsed(): string[] {\n return this.statusLegendRow ? [this.statusLegendRow] : []\n }\n\n get auxLegend() {\n return this.legend\n }\n\n getLegendFallback() {\n return LEGEND_UNIT\n }\n\n /**\n * 2D 에서는 state.alpha 무시. hidden/모델링 dim 흐림은 코어(draw)가 일괄 처리 (MCSMachine 동일).\n */\n prerender(ctx: any) {\n super.prerender(ctx)\n ctx.globalAlpha = 1 - this._delta.fade\n }\n\n contains(x, y) {\n var { left, top, width, height, lineWidth = 0 } = this.state\n var extend = lineWidth / 2\n\n return (\n x < Math.max(left + width, left) + extend &&\n x > Math.min(left + width, left) - extend &&\n y < Math.max(top + height, top) + extend &&\n y > Math.min(top + height, top) - extend\n )\n }\n\n set path(path) {\n var left_top = path[0]\n var right_bottom = path[2]\n\n this.set({\n left: left_top.x,\n top: left_top.y,\n width: right_bottom.x - left_top.x,\n height: right_bottom.y - left_top.y\n })\n }\n\n get path() {\n var { left = 0, top = 0, width = 0, height = 0 } = this.state\n\n return [\n {\n x: left,\n y: top\n },\n {\n x: left + width,\n y: top\n },\n {\n x: left + width,\n y: top + height\n },\n {\n x: left,\n y: top + height\n }\n ]\n }\n\n async detailInfo() {\n const { type, id } = this.state\n\n if (!id) {\n return\n }\n\n return await getPopupData(type, id)\n }\n}\n"]}
@@ -1,24 +1,11 @@
1
1
  import { LEGEND_VEHICLE } from './features/mcs-status-default';
2
+ import { VehicleTravel } from './features/vehicle-travel';
2
3
  import MCSCarrierHolder from './mcs-carrier-holder';
3
4
  const DIRECTION_GAP = 3;
4
- function findNode(vehicle, nodeId, nodeMachine) {
5
- var _a, _b;
6
- if (!nodeId || !nodeMachine) {
7
- return null;
8
- }
9
- const nodes = (((_b = (_a = vehicle.root).findAllById) === null || _b === void 0 ? void 0 : _b.call(_a, nodeId)) || []).filter(node => node.state.type == 'Node');
10
- return nodes.find((node) => {
11
- return node.nodeMachine === nodeMachine;
12
- });
13
- }
14
5
  /**
15
6
  * MCS용 Unit > Transport들의 공통 속성을 정의한 오브젝트
16
7
  */
17
- export default class MCSVehicle extends MCSCarrierHolder {
18
- constructor() {
19
- super(...arguments);
20
- this.lastWaypoint = null;
21
- }
8
+ export default class MCSVehicle extends VehicleTravel(MCSCarrierHolder) {
22
9
  static get properties() {
23
10
  return [
24
11
  ...MCSCarrierHolder.properties,
@@ -80,50 +67,5 @@ export default class MCSVehicle extends MCSCarrierHolder {
80
67
  super.postrender(ctx);
81
68
  // this.renderDirection(ctx)
82
69
  }
83
- onchangeData(after, before) {
84
- super.onchangeData(after, before);
85
- const { NODEID: beforeNodeId, NODEMACHINE: beforeNodeMachine } = before.data || {};
86
- const { NODEID: NodeId, NODEMACHINE: NodeMachine } = after.data || {};
87
- if (NodeId === undefined ||
88
- NodeMachine === undefined ||
89
- (beforeNodeId === NodeId && beforeNodeMachine === NodeMachine) ||
90
- (this.lastWaypoint && this.lastWaypoint.NodeId === NodeId && this.lastWaypoint.NodeMachine === NodeMachine)) {
91
- return; // not changed
92
- }
93
- const afterNode = findNode(this, NodeId, NodeMachine);
94
- if (!afterNode) {
95
- // 보드는 전체 노드의 부분 뷰 — 모든 노드를 그리지 않는다. 위치 NODEID 가 이 보드에
96
- // 없는 노드를 가리키는 건 오류가 아니라 정상(그 노드는 이 보드에 미표시)이므로,
97
- // 경고 없이 조용히 배치를 생략한다. (데이터 갱신마다 도는 hot path — 거짓 경보 방지.)
98
- return;
99
- }
100
- const beforeNode = this.lastWaypoint
101
- ? findNode(this, this.lastWaypoint.NodeId, this.lastWaypoint.NodeMachine)
102
- : afterNode;
103
- // 실제 존재하는 노드 중 가장 최근에 이동한 노드
104
- this.lastWaypoint = { NodeId, NodeMachine };
105
- if (this.root.vehicleAnimation) {
106
- this.trigger('waypoint', {
107
- from: beforeNode || afterNode,
108
- to: afterNode,
109
- duration: 5000
110
- });
111
- }
112
- else if (beforeNode) {
113
- const fromCenter = beforeNode.center;
114
- const toCenter = afterNode.center;
115
- const { x: startX, y: startY } = beforeNode.transcoordS2T(fromCenter.x, fromCenter.y);
116
- const { x: endX, y: endY } = afterNode.transcoordS2T(toCenter.x, toCenter.y);
117
- const theta = Math.atan2(endY - startY, endX - startX) + Math.PI / 2;
118
- this.location = { x: endX, y: endY };
119
- this.setState('rotation', theta);
120
- }
121
- else {
122
- // beforeNode 없음: afterNode 위치로 즉시 이동
123
- const toCenter = afterNode.center;
124
- const { x, y } = afterNode.transcoordS2T(toCenter.x, toCenter.y);
125
- this.location = { x, y };
126
- }
127
- }
128
70
  }
129
71
  //# sourceMappingURL=mcs-vehicle.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcs-vehicle.js","sourceRoot":"","sources":["../src/mcs-vehicle.ts"],"names":[],"mappings":"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","sourcesContent":["import { LEGEND_VEHICLE, Legend } from './features/mcs-status-default'\nimport MCSCarrierHolder from './mcs-carrier-holder'\nimport Node from './node'\n\nconst DIRECTION_GAP = 3\n\nfunction findNode(vehicle: MCSVehicle, nodeId: string, nodeMachine: string) {\n if (!nodeId || !nodeMachine) {\n return null\n }\n\n const nodes = (vehicle.root.findAllById?.(nodeId) || []).filter(node => node.state.type == 'Node') as Node[]\n\n return nodes.find((node: Node) => {\n return node.nodeMachine === nodeMachine\n })\n}\n\n/**\n * MCS용 Unit > Transport들의 공통 속성을 정의한 오브젝트\n */\nexport default class MCSVehicle extends MCSCarrierHolder {\n static get properties(): any {\n return [\n ...MCSCarrierHolder.properties,\n {\n type: 'select',\n label: 'direction',\n name: 'direction',\n property: {\n options: ['', 'up', 'down', 'left', 'right']\n }\n }\n ]\n }\n\n private lastWaypoint: { NodeId: string; NodeMachine: string } | null = null\n\n getLegendFallback(): Legend {\n return LEGEND_VEHICLE\n }\n\n renderDirection(ctx: CanvasRenderingContext2D) {\n const { direction } = this.state\n\n if (direction) {\n const { left, top, width, height } = this.state\n\n ctx.beginPath()\n ctx.translate(left, top)\n\n ctx.strokeStyle = 'black'\n ctx.fillStyle = 'black'\n ctx.lineJoin = 'round'\n ctx.lineWidth = 1\n ctx.setLineDash([])\n\n switch (direction) {\n case 'up':\n ctx.moveTo((width * 1) / 3, -DIRECTION_GAP)\n ctx.lineTo(width / 2, -height / 10 - DIRECTION_GAP)\n ctx.lineTo((width * 2) / 3, -DIRECTION_GAP)\n break\n case 'down':\n ctx.moveTo((width * 1) / 3, height + DIRECTION_GAP)\n ctx.lineTo(width / 2, height + height / 10 + DIRECTION_GAP)\n ctx.lineTo((width * 2) / 3, height + DIRECTION_GAP)\n break\n case 'left':\n ctx.moveTo(-DIRECTION_GAP, (height * 1) / 3)\n ctx.lineTo(-width / 10 - 2, height / 2)\n ctx.lineTo(-DIRECTION_GAP, (height * 2) / 3)\n break\n case 'right':\n default:\n ctx.moveTo(DIRECTION_GAP + width, (height * 1) / 3)\n ctx.lineTo(DIRECTION_GAP + width + width / 10, height / 2)\n ctx.lineTo(DIRECTION_GAP + width, (height * 2) / 3)\n break\n }\n\n ctx.translate(-left, -top)\n ctx.closePath()\n\n ctx.fill()\n ctx.stroke()\n }\n }\n\n // Performance aware\n postrender(ctx: CanvasRenderingContext2D): void {\n super.postrender(ctx)\n // this.renderDirection(ctx)\n }\n\n onchangeData(after: Record<string, any>, before: Record<string, any>): void {\n super.onchangeData(after, before)\n\n const { NODEID: beforeNodeId, NODEMACHINE: beforeNodeMachine } = before.data || {}\n const { NODEID: NodeId, NODEMACHINE: NodeMachine } = after.data || {}\n\n if (\n NodeId === undefined ||\n NodeMachine === undefined ||\n (beforeNodeId === NodeId && beforeNodeMachine === NodeMachine) ||\n (this.lastWaypoint && this.lastWaypoint.NodeId === NodeId && this.lastWaypoint.NodeMachine === NodeMachine)\n ) {\n return // not changed\n }\n\n const afterNode = findNode(this, NodeId, NodeMachine)\n if (!afterNode) {\n // 보드는 전체 노드의 부분 뷰 — 모든 노드를 그리지 않는다. 위치 NODEID 가 이 보드에\n // 없는 노드를 가리키는 건 오류가 아니라 정상(그 노드는 이 보드에 미표시)이므로,\n // 경고 없이 조용히 배치를 생략한다. (데이터 갱신마다 도는 hot path — 거짓 경보 방지.)\n return\n }\n\n const beforeNode = this.lastWaypoint\n ? findNode(this, this.lastWaypoint.NodeId, this.lastWaypoint.NodeMachine)\n : afterNode\n\n // 실제 존재하는 노드 중 가장 최근에 이동한 노드\n this.lastWaypoint = { NodeId, NodeMachine }\n\n if ((this.root as any).vehicleAnimation) {\n this.trigger('waypoint', {\n from: beforeNode || afterNode,\n to: afterNode,\n duration: 5000\n })\n } else if (beforeNode) {\n const fromCenter = beforeNode.center\n const toCenter = afterNode.center\n\n const { x: startX, y: startY } = beforeNode.transcoordS2T(fromCenter.x, fromCenter.y)\n const { x: endX, y: endY } = afterNode.transcoordS2T(toCenter.x, toCenter.y)\n\n const theta = Math.atan2(endY - startY, endX - startX) + Math.PI / 2\n\n this.location = { x: endX, y: endY }\n this.setState('rotation', theta)\n } else {\n // beforeNode 없음: afterNode 위치로 즉시 이동\n const toCenter = afterNode.center\n const { x, y } = afterNode.transcoordS2T(toCenter.x, toCenter.y)\n this.location = { x, y }\n }\n }\n}\n"]}
1
+ {"version":3,"file":"mcs-vehicle.js","sourceRoot":"","sources":["../src/mcs-vehicle.ts"],"names":[],"mappings":"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","sourcesContent":["import { LEGEND_VEHICLE, Legend } from './features/mcs-status-default'\nimport { VehicleTravel } from './features/vehicle-travel'\nimport MCSCarrierHolder from './mcs-carrier-holder'\n\nconst DIRECTION_GAP = 3\n\n/**\n * MCS용 Unit > Transport들의 공통 속성을 정의한 오브젝트\n */\nexport default class MCSVehicle extends VehicleTravel(MCSCarrierHolder) {\n static get properties(): any {\n return [\n ...MCSCarrierHolder.properties,\n {\n type: 'select',\n label: 'direction',\n name: 'direction',\n property: {\n options: ['', 'up', 'down', 'left', 'right']\n }\n }\n ]\n }\n\n getLegendFallback(): Legend {\n return LEGEND_VEHICLE\n }\n\n renderDirection(ctx: CanvasRenderingContext2D) {\n const { direction } = this.state\n\n if (direction) {\n const { left, top, width, height } = this.state\n\n ctx.beginPath()\n ctx.translate(left, top)\n\n ctx.strokeStyle = 'black'\n ctx.fillStyle = 'black'\n ctx.lineJoin = 'round'\n ctx.lineWidth = 1\n ctx.setLineDash([])\n\n switch (direction) {\n case 'up':\n ctx.moveTo((width * 1) / 3, -DIRECTION_GAP)\n ctx.lineTo(width / 2, -height / 10 - DIRECTION_GAP)\n ctx.lineTo((width * 2) / 3, -DIRECTION_GAP)\n break\n case 'down':\n ctx.moveTo((width * 1) / 3, height + DIRECTION_GAP)\n ctx.lineTo(width / 2, height + height / 10 + DIRECTION_GAP)\n ctx.lineTo((width * 2) / 3, height + DIRECTION_GAP)\n break\n case 'left':\n ctx.moveTo(-DIRECTION_GAP, (height * 1) / 3)\n ctx.lineTo(-width / 10 - 2, height / 2)\n ctx.lineTo(-DIRECTION_GAP, (height * 2) / 3)\n break\n case 'right':\n default:\n ctx.moveTo(DIRECTION_GAP + width, (height * 1) / 3)\n ctx.lineTo(DIRECTION_GAP + width + width / 10, height / 2)\n ctx.lineTo(DIRECTION_GAP + width, (height * 2) / 3)\n break\n }\n\n ctx.translate(-left, -top)\n ctx.closePath()\n\n ctx.fill()\n ctx.stroke()\n }\n }\n\n // Performance aware\n postrender(ctx: CanvasRenderingContext2D): void {\n super.postrender(ctx)\n // this.renderDirection(ctx)\n }\n}\n\n"]}
package/dist/oht-line.js CHANGED
@@ -5,7 +5,11 @@ const NATURE = {
5
5
  mutable: false,
6
6
  resizable: true,
7
7
  rotatable: true,
8
- properties: [...MCSTransport.properties]
8
+ properties: [
9
+ ...MCSTransport.properties,
10
+ /* 레일 윗면이 작업환경 천장에서 내려온 길이(mm). 레일과 그 위를 다니는 OHT 가 천장을 따라 움직인다 */
11
+ { type: 'number', label: 'rail-hang', name: 'railHang', property: { min: 0, step: 100 } }
12
+ ]
9
13
  };
10
14
  let OHTLine = class OHTLine extends MCSTransport {
11
15
  static get nature() {
@@ -14,8 +18,8 @@ let OHTLine = class OHTLine extends MCSTransport {
14
18
  get auxColor() {
15
19
  return '#333';
16
20
  }
17
- getLegendFallback() {
18
- return this.root.ohtlineLegendTheme || super.getLegendFallback();
21
+ get statusLegendRow() {
22
+ return 'ohtline';
19
23
  }
20
24
  containable(component) {
21
25
  return ['OHT', 'Node'].includes(component.state.type);
@@ -1 +1 @@
1
- {"version":3,"file":"oht-line.js","sourceRoot":"","sources":["../src/oht-line.ts"],"names":[],"mappings":";AAAA,OAAO,EAA8B,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACnF,OAAO,YAAY,MAAM,iBAAiB,CAAA;AAE1C,MAAM,MAAM,GAAoB;IAC9B,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,UAAU,EAAE,CAAC,GAAG,YAAY,CAAC,UAAU,CAAC;CACzC,CAAA;AAGc,IAAM,OAAO,GAAb,MAAM,OAAQ,SAAQ,YAAY;IAC/C,MAAM,KAAK,MAAM;QACf,OAAO,MAAM,CAAA;IACf,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,MAAM,CAAA;IACf,CAAC;IAED,iBAAiB;QACf,OAAQ,IAAI,CAAC,IAAY,CAAC,kBAAkB,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAA;IAC3E,CAAC;IAED,WAAW,CAAC,SAAoB;QAC9B,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACvD,CAAC;IAED,MAAM,CAAC,OAAiC;QACtC,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAA;QAEhD,OAAO,CAAC,SAAS,EAAE,CAAA;QAEnB,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAE5B,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,WAAY,CAAA;QACrC,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,QAAS,CAAA;QAEpC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;QAErC,OAAO,CAAC,IAAI,EAAE,CAAA;QACd,OAAO,CAAC,MAAM,EAAE,CAAA;QAEhB,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAA;IAChC,CAAC;CACF,CAAA;AAlCoB,OAAO;IAD3B,cAAc,CAAC,SAAS,CAAC;GACL,OAAO,CAkC3B;eAlCoB,OAAO","sourcesContent":["import { Component, ComponentNature, sceneComponent } from '@hatiolab/things-scene'\nimport MCSTransport from './mcs-transport'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [...MCSTransport.properties]\n}\n\n@sceneComponent('OHTLine')\nexport default class OHTLine extends MCSTransport {\n static get nature() {\n return NATURE\n }\n\n get auxColor() {\n return '#333'\n }\n\n getLegendFallback() {\n return (this.root as any).ohtlineLegendTheme || super.getLegendFallback()\n }\n\n containable(component: Component) {\n return ['OHT', 'Node'].includes(component.state.type)\n }\n\n render(context: CanvasRenderingContext2D) {\n const { left, top, width, height } = this.bounds\n\n context.beginPath()\n\n context.translate(left, top)\n\n context.fillStyle = this.statusColor!\n context.strokeStyle = this.auxColor!\n\n context.fillRect(0, 0, width, height)\n\n context.fill()\n context.stroke()\n\n context.translate(-left, -top)\n }\n}\n"]}
1
+ {"version":3,"file":"oht-line.js","sourceRoot":"","sources":["../src/oht-line.ts"],"names":[],"mappings":";AAAA,OAAO,EAA8B,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACnF,OAAO,YAAY,MAAM,iBAAiB,CAAA;AAE1C,MAAM,MAAM,GAAoB;IAC9B,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,UAAU,EAAE;QACV,GAAG,YAAY,CAAC,UAAU;QAC1B,iEAAiE;QACjE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;KAC1F;CACF,CAAA;AAGc,IAAM,OAAO,GAAb,MAAM,OAAQ,SAAQ,YAAY;IAC/C,MAAM,KAAK,MAAM;QACf,OAAO,MAAM,CAAA;IACf,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,MAAM,CAAA;IACf,CAAC;IAED,IAAI,eAAe;QACjB,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,WAAW,CAAC,SAAoB;QAC9B,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACvD,CAAC;IAED,MAAM,CAAC,OAAiC;QACtC,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAA;QAEhD,OAAO,CAAC,SAAS,EAAE,CAAA;QAEnB,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAE5B,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,WAAY,CAAA;QACrC,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,QAAS,CAAA;QAEpC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;QAErC,OAAO,CAAC,IAAI,EAAE,CAAA;QACd,OAAO,CAAC,MAAM,EAAE,CAAA;QAEhB,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAA;IAChC,CAAC;CACF,CAAA;AAlCoB,OAAO;IAD3B,cAAc,CAAC,SAAS,CAAC;GACL,OAAO,CAkC3B;eAlCoB,OAAO","sourcesContent":["import { Component, ComponentNature, sceneComponent } from '@hatiolab/things-scene'\nimport MCSTransport from './mcs-transport'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n ...MCSTransport.properties,\n /* 레일 윗면이 작업환경 천장에서 내려온 길이(mm). 레일과 그 위를 다니는 OHT 가 천장을 따라 움직인다 */\n { type: 'number', label: 'rail-hang', name: 'railHang', property: { min: 0, step: 100 } }\n ]\n}\n\n@sceneComponent('OHTLine')\nexport default class OHTLine extends MCSTransport {\n static get nature() {\n return NATURE\n }\n\n get auxColor() {\n return '#333'\n }\n\n get statusLegendRow(): string {\n return 'ohtline'\n }\n\n containable(component: Component) {\n return ['OHT', 'Node'].includes(component.state.type)\n }\n\n render(context: CanvasRenderingContext2D) {\n const { left, top, width, height } = this.bounds\n\n context.beginPath()\n\n context.translate(left, top)\n\n context.fillStyle = this.statusColor!\n context.strokeStyle = this.auxColor!\n\n context.fillRect(0, 0, width, height)\n\n context.fill()\n context.stroke()\n\n context.translate(-left, -top)\n }\n}\n"]}
package/dist/oht.js CHANGED
@@ -23,8 +23,8 @@ let OHT = class OHT extends MCSVehicle {
23
23
  get parentObjectTypes() {
24
24
  return ['OHTLine'];
25
25
  }
26
- getLegendFallback() {
27
- return this.root.ohtLegendTheme || super.getLegendFallback();
26
+ get statusLegendRow() {
27
+ return 'oht';
28
28
  }
29
29
  render(ctx) {
30
30
  var { left, top, width, height } = this.bounds;
package/dist/oht.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"oht.js","sourceRoot":"","sources":["../src/oht.ts"],"names":[],"mappings":";AAAA,OAAO,EAA8B,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACnF,OAAO,UAAU,MAAM,eAAe,CAAA;AAEtC,MAAM,MAAM,GAAoB;IAC9B,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,UAAU,EAAE,CAAC,GAAG,UAAU,CAAC,UAAU,CAAC;CACvC,CAAA;AAED,MAAM,GAAG,GAAG,CAAC,CAAA;AAGE,IAAM,GAAG,GAAT,MAAM,GAAI,SAAQ,UAAU;IACzC,MAAM,KAAK,MAAM;QACf,OAAO,MAAM,CAAA;IACf,CAAC;IAED,qEAAqE;IACrE,IAAI,WAAW;QACb,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;IACrC,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,oCAAoC;IACpC,IAAI,iBAAiB;QACnB,OAAO,CAAC,SAAS,CAAC,CAAA;IACpB,CAAC;IAED,iBAAiB;QACf,OAAQ,IAAI,CAAC,IAAY,CAAC,cAAc,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAA;IACvE,CAAC;IAED,MAAM,CAAC,GAA6B;QAClC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAA;QAE9C,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QACxB,GAAG,CAAC,SAAS,EAAE,CAAA;QAEf,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAA;QAC/B,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,WAAY,CAAA;QACjC,GAAG,CAAC,SAAS,GAAG,CAAC,CAAA;QACjB,GAAG,CAAC,OAAO,GAAG,OAAO,CAAA;QACrB,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;QAEnB,oBAAoB;QACpB,2DAA2D;QAC3D,6CAA6C;QAC7C,yEAAyE;QACzE,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;QAC7B,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,GAAG,GAAG,GAAG,CAAC,EAAE,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,CAAA;QAErD,GAAG,CAAC,IAAI,EAAE,CAAA;QACV,GAAG,CAAC,MAAM,EAAE,CAAA;QAEZ,GAAG,CAAC,SAAS,EAAE,CAAA;QAEf,GAAG,CAAC,OAAO,GAAG,MAAM,CAAA;QACpB,GAAG,CAAC,WAAW,GAAG,OAAO,CAAA;QACzB,GAAG,CAAC,SAAS,GAAG,CAAC,CAAA;QACjB,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAA;QAC9B,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,CAAA;QAEvC,GAAG,CAAC,MAAM,EAAE,CAAA;QAEZ,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC;CACF,CAAA;AAzDoB,GAAG;IADvB,cAAc,CAAC,KAAK,CAAC;GACD,GAAG,CAyDvB;eAzDoB,GAAG","sourcesContent":["import { Component, ComponentNature, sceneComponent } from '@hatiolab/things-scene'\nimport MCSVehicle from './mcs-vehicle'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [...MCSVehicle.properties]\n}\n\nconst GAP = 2\n\n@sceneComponent('OHT')\nexport default class OHT extends MCSVehicle {\n static get nature() {\n return NATURE\n }\n\n /** Carriers hang below the OHT's bottom, the gripper's (fmsim v2) */\n get carrierRest(): { height: number; mount: 'ON' | 'HANG' } {\n return { height: 0, mount: 'HANG' }\n }\n\n get auxColor() {\n return 'black'\n }\n\n /** OHT 의 parentObject 는 OHTLine. */\n get parentObjectTypes(): string[] {\n return ['OHTLine']\n }\n\n getLegendFallback() {\n return (this.root as any).ohtLegendTheme || super.getLegendFallback()\n }\n\n render(ctx: CanvasRenderingContext2D) {\n var { left, top, width, height } = this.bounds\n\n ctx.translate(left, top)\n ctx.beginPath()\n\n ctx.strokeStyle = this.auxColor\n ctx.fillStyle = this.statusColor!\n ctx.lineWidth = 1\n ctx.lineCap = 'round'\n ctx.setLineDash([])\n\n // Performance aware\n // const radius = Math.round(Math.min(width, height) * 0.1)\n // ctx.roundRect(0, 0, width, height, radius)\n // ctx.roundRect(GAP, GAP, width - GAP * 2, height - GAP * 2, radius - 1)\n ctx.rect(0, 0, width, height)\n ctx.rect(GAP, GAP, width - GAP * 2, height - GAP * 2)\n\n ctx.fill()\n ctx.stroke()\n\n ctx.beginPath()\n\n ctx.lineCap = 'butt'\n ctx.strokeStyle = 'black'\n ctx.lineWidth = 3\n ctx.moveTo(width / 2, GAP * 2)\n ctx.lineTo(width / 2, height - GAP * 2)\n\n ctx.stroke()\n\n ctx.translate(-left, -top)\n }\n}\n"]}
1
+ {"version":3,"file":"oht.js","sourceRoot":"","sources":["../src/oht.ts"],"names":[],"mappings":";AAAA,OAAO,EAA8B,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACnF,OAAO,UAAU,MAAM,eAAe,CAAA;AAEtC,MAAM,MAAM,GAAoB;IAC9B,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,UAAU,EAAE,CAAC,GAAG,UAAU,CAAC,UAAU,CAAC;CACvC,CAAA;AAED,MAAM,GAAG,GAAG,CAAC,CAAA;AAGE,IAAM,GAAG,GAAT,MAAM,GAAI,SAAQ,UAAU;IACzC,MAAM,KAAK,MAAM;QACf,OAAO,MAAM,CAAA;IACf,CAAC;IAED,qEAAqE;IACrE,IAAI,WAAW;QACb,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;IACrC,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,oCAAoC;IACpC,IAAI,iBAAiB;QACnB,OAAO,CAAC,SAAS,CAAC,CAAA;IACpB,CAAC;IAED,IAAI,eAAe;QACjB,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,CAAC,GAA6B;QAClC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAA;QAE9C,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QACxB,GAAG,CAAC,SAAS,EAAE,CAAA;QAEf,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAA;QAC/B,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,WAAY,CAAA;QACjC,GAAG,CAAC,SAAS,GAAG,CAAC,CAAA;QACjB,GAAG,CAAC,OAAO,GAAG,OAAO,CAAA;QACrB,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;QAEnB,oBAAoB;QACpB,2DAA2D;QAC3D,6CAA6C;QAC7C,yEAAyE;QACzE,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;QAC7B,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,GAAG,GAAG,GAAG,CAAC,EAAE,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,CAAA;QAErD,GAAG,CAAC,IAAI,EAAE,CAAA;QACV,GAAG,CAAC,MAAM,EAAE,CAAA;QAEZ,GAAG,CAAC,SAAS,EAAE,CAAA;QAEf,GAAG,CAAC,OAAO,GAAG,MAAM,CAAA;QACpB,GAAG,CAAC,WAAW,GAAG,OAAO,CAAA;QACzB,GAAG,CAAC,SAAS,GAAG,CAAC,CAAA;QACjB,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAA;QAC9B,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,CAAA;QAEvC,GAAG,CAAC,MAAM,EAAE,CAAA;QAEZ,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC;CACF,CAAA;AAzDoB,GAAG;IADvB,cAAc,CAAC,KAAK,CAAC;GACD,GAAG,CAyDvB;eAzDoB,GAAG","sourcesContent":["import { Component, ComponentNature, sceneComponent } from '@hatiolab/things-scene'\nimport MCSVehicle from './mcs-vehicle'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [...MCSVehicle.properties]\n}\n\nconst GAP = 2\n\n@sceneComponent('OHT')\nexport default class OHT extends MCSVehicle {\n static get nature() {\n return NATURE\n }\n\n /** Carriers hang below the OHT's bottom, the gripper's (fmsim v2) */\n get carrierRest(): { height: number; mount: 'ON' | 'HANG' } {\n return { height: 0, mount: 'HANG' }\n }\n\n get auxColor() {\n return 'black'\n }\n\n /** OHT 의 parentObject 는 OHTLine. */\n get parentObjectTypes(): string[] {\n return ['OHTLine']\n }\n\n get statusLegendRow(): string {\n return 'oht'\n }\n\n render(ctx: CanvasRenderingContext2D) {\n var { left, top, width, height } = this.bounds\n\n ctx.translate(left, top)\n ctx.beginPath()\n\n ctx.strokeStyle = this.auxColor\n ctx.fillStyle = this.statusColor!\n ctx.lineWidth = 1\n ctx.lineCap = 'round'\n ctx.setLineDash([])\n\n // Performance aware\n // const radius = Math.round(Math.min(width, height) * 0.1)\n // ctx.roundRect(0, 0, width, height, radius)\n // ctx.roundRect(GAP, GAP, width - GAP * 2, height - GAP * 2, radius - 1)\n ctx.rect(0, 0, width, height)\n ctx.rect(GAP, GAP, width - GAP * 2, height - GAP * 2)\n\n ctx.fill()\n ctx.stroke()\n\n ctx.beginPath()\n\n ctx.lineCap = 'butt'\n ctx.strokeStyle = 'black'\n ctx.lineWidth = 3\n ctx.moveTo(width / 2, GAP * 2)\n ctx.lineTo(width / 2, height - GAP * 2)\n\n ctx.stroke()\n\n ctx.translate(-left, -top)\n }\n}\n"]}
package/dist/port.js CHANGED
@@ -20,8 +20,8 @@ let Port = class Port extends LoadLayoutHolder(MCSZoneMixin(MCSCarrierHolder)) {
20
20
  get auxColor() {
21
21
  return 'black';
22
22
  }
23
- getLegendFallback() {
24
- return this.root.portLegendTheme || super.getLegendFallback();
23
+ get statusLegendRow() {
24
+ return 'port';
25
25
  }
26
26
  /** Port 는 후보가 매우 많아 부모 머신 없이는 id 리스트를 조회하지 않는다 (machine 필수). */
27
27
  get idLookupRequiresMachine() {
package/dist/port.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"port.js","sourceRoot":"","sources":["../src/port.ts"],"names":[],"mappings":";AAAA,OAAO,EAA8B,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACnF,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAA;AAChF,OAAO,gBAAgB,MAAM,sBAAsB,CAAA;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAEhE,MAAM,MAAM,GAAoB;IAC9B,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,UAAU,EAAE,CAAC,GAAG,sBAAsB,EAAE,GAAG,gBAAgB,CAAC,UAAU,CAAC;CACxE,CAAA;AAGc,IAAM,IAAI,GAAV,MAAM,IAAK,SAAQ,gBAAgB,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC;IAChF,MAAM,KAAK,MAAM;QACf,OAAO,MAAM,CAAA;IACf,CAAC;IAED,qDAAqD;IACrD,IAAI,WAAW;QACb,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;IACnC,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,iBAAiB;QACf,OAAQ,IAAI,CAAC,IAAY,CAAC,eAAe,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAA;IACxE,CAAC;IAED,gEAAgE;IAChE,IAAI,uBAAuB;QACzB,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,CAAC,GAA6B;QAClC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAA;QAE9C,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAA;QAC/B,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,WAAY,CAAA;QACjC,GAAG,CAAC,SAAS,GAAG,CAAC,CAAA;QACjB,GAAG,CAAC,OAAO,GAAG,OAAO,CAAA;QACrB,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;QAEnB,GAAG,CAAC,SAAS,EAAE,CAAA;QAEf,oBAAoB;QACpB,2DAA2D;QAC3D,kDAAkD;QAClD,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;QAElC,GAAG,CAAC,IAAI,EAAE,CAAA;QACV,GAAG,CAAC,MAAM,EAAE,CAAA;IACd,CAAC;CACF,CAAA;AA1CoB,IAAI;IADxB,cAAc,CAAC,MAAM,CAAC;GACF,IAAI,CA0CxB;eA1CoB,IAAI","sourcesContent":["import { Component, ComponentNature, sceneComponent } from '@hatiolab/things-scene'\nimport { MCSZoneMixin, MCSZoneMixinProperties } from './features/mcs-zone-mixin'\nimport MCSCarrierHolder from './mcs-carrier-holder'\nimport { LoadLayoutHolder } from './features/load-layout-holder'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [...MCSZoneMixinProperties, ...MCSCarrierHolder.properties]\n}\n\n@sceneComponent('Port')\nexport default class Port extends LoadLayoutHolder(MCSZoneMixin(MCSCarrierHolder)) {\n static get nature() {\n return NATURE\n }\n\n /** Carriers stand at the Port's bottom (fmsim v2) */\n get carrierRest(): { height: number; mount: 'ON' | 'HANG' } {\n return { height: 0, mount: 'ON' }\n }\n\n get auxColor() {\n return 'black'\n }\n\n getLegendFallback() {\n return (this.root as any).portLegendTheme || super.getLegendFallback()\n }\n\n /** Port 는 후보가 매우 많아 부모 머신 없이는 id 리스트를 조회하지 않는다 (machine 필수). */\n get idLookupRequiresMachine() {\n return true\n }\n\n render(ctx: CanvasRenderingContext2D) {\n var { left, top, width, height } = this.bounds\n\n ctx.strokeStyle = this.auxColor\n ctx.fillStyle = this.statusColor!\n ctx.lineWidth = 1\n ctx.lineCap = 'round'\n ctx.setLineDash([])\n\n ctx.beginPath()\n\n // Performance aware\n // const radius = Math.round(Math.min(width, height) * 0.1)\n // ctx.roundRect(left, top, width, height, radius)\n ctx.rect(left, top, width, height)\n\n ctx.fill()\n ctx.stroke()\n }\n}\n"]}
1
+ {"version":3,"file":"port.js","sourceRoot":"","sources":["../src/port.ts"],"names":[],"mappings":";AAAA,OAAO,EAA8B,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACnF,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAA;AAChF,OAAO,gBAAgB,MAAM,sBAAsB,CAAA;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAEhE,MAAM,MAAM,GAAoB;IAC9B,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,UAAU,EAAE,CAAC,GAAG,sBAAsB,EAAE,GAAG,gBAAgB,CAAC,UAAU,CAAC;CACxE,CAAA;AAGc,IAAM,IAAI,GAAV,MAAM,IAAK,SAAQ,gBAAgB,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC;IAChF,MAAM,KAAK,MAAM;QACf,OAAO,MAAM,CAAA;IACf,CAAC;IAED,qDAAqD;IACrD,IAAI,WAAW;QACb,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;IACnC,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,IAAI,eAAe;QACjB,OAAO,MAAM,CAAA;IACf,CAAC;IAED,gEAAgE;IAChE,IAAI,uBAAuB;QACzB,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,CAAC,GAA6B;QAClC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAA;QAE9C,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAA;QAC/B,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,WAAY,CAAA;QACjC,GAAG,CAAC,SAAS,GAAG,CAAC,CAAA;QACjB,GAAG,CAAC,OAAO,GAAG,OAAO,CAAA;QACrB,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;QAEnB,GAAG,CAAC,SAAS,EAAE,CAAA;QAEf,oBAAoB;QACpB,2DAA2D;QAC3D,kDAAkD;QAClD,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;QAElC,GAAG,CAAC,IAAI,EAAE,CAAA;QACV,GAAG,CAAC,MAAM,EAAE,CAAA;IACd,CAAC;CACF,CAAA;AA1CoB,IAAI;IADxB,cAAc,CAAC,MAAM,CAAC;GACF,IAAI,CA0CxB;eA1CoB,IAAI","sourcesContent":["import { Component, ComponentNature, sceneComponent } from '@hatiolab/things-scene'\nimport { MCSZoneMixin, MCSZoneMixinProperties } from './features/mcs-zone-mixin'\nimport MCSCarrierHolder from './mcs-carrier-holder'\nimport { LoadLayoutHolder } from './features/load-layout-holder'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [...MCSZoneMixinProperties, ...MCSCarrierHolder.properties]\n}\n\n@sceneComponent('Port')\nexport default class Port extends LoadLayoutHolder(MCSZoneMixin(MCSCarrierHolder)) {\n static get nature() {\n return NATURE\n }\n\n /** Carriers stand at the Port's bottom (fmsim v2) */\n get carrierRest(): { height: number; mount: 'ON' | 'HANG' } {\n return { height: 0, mount: 'ON' }\n }\n\n get auxColor() {\n return 'black'\n }\n\n get statusLegendRow(): string {\n return 'port'\n }\n\n /** Port 는 후보가 매우 많아 부모 머신 없이는 id 리스트를 조회하지 않는다 (machine 필수). */\n get idLookupRequiresMachine() {\n return true\n }\n\n render(ctx: CanvasRenderingContext2D) {\n var { left, top, width, height } = this.bounds\n\n ctx.strokeStyle = this.auxColor\n ctx.fillStyle = this.statusColor!\n ctx.lineWidth = 1\n ctx.lineCap = 'round'\n ctx.setLineDash([])\n\n ctx.beginPath()\n\n // Performance aware\n // const radius = Math.round(Math.min(width, height) * 0.1)\n // ctx.roundRect(left, top, width, height, radius)\n ctx.rect(left, top, width, height)\n\n ctx.fill()\n ctx.stroke()\n }\n}\n"]}