@operato/scene-visualizer 8.0.0-beta.1 → 8.0.0-beta.2

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/package.json +2 -2
  2. package/CHANGELOG.md +0 -649
  3. package/attachments/0d91a37d-c2d7-4c6d-88dc-a29e5bbea361.png +0 -0
  4. package/attachments/1b07c8d3-07d5-4007-b02e-031ee1755539.glb +0 -0
  5. package/attachments/226c6c23-c4fd-46c8-93e3-3d3d9c4bb8a9.glb +0 -0
  6. package/attachments/4425ca46-cf1d-476d-9185-dcb881ecad1f.glb +0 -0
  7. package/attachments/51e7c45d-6eae-4baf-a4e2-ba979b7e77cd.glb +0 -0
  8. package/attachments/54427925-c109-4499-875c-fb14207b95c5.glb +0 -0
  9. package/attachments/8cc70a65-e20f-4187-83c8-64deb3faf3d9.glb +0 -0
  10. package/attachments/964d004d-1fe7-4224-89a6-2b6e86db233c.glb +0 -0
  11. package/attachments/ff47fd63-6f1c-4a69-b965-9bb03797a415.png +0 -0
  12. package/db.sqlite +0 -0
  13. package/demo/index-modeller.html +0 -112
  14. package/demo/index.html +0 -109
  15. package/logs/.08636eb59927f12972f6774f5947c8507b3564c2-audit.json +0 -25
  16. package/logs/.5e5d741d8b7784a2fbad65eedc0fd46946aaf6f2-audit.json +0 -25
  17. package/logs/application-2025-01-07-10.log +0 -106
  18. package/logs/application-2025-01-07-14.log +0 -4
  19. package/logs/application-2025-01-07-15.log +0 -4
  20. package/logs/connections-2025-01-07-10.log +0 -106
  21. package/logs/connections-2025-01-07-14.log +0 -53
  22. package/logs/connections-2025-01-07-15.log +0 -53
  23. package/schema.graphql +0 -4552
  24. package/src/banner.ts +0 -88
  25. package/src/camera.ts +0 -132
  26. package/src/component.d.ts +0 -10
  27. package/src/cube.ts +0 -39
  28. package/src/cylinder.ts +0 -39
  29. package/src/desk.ts +0 -135
  30. package/src/editors/index.ts +0 -13
  31. package/src/editors/property-editor-gltf-info.ts +0 -135
  32. package/src/editors/property-editor-location-increase-pattern.ts +0 -260
  33. package/src/effects/outline.ts +0 -54
  34. package/src/ellipse.ts +0 -37
  35. package/src/gltf-object.ts +0 -117
  36. package/src/html-overlay-element.ts +0 -13
  37. package/src/index.ts +0 -29
  38. package/src/light.ts +0 -155
  39. package/src/polygon.ts +0 -88
  40. package/src/rack-table-cell.ts +0 -386
  41. package/src/rack-table.ts +0 -1296
  42. package/src/rack.ts +0 -232
  43. package/src/rect.ts +0 -39
  44. package/src/scene/component.ts +0 -38
  45. package/src/sphere.ts +0 -39
  46. package/src/sprite.ts +0 -30
  47. package/src/stock.ts +0 -262
  48. package/src/templates/3d-container.ts +0 -21
  49. package/src/templates/banner.ts +0 -21
  50. package/src/templates/camera.ts +0 -25
  51. package/src/templates/cube.ts +0 -20
  52. package/src/templates/cylinder.ts +0 -20
  53. package/src/templates/desk.ts +0 -20
  54. package/src/templates/gltf-object.ts +0 -20
  55. package/src/templates/index.ts +0 -29
  56. package/src/templates/light.ts +0 -23
  57. package/src/templates/pallet.ts +0 -20
  58. package/src/templates/rack-table.ts +0 -21
  59. package/src/templates/sphere.ts +0 -20
  60. package/src/templates/sprite.ts +0 -21
  61. package/src/templates/visualizer.ts +0 -21
  62. package/src/templates/wall.ts +0 -20
  63. package/src/text.ts +0 -10
  64. package/src/three-container-editor.ts +0 -187
  65. package/src/three-container.ts +0 -724
  66. package/src/three-controls.ts +0 -778
  67. package/src/three-layout.ts +0 -25
  68. package/src/three-space.ts +0 -732
  69. package/src/threed/common.ts +0 -21
  70. package/src/threed/floor/floor.ts +0 -62
  71. package/src/threed/html/elements.ts +0 -27
  72. package/src/threed/index.ts +0 -15
  73. package/src/threed/real-object-camera-meshed.ts +0 -67
  74. package/src/threed/real-object-camera.ts +0 -41
  75. package/src/threed/real-object-dom-element.ts +0 -55
  76. package/src/threed/real-object-dummy.ts +0 -13
  77. package/src/threed/real-object-extrude.ts +0 -210
  78. package/src/threed/real-object-gltf.ts +0 -136
  79. package/src/threed/real-object-group.ts +0 -35
  80. package/src/threed/real-object-mesh.ts +0 -74
  81. package/src/threed/real-object-plane.ts +0 -27
  82. package/src/threed/real-object-scene.ts +0 -84
  83. package/src/threed/real-object-sprite-2d.ts +0 -54
  84. package/src/threed/real-object-sprite.ts +0 -64
  85. package/src/threed/real-object-text.ts +0 -86
  86. package/src/threed/real-object.ts +0 -326
  87. package/src/threed/texture/canvas-texture.ts +0 -67
  88. package/src/threed/texture/text-texture.ts +0 -100
  89. package/src/threed/three-dimensional-container.ts +0 -9
  90. package/src/threed/utils/bound-uv-generator.ts +0 -80
  91. package/src/visualizer.ts +0 -319
  92. package/src/wall.ts +0 -50
  93. package/tsconfig.json +0 -24
  94. package/tsconfig.tsbuildinfo +0 -1
  95. package/web-dev-server.config.mjs +0 -27
package/src/rack-table.ts DELETED
@@ -1,1296 +0,0 @@
1
- /*
2
- * Copyright © HatioLab Inc. All rights reserved.
3
- */
4
-
5
- import * as THREE from 'three'
6
- import * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js'
7
-
8
- import {
9
- ApplicationContext,
10
- Component,
11
- ComponentNature,
12
- ContainerAbstract,
13
- Control,
14
- Layout,
15
- Model,
16
- POINT,
17
- Properties
18
- } from '@hatiolab/things-scene'
19
- import { Rack } from './rack'
20
- import { RackTableCell } from './rack-table-cell'
21
- import { RealObjectGroup } from './threed/real-object-group'
22
- import { RealObject } from './threed'
23
-
24
- const NATURE: ComponentNature = {
25
- mutable: false,
26
- resizable: true,
27
- rotatable: true,
28
- properties: [
29
- {
30
- type: 'number',
31
- label: 'rows',
32
- name: 'rows',
33
- property: 'rows'
34
- },
35
- {
36
- type: 'number',
37
- label: 'columns',
38
- name: 'columns',
39
- property: 'columns'
40
- },
41
- {
42
- type: 'string',
43
- label: 'zone',
44
- name: 'zone',
45
- property: 'zone'
46
- },
47
- {
48
- type: 'number',
49
- label: 'shelves',
50
- name: 'shelves',
51
- property: 'shelves'
52
- },
53
- {
54
- type: 'number',
55
- label: 'depth',
56
- name: 'depth',
57
- property: 'depth'
58
- },
59
- {
60
- type: 'string',
61
- label: 'location-pattern',
62
- name: 'locPattern',
63
- placeholder: '{z}{s}-{u}-{sh}'
64
- },
65
- {
66
- type: 'number',
67
- label: 'section-digits',
68
- name: 'sectionDigits',
69
- placeholder: '1, 2, 3, ...'
70
- },
71
- {
72
- type: 'number',
73
- label: 'unit-digits',
74
- name: 'unitDigits',
75
- placeholder: '1, 2, 3, ...'
76
- },
77
- {
78
- type: 'string',
79
- label: 'shelf-locations',
80
- name: 'shelfLocations',
81
- placeholder: '1,2,3,... / ,,,04'
82
- },
83
- {
84
- type: 'number',
85
- label: 'stock-scale',
86
- name: 'stockScale',
87
- property: {
88
- step: 0.01,
89
- min: 0,
90
- max: 1
91
- }
92
- },
93
- {
94
- type: 'checkbox',
95
- label: 'hide-rack-frame',
96
- name: 'hideRackFrame'
97
- }
98
- ],
99
- help: 'scene/component/rack-table'
100
- }
101
-
102
- type SIDE_KEY = 'all' | 'out' | 'left' | 'right' | 'top' | 'bottom' | 'leftright' | 'topbottom'
103
-
104
- const SIDES = {
105
- all: ['top', 'left', 'bottom', 'right'],
106
- out: ['top', 'left', 'bottom', 'right'],
107
- left: ['left'],
108
- right: ['right'],
109
- top: ['top'],
110
- bottom: ['bottom'],
111
- leftright: ['left', 'right'],
112
- topbottom: ['top', 'bottom']
113
- } as { [key: string]: SIDE_KEY[] }
114
-
115
- const CLEAR_STYLE = {
116
- strokeStyle: '',
117
- lineDash: 'solid',
118
- lineWidth: 0
119
- }
120
-
121
- const DEFAULT_STYLE = {
122
- strokeStyle: '#999',
123
- lineDash: 'solid',
124
- lineWidth: 1
125
- }
126
-
127
- const TABLE_LAYOUT = Layout.get('table')
128
-
129
- function buildNewCell(app: ApplicationContext) {
130
- return Model.compile(
131
- {
132
- type: 'rack-table-cell',
133
- strokeStyle: 'black',
134
- fillStyle: 'transparent',
135
- left: 0,
136
- top: 0,
137
- width: 1,
138
- height: 1,
139
- textWrap: true,
140
- isEmpty: false,
141
- border: buildBorderStyle(DEFAULT_STYLE, 'all')
142
- },
143
- app
144
- )
145
- }
146
-
147
- function buildCopiedCell(copy: Model, app: ApplicationContext) {
148
- var obj = JSON.parse(JSON.stringify(copy))
149
- delete obj.text
150
-
151
- return Model.compile(obj, app)
152
- }
153
-
154
- function buildBorderStyle(style: any, where: SIDE_KEY): { [key: string]: any } {
155
- return (SIDES[where] || []).reduce((border: { [key: string]: any }, side: string) => {
156
- border[side] = style
157
- return border
158
- }, {} as { [key: string]: any })
159
- }
160
-
161
- function setCellBorder(cell: RackTableCell, style: any, where: SIDE_KEY) {
162
- if (!cell) {
163
- return
164
- }
165
-
166
- cell.set('border', Object.assign({}, cell.getState('border') || {}, buildBorderStyle(style, where)))
167
- }
168
-
169
- function isLeftMost(total: number, columns: number, indices: number[], i: number) {
170
- return i == 0 || !(i % columns) || indices.indexOf(i - 1) == -1
171
- }
172
-
173
- function isRightMost(total: number, columns: number, indices: number[], i: number) {
174
- return i == total - 1 || i % columns == columns - 1 || indices.indexOf(i + 1) == -1
175
- }
176
-
177
- function isTopMost(total: number, columns: number, indices: number[], i: number) {
178
- return i < columns || indices.indexOf(i - columns) == -1
179
- }
180
-
181
- function isBottomMost(total: number, columns: number, indices: number[], i: number) {
182
- return i > total - columns - 1 || indices.indexOf(i + columns) == -1
183
- }
184
-
185
- function above(columns: number, i: number) {
186
- return i - columns
187
- }
188
-
189
- function below(columns: number, i: number) {
190
- return i + columns
191
- }
192
-
193
- function before(columns: number, i: number) {
194
- return !(i % columns) ? -1 : i - 1
195
- }
196
-
197
- function after(columns: number, i: number) {
198
- return !((i + 1) % columns) ? -1 : i + 1
199
- }
200
-
201
- function array(value: any, size: number) {
202
- var arr = []
203
- for (let i = 0; i < size; i++) arr.push(1)
204
- return arr
205
- }
206
-
207
- var columnControlHandler = {
208
- ondragmove: function (point: POINT, index: number, component: RackTable) {
209
- var { left, top, width, height } = component.textBounds
210
- var widths_sum = component.widths_sum
211
-
212
- var widths = component.widths.slice()
213
-
214
- /* 컨트롤의 원래 위치를 구한다. */
215
- var origin_pos_unit = widths.slice(0, index + 1).reduce((sum: number, width: number) => sum + width, 0)
216
- var origin_offset = left + (origin_pos_unit / widths_sum) * width
217
-
218
- /*
219
- * point의 좌표는 부모 레이어 기준의 x, y 값이다.
220
- * 따라서, 도형의 회전을 감안한 좌표로의 변환이 필요하다.
221
- * Transcoord시에는 point좌표가 부모까지 transcoord되어있는 상태이므로,
222
- * 컴포넌트자신에 대한 transcoord만 필요하다.(마지막 파라미터를 false로).
223
- */
224
- var transcoorded = component.transcoordP2S(point.x, point.y)
225
- var diff = transcoorded.x - origin_offset
226
-
227
- var diff_unit = (diff / width) * widths_sum
228
-
229
- var min_width_unit = (widths_sum / width) * 5 // 5픽셀정도를 최소로
230
-
231
- if (diff_unit < 0) diff_unit = -Math.min(widths[index] - min_width_unit, -diff_unit)
232
- else diff_unit = Math.min(widths[index + 1] - min_width_unit, diff_unit)
233
-
234
- widths[index] = Math.round((widths[index] + diff_unit) * 100) / 100
235
- widths[index + 1] = Math.round((widths[index + 1] - diff_unit) * 100) / 100
236
-
237
- component.set('widths', widths)
238
- }
239
- }
240
-
241
- var rowControlHandler = {
242
- ondragmove: function (point: POINT, index: number, component: RackTable) {
243
- var { left, top, width, height } = component.textBounds
244
- var heights_sum = component.heights_sum
245
-
246
- var heights = component.heights.slice()
247
-
248
- /* 컨트롤의 원래 위치를 구한다. */
249
- index -= component.columns - 1
250
- var origin_pos_unit = heights.slice(0, index + 1).reduce((sum: number, height: number) => sum + height, 0)
251
- var origin_offset = top + (origin_pos_unit / heights_sum) * height
252
-
253
- /*
254
- * point의 좌표는 부모 레이어 기준의 x, y 값이다.
255
- * 따라서, 도형의 회전을 감안한 좌표로의 변환이 필요하다.
256
- * Transcoord시에는 point좌표가 부모까지 transcoord되어있는 상태이므로,
257
- * 컴포넌트자신에 대한 transcoord만 필요하다.(마지막 파라미터를 false로).
258
- */
259
- var transcoorded = component.transcoordP2S(point.x, point.y)
260
- var diff = transcoorded.y - origin_offset
261
-
262
- var diff_unit = (diff / height) * heights_sum
263
-
264
- var min_height_unit = (heights_sum / height) * 5 // 5픽셀정도를 최소로
265
-
266
- if (diff_unit < 0) diff_unit = -Math.min(heights[index] - min_height_unit, -diff_unit)
267
- else diff_unit = Math.min(heights[index + 1] - min_height_unit, diff_unit)
268
-
269
- heights[index] = Math.round((heights[index] + diff_unit) * 100) / 100
270
- heights[index + 1] = Math.round((heights[index + 1] - diff_unit) * 100) / 100
271
-
272
- component.set('heights', heights)
273
- }
274
- }
275
-
276
- export class RackTable3d extends RealObjectGroup {
277
- build() {
278
- super.build()
279
-
280
- this.createRacks()
281
- }
282
-
283
- get position() {
284
- var { zPos = 0 } = this.component.state
285
-
286
- return {
287
- x: this.cx || 0,
288
- y: zPos,
289
- z: this.cy || 0
290
- }
291
- }
292
-
293
- createRacks() {
294
- var { rotation = 0, shelfLocations, shelves = 1 } = this.component.state
295
-
296
- this.object3d.rotation.y = -rotation
297
-
298
- const racks = (this.component as RackTable).components
299
- .map((cell: Component) => {
300
- let { shelfLocations: shelfLoc = shelfLocations, isEmpty } = cell.state
301
-
302
- if (!isEmpty) {
303
- cell.setState('shelfLocations', shelfLoc)
304
-
305
- var rack = new Rack(cell)
306
-
307
- rack.update()
308
- this.object3d.add(rack.object3d)
309
-
310
- return rack
311
- }
312
- return
313
- })
314
- .filter(rack => !!rack) as Rack[]
315
-
316
- this.mergeAndAddRackCommonObjects(racks)
317
- }
318
-
319
- mergeAndAddRackCommonObjects(racks: Rack[]) {
320
- var framesGeometries: THREE.BufferGeometry[] = []
321
- var boardsGeometries: THREE.BufferGeometry[] = []
322
-
323
- if (racks.length > 0) {
324
- racks.forEach(rack => {
325
- const geometry = rack.frame
326
-
327
- if (!geometry) {
328
- return
329
- }
330
-
331
- geometry.translate(rack.position.x, rack.position.y, rack.position.z)
332
- geometry.scale(rack.scale.x, rack.scale.y, rack.scale.z)
333
- framesGeometries.push(geometry)
334
- })
335
-
336
- if (framesGeometries.length > 0) {
337
- const frameMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(framesGeometries), Rack.frameMaterial)
338
- this.object3d.add(frameMesh)
339
- }
340
-
341
- racks.forEach(rack => {
342
- const geometry = rack.board
343
-
344
- if (!geometry) {
345
- return
346
- }
347
-
348
- geometry.translate(rack.position.x, rack.position.y, rack.position.z)
349
- geometry.scale(rack.scale.x, rack.scale.y, rack.scale.z)
350
- boardsGeometries.push(geometry)
351
- })
352
-
353
- if (boardsGeometries.length > 0) {
354
- const material = Rack.boardMaterial
355
- material.opacity = 0.5
356
- material.transparent = true
357
-
358
- const boardMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(boardsGeometries), material)
359
-
360
- this.object3d.add(boardMesh)
361
- }
362
- }
363
- }
364
-
365
- makeShelfString(pattern: string, shelf: number, length: number) {
366
- /**
367
- * pattern #: 숫자
368
- * pattern 0: 고정 자리수
369
- * pattern -: 역순
370
- */
371
-
372
- if (!pattern || !shelf || !length) return
373
-
374
- var isReverse = /^\-/.test(pattern)
375
- pattern = pattern.replace(/#+/, '#')
376
-
377
- var fixedLength = (pattern.match(/0/g) || []).length || 0
378
- var shelfString = String(isReverse ? length - shelf + 1 : shelf)
379
-
380
- if (shelfString.length > fixedLength && fixedLength > 0) {
381
- shelfString = shelfString.substring(shelfString.length - fixedLength)
382
- } else {
383
- var prefix = ''
384
- for (var i = 0; i < fixedLength - shelfString.length; i++) {
385
- prefix += '0'
386
- }
387
- shelfString = prefix + shelfString
388
- }
389
-
390
- return shelfString
391
- }
392
-
393
- updateAlpha() {}
394
- }
395
-
396
- export class RackTable extends ContainerAbstract {
397
- _focused_cell?: RackTableCell
398
-
399
- is3dish() {
400
- return true
401
- }
402
-
403
- buildRealObject(): RealObject | undefined {
404
- return new RackTable3d(this)
405
- }
406
-
407
- dispose() {
408
- super.dispose()
409
-
410
- delete this._focused_cell
411
- }
412
-
413
- created() {
414
- var tobeSize = this.rows * this.columns
415
- var gap = this.size() - tobeSize
416
-
417
- if (gap == 0) {
418
- return
419
- } else if (gap > 0) {
420
- let removals = this.components.slice(gap)
421
- this.remove(removals)
422
- } else {
423
- let newbies = []
424
-
425
- for (let i = 0; i < -gap; i++) newbies.push(buildNewCell(this.app))
426
-
427
- this.add(newbies)
428
- }
429
-
430
- var widths = this.getState('widths')
431
- var heights = this.getState('heights')
432
-
433
- if (!widths || widths.length < this.columns) this.set('widths', this.widths)
434
- if (!heights || heights.length < this.rows) this.set('heights', this.heights)
435
- }
436
-
437
- // 컴포넌트를 임의로 추가 및 삭제할 수 있는 지를 지정하는 속성임.
438
- get focusible() {
439
- return false
440
- }
441
-
442
- get widths(): number[] {
443
- var widths = this.getState('widths')
444
-
445
- if (!widths) return array(1, this.columns)
446
-
447
- if (widths.length < this.columns) return widths.concat(array(1, this.columns - widths.length))
448
- else if (widths.length > this.columns) return widths.slice(0, this.columns)
449
-
450
- return widths
451
- }
452
-
453
- get heights(): number[] {
454
- var heights = this.getState('heights')
455
-
456
- if (!heights) return array(1, this.rows)
457
-
458
- if (heights.length < this.rows) return heights.concat(array(1, this.rows - heights.length))
459
- else if (heights.length > this.rows) return heights.slice(0, this.rows)
460
-
461
- return heights
462
- }
463
-
464
- buildCells(newrows: number, newcolumns: number, oldrows: number, oldcolumns: number) {
465
- if (newrows < oldrows) {
466
- let removals = this.components.slice(oldcolumns * newrows)
467
- this.remove(removals)
468
- }
469
-
470
- var minrows = Math.min(newrows, oldrows)
471
-
472
- if (newcolumns > oldcolumns) {
473
- for (let r = 0; r < minrows; r++) {
474
- for (let c = oldcolumns; c < newcolumns; c++) {
475
- this.insertComponentAt(buildNewCell(this.app), r * newcolumns + c)
476
- }
477
- }
478
- } else if (newcolumns < oldcolumns) {
479
- let removals = []
480
-
481
- for (let r = 0; r < minrows; r++) {
482
- for (let c = newcolumns; c < oldcolumns; c++) {
483
- removals.push(this.components[r * oldcolumns + c])
484
- }
485
- }
486
- this.remove(removals)
487
- }
488
-
489
- if (newrows > oldrows) {
490
- let newbies = []
491
-
492
- for (let r = oldrows; r < newrows; r++) {
493
- for (let i = 0; i < newcolumns; i++) {
494
- newbies.push(buildNewCell(this.app))
495
- }
496
- }
497
- this.add(newbies)
498
- }
499
-
500
- this.set({
501
- widths: this.widths,
502
- heights: this.heights
503
- })
504
- }
505
-
506
- get layout() {
507
- return TABLE_LAYOUT
508
- }
509
-
510
- get rows() {
511
- return this.getState('rows')
512
- }
513
-
514
- setCellsStyle(cells: RackTableCell[], style: any, where: string) {
515
- var components = this.components
516
- var total = components.length
517
- var columns = this.getState('columns')
518
-
519
- // 병합된 셀도 포함시킨다.
520
- var _cells = [] as RackTableCell[]
521
- cells.forEach(c => {
522
- _cells.push(c)
523
- if (c.colspan || c.rowspan) {
524
- let col = this.getRowColumn(c).column
525
- let row = this.getRowColumn(c).row
526
- for (let i = row; i < row + c.rowspan; i++)
527
- for (let j = col; j < col + c.colspan; j++)
528
- if (i != row || j != col) _cells.push(this.components[i * this.columns + j] as RackTableCell)
529
- }
530
- })
531
-
532
- var indices = _cells.map(cell => components.indexOf(cell))
533
- indices.forEach(i => {
534
- var cell = components[i] as RackTableCell
535
-
536
- switch (where) {
537
- case 'all':
538
- setCellBorder(cell, style, where)
539
-
540
- if (isLeftMost(total, columns, indices, i))
541
- setCellBorder(components[before(columns, i)] as RackTableCell, style, 'right')
542
- if (isRightMost(total, columns, indices, i))
543
- setCellBorder(components[after(columns, i)] as RackTableCell, style, 'left')
544
- if (isTopMost(total, columns, indices, i))
545
- setCellBorder(components[above(columns, i)] as RackTableCell, style, 'bottom')
546
- if (isBottomMost(total, columns, indices, i))
547
- setCellBorder(components[below(columns, i)] as RackTableCell, style, 'top')
548
- break
549
- case 'in':
550
- if (!isLeftMost(total, columns, indices, i)) {
551
- setCellBorder(cell, style, 'left')
552
- }
553
- if (!isRightMost(total, columns, indices, i)) {
554
- setCellBorder(cell, style, 'right')
555
- }
556
- if (!isTopMost(total, columns, indices, i)) {
557
- setCellBorder(cell, style, 'top')
558
- }
559
- if (!isBottomMost(total, columns, indices, i)) {
560
- setCellBorder(cell, style, 'bottom')
561
- }
562
- break
563
- case 'out':
564
- if (isLeftMost(total, columns, indices, i)) {
565
- setCellBorder(cell, style, 'left')
566
- setCellBorder(components[before(columns, i)] as RackTableCell, style, 'right')
567
- }
568
- if (isRightMost(total, columns, indices, i)) {
569
- setCellBorder(cell, style, 'right')
570
- setCellBorder(components[after(columns, i)] as RackTableCell, style, 'left')
571
- }
572
- if (isTopMost(total, columns, indices, i)) {
573
- setCellBorder(cell, style, 'top')
574
- setCellBorder(components[above(columns, i)] as RackTableCell, style, 'bottom')
575
- }
576
- if (isBottomMost(total, columns, indices, i)) {
577
- setCellBorder(cell, style, 'bottom')
578
- setCellBorder(components[below(columns, i)] as RackTableCell, style, 'top')
579
- }
580
- break
581
- case 'left':
582
- if (isLeftMost(total, columns, indices, i)) {
583
- setCellBorder(cell, style, 'left')
584
- setCellBorder(components[before(columns, i)] as RackTableCell, style, 'right')
585
- }
586
- break
587
- case 'right':
588
- if (isRightMost(total, columns, indices, i)) {
589
- setCellBorder(cell, style, 'right')
590
- setCellBorder(components[after(columns, i)] as RackTableCell, style, 'left')
591
- }
592
- break
593
- case 'center':
594
- if (!isLeftMost(total, columns, indices, i)) {
595
- setCellBorder(cell, style, 'left')
596
- }
597
- if (!isRightMost(total, columns, indices, i)) {
598
- setCellBorder(cell, style, 'right')
599
- }
600
- break
601
- case 'middle':
602
- if (!isTopMost(total, columns, indices, i)) {
603
- setCellBorder(cell, style, 'top')
604
- }
605
- if (!isBottomMost(total, columns, indices, i)) {
606
- setCellBorder(cell, style, 'bottom')
607
- }
608
- break
609
- case 'top':
610
- if (isTopMost(total, columns, indices, i)) {
611
- setCellBorder(cell, style, 'top')
612
- setCellBorder(components[above(columns, i)] as RackTableCell, style, 'bottom')
613
- }
614
- break
615
- case 'bottom':
616
- if (isBottomMost(total, columns, indices, i)) {
617
- setCellBorder(cell, style, 'bottom')
618
- setCellBorder(components[below(columns, i)] as RackTableCell, style, 'top')
619
- }
620
- break
621
- case 'clear':
622
- setCellBorder(cell, CLEAR_STYLE, 'all')
623
-
624
- if (isLeftMost(total, columns, indices, i))
625
- setCellBorder(components[before(columns, i)] as RackTableCell, CLEAR_STYLE, 'right')
626
- if (isRightMost(total, columns, indices, i))
627
- setCellBorder(components[after(columns, i)] as RackTableCell, CLEAR_STYLE, 'left')
628
- if (isTopMost(total, columns, indices, i))
629
- setCellBorder(components[above(columns, i)] as RackTableCell, CLEAR_STYLE, 'bottom')
630
- if (isBottomMost(total, columns, indices, i))
631
- setCellBorder(components[below(columns, i)] as RackTableCell, CLEAR_STYLE, 'top')
632
- }
633
- })
634
- }
635
-
636
- getRowColumn(cell: RackTableCell) {
637
- var idx = this.components.indexOf(cell)
638
- var length = this.components.length
639
-
640
- return {
641
- column: idx % this.columns,
642
- row: Math.floor(idx / this.columns)
643
- }
644
- }
645
-
646
- getCellsByRow(row: number) {
647
- return this.components.slice(row * this.columns, (row + 1) * this.columns)
648
- }
649
-
650
- getCellsByColumn(column: number) {
651
- var cells = []
652
- for (var i = 0; i < this.rows; i++) cells.push(this.components[this.columns * i + column])
653
-
654
- return cells
655
- }
656
-
657
- deleteRows(cells: RackTableCell[]) {
658
- // 먼저 cells 위치의 행을 구한다.
659
- let rows = [] as number[]
660
-
661
- cells.forEach(cell => {
662
- let row = this.getRowColumn(cell).row
663
- if (-1 == rows.indexOf(row)) {
664
- rows.push(row)
665
- }
666
- })
667
-
668
- rows.sort((a, b) => {
669
- return a - b
670
- })
671
-
672
- rows.reverse()
673
-
674
- var heights = this.heights.slice()
675
- rows.forEach(row => {
676
- this.remove(this.getCellsByRow(row))
677
- })
678
-
679
- rows.forEach(row => heights.splice(row, 1))
680
-
681
- this.model.rows -= rows.length // 고의적으로, change 이벤트가 발생하지 않도록 set(..)을 사용하지 않음.
682
- this.set('heights', heights)
683
- }
684
-
685
- deleteColumns(cells: RackTableCell[]) {
686
- // 먼저 cells 위치의 열을 구한다.
687
- let columns = [] as number[]
688
- cells.forEach(cell => {
689
- let column = this.getRowColumn(cell).column
690
- if (-1 == columns.indexOf(column)) columns.push(column)
691
- })
692
- columns.sort((a, b) => {
693
- return a - b
694
- })
695
- columns.reverse()
696
-
697
- columns.forEach(column => {
698
- var widths = this.widths.slice()
699
- this.remove(this.getCellsByColumn(column))
700
- widths.splice(column, 1)
701
- this.model.columns -= 1 // 고의적으로, change 이벤트가 발생하지 않도록 set(..)을 사용하지 않음.
702
- this.set('widths', widths)
703
- })
704
- }
705
-
706
- insertCellsAbove(cells: RackTableCell[]) {
707
- // 먼저 cells 위치의 행을 구한다.
708
- let rows = [] as number[]
709
- cells.forEach(cell => {
710
- let row = this.getRowColumn(cell).row
711
- if (-1 == rows.indexOf(row)) rows.push(row)
712
- })
713
- rows.sort((a, b) => {
714
- return a - b
715
- })
716
- rows.reverse()
717
- // 행 2개 이상은 추가 안함. 임시로 막아놓음
718
- if (rows.length >= 2) return false
719
- let insertionRowPosition = rows[0]
720
- let newbieRowHeights = [] as number[]
721
- let newbieCells = [] as RackTableCell[]
722
- rows.forEach(row => {
723
- for (let i = 0; i < this.columns; i++)
724
- newbieCells.push(buildCopiedCell(this.components[row * this.columns + i].model, this.app) as RackTableCell)
725
-
726
- newbieRowHeights.push(this.heights[row])
727
-
728
- newbieCells.reverse().forEach(cell => {
729
- this.insertComponentAt(cell, insertionRowPosition * this.columns)
730
- })
731
-
732
- let heights = this.heights.slice()
733
- heights.splice(insertionRowPosition, 0, ...newbieRowHeights)
734
- this.set('heights', heights)
735
-
736
- this.model.rows += rows.length
737
-
738
- this.clearCache()
739
- })
740
- }
741
-
742
- insertCellsBelow(cells: RackTableCell[]) {
743
- // 먼저 cells 위치의 행을 구한다.
744
- let rows = [] as number[]
745
- cells.forEach(cell => {
746
- let row = this.getRowColumn(cell).row
747
- if (-1 == rows.indexOf(row)) rows.push(row)
748
- })
749
- rows.sort((a, b) => {
750
- return a - b
751
- })
752
- rows.reverse()
753
- // 행 2개 이상은 추가 안함. 임시로 막아놓음
754
- if (rows.length >= 2) return false
755
- let insertionRowPosition = rows[rows.length - 1] + 1
756
- let newbieRowHeights = [] as number[]
757
- let newbieCells = [] as RackTableCell[]
758
- rows.forEach(row => {
759
- for (let i = 0; i < this.columns; i++)
760
- newbieCells.push(buildCopiedCell(this.components[row * this.columns + i].model, this.app) as RackTableCell)
761
- newbieRowHeights.push(this.heights[row])
762
-
763
- newbieCells.reverse().forEach(cell => {
764
- this.insertComponentAt(cell, insertionRowPosition * this.columns)
765
- })
766
-
767
- let heights = this.heights.slice()
768
- heights.splice(insertionRowPosition, 0, ...newbieRowHeights)
769
- this.set('heights', heights)
770
-
771
- this.model.rows += 1
772
-
773
- this.clearCache()
774
- })
775
- }
776
-
777
- insertCellsLeft(cells: RackTableCell[]) {
778
- // 먼저 cells 위치의 열을 구한다.
779
- let columns = [] as number[]
780
- cells.forEach(cell => {
781
- let column = this.getRowColumn(cell).column
782
- if (-1 == columns.indexOf(column)) columns.push(column)
783
- })
784
- columns.sort((a, b) => {
785
- return a - b
786
- })
787
- columns.reverse()
788
- // 열 2개 이상은 추가 안함. 임시로 막아놓음
789
- if (columns.length >= 2) return false
790
- let insertionColumnPosition = columns[0]
791
- let newbieColumnWidths = [] as number[]
792
- let newbieCells = [] as RackTableCell[]
793
- columns.forEach(column => {
794
- for (let i = 0; i < this.rows; i++)
795
- newbieCells.push(buildCopiedCell(this.components[column + this.columns * i].model, this.app) as RackTableCell)
796
- newbieColumnWidths.push(this.widths[column])
797
-
798
- let increasedColumns = this.columns
799
- let index = this.rows
800
- newbieCells.reverse().forEach(cell => {
801
- if (index == 0) {
802
- index = this.rows
803
- increasedColumns++
804
- }
805
-
806
- index--
807
- this.insertComponentAt(cell, insertionColumnPosition + index * increasedColumns)
808
- })
809
-
810
- let widths = this.widths.slice()
811
- this.model.columns += columns.length // 고의적으로, change 이벤트가 발생하지 않도록 set(..)을 사용하지 않음.
812
-
813
- widths.splice(insertionColumnPosition, 0, ...newbieColumnWidths)
814
-
815
- this.set('widths', widths)
816
- })
817
- }
818
-
819
- insertCellsRight(cells: RackTableCell[]) {
820
- // 먼저 cells 위치의 열을 구한다.
821
- let columns = [] as number[]
822
- cells.forEach(cell => {
823
- let column = this.getRowColumn(cell).column
824
- if (-1 == columns.indexOf(column)) columns.push(column)
825
- })
826
- columns.sort((a, b) => {
827
- return a - b
828
- })
829
- columns.reverse()
830
- // 열 2개 이상은 추가 안함. 임시로 막아놓음
831
- if (columns.length >= 2) return false
832
- let insertionColumnPosition = columns[columns.length - 1] + 1
833
- let newbieColumnWidths = [] as number[]
834
- let newbieCells = [] as RackTableCell[]
835
- columns.forEach(column => {
836
- for (let i = 0; i < this.rows; i++)
837
- newbieCells.push(buildCopiedCell(this.components[column + this.columns * i].model, this.app) as RackTableCell)
838
- newbieColumnWidths.push(this.widths[column])
839
-
840
- let increasedColumns = this.columns
841
- let index = this.rows
842
- newbieCells.reverse().forEach(cell => {
843
- if (index == 0) {
844
- index = this.rows
845
- increasedColumns++
846
- }
847
-
848
- index--
849
- this.insertComponentAt(cell, insertionColumnPosition + index * increasedColumns)
850
- })
851
-
852
- let widths = this.widths.slice()
853
- this.model.columns += columns.length // 고의적으로, change 이벤트가 발생하지 않도록 set(..)을 사용하지 않음.
854
-
855
- widths.splice(insertionColumnPosition, 0, ...newbieColumnWidths)
856
-
857
- this.set('widths', widths)
858
- })
859
- }
860
-
861
- distributeHorizontal(cells: RackTableCell[]) {
862
- var columns = [] as number[]
863
-
864
- cells.forEach(cell => {
865
- let rowcolumn = this.getRowColumn(cell)
866
-
867
- if (-1 == columns.indexOf(rowcolumn.column)) columns.push(rowcolumn.column)
868
- })
869
-
870
- var sum = columns.reduce((sum, column) => {
871
- return sum + this.widths[column]
872
- }, 0)
873
-
874
- var newval = Math.round((sum / columns.length) * 100) / 100
875
- var widths = this.widths.slice()
876
- columns.forEach(column => {
877
- widths[column] = newval
878
- })
879
-
880
- this.set('widths', widths)
881
- }
882
-
883
- distributeVertical(cells: RackTableCell[]) {
884
- var rows = [] as number[]
885
-
886
- cells.forEach(cell => {
887
- let rowcolumn = this.getRowColumn(cell)
888
-
889
- if (-1 == rows.indexOf(rowcolumn.row)) rows.push(rowcolumn.row)
890
- })
891
-
892
- var sum = rows.reduce((sum, row) => {
893
- return sum + this.heights[row]
894
- }, 0)
895
-
896
- var newval = Math.round((sum / rows.length) * 100) / 100
897
- var heights = this.heights.slice()
898
- rows.forEach(row => {
899
- heights[row] = newval
900
- })
901
-
902
- this.set('heights', heights)
903
- }
904
-
905
- /**
906
- * visualizer location setting functions
907
- */
908
- increaseLocation(type: string, skipNumbering: boolean, startSection: number, startUnit: number) {
909
- /**
910
- * step 1
911
- *
912
- * selected collect rack-cell
913
- */
914
- var selectedCells = this.root.selected
915
-
916
- /**
917
- * step 2
918
- *
919
- * classify cells by row
920
- */
921
- var classified = this.classifyByRow(selectedCells as RackTableCell[])
922
-
923
- /**
924
- * step 3
925
- *
926
- * find aisle
927
- */
928
- var aisleRowIndices = this.getAisleRowIndices(classified)
929
-
930
- /**
931
- * step 4
932
- *
933
- * classify cells by section
934
- */
935
- var sections = this.classifyCellsBySection(classified, aisleRowIndices)
936
-
937
- /**
938
- * step 5
939
- *
940
- * rearrange by aisle
941
- */
942
- var rearranged = this.rearrangeByAisle(type, sections)
943
-
944
- /**
945
- * step 6
946
- *
947
- * if skip numbering, remove empty cells
948
- */
949
- if (skipNumbering) rearranged = this.removeEmptyCells(rearranged)
950
-
951
- /**
952
- * step 7
953
- *
954
- * merge rows
955
- */
956
- var merged = this.mergeRows(rearranged)
957
-
958
- /**
959
- * step 8
960
- *
961
- * set location
962
- */
963
- this.setLocations(merged, startSection, startUnit)
964
- }
965
-
966
- classifyByRow(cells: RackTableCell[]) {
967
- var classified = [] as RackTableCell[][]
968
-
969
- cells.forEach(c => {
970
- var index = c.index
971
- var { row, column } = index
972
-
973
- if (!classified[row]) {
974
- classified[row] = []
975
- }
976
-
977
- classified[row][column] = c
978
- })
979
-
980
- return classified
981
- }
982
-
983
- findAisle(rows?: RackTableCell[][]) {
984
- if (!rows) {
985
- return []
986
- }
987
-
988
- return rows.filter(r => {
989
- return r[0] && r[0].isAisle
990
- })
991
- }
992
-
993
- getAisleRowIndices(rows?: RackTableCell[][]) {
994
- var aisles = this.findAisle(rows)
995
- var aisleRowIndices = [] as number[]
996
-
997
- aisles.forEach(aisle => {
998
- aisleRowIndices.push(rows!.indexOf(aisle))
999
- })
1000
-
1001
- return aisleRowIndices
1002
- }
1003
-
1004
- classifyCellsBySection(rows: RackTableCell[][], aisleRowIndices: number[]): RackTableCell[][][] {
1005
- var sections = [] as RackTableCell[][][]
1006
- var wasAisle = false
1007
- var section: RackTableCell[][]
1008
-
1009
- rows.forEach((row, i) => {
1010
- var isAisle = aisleRowIndices.indexOf(i) > -1
1011
-
1012
- if (!(wasAisle || isAisle)) {
1013
- section = []
1014
- sections.push(section)
1015
- }
1016
-
1017
- wasAisle = isAisle
1018
-
1019
- section.push(row)
1020
- })
1021
-
1022
- return sections
1023
- }
1024
-
1025
- rearrangeByAisle(type: string, sections: RackTableCell[][][]) {
1026
- var rearranged = [] as RackTableCell[][][]
1027
-
1028
- switch (type.toLowerCase()) {
1029
- case 'cw':
1030
- var reverse = false
1031
- sections.forEach((rows, i) => {
1032
- var section = [] as RackTableCell[][]
1033
- rearranged.push(section)
1034
- rows.forEach((r, i) => {
1035
- if (reverse) r.reverse()
1036
-
1037
- if (i % 2 === 0) {
1038
- section.push(r)
1039
- reverse = !reverse
1040
- }
1041
- })
1042
- })
1043
- break
1044
- case 'ccw':
1045
- var reverse = true
1046
- sections.forEach((rows, i) => {
1047
- var section = [] as RackTableCell[][]
1048
- rearranged.push(section)
1049
- rows.forEach((r, i) => {
1050
- if (reverse) r.reverse()
1051
-
1052
- if (i % 2 === 0) {
1053
- section.push(r)
1054
- reverse = !reverse
1055
- }
1056
- })
1057
- })
1058
- break
1059
- case 'zigzag':
1060
- sections.forEach((rows, i) => {
1061
- var section = [] as RackTableCell[][]
1062
-
1063
- rows.forEach((r, i) => {
1064
- if (i % 2 === 0) {
1065
- section.push(r)
1066
- }
1067
- })
1068
-
1069
- var sectionLength = section.length
1070
- var tempRow = [] as RackTableCell[]
1071
- var tempSection = [] as RackTableCell[][]
1072
-
1073
- section.forEach((row, rowIdx) => {
1074
- row.forEach((cell, idx) => {
1075
- tempRow[rowIdx + idx * section.length] = cell
1076
- })
1077
- })
1078
-
1079
- var chunkSize = tempRow.length / sectionLength
1080
- for (var idx = 0; idx < sectionLength; idx++) {
1081
- tempSection.push(tempRow.slice(idx * chunkSize, (idx + 1) * chunkSize))
1082
- }
1083
-
1084
- rearranged.push(tempSection)
1085
- })
1086
- break
1087
- case 'zigzag-reverse':
1088
- sections.forEach((rows, i) => {
1089
- var section = [] as RackTableCell[][]
1090
-
1091
- rows.forEach((r, i) => {
1092
- if (i % 2 === 0) {
1093
- r.reverse()
1094
- section.push(r)
1095
- }
1096
- })
1097
-
1098
- var sectionLength = section.length
1099
- var tempRow = [] as RackTableCell[]
1100
- var tempSection = [] as RackTableCell[][]
1101
-
1102
- section.forEach((row, rowIdx) => {
1103
- row.forEach((cell, idx) => {
1104
- tempRow[rowIdx + idx * section.length] = cell
1105
- })
1106
- })
1107
-
1108
- var chunkSize = tempRow.length / sectionLength
1109
- for (var idx = 0; idx < sectionLength; idx++) {
1110
- tempSection.push(tempRow.slice(idx * chunkSize, (idx + 1) * chunkSize))
1111
- }
1112
-
1113
- rearranged.push(tempSection)
1114
- })
1115
- break
1116
- }
1117
-
1118
- return rearranged
1119
- }
1120
-
1121
- removeEmptyCells(sections: RackTableCell[][][]) {
1122
- var newSections = [] as RackTableCell[][][]
1123
- sections.forEach(rows => {
1124
- var newRows = [] as RackTableCell[][]
1125
- newSections.push(newRows)
1126
- rows.forEach(row => {
1127
- var newRow = [] as RackTableCell[]
1128
- newRows.push(newRow)
1129
- row.forEach((c, i) => {
1130
- if (!c.isEmpty) newRow.push(c)
1131
- })
1132
- })
1133
- })
1134
-
1135
- return newSections
1136
- }
1137
-
1138
- mergeRows(sections: RackTableCell[][][]): RackTableCell[][] {
1139
- var merged = [] as RackTableCell[][]
1140
-
1141
- sections.forEach(section => {
1142
- var newSection = [] as RackTableCell[]
1143
-
1144
- section.forEach(rows => {
1145
- var mergedRow = [] as RackTableCell[]
1146
- rows.forEach(row => {
1147
- mergedRow = mergedRow.concat(row)
1148
- })
1149
- newSection = newSection.concat(mergedRow)
1150
- })
1151
- merged.push(newSection)
1152
- })
1153
-
1154
- return merged
1155
- }
1156
-
1157
- setLocations(sections: RackTableCell[][], startSection: number, startUnit: number) {
1158
- var { sectionDigits = 2, unitDigits = 2 } = this.state
1159
-
1160
- var sectionNumber = Number(startSection) || 1
1161
-
1162
- sections.forEach(section => {
1163
- var unitNumber = Number(startUnit) || 1
1164
- section.forEach(c => {
1165
- if (!c.isEmpty) {
1166
- c.set('section', String(sectionNumber).padStart(sectionDigits, '0'))
1167
- c.set('unit', String(unitNumber).padStart(unitDigits, '0'))
1168
- } else {
1169
- c.set('section', null)
1170
- c.set('unit', null)
1171
- }
1172
- unitNumber++
1173
- })
1174
- sectionNumber++
1175
- })
1176
- }
1177
-
1178
- get columns() {
1179
- return this.getState('columns')
1180
- }
1181
-
1182
- get lefts() {
1183
- return this.components.filter((c, i) => {
1184
- return !(i % this.columns)
1185
- })
1186
- }
1187
-
1188
- get centers() {
1189
- return this.components.filter((c, i) => {
1190
- return i % this.columns && (i + 1) % this.columns
1191
- })
1192
- }
1193
-
1194
- get rights() {
1195
- return this.components.filter((c, i) => {
1196
- return !((i + 1) % this.columns)
1197
- })
1198
- }
1199
-
1200
- get tops() {
1201
- return this.components.slice(0, this.columns)
1202
- }
1203
-
1204
- get middles() {
1205
- return this.components.slice(this.columns, this.columns * (this.rows - 1))
1206
- }
1207
-
1208
- get bottoms() {
1209
- return this.components.slice(this.columns * (this.rows - 1))
1210
- }
1211
-
1212
- get all() {
1213
- return this.components
1214
- }
1215
-
1216
- get widths_sum() {
1217
- var widths = this.widths
1218
- return widths ? widths.filter((width, i) => i < this.columns).reduce((sum, width) => sum + width, 0) : this.columns
1219
- }
1220
-
1221
- get heights_sum() {
1222
- var heights = this.heights
1223
- return heights ? heights.filter((height, i) => i < this.rows).reduce((sum, height) => sum + height, 0) : this.rows
1224
- }
1225
-
1226
- get nature() {
1227
- return NATURE
1228
- }
1229
-
1230
- get controls(): Array<Control> | undefined {
1231
- var widths = this.widths
1232
- var heights = this.heights
1233
- var inside = this.textBounds
1234
-
1235
- var width_unit = inside.width / this.widths_sum
1236
- var height_unit = inside.height / this.heights_sum
1237
-
1238
- var x = inside.left
1239
- var y = inside.top
1240
-
1241
- var controls: Array<Control> = []
1242
-
1243
- widths.slice(0, this.columns - 1).forEach((width: number) => {
1244
- x += width * width_unit
1245
- controls.push({
1246
- x: x,
1247
- y: inside.top,
1248
- handler: columnControlHandler
1249
- })
1250
- })
1251
-
1252
- heights.slice(0, this.rows - 1).forEach((height: number) => {
1253
- y += height * height_unit
1254
- controls.push({
1255
- x: inside.left,
1256
- y: y,
1257
- handler: rowControlHandler
1258
- })
1259
- })
1260
-
1261
- return controls
1262
- }
1263
-
1264
- onchange(after: Properties, before: Properties) {
1265
- if ('rows' in after || 'columns' in after) {
1266
- this.buildCells(
1267
- this.getState('rows'),
1268
- this.getState('columns'),
1269
- before.hasOwnProperty('rows') ? before.rows : this.getState('rows'),
1270
- before.hasOwnProperty('columns') ? before.columns : this.getState('columns')
1271
- )
1272
- }
1273
-
1274
- this.invalidate()
1275
- }
1276
-
1277
- get eventMap() {
1278
- return {
1279
- '(self)': {
1280
- '(descendant)': {
1281
- change: this.oncellchanged
1282
- }
1283
- }
1284
- }
1285
- }
1286
-
1287
- oncellchanged(after: Properties, before: Properties) {
1288
- this.invalidate()
1289
- }
1290
- }
1291
-
1292
- ;['rows', 'columns', 'widths', 'heights', 'widths_sum', 'heights_sum', 'controls'].forEach(getter =>
1293
- Component.memoize(RackTable.prototype, getter, false)
1294
- )
1295
-
1296
- Component.register('rack-table', RackTable)