@fmsim/machine 2.0.1 → 3.0.0-beta.1

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 (95) hide show
  1. package/dist/agv.js +2 -3
  2. package/dist/agv.js.map +1 -1
  3. package/dist/carrier.js +53 -43
  4. package/dist/carrier.js.map +1 -1
  5. package/dist/crane.js +37 -2
  6. package/dist/crane.js.map +1 -1
  7. package/dist/editors/index.js +2 -0
  8. package/dist/editors/index.js.map +1 -1
  9. package/dist/editors/load-layout-host.js +96 -0
  10. package/dist/editors/load-layout-host.js.map +1 -0
  11. package/dist/editors/ox-load-layout-panel.js +124 -0
  12. package/dist/editors/ox-load-layout-panel.js.map +1 -0
  13. package/dist/factories/crane-3d.js +77 -18
  14. package/dist/factories/crane-3d.js.map +1 -1
  15. package/dist/factories/machine-3d.js +29 -52
  16. package/dist/factories/machine-3d.js.map +1 -1
  17. package/dist/features/capacity-gauge-mixin.js +2 -3
  18. package/dist/features/capacity-gauge-mixin.js.map +1 -1
  19. package/dist/features/load-layout-holder.js +77 -0
  20. package/dist/features/load-layout-holder.js.map +1 -0
  21. package/dist/features/mcs-status-default.js +30 -7
  22. package/dist/features/mcs-status-default.js.map +1 -1
  23. package/dist/features/mcs-status-mixin.js +3 -3
  24. package/dist/features/mcs-status-mixin.js.map +1 -1
  25. package/dist/index.js +5 -0
  26. package/dist/index.js.map +1 -1
  27. package/dist/mcs-carrier-holder.js +287 -82
  28. package/dist/mcs-carrier-holder.js.map +1 -1
  29. package/dist/oht.js +4 -0
  30. package/dist/oht.js.map +1 -1
  31. package/dist/port.js +6 -1
  32. package/dist/port.js.map +1 -1
  33. package/dist/scene/root-container-override.js +5 -11
  34. package/dist/scene/root-container-override.js.map +1 -1
  35. package/dist/shelf.js +4 -0
  36. package/dist/shelf.js.map +1 -1
  37. package/dist/shuttle.js +4 -0
  38. package/dist/shuttle.js.map +1 -1
  39. package/dist/stocker-carrier-bar.js +4 -4
  40. package/dist/stocker-carrier-bar.js.map +1 -1
  41. package/dist/tsconfig.tsbuildinfo +1 -1
  42. package/dist/utils/carrier-type-code.js +10 -0
  43. package/dist/utils/carrier-type-code.js.map +1 -0
  44. package/dist/utils/crane-forks.js +5 -0
  45. package/dist/utils/crane-forks.js.map +1 -0
  46. package/dist/utils/layout-issue-text.js +16 -0
  47. package/dist/utils/layout-issue-text.js.map +1 -0
  48. package/dist/utils/layout-issue.js +16 -0
  49. package/dist/utils/layout-issue.js.map +1 -0
  50. package/dist/utils/load-address.js +217 -0
  51. package/dist/utils/load-address.js.map +1 -0
  52. package/dist/utils/stocker-gauge.js +3 -2
  53. package/dist/utils/stocker-gauge.js.map +1 -1
  54. package/jest.config.js +9 -1
  55. package/package.json +9 -6
  56. package/src/agv.ts +2 -3
  57. package/src/carrier.ts +50 -41
  58. package/src/crane.ts +39 -2
  59. package/src/editors/index.ts +2 -0
  60. package/src/editors/load-layout-host.ts +121 -0
  61. package/src/editors/ox-load-layout-panel.ts +129 -0
  62. package/src/factories/crane-3d.ts +74 -20
  63. package/src/factories/machine-3d.ts +26 -49
  64. package/src/features/capacity-gauge-mixin.ts +2 -3
  65. package/src/features/load-layout-holder.ts +83 -0
  66. package/src/features/mcs-status-default.ts +29 -10
  67. package/src/features/mcs-status-mixin.ts +3 -7
  68. package/src/index.ts +7 -0
  69. package/src/mcs-carrier-holder.ts +319 -78
  70. package/src/oht.ts +5 -0
  71. package/src/port.ts +7 -1
  72. package/src/scene/root-container-override.ts +4 -14
  73. package/src/shelf.ts +5 -0
  74. package/src/shuttle.ts +5 -0
  75. package/src/stocker-carrier-bar.ts +4 -4
  76. package/src/utils/carrier-type-code.ts +9 -0
  77. package/src/utils/crane-forks.ts +4 -0
  78. package/src/utils/layout-issue-text.ts +18 -0
  79. package/src/utils/layout-issue.ts +41 -0
  80. package/src/utils/load-address.ts +270 -0
  81. package/src/utils/stocker-gauge.ts +3 -3
  82. package/translations/en.json +42 -1
  83. package/translations/ja.json +42 -1
  84. package/translations/ko.json +59 -18
  85. package/translations/ms.json +42 -1
  86. package/translations/zh.json +42 -1
  87. package/dist/carrier-manager.js +0 -191
  88. package/dist/carrier-manager.js.map +0 -1
  89. package/dist/features/animation-default.js +0 -6
  90. package/dist/features/animation-default.js.map +0 -1
  91. package/dist/utils/get-value-on-ranges.js +0 -21
  92. package/dist/utils/get-value-on-ranges.js.map +0 -1
  93. package/src/carrier-manager.ts +0 -231
  94. package/src/features/animation-default.ts +0 -13
  95. package/src/utils/get-value-on-ranges.ts +0 -23
@@ -1 +1 @@
1
- {"version":3,"file":"capacity-gauge-mixin.js","sourceRoot":"","sources":["../../src/features/capacity-gauge-mixin.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, POSITION } from '@hatiolab/things-scene'\nimport { themesColorRange } from '@fmsim/api'\nimport { LEGEND_CAPACITY, Legend, resolveCarrierLegend } from './mcs-status-default'\nimport { safeRound } from '../utils/safe-round'\nimport { getValueOnRanges } from '../utils/get-value-on-ranges'\nimport { carrierSegments, abnormalSegments, carrierColorsFromLegend, pickSegmentAt, GaugeSegment } from '../utils/stocker-gauge'\n\ntype Constructor<T = {}> = new (...args: any[]) => T\n\n/**\n * 용량 게이지 (통합 로직).\n *\n * 하나의 컴포넌트가 mode 에 따라 3가지 게이지를 표현한다:\n * - 'capacity' : 용량 사용률(usage%) 채움 게이지 + high/low watermark (기본)\n * - 'carrier' : 캐리어 상태비율 세그먼트 (Full / Empty / EmptyEmpty)\n * - 'abnormal' : 캐리어 정상/비정상 비율 세그먼트 (Normal / Abnormal)\n *\n * StockerCapacityBar(스토커 지붕 게이지)와 ZoneCapacityBar(존 게이지)가 이 로직을 공유한다.\n * 두 컴포넌트는 base(스토커=Shape, 존=Container)·정체성(identifiable)·legend 폴백만 다르고,\n * 게이지를 그리는 규칙은 완전히 동일하다 — 규칙을 이 믹스인 한 곳에 두어 drift 를 막는다.\n *\n * mode 소스: root.stockerGaugeMode (기본 'capacity'). RootContainer 의 런타임 전용\n * transient 속성으로, 3D(machine-3d buildGauge)와도 동일 소스라 2D/3D 게이지가 항상 일치한다.\n * (root-container-override.ts 정의. 모드가 바뀌면 _refreshStockerGauges 가 두 게이지를 갱신.)\n *\n * 데이터 필드(2D 기준, canonical):\n * - capacity : CURRENTCAPACITY / MAXCAPACITY / HIGHWATERMARK / LOWWATERMARK / FULLUP\n * - carrier : CARRIER_FULL / CARRIER_EMPTY / CARRIER_EMPTY_EMPTY\n * - abnormal : CARRIER_NORMAL / CARRIER_ABNORMAL\n */\n\n/** 게이지 NATURE 속성 조각 (스토커/존 공통). 각 컴포넌트 NATURE 에 spread 로 합친다. */\nexport const CapacityGaugeMixinProperties = [\n {\n type: 'select',\n label: 'legend-name',\n name: 'legendName',\n property: {\n options: themesColorRange\n }\n },\n {\n type: 'number',\n name: 'currentUsage',\n label: 'current-usage'\n },\n {\n type: 'number',\n name: 'highWatermark',\n label: 'high-watermark'\n },\n {\n type: 'number',\n name: 'lowWatermark',\n label: 'low-watermark'\n },\n {\n type: 'number',\n name: 'maxCapacity',\n label: 'max-capacity'\n },\n {\n type: 'boolean',\n name: 'fullup',\n label: 'fullup'\n },\n {\n type: 'number',\n name: 'carrierFull',\n label: 'carrier-full'\n },\n {\n type: 'number',\n name: 'carrierEmpty',\n label: 'carrier-empty'\n },\n {\n type: 'number',\n name: 'carrierEmptyEmpty',\n label: 'carrier-empty-empty'\n },\n {\n type: 'number',\n name: 'carrierNormal',\n label: 'carrier-normal'\n },\n {\n type: 'number',\n name: 'carrierAbnormal',\n label: 'carrier-abnormal'\n },\n {\n type: 'number',\n label: 'round',\n name: 'round',\n property: {\n min: 0\n }\n },\n {\n type: 'hidden',\n name: 'usage',\n label: 'usage'\n }\n]\n\nconst controlHandler = {\n ondragmove: function (point: POSITION, index: number, component: Component) {\n var { left, top, width, height } = (component as any).model\n\n var transcoorded = (component as any).transcoordP2S(point.x, point.y)\n var round = ((transcoorded.x - left) / (width / 2)) * 100\n\n round = safeRound(round, width, height)\n\n ;(component as any).set({\n round\n })\n }\n}\n\nexport function CapacityGaugeMixin<TBase extends Constructor<Component>>(Base: TBase): any {\n return class extends Base {\n /** 게이지 모드: RootContainer 런타임 transient 속성. 3D(machine-3d) 와 동일 소스. */\n get gaugeMode(): string {\n return (this as any).root?.stockerGaugeMode || 'capacity'\n }\n\n get controls() {\n var { left, top, width, round, height } = (this as any).state\n round = round == undefined ? 0 : safeRound(round, width, height)\n\n return [\n {\n x: left + (width / 2) * (round / 100),\n y: top,\n handler: controlHandler\n }\n ]\n }\n\n getTheme() {\n const { legendName } = (this as any).state\n\n if (legendName) {\n return (this as any).root?.style?.[legendName]\n }\n }\n\n get legend(): Legend {\n return this.getTheme() || this.getLegendFallback()\n }\n\n /** legend 미지정 시 폴백 테마. 컴포넌트별로 override (스토커/존 각자 전역 테마). */\n getLegendFallback(): Legend {\n return LEGEND_CAPACITY\n }\n\n get statusColor(): string | undefined {\n const { fullup } = (this as any).state\n return fullup ? 'red' : getValueOnRanges(this.usage, this.legend)\n }\n\n get text() {\n // usage% 값은 capacity 모드에서만 표시. carrier/abnormal 은 세그먼트별 자체 라벨을 그리므로\n // base 의 value 텍스트를 억제한다.\n if (this.gaugeMode !== 'capacity') {\n return ''\n }\n return this.usage + '%'\n }\n\n render(context: CanvasRenderingContext2D) {\n const mode = this.gaugeMode\n\n if (mode === 'carrier' || mode === 'abnormal') {\n // carrier/abnormal 모드는 세그먼트 값이 전부 0(데이터 없음)일 때 빈 막대 대신 '0%' 를 표시한다.\n this.renderSegmentGauge(context, this.segments(mode), true)\n return\n }\n\n // capacity (기본)\n const { width, height } = (this as any).bounds\n if (width >= height) {\n this.renderLandscape(context)\n } else {\n this.renderPortrait(context)\n }\n }\n\n /**\n * carrier/abnormal mode 의 세그먼트 목록 (공유 유틸 = 3D 와 동일 계산).\n * 배열 순서 = portrait 아래→위 / landscape 왼→오.\n */\n segments(mode: string): GaugeSegment[] {\n if (mode === 'abnormal') {\n const { carrierNormal = 0, carrierAbnormal = 0 } = (this as any).state\n return abnormalSegments(carrierNormal, carrierAbnormal)\n }\n const { carrierFull = 0, carrierEmpty = 0, carrierEmptyEmpty = 0 } = (this as any).state\n // 색상은 carrier 컴포넌트와 동일한 legend(테마)에서 취득 (carrierColorsFromLegend).\n const colors = carrierColorsFromLegend(resolveCarrierLegend(this))\n return carrierSegments(carrierFull, carrierEmpty, carrierEmptyEmpty, colors)\n }\n\n /**\n * 클릭(또는 hover) 지점이 어떤 세그먼트에 속하는지 판정. carrier/abnormal 모드 전용 —\n * capacity 모드·데이터 없음·좌표 변환 실패 시 null.\n *\n * renderSegmentGauge 와 동일한 배치 규칙으로 매핑한다: landscape(가로) 는 왼→오(누적 x),\n * portrait(세로) 는 아래→위(바닥부터 누적). ratio 0 세그먼트는 화면에 없으므로 건너뛴다.\n */\n segmentAtEvent(event: MouseEvent): { mode: string; key: string; count: number } | null {\n const mode = this.gaugeMode\n if (mode !== 'carrier' && mode !== 'abnormal') return null\n\n // 3D 게이지는 부모 STOCKER 의 real-object 가 그린다(이 컴포넌트가 아님) → 2D 세그먼트 판정 대상 아님.\n if ((this as any).root?.is3dMode) return null\n\n const ox = (event as any)?.offsetX\n const oy = (event as any)?.offsetY\n if (typeof ox !== 'number' || typeof oy !== 'number') return null\n\n // 표면 픽셀(offsetX/offsetY) → 이 컴포넌트 로컬 프레임.\n // 주의: transcoordP2S 는 '부모→로컬' 한 단계라 캔버스 픽셀로 단독 호출하면 안 된다.\n // 엔진 capture() 와 동일하게 루트부터 전체 체인을 적용하는 helper 가 toLocal.\n let local: { x: number; y: number } | undefined\n try {\n local = (this as any).toLocal(ox, oy)\n } catch {\n return null\n }\n if (!local) return null\n\n const { left, top, width, height } = (this as any).bounds\n if (!(width > 0) || !(height > 0)) return null\n\n // 컴포넌트 로컬프레임 좌표 → bounds 기준 within-box. 경계 반올림 방어로 clamp.\n const lx = Math.min(Math.max(local.x - left, 0), width)\n const ly = Math.min(Math.max(local.y - top, 0), height)\n\n const landscape = width >= height\n const pos = landscape ? lx : height - ly // portrait 는 바닥 기준 거리\n const span = landscape ? width : height\n\n const picked = pickSegmentAt(this.segments(mode), pos, span)\n if (!picked) return null\n\n // label 은 key 로 도출 가능하고 로케일 의존이라 payload 에서 제외 — key(대문자 토큰)로 식별.\n return { mode, key: picked.key, count: picked.count }\n }\n\n /** 세그먼트 게이지 렌더 (carrier/abnormal 공통). bounds 방향으로 landscape/portrait 자동. */\n renderSegmentGauge(context: CanvasRenderingContext2D, segments: GaugeSegment[], zeroPercentWhenEmpty = false) {\n const { left, top, width, height } = (this as any).bounds\n const { lineWidth, strokeStyle, round, fillStyle = 'white' } = (this as any).state\n const landscape = width >= height\n\n context.save()\n context.translate(left, top)\n\n // background\n context.beginPath()\n context.fillStyle = fillStyle\n context.roundRect(0, 0, width, height, round)\n context.fill()\n context.clip()\n\n if (landscape) {\n // 왼→오\n let x = 0\n for (const seg of segments) {\n const segWidth = width * seg.ratio\n if (segWidth <= 0) continue\n\n context.beginPath()\n context.fillStyle = seg.color\n context.rect(x, 0, segWidth, height)\n context.fill()\n\n this._drawSegmentLabel(context, seg, x, 0, segWidth, height)\n x += segWidth\n }\n } else {\n // 아래→위 (배열 첫 세그먼트가 바닥)\n let y = height\n for (const seg of segments) {\n const segHeight = height * seg.ratio\n if (segHeight <= 0) continue\n\n y -= segHeight\n\n context.beginPath()\n context.fillStyle = seg.color\n context.rect(0, y, width, segHeight)\n context.fill()\n\n this._drawSegmentLabel(context, seg, 0, y, width, segHeight)\n }\n }\n\n // 데이터가 전혀 없어(모든 ratio 0) 세그먼트가 하나도 안 그려진 경우 —\n // carrier/abnormal 모드는 빈 막대 대신 '0%' 를 막대 중앙에 표시한다.\n if (zeroPercentWhenEmpty && segments.every(s => s.ratio <= 0)) {\n this._drawSegmentLabel(\n context,\n { key: 'EMPTY', label: '', count: 0, ratio: 0, color: '' },\n 0,\n 0,\n width,\n height\n )\n }\n\n // outline\n context.beginPath()\n context.setLineDash([])\n context.strokeStyle = strokeStyle\n context.lineWidth = lineWidth\n context.roundRect(0, 0, width, height, round)\n context.stroke()\n\n context.translate(-left, -top)\n context.restore()\n }\n\n private _drawSegmentLabel(\n context: CanvasRenderingContext2D,\n seg: GaugeSegment,\n x: number,\n y: number,\n w: number,\n h: number\n ) {\n // 이름 라벨(Full/Empty/Abnormal…)은 그리지 않는다. 각 세그먼트 영역 중심에 숫자(%)만 표시.\n // 컴포넌트의 폰트 설정(fontFamily/fontSize/bold/italic)을 그대로 적용 — this.font.\n const fontSize = (this as any).state.fontSize || 15\n context.font = (this as any).font\n\n // 공간에 따라 단계적 축소: 넉넉하면 '값%', 좁으면 '%' 떼고 값만, 더 좁으면 생략.\n const value = `${Math.round(seg.ratio * 100)}`\n const fits = (t: string) => fontSize <= h && context.measureText(t).width <= w\n\n let text: string | null = null\n if (fits(`${value}%`)) {\n text = `${value}%`\n } else if (fits(value)) {\n text = value\n }\n if (text === null) {\n return\n }\n\n context.fillStyle = '#333'\n context.textAlign = 'center'\n context.textBaseline = 'middle'\n context.fillText(text, x + w / 2, y + h / 2)\n }\n\n renderLandscape(context: CanvasRenderingContext2D) {\n const { left, top, width, height } = (this as any).bounds\n const { highWatermark, lowWatermark, lineWidth, strokeStyle, round, fillStyle = 'white' } = (this as any).state\n\n context.save()\n context.translate(left, top)\n\n // gauge background\n context.beginPath()\n\n context.fillStyle = fillStyle\n context.roundRect(0, 0, width, height, round)\n\n context.fill()\n\n context.clip()\n\n // gauge foreground\n context.beginPath()\n\n context.fillStyle = this.statusColor!\n\n context.rect(0, 0, (width / 100) * this.usage, height)\n context.fill()\n\n // high-watermark level\n\n if (highWatermark && highWatermark > 0 && highWatermark < 100) {\n context.beginPath()\n\n context.strokeStyle = 'black'\n context.lineWidth = 1\n context.setLineDash([3])\n\n const x = (width / 100) * highWatermark\n context.moveTo(x, 0)\n context.lineTo(x, height)\n\n context.stroke()\n }\n\n // low-watermark level\n\n if (lowWatermark && lowWatermark > 0 && lowWatermark < 100) {\n context.beginPath()\n\n context.strokeStyle = 'black'\n context.lineWidth = 1\n context.setLineDash([3])\n\n const x = (width / 100) * lowWatermark\n context.moveTo(x, 0)\n context.lineTo(x, height)\n\n context.stroke()\n }\n\n // gauge outline\n context.beginPath()\n\n context.setLineDash([])\n context.strokeStyle = strokeStyle\n context.lineWidth = lineWidth\n context.roundRect(0, 0, width, height, round)\n context.stroke()\n\n context.beginPath()\n\n context.translate(-left, -top)\n context.restore()\n }\n\n renderPortrait(context: CanvasRenderingContext2D) {\n const { left, top, width, height } = (this as any).bounds\n const { highWatermark, lowWatermark, lineWidth, strokeStyle, round, fillStyle = 'white' } = (this as any).state\n\n context.save()\n context.translate(left, top)\n\n // gauge background\n context.beginPath()\n\n context.fillStyle = fillStyle\n context.roundRect(0, 0, width, height, round)\n\n context.fill()\n\n context.clip()\n\n // gauge foreground\n context.beginPath()\n\n context.fillStyle = this.statusColor!\n\n context.rect(0, height - (height / 100) * this.usage, width, (height / 100) * this.usage)\n context.fill()\n\n // high-watermark level\n\n if (highWatermark && highWatermark > 0 && highWatermark < 100) {\n context.beginPath()\n\n context.strokeStyle = 'black'\n context.lineWidth = 1\n context.setLineDash([3])\n\n const y = height - (height / 100) * highWatermark\n context.moveTo(0, y)\n context.lineTo(width, y)\n\n context.stroke()\n }\n\n // low-watermark level\n\n if (lowWatermark && lowWatermark > 0 && lowWatermark < 100) {\n context.beginPath()\n\n context.strokeStyle = 'black'\n context.lineWidth = 1\n context.setLineDash([3])\n\n const y = height - (height / 100) * lowWatermark\n context.moveTo(0, y)\n context.lineTo(width, y)\n\n context.stroke()\n }\n\n // gauge outline\n context.beginPath()\n\n context.setLineDash([])\n context.strokeStyle = strokeStyle\n context.lineWidth = lineWidth\n context.roundRect(0, 0, width, height, round)\n context.stroke()\n\n context.beginPath()\n\n context.translate(-left, -top)\n context.restore()\n }\n\n get usage() {\n const { currentUsage = 0, maxCapacity = 100 } = (this as any).state\n return Math.round((currentUsage / maxCapacity) * 100)\n }\n\n set usage(usage: number) {\n // intentionally have done nothing\n }\n\n onchangeData(after: Record<string, any>, before: Record<string, any>): void {\n const data = (this as any).data && typeof (this as any).data == 'object' ? (this as any).data : {}\n const {\n CURRENTCAPACITY = 0,\n MAXCAPACITY = 100,\n HIGHWATERMARK = 100,\n LOWWATERMARK = 0,\n FULLUP = 'F',\n CARRIER_FULL = 0,\n CARRIER_EMPTY = 0,\n CARRIER_EMPTY_EMPTY = 0,\n CARRIER_NORMAL = 0,\n CARRIER_ABNORMAL = 0\n } = data\n\n const currentUsage = Number(CURRENTCAPACITY) || 0\n const maxCapacity = Number(MAXCAPACITY) || 100\n const highWatermark = Number(HIGHWATERMARK) || 100\n const lowWatermark = Number(LOWWATERMARK) || 0\n\n ;(this as any).setState({\n currentUsage,\n maxCapacity,\n highWatermark,\n lowWatermark,\n fullup: FULLUP == 'T',\n usage: Math.round((currentUsage / maxCapacity) * 100),\n carrierFull: Number(CARRIER_FULL) || 0,\n carrierEmpty: Number(CARRIER_EMPTY) || 0,\n carrierEmptyEmpty: Number(CARRIER_EMPTY_EMPTY) || 0,\n carrierNormal: Number(CARRIER_NORMAL) || 0,\n carrierAbnormal: Number(CARRIER_ABNORMAL) || 0\n })\n }\n\n // ── hover 툴팁 (carrier/abnormal 모드 세그먼트별 수치) ───────────────────────────\n // 색상만으로 타입 구분이 어려울 때, 마우스 hover 로 정확한 수치 확인. 뷰어 모드 전용\n // (model-layer 가 편집 모드에선 hover dispatch 안 함).\n\n async ready(): Promise<void> {\n await super.ready()\n // hover 이벤트 수신 opt-in: model-layer _onmouseenter_all guard(hasLegacyHover) 통과.\n const ev = (this as any).model.event\n if (!ev || !ev.hover) {\n ;(this as any).model.event = { ...(ev || {}), hover: true }\n }\n }\n\n onMouseEnter(): void {\n // capacity 는 값이 한 개(usage%)라 툴팁 불필요. carrier/abnormal 만.\n if (this.gaugeMode === 'capacity') return\n this._showGaugeTooltip()\n }\n\n onMouseLeave(): void {\n this._hideGaugeTooltip()\n }\n\n dispose(): void {\n this._hideGaugeTooltip()\n super.dispose()\n }\n\n private _tooltipEl?: HTMLDivElement\n private _tooltipMove?: (e: MouseEvent) => void\n\n private _showGaugeTooltip(): void {\n if (typeof document === 'undefined') return\n const segments = this.segments(this.gaugeMode).filter(s => s.count > 0)\n if (!segments.length) return\n\n this._hideGaugeTooltip()\n\n const el = document.createElement('div')\n el.style.cssText = [\n 'position:fixed',\n 'left:-9999px',\n 'top:0',\n 'z-index:2147483647',\n 'pointer-events:none',\n 'background:rgba(30,30,30,0.92)',\n 'color:#fff',\n 'padding:6px 9px',\n 'border-radius:6px',\n 'font:12px/1.5 sans-serif',\n 'box-shadow:0 2px 10px rgba(0,0,0,0.35)',\n 'white-space:nowrap'\n ].join(';')\n\n for (const seg of segments) {\n const row = document.createElement('div')\n row.style.cssText = 'display:flex;align-items:center;gap:6px'\n\n const swatch = document.createElement('span')\n swatch.style.cssText = `display:inline-block;width:10px;height:10px;border-radius:2px;background:${seg.color}`\n\n const label = document.createElement('span')\n label.textContent = seg.label.replace(/\\n/g, ' ')\n label.style.cssText = 'flex:1'\n\n const value = document.createElement('span')\n value.textContent = String(seg.count)\n value.style.cssText = 'font-weight:700;margin-left:12px'\n\n row.append(swatch, label, value)\n el.appendChild(row)\n }\n\n document.body.appendChild(el)\n this._tooltipEl = el\n\n this._tooltipMove = (e: MouseEvent) => {\n el.style.left = `${e.clientX + 14}px`\n el.style.top = `${e.clientY + 14}px`\n }\n document.addEventListener('mousemove', this._tooltipMove, true)\n }\n\n private _hideGaugeTooltip(): void {\n if (this._tooltipMove) {\n document.removeEventListener('mousemove', this._tooltipMove, true)\n this._tooltipMove = undefined\n }\n if (this._tooltipEl) {\n this._tooltipEl.remove()\n this._tooltipEl = undefined\n }\n }\n }\n}\n"]}
1
+ {"version":3,"file":"capacity-gauge-mixin.js","sourceRoot":"","sources":["../../src/features/capacity-gauge-mixin.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, POSITION } from '@hatiolab/things-scene'\nimport { themesColorRange } from '@fmsim/api'\nimport { LEGEND_CAPACITY, Legend, legendColor, legendRangeEntryOf, resolveCarrierLegend } from './mcs-status-default'\nimport { safeRound } from '../utils/safe-round'\nimport { carrierSegments, abnormalSegments, carrierColorsFromLegend, pickSegmentAt, GaugeSegment } from '../utils/stocker-gauge'\n\ntype Constructor<T = {}> = new (...args: any[]) => T\n\n/**\n * 용량 게이지 (통합 로직).\n *\n * 하나의 컴포넌트가 mode 에 따라 3가지 게이지를 표현한다:\n * - 'capacity' : 용량 사용률(usage%) 채움 게이지 + high/low watermark (기본)\n * - 'carrier' : 캐리어 상태비율 세그먼트 (Full / Empty / EmptyEmpty)\n * - 'abnormal' : 캐리어 정상/비정상 비율 세그먼트 (Normal / Abnormal)\n *\n * StockerCapacityBar(스토커 지붕 게이지)와 ZoneCapacityBar(존 게이지)가 이 로직을 공유한다.\n * 두 컴포넌트는 base(스토커=Shape, 존=Container)·정체성(identifiable)·legend 폴백만 다르고,\n * 게이지를 그리는 규칙은 완전히 동일하다 — 규칙을 이 믹스인 한 곳에 두어 drift 를 막는다.\n *\n * mode 소스: root.stockerGaugeMode (기본 'capacity'). RootContainer 의 런타임 전용\n * transient 속성으로, 3D(machine-3d buildGauge)와도 동일 소스라 2D/3D 게이지가 항상 일치한다.\n * (root-container-override.ts 정의. 모드가 바뀌면 _refreshStockerGauges 가 두 게이지를 갱신.)\n *\n * 데이터 필드(2D 기준, canonical):\n * - capacity : CURRENTCAPACITY / MAXCAPACITY / HIGHWATERMARK / LOWWATERMARK / FULLUP\n * - carrier : CARRIER_FULL / CARRIER_EMPTY / CARRIER_EMPTY_EMPTY\n * - abnormal : CARRIER_NORMAL / CARRIER_ABNORMAL\n */\n\n/** 게이지 NATURE 속성 조각 (스토커/존 공통). 각 컴포넌트 NATURE 에 spread 로 합친다. */\nexport const CapacityGaugeMixinProperties = [\n {\n type: 'select',\n label: 'legend-name',\n name: 'legendName',\n property: {\n options: themesColorRange\n }\n },\n {\n type: 'number',\n name: 'currentUsage',\n label: 'current-usage'\n },\n {\n type: 'number',\n name: 'highWatermark',\n label: 'high-watermark'\n },\n {\n type: 'number',\n name: 'lowWatermark',\n label: 'low-watermark'\n },\n {\n type: 'number',\n name: 'maxCapacity',\n label: 'max-capacity'\n },\n {\n type: 'boolean',\n name: 'fullup',\n label: 'fullup'\n },\n {\n type: 'number',\n name: 'carrierFull',\n label: 'carrier-full'\n },\n {\n type: 'number',\n name: 'carrierEmpty',\n label: 'carrier-empty'\n },\n {\n type: 'number',\n name: 'carrierEmptyEmpty',\n label: 'carrier-empty-empty'\n },\n {\n type: 'number',\n name: 'carrierNormal',\n label: 'carrier-normal'\n },\n {\n type: 'number',\n name: 'carrierAbnormal',\n label: 'carrier-abnormal'\n },\n {\n type: 'number',\n label: 'round',\n name: 'round',\n property: {\n min: 0\n }\n },\n {\n type: 'hidden',\n name: 'usage',\n label: 'usage'\n }\n]\n\nconst controlHandler = {\n ondragmove: function (point: POSITION, index: number, component: Component) {\n var { left, top, width, height } = (component as any).model\n\n var transcoorded = (component as any).transcoordP2S(point.x, point.y)\n var round = ((transcoorded.x - left) / (width / 2)) * 100\n\n round = safeRound(round, width, height)\n\n ;(component as any).set({\n round\n })\n }\n}\n\nexport function CapacityGaugeMixin<TBase extends Constructor<Component>>(Base: TBase): any {\n return class extends Base {\n /** 게이지 모드: RootContainer 런타임 transient 속성. 3D(machine-3d) 와 동일 소스. */\n get gaugeMode(): string {\n return (this as any).root?.stockerGaugeMode || 'capacity'\n }\n\n get controls() {\n var { left, top, width, round, height } = (this as any).state\n round = round == undefined ? 0 : safeRound(round, width, height)\n\n return [\n {\n x: left + (width / 2) * (round / 100),\n y: top,\n handler: controlHandler\n }\n ]\n }\n\n getTheme() {\n const { legendName } = (this as any).state\n\n if (legendName) {\n return (this as any).root?.style?.[legendName]\n }\n }\n\n get legend(): Legend {\n return this.getTheme() || this.getLegendFallback()\n }\n\n /** legend 미지정 시 폴백 테마. 컴포넌트별로 override (스토커/존 각자 전역 테마). */\n getLegendFallback(): Legend {\n return LEGEND_CAPACITY\n }\n\n get statusColor(): string | undefined {\n const { fullup } = (this as any).state\n return fullup ? 'red' : legendColor(legendRangeEntryOf(this.usage, this.legend))\n }\n\n get text() {\n // usage% 값은 capacity 모드에서만 표시. carrier/abnormal 은 세그먼트별 자체 라벨을 그리므로\n // base 의 value 텍스트를 억제한다.\n if (this.gaugeMode !== 'capacity') {\n return ''\n }\n return this.usage + '%'\n }\n\n render(context: CanvasRenderingContext2D) {\n const mode = this.gaugeMode\n\n if (mode === 'carrier' || mode === 'abnormal') {\n // carrier/abnormal 모드는 세그먼트 값이 전부 0(데이터 없음)일 때 빈 막대 대신 '0%' 를 표시한다.\n this.renderSegmentGauge(context, this.segments(mode), true)\n return\n }\n\n // capacity (기본)\n const { width, height } = (this as any).bounds\n if (width >= height) {\n this.renderLandscape(context)\n } else {\n this.renderPortrait(context)\n }\n }\n\n /**\n * carrier/abnormal mode 의 세그먼트 목록 (공유 유틸 = 3D 와 동일 계산).\n * 배열 순서 = portrait 아래→위 / landscape 왼→오.\n */\n segments(mode: string): GaugeSegment[] {\n if (mode === 'abnormal') {\n const { carrierNormal = 0, carrierAbnormal = 0 } = (this as any).state\n return abnormalSegments(carrierNormal, carrierAbnormal)\n }\n const { carrierFull = 0, carrierEmpty = 0, carrierEmptyEmpty = 0 } = (this as any).state\n // 색상은 carrier 컴포넌트와 동일한 legend(테마)에서 취득 (carrierColorsFromLegend).\n const colors = carrierColorsFromLegend(resolveCarrierLegend(this))\n return carrierSegments(carrierFull, carrierEmpty, carrierEmptyEmpty, colors)\n }\n\n /**\n * 클릭(또는 hover) 지점이 어떤 세그먼트에 속하는지 판정. carrier/abnormal 모드 전용 —\n * capacity 모드·데이터 없음·좌표 변환 실패 시 null.\n *\n * renderSegmentGauge 와 동일한 배치 규칙으로 매핑한다: landscape(가로) 는 왼→오(누적 x),\n * portrait(세로) 는 아래→위(바닥부터 누적). ratio 0 세그먼트는 화면에 없으므로 건너뛴다.\n */\n segmentAtEvent(event: MouseEvent): { mode: string; key: string; count: number } | null {\n const mode = this.gaugeMode\n if (mode !== 'carrier' && mode !== 'abnormal') return null\n\n // 3D 게이지는 부모 STOCKER 의 real-object 가 그린다(이 컴포넌트가 아님) → 2D 세그먼트 판정 대상 아님.\n if ((this as any).root?.is3dMode) return null\n\n const ox = (event as any)?.offsetX\n const oy = (event as any)?.offsetY\n if (typeof ox !== 'number' || typeof oy !== 'number') return null\n\n // 표면 픽셀(offsetX/offsetY) → 이 컴포넌트 로컬 프레임.\n // 주의: transcoordP2S 는 '부모→로컬' 한 단계라 캔버스 픽셀로 단독 호출하면 안 된다.\n // 엔진 capture() 와 동일하게 루트부터 전체 체인을 적용하는 helper 가 toLocal.\n let local: { x: number; y: number } | undefined\n try {\n local = (this as any).toLocal(ox, oy)\n } catch {\n return null\n }\n if (!local) return null\n\n const { left, top, width, height } = (this as any).bounds\n if (!(width > 0) || !(height > 0)) return null\n\n // 컴포넌트 로컬프레임 좌표 → bounds 기준 within-box. 경계 반올림 방어로 clamp.\n const lx = Math.min(Math.max(local.x - left, 0), width)\n const ly = Math.min(Math.max(local.y - top, 0), height)\n\n const landscape = width >= height\n const pos = landscape ? lx : height - ly // portrait 는 바닥 기준 거리\n const span = landscape ? width : height\n\n const picked = pickSegmentAt(this.segments(mode), pos, span)\n if (!picked) return null\n\n // label 은 key 로 도출 가능하고 로케일 의존이라 payload 에서 제외 — key(대문자 토큰)로 식별.\n return { mode, key: picked.key, count: picked.count }\n }\n\n /** 세그먼트 게이지 렌더 (carrier/abnormal 공통). bounds 방향으로 landscape/portrait 자동. */\n renderSegmentGauge(context: CanvasRenderingContext2D, segments: GaugeSegment[], zeroPercentWhenEmpty = false) {\n const { left, top, width, height } = (this as any).bounds\n const { lineWidth, strokeStyle, round, fillStyle = 'white' } = (this as any).state\n const landscape = width >= height\n\n context.save()\n context.translate(left, top)\n\n // background\n context.beginPath()\n context.fillStyle = fillStyle\n context.roundRect(0, 0, width, height, round)\n context.fill()\n context.clip()\n\n if (landscape) {\n // 왼→오\n let x = 0\n for (const seg of segments) {\n const segWidth = width * seg.ratio\n if (segWidth <= 0) continue\n\n context.beginPath()\n context.fillStyle = seg.color\n context.rect(x, 0, segWidth, height)\n context.fill()\n\n this._drawSegmentLabel(context, seg, x, 0, segWidth, height)\n x += segWidth\n }\n } else {\n // 아래→위 (배열 첫 세그먼트가 바닥)\n let y = height\n for (const seg of segments) {\n const segHeight = height * seg.ratio\n if (segHeight <= 0) continue\n\n y -= segHeight\n\n context.beginPath()\n context.fillStyle = seg.color\n context.rect(0, y, width, segHeight)\n context.fill()\n\n this._drawSegmentLabel(context, seg, 0, y, width, segHeight)\n }\n }\n\n // 데이터가 전혀 없어(모든 ratio 0) 세그먼트가 하나도 안 그려진 경우 —\n // carrier/abnormal 모드는 빈 막대 대신 '0%' 를 막대 중앙에 표시한다.\n if (zeroPercentWhenEmpty && segments.every(s => s.ratio <= 0)) {\n this._drawSegmentLabel(\n context,\n { key: 'EMPTY', label: '', count: 0, ratio: 0, color: '' },\n 0,\n 0,\n width,\n height\n )\n }\n\n // outline\n context.beginPath()\n context.setLineDash([])\n context.strokeStyle = strokeStyle\n context.lineWidth = lineWidth\n context.roundRect(0, 0, width, height, round)\n context.stroke()\n\n context.translate(-left, -top)\n context.restore()\n }\n\n private _drawSegmentLabel(\n context: CanvasRenderingContext2D,\n seg: GaugeSegment,\n x: number,\n y: number,\n w: number,\n h: number\n ) {\n // 이름 라벨(Full/Empty/Abnormal…)은 그리지 않는다. 각 세그먼트 영역 중심에 숫자(%)만 표시.\n // 컴포넌트의 폰트 설정(fontFamily/fontSize/bold/italic)을 그대로 적용 — this.font.\n const fontSize = (this as any).state.fontSize || 15\n context.font = (this as any).font\n\n // 공간에 따라 단계적 축소: 넉넉하면 '값%', 좁으면 '%' 떼고 값만, 더 좁으면 생략.\n const value = `${Math.round(seg.ratio * 100)}`\n const fits = (t: string) => fontSize <= h && context.measureText(t).width <= w\n\n let text: string | null = null\n if (fits(`${value}%`)) {\n text = `${value}%`\n } else if (fits(value)) {\n text = value\n }\n if (text === null) {\n return\n }\n\n context.fillStyle = '#333'\n context.textAlign = 'center'\n context.textBaseline = 'middle'\n context.fillText(text, x + w / 2, y + h / 2)\n }\n\n renderLandscape(context: CanvasRenderingContext2D) {\n const { left, top, width, height } = (this as any).bounds\n const { highWatermark, lowWatermark, lineWidth, strokeStyle, round, fillStyle = 'white' } = (this as any).state\n\n context.save()\n context.translate(left, top)\n\n // gauge background\n context.beginPath()\n\n context.fillStyle = fillStyle\n context.roundRect(0, 0, width, height, round)\n\n context.fill()\n\n context.clip()\n\n // gauge foreground\n context.beginPath()\n\n context.fillStyle = this.statusColor!\n\n context.rect(0, 0, (width / 100) * this.usage, height)\n context.fill()\n\n // high-watermark level\n\n if (highWatermark && highWatermark > 0 && highWatermark < 100) {\n context.beginPath()\n\n context.strokeStyle = 'black'\n context.lineWidth = 1\n context.setLineDash([3])\n\n const x = (width / 100) * highWatermark\n context.moveTo(x, 0)\n context.lineTo(x, height)\n\n context.stroke()\n }\n\n // low-watermark level\n\n if (lowWatermark && lowWatermark > 0 && lowWatermark < 100) {\n context.beginPath()\n\n context.strokeStyle = 'black'\n context.lineWidth = 1\n context.setLineDash([3])\n\n const x = (width / 100) * lowWatermark\n context.moveTo(x, 0)\n context.lineTo(x, height)\n\n context.stroke()\n }\n\n // gauge outline\n context.beginPath()\n\n context.setLineDash([])\n context.strokeStyle = strokeStyle\n context.lineWidth = lineWidth\n context.roundRect(0, 0, width, height, round)\n context.stroke()\n\n context.beginPath()\n\n context.translate(-left, -top)\n context.restore()\n }\n\n renderPortrait(context: CanvasRenderingContext2D) {\n const { left, top, width, height } = (this as any).bounds\n const { highWatermark, lowWatermark, lineWidth, strokeStyle, round, fillStyle = 'white' } = (this as any).state\n\n context.save()\n context.translate(left, top)\n\n // gauge background\n context.beginPath()\n\n context.fillStyle = fillStyle\n context.roundRect(0, 0, width, height, round)\n\n context.fill()\n\n context.clip()\n\n // gauge foreground\n context.beginPath()\n\n context.fillStyle = this.statusColor!\n\n context.rect(0, height - (height / 100) * this.usage, width, (height / 100) * this.usage)\n context.fill()\n\n // high-watermark level\n\n if (highWatermark && highWatermark > 0 && highWatermark < 100) {\n context.beginPath()\n\n context.strokeStyle = 'black'\n context.lineWidth = 1\n context.setLineDash([3])\n\n const y = height - (height / 100) * highWatermark\n context.moveTo(0, y)\n context.lineTo(width, y)\n\n context.stroke()\n }\n\n // low-watermark level\n\n if (lowWatermark && lowWatermark > 0 && lowWatermark < 100) {\n context.beginPath()\n\n context.strokeStyle = 'black'\n context.lineWidth = 1\n context.setLineDash([3])\n\n const y = height - (height / 100) * lowWatermark\n context.moveTo(0, y)\n context.lineTo(width, y)\n\n context.stroke()\n }\n\n // gauge outline\n context.beginPath()\n\n context.setLineDash([])\n context.strokeStyle = strokeStyle\n context.lineWidth = lineWidth\n context.roundRect(0, 0, width, height, round)\n context.stroke()\n\n context.beginPath()\n\n context.translate(-left, -top)\n context.restore()\n }\n\n get usage() {\n const { currentUsage = 0, maxCapacity = 100 } = (this as any).state\n return Math.round((currentUsage / maxCapacity) * 100)\n }\n\n set usage(usage: number) {\n // intentionally have done nothing\n }\n\n onchangeData(after: Record<string, any>, before: Record<string, any>): void {\n const data = (this as any).data && typeof (this as any).data == 'object' ? (this as any).data : {}\n const {\n CURRENTCAPACITY = 0,\n MAXCAPACITY = 100,\n HIGHWATERMARK = 100,\n LOWWATERMARK = 0,\n FULLUP = 'F',\n CARRIER_FULL = 0,\n CARRIER_EMPTY = 0,\n CARRIER_EMPTY_EMPTY = 0,\n CARRIER_NORMAL = 0,\n CARRIER_ABNORMAL = 0\n } = data\n\n const currentUsage = Number(CURRENTCAPACITY) || 0\n const maxCapacity = Number(MAXCAPACITY) || 100\n const highWatermark = Number(HIGHWATERMARK) || 100\n const lowWatermark = Number(LOWWATERMARK) || 0\n\n ;(this as any).setState({\n currentUsage,\n maxCapacity,\n highWatermark,\n lowWatermark,\n fullup: FULLUP == 'T',\n usage: Math.round((currentUsage / maxCapacity) * 100),\n carrierFull: Number(CARRIER_FULL) || 0,\n carrierEmpty: Number(CARRIER_EMPTY) || 0,\n carrierEmptyEmpty: Number(CARRIER_EMPTY_EMPTY) || 0,\n carrierNormal: Number(CARRIER_NORMAL) || 0,\n carrierAbnormal: Number(CARRIER_ABNORMAL) || 0\n })\n }\n\n // ── hover 툴팁 (carrier/abnormal 모드 세그먼트별 수치) ───────────────────────────\n // 색상만으로 타입 구분이 어려울 때, 마우스 hover 로 정확한 수치 확인. 뷰어 모드 전용\n // (model-layer 가 편집 모드에선 hover dispatch 안 함).\n\n async ready(): Promise<void> {\n await super.ready()\n // hover 이벤트 수신 opt-in: model-layer _onmouseenter_all guard(hasLegacyHover) 통과.\n const ev = (this as any).model.event\n if (!ev || !ev.hover) {\n ;(this as any).model.event = { ...(ev || {}), hover: true }\n }\n }\n\n onMouseEnter(): void {\n // capacity 는 값이 한 개(usage%)라 툴팁 불필요. carrier/abnormal 만.\n if (this.gaugeMode === 'capacity') return\n this._showGaugeTooltip()\n }\n\n onMouseLeave(): void {\n this._hideGaugeTooltip()\n }\n\n dispose(): void {\n this._hideGaugeTooltip()\n super.dispose()\n }\n\n private _tooltipEl?: HTMLDivElement\n private _tooltipMove?: (e: MouseEvent) => void\n\n private _showGaugeTooltip(): void {\n if (typeof document === 'undefined') return\n const segments = this.segments(this.gaugeMode).filter(s => s.count > 0)\n if (!segments.length) return\n\n this._hideGaugeTooltip()\n\n const el = document.createElement('div')\n el.style.cssText = [\n 'position:fixed',\n 'left:-9999px',\n 'top:0',\n 'z-index:2147483647',\n 'pointer-events:none',\n 'background:rgba(30,30,30,0.92)',\n 'color:#fff',\n 'padding:6px 9px',\n 'border-radius:6px',\n 'font:12px/1.5 sans-serif',\n 'box-shadow:0 2px 10px rgba(0,0,0,0.35)',\n 'white-space:nowrap'\n ].join(';')\n\n for (const seg of segments) {\n const row = document.createElement('div')\n row.style.cssText = 'display:flex;align-items:center;gap:6px'\n\n const swatch = document.createElement('span')\n swatch.style.cssText = `display:inline-block;width:10px;height:10px;border-radius:2px;background:${seg.color}`\n\n const label = document.createElement('span')\n label.textContent = seg.label.replace(/\\n/g, ' ')\n label.style.cssText = 'flex:1'\n\n const value = document.createElement('span')\n value.textContent = String(seg.count)\n value.style.cssText = 'font-weight:700;margin-left:12px'\n\n row.append(swatch, label, value)\n el.appendChild(row)\n }\n\n document.body.appendChild(el)\n this._tooltipEl = el\n\n this._tooltipMove = (e: MouseEvent) => {\n el.style.left = `${e.clientX + 14}px`\n el.style.top = `${e.clientY + 14}px`\n }\n document.addEventListener('mousemove', this._tooltipMove, true)\n }\n\n private _hideGaugeTooltip(): void {\n if (this._tooltipMove) {\n document.removeEventListener('mousemove', this._tooltipMove, true)\n this._tooltipMove = undefined\n }\n if (this._tooltipEl) {\n this._tooltipEl.remove()\n this._tooltipEl = undefined\n }\n }\n }\n}\n"]}
@@ -0,0 +1,77 @@
1
+ /*
2
+ * 적재 레이아웃 홀더 (설계 02번 3.2.1절, 3.6.1절, 3.7.1절)
3
+ * 홀더의 실효 레이아웃에서 Carrier 를 주소의 자리에 배정한다.
4
+ *
5
+ * 보유·자리·안착·판정은 공통 아이템 계약의 것이다(things-scene Capacity·Holdable, figure-model). 실효 레이아웃은
6
+ * Capacity.effectiveLayout 이 정한다: 도면 노드의 개별 설정(state.slotLayout)이 있으면 그것, 없으면 홀더의 기본값.
7
+ * 이 믹스인에 남는 것은 MCS 의 몫이다: 실시간 데이터의 주소 읽기와 점유 배정, 예외를 어느 밖 자리에 둘지.
8
+ *
9
+ * 유효한 실효 레이아웃이 있고 도면 축척을 알 때만 자리를 배정한다. 그 밖에는 MCSCarrierHolder 대로 모두 한 무더기(pile)다.
10
+ */
11
+ import { resolveSlot, slotAddresses, slotIdOf } from '@hatiolab/figure-model';
12
+ import { drawingScaleFor } from '@hatiolab/things-scene';
13
+ import { incomingFromV2, resolveOccupancy } from '../utils/load-address';
14
+ import { EXCEPTION_SLOT } from '../mcs-carrier-holder';
15
+ export function LoadLayoutHolder(Base) {
16
+ return class extends Base {
17
+ /** 기본 레이아웃의 Tier 가 서는 방식. 기종별 프리셋 배정은 확정 대기 (3.8절) */
18
+ get loadMount() {
19
+ return 'ON';
20
+ }
21
+ /**
22
+ * 도면 좌표 1단위당 mm 와 그것을 아는지. things-scene 이 도면 축척을 읽는 한 곳(drawingScaleFor, ADR-0144 2.2)에서
23
+ * 받는다. 축척이 없는 도면(known: false)에서는 자리를 배정하지 않는다.
24
+ */
25
+ get mmPerUnit() {
26
+ return drawingScaleFor(this);
27
+ }
28
+ /** 자리를 배정하는 레이아웃. 유효한 실효 레이아웃이 없거나 축척을 모르면 undefined (한 무더기로 쌓는다) */
29
+ get _validLoadLayout() {
30
+ const sel = this.effectiveLayout;
31
+ return sel.status === 'valid' && this.mmPerUnit.known ? sel.layout : undefined;
32
+ }
33
+ /**
34
+ * Carrier 마다 자리를 정한 레코드 (설계 02번 3.6.1절). 정상 자리는 자리마다 아래에서 위로, 예외는 그 뒤에 예외 영역에.
35
+ * 같은 이름이 두 번 오면 데이터 그대로 넘겨 공통 대조가 스냅샷째 거절하게 한다 (계약 Q2).
36
+ */
37
+ carrierRecords(data) {
38
+ const layout = this._validLoadLayout;
39
+ if (!layout) {
40
+ this._loadOccupancy = undefined;
41
+ return super.carrierRecords(data);
42
+ }
43
+ const incoming = incomingFromV2(data);
44
+ const occupancy = resolveOccupancy(layout, incoming, this._loadOccupancy);
45
+ this._loadOccupancy = occupancy;
46
+ const stateOf = new Map(incoming.map(c => [c.name, this.carrierStateOf(c.record, c.record === data)]));
47
+ if (stateOf.size !== incoming.length)
48
+ return incoming.map(c => ({ slotId: EXCEPTION_SLOT, itemId: c.name, itemState: stateOf.get(c.name) }));
49
+ const records = [];
50
+ for (const list of occupancy.slots.values())
51
+ for (const c of list)
52
+ records.push({ slotId: slotIdOf(c.address), itemId: c.name, itemState: stateOf.get(c.name) });
53
+ // 예외는 정상 자리와 나눈 예외 영역에 차례로 둔다. 다른 정상 자리를 대신 쓰지 않는다
54
+ for (const c of [...occupancy.addressUnknown, ...occupancy.addressError])
55
+ records.push({ slotId: EXCEPTION_SLOT, itemId: c.name, itemState: stateOf.get(c.name) });
56
+ return records;
57
+ }
58
+ /** 예외 영역의 치수 모르는 Carrier 는 첫 자리를 채우는 표시용 상자로 보인다 */
59
+ itemShownDimsOf(carrier, slot, slotId) {
60
+ if (slotId !== EXCEPTION_SLOT)
61
+ return super.itemShownDimsOf(carrier, slot, slotId);
62
+ const first = this._firstSlot;
63
+ return first ? super.itemShownDimsOf(carrier, first, slotIdOf({ tier: first.tier, slot: first.slotNo })) : null;
64
+ }
65
+ /** 예외 영역의 Carrier 는 첫 자리 폭의 절반만큼 더 떨어져 선다 */
66
+ get exceptionHalfWidth() {
67
+ const first = this._firstSlot;
68
+ return first && Number.isFinite(first.allowed.width) ? first.allowed.width / 2 : 0;
69
+ }
70
+ get _firstSlot() {
71
+ const layout = this._validLoadLayout;
72
+ const address = layout ? [...slotAddresses(layout)][0] : undefined;
73
+ return layout && address ? resolveSlot(layout, address) : null;
74
+ }
75
+ };
76
+ }
77
+ //# sourceMappingURL=load-layout-holder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-layout-holder.js","sourceRoot":"","sources":["../../src/features/load-layout-holder.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * 적재 레이아웃 홀더 (설계 02번 3.2.1절, 3.6.1절, 3.7.1절)\n * 홀더의 실효 레이아웃에서 Carrier 를 주소의 자리에 배정한다.\n *\n * 보유·자리·안착·판정은 공통 아이템 계약의 것이다(things-scene Capacity·Holdable, figure-model). 실효 레이아웃은\n * Capacity.effectiveLayout 이 정한다: 도면 노드의 개별 설정(state.slotLayout)이 있으면 그것, 없으면 홀더의 기본값.\n * 이 믹스인에 남는 것은 MCS 의 몫이다: 실시간 데이터의 주소 읽기와 점유 배정, 예외를 어느 밖 자리에 둘지.\n *\n * 유효한 실효 레이아웃이 있고 도면 축척을 알 때만 자리를 배정한다. 그 밖에는 MCSCarrierHolder 대로 모두 한 무더기(pile)다.\n */\n\nimport { resolveSlot, slotAddresses, slotIdOf, type ItemDims, type ResolvedSlot, type SlotMount } from '@hatiolab/figure-model'\nimport { drawingScaleFor, type DrawingScale } from '@hatiolab/things-scene'\nimport { LoadLayout, OccupancyResult, incomingFromV2, resolveOccupancy } from '../utils/load-address'\nimport { EXCEPTION_SLOT, type CarrierRecord } from '../mcs-carrier-holder'\n\ntype Constructor<T = any> = new (...args: any[]) => T\n\nexport function LoadLayoutHolder<TBase extends Constructor>(Base: TBase) {\n return class extends Base {\n _loadOccupancy?: OccupancyResult\n\n /** 기본 레이아웃의 Tier 가 서는 방식. 기종별 프리셋 배정은 확정 대기 (3.8절) */\n get loadMount(): SlotMount {\n return 'ON'\n }\n\n /**\n * 도면 좌표 1단위당 mm 와 그것을 아는지. things-scene 이 도면 축척을 읽는 한 곳(drawingScaleFor, ADR-0144 2.2)에서\n * 받는다. 축척이 없는 도면(known: false)에서는 자리를 배정하지 않는다.\n */\n get mmPerUnit(): DrawingScale {\n return drawingScaleFor(this as any)\n }\n\n /** 자리를 배정하는 레이아웃. 유효한 실효 레이아웃이 없거나 축척을 모르면 undefined (한 무더기로 쌓는다) */\n get _validLoadLayout(): LoadLayout | undefined {\n const sel = (this as any).effectiveLayout\n return sel.status === 'valid' && this.mmPerUnit.known ? (sel.layout as LoadLayout) : undefined\n }\n\n /**\n * Carrier 마다 자리를 정한 레코드 (설계 02번 3.6.1절). 정상 자리는 자리마다 아래에서 위로, 예외는 그 뒤에 예외 영역에.\n * 같은 이름이 두 번 오면 데이터 그대로 넘겨 공통 대조가 스냅샷째 거절하게 한다 (계약 Q2).\n */\n carrierRecords(data: Record<string, any> | undefined): CarrierRecord[] {\n const layout = this._validLoadLayout\n if (!layout) {\n this._loadOccupancy = undefined\n return super.carrierRecords(data)\n }\n const incoming = incomingFromV2(data)\n const occupancy = resolveOccupancy(layout, incoming, this._loadOccupancy)\n this._loadOccupancy = occupancy\n const stateOf = new Map(incoming.map(c => [c.name, (this as any).carrierStateOf(c.record, c.record === data)] as const))\n if (stateOf.size !== incoming.length) return incoming.map(c => ({ slotId: EXCEPTION_SLOT, itemId: c.name, itemState: stateOf.get(c.name)! }))\n const records: CarrierRecord[] = []\n for (const list of occupancy.slots.values()) for (const c of list) records.push({ slotId: slotIdOf(c.address), itemId: c.name, itemState: stateOf.get(c.name)! })\n // 예외는 정상 자리와 나눈 예외 영역에 차례로 둔다. 다른 정상 자리를 대신 쓰지 않는다\n for (const c of [...occupancy.addressUnknown, ...occupancy.addressError]) records.push({ slotId: EXCEPTION_SLOT, itemId: c.name, itemState: stateOf.get(c.name)! })\n return records\n }\n\n /** 예외 영역의 치수 모르는 Carrier 는 첫 자리를 채우는 표시용 상자로 보인다 */\n itemShownDimsOf(carrier: any, slot: ResolvedSlot, slotId: string): ItemDims | null {\n if (slotId !== EXCEPTION_SLOT) return super.itemShownDimsOf(carrier, slot, slotId)\n const first = this._firstSlot\n return first ? super.itemShownDimsOf(carrier, first, slotIdOf({ tier: first.tier, slot: first.slotNo })) : null\n }\n\n /** 예외 영역의 Carrier 는 첫 자리 폭의 절반만큼 더 떨어져 선다 */\n get exceptionHalfWidth(): number {\n const first = this._firstSlot\n return first && Number.isFinite(first.allowed.width) ? first.allowed.width / 2 : 0\n }\n\n get _firstSlot(): ResolvedSlot | null {\n const layout = this._validLoadLayout\n const address = layout ? [...slotAddresses(layout)][0] : undefined\n return layout && address ? resolveSlot(layout, address) : null\n }\n }\n}\n"]}
@@ -1,3 +1,32 @@
1
+ import { resolveLegend, resolveLegendEntries } from '@hatiolab/things-scene';
2
+ import { LEGEND_CARRIER, legendColor } from '@fmsim/figure-capabilities';
3
+ /* 범례 항목 모양과 캐리어 기본 범례는 피규어 능력과 한 곳(@fmsim/figure-capabilities, ADR-0167) */
4
+ export { LEGEND_CARRIER, legendColor };
5
+ /**
6
+ * 코드의 범례 항목: 그 코드의 항목, 없으면 `default` (ADR-0166 판정 6). things-scene 의 한 조회(resolveLegend)로 읽는다 — 피규어의 표와
7
+ * 보드 매핑이 읽는 것과 같다.
8
+ */
9
+ export function legendEntryOf(code, legend) {
10
+ return resolveLegend(code, legend);
11
+ }
12
+ /**
13
+ * 수의 구간 범례 항목: 키 `from~to`(from 이상 to 미만, 한쪽 열림 가능)에서 그 값을 품은 항목, 없으면 `default`. 값이 없거나 수가 아니면
14
+ * `default` 다(ADR-0166 판정 6 — 0 으로 읽지 않는다). things-scene 의 한 조회(resolveLegendEntries)로 읽는다.
15
+ */
16
+ export function legendRangeEntryOf(value, legend) {
17
+ if (!legend)
18
+ return undefined;
19
+ const entries = [];
20
+ for (const [key, entry] of Object.entries(legend)) {
21
+ if (key === 'default')
22
+ continue;
23
+ const [from = '', to = ''] = key.split('~');
24
+ if (!key.includes('~'))
25
+ continue;
26
+ entries.push({ min: from === '' ? null : from, max: to === '' ? null : to, result: entry });
27
+ }
28
+ return resolveLegendEntries(value, entries, legend.default);
29
+ }
1
30
  export const LEGEND_NULL = { default: '#F0F0F0' };
2
31
  export const LEGEND_MACHINE = {
3
32
  '1000': '#707070', // DISCONNECTED
@@ -45,12 +74,6 @@ export const LEGEND_CRANE = {
45
74
  // '3006': '#EB3245', // NOTINSERVICE
46
75
  default: '#F0F0F0'
47
76
  };
48
- export const LEGEND_CARRIER = {
49
- FULL: '#4AA7FE',
50
- EMPTY: '#8BDA5B',
51
- EMPTYEMPTY: '#019D59',
52
- default: '#F0F0F0'
53
- };
54
77
  /**
55
78
  * carrier legend(테마) 해석 — carrier 컴포넌트(carrier.ts get legend)와 동일 로직 단일 소스.
56
79
  * parent 에 carrierLegendName 이 지정되면 그 style 을, 아니면 board 전역 carrierLegendTheme,
@@ -68,7 +91,7 @@ export const LEGEND_CAPACITY = {
68
91
  '0~20': '#5630D0',
69
92
  '20~80': '#8BDA5B',
70
93
  '80~': '#FD9B00', // 80% 이상 (= 100% 초과도 포함). 'from~' 형식이라
71
- // getValueOnRanges 가 value >= 80 매칭.
94
+ // legendRangeEntryOf 가 value >= 80 매칭.
72
95
  default: '#F0F0F0'
73
96
  };
74
97
  export const BATTERY_RATE_LEGEND = {
@@ -1 +1 @@
1
- {"version":3,"file":"mcs-status-default.js","sourceRoot":"","sources":["../../src/features/mcs-status-default.ts"],"names":[],"mappings":"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","sourcesContent":["export interface Legend {\n [key: string]: string\n}\n\nexport const LEGEND_NULL: Legend = { default: '#F0F0F0' }\n\nexport const LEGEND_MACHINE: Legend = {\n '1000': '#707070', // DISCONNECTED\n '1001': '#8BDA5B', // UP\n '1002': '#EB3245', // OUTOFSERVICE\n '1003': '#5630D0', // PM\n '1004': '#FFFFFF', // NOTONLINE\n '1005': '#404040', // DOWN\n '1006': '#F4F226', // NOTAUTO\n '1007': '#FD9B00', // ALARM\n '1008': '#4AA7FE', // FULL\n default: '#F0F0F0'\n}\n\nexport const LEGEND_VEHICLE: Legend = {\n '4000': '#EB3245', // OUTOFSERVICE\n '4001': '#8BDA5B', // ASSIGNED\n // '4002': '#cbf266', // ASSIGNED_ACQUIRING\n // '4003': '#cbf266', // ASSIGNED_DEPOSITING\n // '4004': '#cbf266', // ASSIGNED_ENROUTE\n // '4005': '#cbf266', // ASSIGNED_PARKED\n '4006': '#FD9B00', // NOTASSIGNED\n '4007': '#32D1C4', // INSTALLED\n '4008': '#9790EC', // CHARGING\n '4009': '#4AA7FE', // CHARGED\n '4010': '#404040', // REMOVED\n default: '#F0F0F0'\n}\n\nexport const LEGEND_UNIT: Legend = {\n '2000': '#FD9B00', // BANNED\n '2001': '#404040', // DOWN\n '2002': '#8BDA5B', // EMPTY\n '2003': '#FFFFFF', // EMPTY_RESERVED\n '2004': '#32D1C4', // FULL_RESERVED\n '2005': '#4AA7FE', // FULL\n '2006': '#EB3245', // NOTINSERVICE\n default: '#F0F0F0'\n}\n\nexport const LEGEND_CRANE: Legend = {\n '3000': '#EB3245', // OUTOFSERVICE\n // '3001': '#404040', // DOWN\n // '3002': '#8BDA5B', // EMPTY\n '3003': '#FFFFFF', // IDLE\n '3004': '#32D1C4', // ACTIVE\n // '3005': '#4AA7FE', // FULL\n // '3006': '#EB3245', // NOTINSERVICE\n default: '#F0F0F0'\n}\n\nexport const LEGEND_CARRIER: Legend = {\n FULL: '#4AA7FE',\n EMPTY: '#8BDA5B',\n EMPTYEMPTY: '#019D59',\n default: '#F0F0F0'\n}\n\n/**\n * carrier legend(테마) 해석 — carrier 컴포넌트(carrier.ts get legend)와 동일 로직 단일 소스.\n * parent 에 carrierLegendName 이 지정되면 그 style 을, 아니면 board 전역 carrierLegendTheme,\n * 둘 다 없으면 LEGEND_CARRIER 기본값. carrier 컴포넌트·스토커 게이지(2D/3D)가 공유한다.\n */\nexport function resolveCarrierLegend(component: any): Legend {\n const carrierLegendName = component?.parent?.state?.carrierLegendName\n if (carrierLegendName) {\n return (component.root as any)?.style?.[carrierLegendName] || LEGEND_CARRIER\n }\n return (component.root as any)?.carrierLegendTheme || LEGEND_CARRIER\n}\n\nexport const LEGEND_CAPACITY: Legend = {\n '0~20': '#5630D0',\n '20~80': '#8BDA5B',\n '80~': '#FD9B00', // 80% 이상 (= 100% 초과도 포함). 'from~' 형식이라\n // getValueOnRanges 가 value >= 80 매칭.\n default: '#F0F0F0'\n}\n\nexport const BATTERY_RATE_LEGEND: Legend = {\n '0~20': '#EB3245', // 0-20%: 빨간색 (위험)\n '20~40': '#FD9B00', // 20-40%: 주황색 (경고)\n '40~60': '#F4F226', // 40-60%: 노란색 (주의)\n '60~100': '#8BDA5B', // 60-100%: 녹색 (정상)\n default: '#F0F0F0'\n}\n"]}
1
+ {"version":3,"file":"mcs-status-default.js","sourceRoot":"","sources":["../../src/features/mcs-status-default.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolveLegend, resolveLegendEntries, type LegendEntry as RangeEntry } from '@hatiolab/things-scene'\nimport { LEGEND_CARRIER, legendColor, type Legend, type LegendEntry } from '@fmsim/figure-capabilities'\n\n/* 범례 항목 모양과 캐리어 기본 범례는 피규어 능력과 한 곳(@fmsim/figure-capabilities, ADR-0167) */\nexport { LEGEND_CARRIER, legendColor, type Legend, type LegendEntry }\n\n/**\n * 코드의 범례 항목: 그 코드의 항목, 없으면 `default` (ADR-0166 판정 6). things-scene 의 한 조회(resolveLegend)로 읽는다 — 피규어의 표와\n * 보드 매핑이 읽는 것과 같다.\n */\nexport function legendEntryOf(code: unknown, legend: Legend | null | undefined): LegendEntry | undefined {\n return resolveLegend(code, legend)\n}\n\n/**\n * 수의 구간 범례 항목: 키 `from~to`(from 이상 to 미만, 한쪽 열림 가능)에서 그 값을 품은 항목, 없으면 `default`. 값이 없거나 수가 아니면\n * `default` 다(ADR-0166 판정 6 — 0 으로 읽지 않는다). things-scene 의 한 조회(resolveLegendEntries)로 읽는다.\n */\nexport function legendRangeEntryOf(value: unknown, legend: Legend | null | undefined): LegendEntry | undefined {\n if (!legend) return undefined\n const entries: RangeEntry<LegendEntry>[] = []\n for (const [key, entry] of Object.entries(legend)) {\n if (key === 'default') continue\n const [from = '', to = ''] = key.split('~')\n if (!key.includes('~')) continue\n entries.push({ min: from === '' ? null : from, max: to === '' ? null : to, result: entry })\n }\n return resolveLegendEntries(value, entries, legend.default)\n}\n\nexport const LEGEND_NULL: Legend = { default: '#F0F0F0' }\n\nexport const LEGEND_MACHINE: Legend = {\n '1000': '#707070', // DISCONNECTED\n '1001': '#8BDA5B', // UP\n '1002': '#EB3245', // OUTOFSERVICE\n '1003': '#5630D0', // PM\n '1004': '#FFFFFF', // NOTONLINE\n '1005': '#404040', // DOWN\n '1006': '#F4F226', // NOTAUTO\n '1007': '#FD9B00', // ALARM\n '1008': '#4AA7FE', // FULL\n default: '#F0F0F0'\n}\n\nexport const LEGEND_VEHICLE: Legend = {\n '4000': '#EB3245', // OUTOFSERVICE\n '4001': '#8BDA5B', // ASSIGNED\n // '4002': '#cbf266', // ASSIGNED_ACQUIRING\n // '4003': '#cbf266', // ASSIGNED_DEPOSITING\n // '4004': '#cbf266', // ASSIGNED_ENROUTE\n // '4005': '#cbf266', // ASSIGNED_PARKED\n '4006': '#FD9B00', // NOTASSIGNED\n '4007': '#32D1C4', // INSTALLED\n '4008': '#9790EC', // CHARGING\n '4009': '#4AA7FE', // CHARGED\n '4010': '#404040', // REMOVED\n default: '#F0F0F0'\n}\n\nexport const LEGEND_UNIT: Legend = {\n '2000': '#FD9B00', // BANNED\n '2001': '#404040', // DOWN\n '2002': '#8BDA5B', // EMPTY\n '2003': '#FFFFFF', // EMPTY_RESERVED\n '2004': '#32D1C4', // FULL_RESERVED\n '2005': '#4AA7FE', // FULL\n '2006': '#EB3245', // NOTINSERVICE\n default: '#F0F0F0'\n}\n\nexport const LEGEND_CRANE: Legend = {\n '3000': '#EB3245', // OUTOFSERVICE\n // '3001': '#404040', // DOWN\n // '3002': '#8BDA5B', // EMPTY\n '3003': '#FFFFFF', // IDLE\n '3004': '#32D1C4', // ACTIVE\n // '3005': '#4AA7FE', // FULL\n // '3006': '#EB3245', // NOTINSERVICE\n default: '#F0F0F0'\n}\n\n/**\n * carrier legend(테마) 해석 — carrier 컴포넌트(carrier.ts get legend)와 동일 로직 단일 소스.\n * parent 에 carrierLegendName 이 지정되면 그 style 을, 아니면 board 전역 carrierLegendTheme,\n * 둘 다 없으면 LEGEND_CARRIER 기본값. carrier 컴포넌트·스토커 게이지(2D/3D)가 공유한다.\n */\nexport function resolveCarrierLegend(component: any): Legend {\n const carrierLegendName = component?.parent?.state?.carrierLegendName\n if (carrierLegendName) {\n return (component.root as any)?.style?.[carrierLegendName] || LEGEND_CARRIER\n }\n return (component.root as any)?.carrierLegendTheme || LEGEND_CARRIER\n}\n\nexport const LEGEND_CAPACITY: Legend = {\n '0~20': '#5630D0',\n '20~80': '#8BDA5B',\n '80~': '#FD9B00', // 80% 이상 (= 100% 초과도 포함). 'from~' 형식이라\n // legendRangeEntryOf 가 value >= 80 매칭.\n default: '#F0F0F0'\n}\n\nexport const BATTERY_RATE_LEGEND: Legend = {\n '0~20': '#EB3245', // 0-20%: 빨간색 (위험)\n '20~40': '#FD9B00', // 20-40%: 주황색 (경고)\n '40~60': '#F4F226', // 40-60%: 노란색 (주의)\n '60~100': '#8BDA5B', // 60-100%: 녹색 (정상)\n default: '#F0F0F0'\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { themesColorMap } from '@fmsim/api';
2
- import { LEGEND_NULL } from './mcs-status-default';
2
+ import { LEGEND_NULL, legendColor, legendEntryOf } from './mcs-status-default';
3
3
  export const MCSStatusMixinProperties = [
4
4
  {
5
5
  type: 'select',
@@ -30,12 +30,12 @@ export function MCSStatusMixin(Base) {
30
30
  get statusColor() {
31
31
  const status = this.status;
32
32
  const legend = this.legend;
33
- return (status && legend && (legend[status] || legend[status] || legend.default)) || (legend === null || legend === void 0 ? void 0 : legend.default) || '#F0F0F0';
33
+ return (status && legend && legendColor(legendEntryOf(status, legend))) || legendColor(legend === null || legend === void 0 ? void 0 : legend.default) || '#F0F0F0';
34
34
  }
35
35
  get auxColor() {
36
36
  const status = this.auxStatus;
37
37
  const legend = this.auxLegend;
38
- return (status && legend && (legend[status] || legend[status] || legend.default)) || (legend === null || legend === void 0 ? void 0 : legend.default);
38
+ return (status && legend && legendColor(legendEntryOf(status, legend))) || legendColor(legend === null || legend === void 0 ? void 0 : legend.default);
39
39
  }
40
40
  /**
41
41
  * 데이터 변경 시 status 기반 색상을 state.fillStyle 로 반영.
@@ -1 +1 @@
1
- {"version":3,"file":"mcs-status-mixin.js","sourceRoot":"","sources":["../../src/features/mcs-status-mixin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAQlD,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC;QACE,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,aAAa;QACpB,IAAI,EAAE,YAAY;QAClB,QAAQ,EAAE;YACR,OAAO,EAAE,cAAc;SACxB;KACF;CACF,CAAA;AAED,MAAM,UAAU,cAAc,CAAuC,IAAW;IAC9E,OAAO,KAAM,SAAQ,IAAI;QACvB,aAAa;YACX,OAAO,IAAI,CAAA;QACb,CAAC;QAED,IAAI,MAAM;YACR,OAAM;QACR,CAAC;QAED,IAAI,SAAS;YACX,OAAM;QACR,CAAC;QAED,IAAI,MAAM;YACR,OAAO,WAAW,CAAA;QACpB,CAAC;QAED,IAAI,SAAS;YACX,OAAO,WAAW,CAAA;QACpB,CAAC;QAED,IAAI,WAAW;YACb,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;YAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;YAE1B,OAAO,CAAC,MAAM,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,KAAI,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,OAAO,CAAA,IAAI,SAAS,CAAA;QACpH,CAAC;QAED,IAAI,QAAQ;YACV,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAA;YAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAA;YAE7B,OAAO,CAAC,MAAM,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,KAAI,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,OAAO,CAAA,CAAA;QACvG,CAAC;QAED;;;;;;;WAOG;QACH,YAAY,CAAC,KAAU,EAAE,MAAW;;YAClC,6CAA6C;YAC7C,yEAAyE;YACzE,MAAM,YAAY,GAAI,IAAI,CAAC,SAAiB,CAAC,YAAY,CAAA;YACzD,IAAI,OAAO,YAAY,KAAK,UAAU,EAAE,CAAC;gBACvC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;YACxC,CAAC;YACD,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAA;YAC9B,IAAI,KAAK,IAAI,KAAK,MAAK,MAAC,IAAY,CAAC,KAAK,0CAAE,SAAS,CAAA,EAAE,CAAC;gBACtD,CAAC;gBAAC,IAAY,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;YAC7C,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC","sourcesContent":["import { Component } from '@hatiolab/things-scene'\nimport { themesColorMap } from '@fmsim/api'\nimport { LEGEND_NULL } from './mcs-status-default'\n\ntype Constructor<T = {}> = new (...args: any[]) => T\n\ninterface Legend {\n [key: string]: string\n}\n\nexport const MCSStatusMixinProperties = [\n {\n type: 'select',\n label: 'legend-name',\n name: 'legendName',\n property: {\n options: themesColorMap\n }\n }\n]\n\nexport function MCSStatusMixin<TBase extends Constructor<Component>>(Base: TBase): any {\n return class extends Base {\n isLVComponent() {\n return true\n }\n\n get status(): string | undefined {\n return\n }\n\n get auxStatus(): string | undefined {\n return\n }\n\n get legend(): Legend {\n return LEGEND_NULL\n }\n\n get auxLegend(): Legend {\n return LEGEND_NULL\n }\n\n get statusColor(): string | undefined {\n const status = this.status\n const legend = this.legend\n\n return (status && legend && (legend[status] || legend[status!] || legend.default)) || legend?.default || '#F0F0F0'\n }\n\n get auxColor(): string | undefined {\n const status = this.auxStatus\n const legend = this.auxLegend\n\n return (status && legend && (legend[status] || legend[status!] || legend.default)) || legend?.default\n }\n\n /**\n * 데이터 변경 시 status 기반 색상을 state.fillStyle 로 반영.\n * things-scene 표준 경로(updateFillStyle)가 2D/3D 모두 자동 갱신하도록 유도.\n *\n * 주의: state.fillStyle 이 runtime 색상으로 덮어써짐. 모델 저장 시 status 색상이\n * 남을 수 있는 트레이드오프가 있음 (data-driven 컴포넌트의 fillStyle 은 의미상\n * 초기값일 뿐 항상 status 가 덮어쓰는 것이 자연스러움).\n */\n onchangeData(after: any, before: any) {\n // Base (mixin 인자) 의 onchangeData 를 렉시컬하게 호출.\n // Object.getPrototypeOf(this) 는 leaf 를 가리켜 무한재귀되므로 Base.prototype 직접 사용.\n const baseOnchange = (Base.prototype as any).onchangeData\n if (typeof baseOnchange === 'function') {\n baseOnchange.call(this, after, before)\n }\n const color = this.statusColor\n if (color && color !== (this as any).state?.fillStyle) {\n ;(this as any).setState('fillStyle', color)\n }\n }\n }\n}\n"]}
1
+ {"version":3,"file":"mcs-status-mixin.js","sourceRoot":"","sources":["../../src/features/mcs-status-mixin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAU,WAAW,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAItF,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC;QACE,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,aAAa;QACpB,IAAI,EAAE,YAAY;QAClB,QAAQ,EAAE;YACR,OAAO,EAAE,cAAc;SACxB;KACF;CACF,CAAA;AAED,MAAM,UAAU,cAAc,CAAuC,IAAW;IAC9E,OAAO,KAAM,SAAQ,IAAI;QACvB,aAAa;YACX,OAAO,IAAI,CAAA;QACb,CAAC;QAED,IAAI,MAAM;YACR,OAAM;QACR,CAAC;QAED,IAAI,SAAS;YACX,OAAM;QACR,CAAC;QAED,IAAI,MAAM;YACR,OAAO,WAAW,CAAA;QACpB,CAAC;QAED,IAAI,SAAS;YACX,OAAO,WAAW,CAAA;QACpB,CAAC;QAED,IAAI,WAAW;YACb,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;YAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;YAE1B,OAAO,CAAC,MAAM,IAAI,MAAM,IAAI,WAAW,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,OAAO,CAAC,IAAI,SAAS,CAAA;QACtH,CAAC;QAED,IAAI,QAAQ;YACV,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAA;YAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAA;YAE7B,OAAO,CAAC,MAAM,IAAI,MAAM,IAAI,WAAW,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,OAAO,CAAC,CAAA;QACzG,CAAC;QAED;;;;;;;WAOG;QACH,YAAY,CAAC,KAAU,EAAE,MAAW;;YAClC,6CAA6C;YAC7C,yEAAyE;YACzE,MAAM,YAAY,GAAI,IAAI,CAAC,SAAiB,CAAC,YAAY,CAAA;YACzD,IAAI,OAAO,YAAY,KAAK,UAAU,EAAE,CAAC;gBACvC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;YACxC,CAAC;YACD,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAA;YAC9B,IAAI,KAAK,IAAI,KAAK,MAAK,MAAC,IAAY,CAAC,KAAK,0CAAE,SAAS,CAAA,EAAE,CAAC;gBACtD,CAAC;gBAAC,IAAY,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;YAC7C,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC","sourcesContent":["import { Component } from '@hatiolab/things-scene'\nimport { themesColorMap } from '@fmsim/api'\nimport { LEGEND_NULL, Legend, legendColor, legendEntryOf } from './mcs-status-default'\n\ntype Constructor<T = {}> = new (...args: any[]) => T\n\nexport const MCSStatusMixinProperties = [\n {\n type: 'select',\n label: 'legend-name',\n name: 'legendName',\n property: {\n options: themesColorMap\n }\n }\n]\n\nexport function MCSStatusMixin<TBase extends Constructor<Component>>(Base: TBase): any {\n return class extends Base {\n isLVComponent() {\n return true\n }\n\n get status(): string | undefined {\n return\n }\n\n get auxStatus(): string | undefined {\n return\n }\n\n get legend(): Legend {\n return LEGEND_NULL\n }\n\n get auxLegend(): Legend {\n return LEGEND_NULL\n }\n\n get statusColor(): string | undefined {\n const status = this.status\n const legend = this.legend\n\n return (status && legend && legendColor(legendEntryOf(status, legend))) || legendColor(legend?.default) || '#F0F0F0'\n }\n\n get auxColor(): string | undefined {\n const status = this.auxStatus\n const legend = this.auxLegend\n\n return (status && legend && legendColor(legendEntryOf(status, legend))) || legendColor(legend?.default)\n }\n\n /**\n * 데이터 변경 시 status 기반 색상을 state.fillStyle 로 반영.\n * things-scene 표준 경로(updateFillStyle)가 2D/3D 모두 자동 갱신하도록 유도.\n *\n * 주의: state.fillStyle 이 runtime 색상으로 덮어써짐. 모델 저장 시 status 색상이\n * 남을 수 있는 트레이드오프가 있음 (data-driven 컴포넌트의 fillStyle 은 의미상\n * 초기값일 뿐 항상 status 가 덮어쓰는 것이 자연스러움).\n */\n onchangeData(after: any, before: any) {\n // Base (mixin 인자) 의 onchangeData 를 렉시컬하게 호출.\n // Object.getPrototypeOf(this) 는 leaf 를 가리켜 무한재귀되므로 Base.prototype 직접 사용.\n const baseOnchange = (Base.prototype as any).onchangeData\n if (typeof baseOnchange === 'function') {\n baseOnchange.call(this, after, before)\n }\n const color = this.statusColor\n if (color && color !== (this as any).state?.fillStyle) {\n ;(this as any).setState('fillStyle', color)\n }\n }\n }\n}\n"]}
package/dist/index.js CHANGED
@@ -45,6 +45,8 @@ import './static-container';
45
45
  import './clickable-popup';
46
46
  // ── groups ──
47
47
  export { default as MachineGroups } from './groups';
48
+ // ── legends ──
49
+ export { legendColor, legendEntryOf, legendRangeEntryOf } from './features/mcs-status-default';
48
50
  // ── base classes ──
49
51
  export { default as MCSMachine } from './mcs-machine';
50
52
  export { default as MCSUnit } from './mcs-unit';
@@ -76,6 +78,7 @@ export { default as Port } from './port';
76
78
  export { default as Crane } from './crane';
77
79
  export { default as Shelf } from './shelf';
78
80
  export { default as Carrier } from './carrier';
81
+ export { CARRIER_HOLDER_PROPERTIES, CarrierHolder, carrierHolderLegend } from './mcs-carrier-holder';
79
82
  // ── topology ──
80
83
  export { default as Node } from './node';
81
84
  export { default as NodePath } from './node-path';
@@ -83,4 +86,6 @@ export { default as NodePath } from './node-path';
83
86
  export { default as FloatingContainer } from './floating-container';
84
87
  export { default as StaticContainer } from './static-container';
85
88
  export { default as ClickablePopup } from './clickable-popup';
89
+ // ── CARRIERTYPE 을 아이템 타입 코드로 맞추는 규칙 (01번 6.8절, ADR-0155) ──
90
+ export { normalizeTypeCode } from './utils/carrier-type-code';
86
91
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// ── side-effect: scene override ──\nimport './scene/root-container-override'\n\n// ── side-effect: 3D factories ──\nimport './factories/machine-3d'\nimport './factories/conveyor-3d'\nimport './factories/agv-3d'\nimport './factories/oht-3d'\nimport './factories/shuttle-3d'\nimport './factories/crane-3d'\nimport './factories/crane-rail-3d'\n// 기본 factory (RealObjectDomTexture) 쓰는 컴포넌트들의 z-priority override\nimport './factories/z-priority-defaults'\n\n// ── side-effect: @sceneComponent 등록 (tree-shaking 방지) ──\n// bars & overlays\nimport './zone-capacity-bar'\nimport './stocker-capacity-bar'\nimport './stocker-carrier-bar'\nimport './stocker-abnormal-bar'\nimport './port-flow'\n\n// facilities\nimport './agv-line'\nimport './buffer'\nimport './conveyor'\nimport './conveyor-join'\nimport './equipment'\nimport './oht-line'\nimport './stocker'\nimport './crane-rail'\nimport './scanner'\n\n// vehicles\nimport './agv'\nimport './oht'\nimport './shuttle'\n\n// units\nimport './port'\nimport './crane'\nimport './shelf'\nimport './carrier'\n\n// topology\nimport './node'\nimport './node-path'\n\n// containers\nimport './floating-container'\nimport './static-container'\nimport './clickable-popup'\n\n// ── groups ──\nexport { default as MachineGroups } from './groups'\n\n// ── base classes ──\nexport { default as MCSMachine } from './mcs-machine'\nexport { default as MCSUnit } from './mcs-unit'\nexport { default as MCSCarrierHolder } from './mcs-carrier-holder'\nexport { default as MCSVehicle } from './mcs-vehicle'\nexport { default as MCSTransport } from './mcs-transport'\n\n// ── bars & overlays ──\nexport { default as ZoneCapacityBar } from './zone-capacity-bar'\nexport { default as StockerCapacityBar } from './stocker-capacity-bar'\nexport { default as StockerCarrierBar } from './stocker-carrier-bar'\nexport { default as StockerAbnormalBar } from './stocker-abnormal-bar'\nexport { default as PortFlow } from './port-flow'\n\n// ── facilities ──\nexport { default as AGVLine } from './agv-line'\nexport { default as Buffer } from './buffer'\nexport { default as Conveyor } from './conveyor'\nexport { default as ConveyorJoin } from './conveyor-join'\nexport { default as Equipment } from './equipment'\nexport { default as OHTLine } from './oht-line'\nexport { default as Stocker } from './stocker'\nexport { default as CraneRail } from './crane-rail'\nexport { default as Scanner } from './scanner'\n\n// ── vehicles ──\nexport { default as AGV } from './agv'\nexport { default as OHT } from './oht'\nexport { default as Shuttle } from './shuttle'\n\n// ── units ──\nexport { default as Port } from './port'\nexport { default as Crane } from './crane'\nexport { default as Shelf } from './shelf'\nexport { default as Carrier } from './carrier'\n\n// ── topology ──\nexport { default as Node } from './node'\nexport { default as NodePath } from './node-path'\n\n// ── containers ──\nexport { default as FloatingContainer } from './floating-container'\nexport { default as StaticContainer } from './static-container'\nexport { default as ClickablePopup } from './clickable-popup'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// ── side-effect: scene override ──\nimport './scene/root-container-override'\n\n// ── side-effect: 3D factories ──\nimport './factories/machine-3d'\nimport './factories/conveyor-3d'\nimport './factories/agv-3d'\nimport './factories/oht-3d'\nimport './factories/shuttle-3d'\nimport './factories/crane-3d'\nimport './factories/crane-rail-3d'\n// 기본 factory (RealObjectDomTexture) 쓰는 컴포넌트들의 z-priority override\nimport './factories/z-priority-defaults'\n\n// ── side-effect: @sceneComponent 등록 (tree-shaking 방지) ──\n// bars & overlays\nimport './zone-capacity-bar'\nimport './stocker-capacity-bar'\nimport './stocker-carrier-bar'\nimport './stocker-abnormal-bar'\nimport './port-flow'\n\n// facilities\nimport './agv-line'\nimport './buffer'\nimport './conveyor'\nimport './conveyor-join'\nimport './equipment'\nimport './oht-line'\nimport './stocker'\nimport './crane-rail'\nimport './scanner'\n\n// vehicles\nimport './agv'\nimport './oht'\nimport './shuttle'\n\n// units\nimport './port'\nimport './crane'\nimport './shelf'\nimport './carrier'\n\n// topology\nimport './node'\nimport './node-path'\n\n// containers\nimport './floating-container'\nimport './static-container'\nimport './clickable-popup'\n\n// ── groups ──\nexport { default as MachineGroups } from './groups'\n\n// ── legends ──\nexport { legendColor, legendEntryOf, legendRangeEntryOf, type Legend, type LegendEntry } from './features/mcs-status-default'\n\n// ── base classes ──\nexport { default as MCSMachine } from './mcs-machine'\nexport { default as MCSUnit } from './mcs-unit'\nexport { default as MCSCarrierHolder } from './mcs-carrier-holder'\nexport { default as MCSVehicle } from './mcs-vehicle'\nexport { default as MCSTransport } from './mcs-transport'\n\n// ── bars & overlays ──\nexport { default as ZoneCapacityBar } from './zone-capacity-bar'\nexport { default as StockerCapacityBar } from './stocker-capacity-bar'\nexport { default as StockerCarrierBar } from './stocker-carrier-bar'\nexport { default as StockerAbnormalBar } from './stocker-abnormal-bar'\nexport { default as PortFlow } from './port-flow'\n\n// ── facilities ──\nexport { default as AGVLine } from './agv-line'\nexport { default as Buffer } from './buffer'\nexport { default as Conveyor } from './conveyor'\nexport { default as ConveyorJoin } from './conveyor-join'\nexport { default as Equipment } from './equipment'\nexport { default as OHTLine } from './oht-line'\nexport { default as Stocker } from './stocker'\nexport { default as CraneRail } from './crane-rail'\nexport { default as Scanner } from './scanner'\n\n// ── vehicles ──\nexport { default as AGV } from './agv'\nexport { default as OHT } from './oht'\nexport { default as Shuttle } from './shuttle'\n\n// ── units ──\nexport { default as Port } from './port'\nexport { default as Crane } from './crane'\nexport { default as Shelf } from './shelf'\nexport { default as Carrier } from './carrier'\nexport { CARRIER_HOLDER_PROPERTIES, CarrierHolder, carrierHolderLegend } from './mcs-carrier-holder'\n\n// ── topology ──\nexport { default as Node } from './node'\nexport { default as NodePath } from './node-path'\n\n// ── containers ──\nexport { default as FloatingContainer } from './floating-container'\nexport { default as StaticContainer } from './static-container'\nexport { default as ClickablePopup } from './clickable-popup'\n\n// ── CARRIERTYPE 을 아이템 타입 코드로 맞추는 규칙 (01번 6.8절, ADR-0155) ──\nexport { normalizeTypeCode } from './utils/carrier-type-code'\n"]}