{\n\t\t\t\t\tif (this.props.preventShortcutEvents) {\n\t\t\t\t\t\tthis.props.setPreventShortcutEvents(false);\n\t\t\t\t\t}\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{\n\t\t\t\t\t(isSelected && !areMultipleBoxesSelected) || (position.type && position.type === 'group') ?\n\t\t\t\t\t(this.props.didDragOrResizeHappen) ?
\n\t\t\t\t\t\t{`${Math.round(position.x * xFactor)}, ${Math.round(position.y * yFactor)}`}\n\t\t\t\t\t :\n\t\t\t\t\t\tnull :null\n\t\t\t\t}\n\t\t\t\t{\n\t\t\t\t\t(isSelected && !areMultipleBoxesSelected) || (position.type && position.type === 'group') ?\n\t\t\t\t\t(this.props.didDragOrResizeHappen) ?
\n\t\t\t\t\t\t{`${Math.round(position.width * xFactor)} x ${Math.round(position.height * yFactor)}`}
\n\t\t\t\t\t :\n\t\t\t\t\t\tnull :null\n\t\t\t\t}\n\t\t\t\t{\n\t\t\t\t\t(isSelected && !areMultipleBoxesSelected) || (position.type && position.type === 'group') ?\n\t\t\t\t\t\tRESIZE_CORNERS.map(handle => {\n\t\t\t\t\t\t\tconst className = `${styles.resizeCorners} ${styles[`resize-${handle}`]} ` + `${dashedCentreNodes ? styles[`stretchable-resize-${handle}`] : null}`;\n\t\t\t\t\t\t\treturn
;\n\t\t\t\t\t\t}) :\n\t\t\t\t\t\tnull\n\t\t\t\t}\n\t\t\t\t{\n\t\t\t\t\tisSelected && !areMultipleBoxesSelected ?\n\t\t\t\t\t\tROTATE_HANDLES.map(handle => {\n\t\t\t\t\t\t\tconst className = `${styles.rotateHandle} ${styles[`rotate-${handle}`]}`;\n\t\t\t\t\t\t\treturn
;\n\t\t\t\t\t\t}) :\n\t\t\t\t\t\tnull\n\t\t\t\t}\n\t\t\t
;\n\t\t}\n\n\t\treturn null;\n\t}\n}\n\nBox.propTypes = {\n\tareMultipleBoxesSelected: PropTypes.bool,\n\tboundToParent: PropTypes.bool,\n\tdrag: PropTypes.bool,\n\tgetBoundingBoxElement: PropTypes.func,\n\tid: PropTypes.string,\n\tisSelected: PropTypes.bool,\n\tkeybindings: PropTypes.bool,\n\tonDragStart: PropTypes.func,\n\tonDrag: PropTypes.func,\n\tonDragEnd: PropTypes.func,\n\tonKeyUp: PropTypes.func,\n\tonKeyEnd: PropTypes.func,\n\tonResizeStart: PropTypes.func,\n\tonResize: PropTypes.func,\n\tonResizeEnd: PropTypes.func,\n\tonRotateStart: PropTypes.func,\n\tonRotate: PropTypes.func,\n\tonRotateEnd: PropTypes.func,\n\tposition: PropTypes.object.isRequired,\n\tresize: PropTypes.bool,\n\tresolution: PropTypes.object,\n\trotate: PropTypes.bool\n};\n\nexport default Box;","import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport Box from './Box';\nimport {\n\tcalculateGuidePositions,\n\tgetMultipleSelectionCoordinates,\n\tgetOffsetCoordinates,\n\tproximityListener,\n} from './utils/helpers'\nimport styles from './styles.scss';\n\nclass AlignmentGuides extends Component {\n\tconstructor(props) {\n\t\tsuper(props);\n\t\tthis.boundingBox = React.createRef();\n\t\tthis.state = {\n\t\t\tactive: '',\n\t\t\tactiveBoxes: [],\n\t\t\tboundingBox: null,\n\t\t\tboxes: {},\n\t\t\tdragging: false,\n\t\t\tguides: {},\n\t\t\tguidesActive: false,\n\t\t\tisShiftKeyActive: false,\n\t\t\tmatch: {},\n\t\t\tresizing: false,\n\t\t\trotating: false,\n\t\t\tactiveBoxSnappedPosition: {},\n\t\t\tpreventShortcutEvents: false\n\t\t};\n\t\tthis.setShiftKeyState = this.setShiftKeyState.bind(this);\n\t\tthis.getBoundingBoxElement = this.getBoundingBoxElement.bind(this);\n\t\tthis.setDragOrResizeState = this.setDragOrResizeState.bind(this);\n\t\tthis.selectBox = this.selectBox.bind(this);\n\t\tthis.unSelectBox = this.unSelectBox.bind(this);\n\t\tthis.dragStartHandler = this.dragStartHandler.bind(this);\n\t\tthis.dragHandler = this.dragHandler.bind(this);\n\t\tthis.dragEndHandler = this.dragEndHandler.bind(this);\n\t\tthis.resizeStartHandler = this.resizeStartHandler.bind(this);\n\t\tthis.resizeHandler = this.resizeHandler.bind(this);\n\t\tthis.resizeEndHandler = this.resizeEndHandler.bind(this);\n\t\tthis.rotateStartHandler = this.rotateStartHandler.bind(this);\n\t\tthis.rotateHandler = this.rotateHandler.bind(this);\n\t\tthis.rotateEndHandler = this.rotateEndHandler.bind(this);\n\t\tthis.keyUpHandler = this.keyUpHandler.bind(this);\n\t\tthis.keyEndHandler = this.keyEndHandler.bind(this);\n\t\tthis.setPreventShortcutEvents = this.setPreventShortcutEvents.bind(this);\n\t\tthis.startingPositions = null;\n\t\tthis.didDragOrResizeHappen = false;\n\t}\n\n\tcomponentDidMount() {\n\t\t// Set the dimensions of the bounding box and the draggable boxes when the component mounts.\n\t\tif (this.boundingBox.current) {\n\t\t\tconst boundingBox = this.boundingBox.current.getBoundingClientRect().toJSON();\n\t\t\tconst boxes = {};\n\t\t\tconst guides = {};\n\t\t\tconst activeBoxes = [];\n\t\t\tlet active = '';\n\n\t\t\t// Adding the guides for the bounding box to the guides object\n\t\t\tguides.boundingBox = {\n\t\t\t\tx: calculateGuidePositions(boundingBox, 'x').map(value => value - boundingBox.left),\n\t\t\t\ty: calculateGuidePositions(boundingBox, 'y').map(value => value - boundingBox.top)\n\t\t\t};\n\n\t\t\tthis.props.boxes.forEach((dimensions, index) => {\n\t\t\t\tboxes[`box${index}`] = dimensions;\n\t\t\t\tguides[`box${index}`] = {\n\t\t\t\t\tx: calculateGuidePositions(dimensions, 'x'),\n\t\t\t\t\ty: calculateGuidePositions(dimensions, 'y')\n\t\t\t\t};\n\t\t\t\tif (dimensions.active) {\n\t\t\t\t\tactiveBoxes.push(`box${index}`);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (activeBoxes.length > 1) {\n\t\t\t\tboxes['box-ms'] = getMultipleSelectionCoordinates(boxes, activeBoxes);\n\t\t\t\tboxes['box-ms'].type = 'group';\n\t\t\t\tboxes['box-ms'].zIndex = 12;\n\t\t\t\tconst selections = [];\n\t\t\t\tfor (let box in boxes) {\n\t\t\t\t\tif (boxes.hasOwnProperty(box) && activeBoxes.includes(box)) {\n\t\t\t\t\t\tselections.push(boxes[box]);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tboxes['box-ms'].selections = selections;\n\t\t\t\tactive = 'box-ms';\n\t\t\t} else if (activeBoxes.length === 1) {\n\t\t\t\tactive = activeBoxes[0];\n\t\t\t}\n\n\t\t\tdocument.addEventListener('click', this.unSelectBox);\n\t\t\twindow.addEventListener('blur', this.unSelectBox);\n\t\t\tdocument.addEventListener('keydown', this.setShiftKeyState);\n\t\t\tdocument.addEventListener('keydown', this.unSelectBox);\n\t\t\tdocument.addEventListener('keyup', this.setShiftKeyState);\n\n\t\t\tthis.setState({\n\t\t\t\tboundingBox,\n\t\t\t\tboxes,\n\t\t\t\tguides,\n\t\t\t\tactiveBoxes,\n\t\t\t\tactive\n\t\t\t});\n\t\t}\n\t}\n\n\tcomponentWillUnmount() {\n\t\tdocument.removeEventListener('click', this.unSelectBox);\n\t\twindow.removeEventListener('blur', this.unSelectBox);\n\t\tdocument.removeEventListener('keydown', this.setShiftKeyState);\n\t\tdocument.removeEventListener('keydown', this.unSelectBox);\n\t\tdocument.removeEventListener('keyup', this.setShiftKeyState);\n\t}\n\n\tsetShiftKeyState(e) {\n\t\tthis.setState({\n\t\t\tisShiftKeyActive: e.shiftKey\n\t\t});\n\t}\n\n\tgetBoundingBoxElement() {\n\t\treturn this.boundingBox;\n\t}\n\n\tsetDragOrResizeState(state) {\n\t\tthis.didDragOrResizeHappen = state;\n\t}\n\n\tsetPreventShortcutEvents(val) {\n\t\tthis.setState({ preventShortcutEvents: val });\n\t}\n\n\tselectBox(e) {\n\t\tconst boundingBox = this.getBoundingBoxElement();\n\t\tconst boundingBoxPosition = boundingBox.current.getBoundingClientRect().toJSON();\n\t\tif (e.target && e.target.id.indexOf('box') >= 0) {\n\t\t\tconst boxDimensions = e.target.getBoundingClientRect().toJSON();\n\t\t\tlet data = {\n\t\t\t\tx: boxDimensions.x - boundingBoxPosition.x,\n\t\t\t\ty: boxDimensions.y - boundingBoxPosition.y,\n\t\t\t\tleft: boxDimensions.left - boundingBoxPosition.x,\n\t\t\t\ttop: boxDimensions.top - boundingBoxPosition.y,\n\t\t\t\twidth: boxDimensions.width,\n\t\t\t\theight: boxDimensions.height,\n\t\t\t\tnode: e.target,\n\t\t\t\tmetadata: this.state.boxes[e.target.id].metadata\n\t\t\t};\n\t\t\tif (e.shiftKey) {\n\t\t\t\tlet { activeBoxes, boxes } = this.state;\n\t\t\t\tif (activeBoxes.includes(e.target.id)) {\n\t\t\t\t\tactiveBoxes = activeBoxes.filter(activeBox => activeBox !== e.target.id);\n\t\t\t\t} else {\n\t\t\t\t\tactiveBoxes = [\n\t\t\t\t\t\t...activeBoxes,\n\t\t\t\t\t\te.target.id\n\t\t\t\t\t];\n\t\t\t\t}\n\t\t\t\tboxes['box-ms'] = getMultipleSelectionCoordinates(boxes, activeBoxes);\n\t\t\t\tboxes['box-ms'].type = 'group';\n\t\t\t\tboxes['box-ms'].zIndex = 12;\n\t\t\t\tconst selections = [];\n\t\t\t\tfor (let box in boxes) {\n\t\t\t\t\tif (boxes.hasOwnProperty(box) && activeBoxes.includes(box)) {\n\t\t\t\t\t\tselections.push(boxes[box]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdata = Object.assign({}, boxes['box-ms'], {\n\t\t\t\t\tmetadata: { type: 'group' },\n\t\t\t\t\tselections\n\t\t\t\t});\n\t\t\t\tthis.setState({\n\t\t\t\t\tactive: 'box-ms',\n\t\t\t\t\tactiveBoxes,\n\t\t\t\t\tboxes\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tlet { activeBoxes, boxes } = this.state;\n\t\t\t\tdelete boxes['box-ms'];\n\t\t\t\tthis.setState({\n\t\t\t\t\tactive: e.target.id,\n\t\t\t\t\tactiveBoxes: [\n\t\t\t\t\t\te.target.id\n\t\t\t\t\t],\n\t\t\t\t\tboxes\n\t\t\t\t});\n\t\t\t}\n\t\t\tthis.props.onSelect && this.props.onSelect(e, data);\n\t\t} else if (e.target && e.target.parentNode && e.target.parentNode.id.indexOf('box') >= 0) {\n\t\t\tconst boxDimensions = e.target.parentNode.getBoundingClientRect().toJSON();\n\t\t\tlet data = {\n\t\t\t\tx: boxDimensions.x - boundingBoxPosition.x,\n\t\t\t\ty: boxDimensions.y - boundingBoxPosition.y,\n\t\t\t\tleft: boxDimensions.left - boundingBoxPosition.x,\n\t\t\t\ttop: boxDimensions.top - boundingBoxPosition.y,\n\t\t\t\twidth: boxDimensions.width,\n\t\t\t\theight: boxDimensions.height,\n\t\t\t\tnode: e.target.parentNode,\n\t\t\t\tmetadata: this.state.boxes[e.target.parentNode.id].metadata\n\t\t\t};\n\t\t\tif (e.shiftKey) {\n\t\t\t\tlet { activeBoxes, boxes } = this.state;\n\t\t\t\tif (activeBoxes.includes(e.target.parentNode.id)) {\n\t\t\t\t\tactiveBoxes = activeBoxes.filter(activeBox => activeBox !== e.target.parentNode.id);\n\t\t\t\t} else {\n\t\t\t\t\tactiveBoxes = [\n\t\t\t\t\t\t...activeBoxes,\n\t\t\t\t\t\te.target.id\n\t\t\t\t\t];\n\t\t\t\t}\n\t\t\t\tboxes['box-ms'] = getMultipleSelectionCoordinates(boxes, activeBoxes);\n\t\t\t\tboxes['box-ms'].type = 'group';\n\t\t\t\tboxes['box-ms'].zIndex = 12;\n\t\t\t\tconst selections = [];\n\t\t\t\tfor (let box in boxes) {\n\t\t\t\t\tif (boxes.hasOwnProperty(box) && activeBoxes.includes(box)) {\n\t\t\t\t\t\tselections.push(boxes[box]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdata = Object.assign({}, boxes['box-ms'], {\n\t\t\t\t\tmetadata: { type: 'group' },\n\t\t\t\t\tselections\n\t\t\t\t});\n\t\t\t\tthis.setState({\n\t\t\t\t\tactive: 'box-ms',\n\t\t\t\t\tactiveBoxes,\n\t\t\t\t\tboxes\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tlet { boxes } = this.state;\n\t\t\t\tdelete boxes['box-ms'];\n\t\t\t\tthis.setState({\n\t\t\t\t\tactive: e.target.parentNode.id,\n\t\t\t\t\tactiveBoxes: [\n\t\t\t\t\t\te.target.parentNode.id\n\t\t\t\t\t],\n\t\t\t\t\tboxes\n\t\t\t\t});\n\t\t\t}\n\t\t\tthis.props.onSelect && this.props.onSelect(e, data);\n\t\t}\n\t}\n\n\tunSelectBox(e) {\n\t\tif (\n\t\t\te.type === 'keydown' ? (e.key === 'Escape' || e.key === 'Esc') :\n\t\t\te.target === window ||\n\t\t\t(\n\t\t\t\te.target &&\n\t\t\t\te.target.id.indexOf('box') === -1 &&\n\t\t\t\te.target.parentNode &&\n\t\t\t\te.target.parentNode.id.indexOf('box') === -1\n\t\t\t)\n\t\t) {\n\t\t\tif (typeof this.props.isValidUnselect === 'function' && this.props.isValidUnselect(e) === false) {\n\t\t\t\tthis.setPreventShortcutEvents(true);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst { boxes } = this.state;\n\t\t\tdelete boxes['box-ms'];\n\t\t\tthis.setState({\n\t\t\t\tactive: '',\n\t\t\t\tactiveBoxes: [],\n\t\t\t\tboxes,\n\t\t\t\tpreventShortcutEvents: false\n\t\t\t});\n\t\t\tthis.props.onUnselect && this.props.onUnselect(e);\n\t\t}\n\t}\n\n\tdragStartHandler(e, data) {\n\t\tthis.setState({\n\t\t\tactive: data.node.id,\n\t\t\tdragging: true\n\t\t});\n\n\t\tlet newData = Object.assign({}, data);\n\t\tif (this.state.boxes[data.node.id].metadata) {\n\t\t\tnewData.metadata = this.state.boxes[data.node.id].metadata;\n\t\t}\n\t\tif (data.type && data.type === 'group') {\n\t\t\tnewData.selections = this.state.activeBoxes.map(box => {\n\t\t\t\treturn Object.assign({}, this.state.boxes[box]);\n\t\t\t});\n\t\t} else if (!e.shiftKey) {\n\t\t\tthis.setState({\n\t\t\t\tactiveBoxes: [\n\t\t\t\t\te.target.parentNode.id\n\t\t\t\t],\n\t\t\t});\n\t\t}\n\n\t\tthis.props.onDragStart && this.props.onDragStart(e, newData);\n\n\t\t// Update starting positions so we can use it to update when group resize happens\n\t\tif (data.type && data.type === 'group') {\n\t\t\tthis.startingPositions = {};\n\t\t\tthis.state.activeBoxes.forEach(box => {\n\t\t\t\tthis.startingPositions[box] = this.state.boxes[box];\n\t\t\t});\n\t\t}\n\t}\n\n\tdragHandler(e, data) {\n\t\tlet newData;\n\t\tif (this.state.dragging) {\n\t\t\tnewData = Object.assign({}, data);\n\t\t\tif (this.state.boxes[this.state.active].metadata) {\n\t\t\t\tnewData.metadata = this.state.boxes[this.state.active].metadata;\n\t\t\t}\n\t\t\tif (data.type && data.type === 'group') {\n\t\t\t\tnewData.selections = this.state.activeBoxes.map(box => {\n\t\t\t\t\treturn Object.assign({}, this.state.boxes[box]);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// this.props.onDrag && this.props.onDrag(e, newData);\n\t\t}\n\n\t\tlet boxes = null;\n\t\tlet guides = null;\n\t\tif (data.type && data.type === 'group') {\n\t\t\tboxes = {};\n\t\t\tfor (let box in this.state.boxes) {\n\t\t\t\tif (this.state.boxes.hasOwnProperty(box)) {\n\t\t\t\t\tif (this.state.activeBoxes.includes(box)) {\n\t\t\t\t\t\tboxes[box] = Object.assign({}, this.state.boxes[box], {\n\t\t\t\t\t\t\tx: this.startingPositions[box].x + data.deltaX,\n\t\t\t\t\t\t\ty: this.startingPositions[box].y + data.deltaY,\n\t\t\t\t\t\t\tleft: this.startingPositions[box].left + data.deltaX,\n\t\t\t\t\t\t\ttop: this.startingPositions[box].top + data.deltaY\n\t\t\t\t\t\t});\n\t\t\t\t\t} else if (box === 'box-ms') {\n\t\t\t\t\t\tboxes[box] = Object.assign({}, data);\n\t\t\t\t\t\tdelete boxes[box].deltaX;\n\t\t\t\t\t\tdelete boxes[box].deltaY;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tboxes[box] = this.state.boxes[box];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tguides = Object.keys(this.state.guides).map(guide => {\n\t\t\t\tif (this.state.activeBoxes.includes(guide)) {\n\t\t\t\t\treturn Object.assign({}, this.state.guides[guide], {\n\t\t\t\t\t\tx: calculateGuidePositions(boxes[guide], 'x'),\n\t\t\t\t\t\ty: calculateGuidePositions(boxes[guide], 'y')\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\treturn this.state.guides[guide];\n\t\t\t});\n\t\t} else {\n\t\t\tboxes = Object.assign({}, this.state.boxes, {\n\t\t\t\t[data.node.id]: Object.assign({}, this.state.boxes[data.node.id], {\n\t\t\t\t\tx: data.x,\n\t\t\t\t\ty: data.y,\n\t\t\t\t\tleft: data.left,\n\t\t\t\t\ttop: data.top,\n\t\t\t\t\twidth: data.width,\n\t\t\t\t\theight: data.height\n\t\t\t\t})\n\t\t\t});\n\n\t\t\tguides = Object.assign({}, this.state.guides, {\n\t\t\t\t[data.node.id]: Object.assign({}, this.state.guides[data.node.id], {\n\t\t\t\t\tx: calculateGuidePositions(boxes[data.node.id], 'x'),\n\t\t\t\t\ty: calculateGuidePositions(boxes[data.node.id], 'y')\n\t\t\t\t})\n\t\t\t});\n\t\t}\n\n\t\tthis.setState({\n\t\t\tguidesActive: true,\n\t\t\tboxes,\n\t\t\tguides\n\t\t}, () => {\n\t\t\tif (this.props.snap && this.state.active && this.state.guides && data.type !== 'group') {\n\t\t\t\tconst match = proximityListener(this.state.active, this.state.guides);\n\t\t\t\tlet newActiveBoxLeft = this.state.boxes[this.state.active].left;\n\t\t\t\tlet newActiveBoxTop = this.state.boxes[this.state.active].top;\n\t\t\t\tfor (let axis in match) {\n\t\t\t\t\tconst { activeBoxGuides, matchedArray, proximity } = match[axis];\n\t\t\t\t\tconst activeBoxProximityIndex = proximity.activeBoxIndex;\n\t\t\t\t\tconst matchedBoxProximityIndex = proximity.matchedBoxIndex;\n\n\t\t\t\t\tif (axis === 'x') {\n\t\t\t\t\t\tif (activeBoxGuides[activeBoxProximityIndex] > matchedArray[matchedBoxProximityIndex]) {\n\t\t\t\t\t\t\tnewActiveBoxLeft = this.state.boxes[this.state.active].left - proximity.value;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tnewActiveBoxLeft = this.state.boxes[this.state.active].left + proximity.value;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (activeBoxGuides[activeBoxProximityIndex] > matchedArray[matchedBoxProximityIndex]) {\n\t\t\t\t\t\t\tnewActiveBoxTop = this.state.boxes[this.state.active].top - proximity.value;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tnewActiveBoxTop = this.state.boxes[this.state.active].top + proximity.value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst boxes = Object.assign({}, this.state.boxes, {\n\t\t\t\t\t[this.state.active]: Object.assign({}, this.state.boxes[this.state.active], {\n\t\t\t\t\t\tleft: newActiveBoxLeft,\n\t\t\t\t\t\ttop: newActiveBoxTop\n\t\t\t\t\t})\n\t\t\t\t});\n\t\t\t\tconst guides = Object.assign({}, this.state.guides, {\n\t\t\t\t\t[this.state.active]: Object.assign({}, this.state.guides[this.state.active], {\n\t\t\t\t\t\tx: calculateGuidePositions(boxes[this.state.active], 'x'),\n\t\t\t\t\t\ty: calculateGuidePositions(boxes[this.state.active], 'y')\n\t\t\t\t\t})\n\t\t\t\t})\n\n\t\t\t\tconst activeBox = {\n\t\t\t\t\tleft: this.state.boxes[this.state.active].left,\n\t\t\t\t\ttop: this.state.boxes[this.state.active].top,\n\t\t\t\t\tx: this.state.boxes[this.state.active].x,\n\t\t\t\t\ty: this.state.boxes[this.state.active].y\n\t\t\t\t}\n\n\t\t\t\tObject.keys(guides).map(box => {\n\t\t\t\t\tguides?.[box]?.x.map(position => {\n\t\t\t\t\t\tif (match?.x?.intersection === position) {\n\t\t\t\t\t\t\tactiveBox.left = newActiveBoxLeft;\n\t\t\t\t\t\t\tactiveBox.x = newActiveBoxLeft;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tguides?.[box]?.y.map(position => {\n\t\t\t\t\t\tif (match?.y?.intersection === position) {\n\t\t\t\t\t\t\tactiveBox.top = newActiveBoxTop;\n\t\t\t\t\t\t\tactiveBox.y = newActiveBoxTop;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\tconst newBoxes = Object.assign({}, this.state.boxes, {\n\t\t\t\t\t[this.state.active] : Object.assign({}, this.state.boxes[this.state.active], {\n\t\t\t\t\t\t...activeBox\n\t\t\t\t\t})\n\t\t\t\t});\n\n\n\t\t\t\tnewData = Object.assign({}, newData, {\n\t\t\t\t\t...activeBox\n\t\t\t\t});\n\t\t\t\t\n\t\t\t\tthis.setState({\n\t\t\t\t\tboxes: newBoxes,\n\t\t\t\t\tguides,\n\t\t\t\t\tmatch,\n\t\t\t\t\tactiveBoxSnappedPosition: activeBox\n\t\t\t\t});\n\t\t\t}\n\t\t\tthis.state.dragging && this.props.onDrag && this.props.onDrag(e, newData);\n\t\t});\n\t}\n\n\tdragEndHandler(e, data) {\n\t\tthis.setState({\n\t\t\tdragging: false,\n\t\t\tguidesActive: false\n\t\t});\n\n\t\tlet newData = Object.assign({}, data);\n\t\tif (this.state.boxes[this.state.active] && this.state.boxes[this.state.active].metadata) {\n\t\t\tnewData.metadata = this.state.boxes[this.state.active].metadata;\n\t\t}\n\n\t\tif (data.type && data.type === 'group') {\n\t\t\tnewData.selections = this.state.activeBoxes.map(box => {\n\t\t\t\treturn Object.assign({}, this.state.boxes[box]);\n\t\t\t});\n\t\t}\n\n\t\tif (this.props.snap && this.state.active && this.state.guides && data.type !== 'group') {\n\t\t\tnewData = Object.assign({}, newData, {\n\t\t\t\t...this.state.activeBoxSnappedPosition\n\t\t\t});\n\t\t}\n\n\t\tthis.props.onDragEnd && this.props.onDragEnd(e, newData);\n\t}\n\n\tresizeStartHandler(e, data) {\n\t\tthis.setState({\n\t\t\tactive: data.node.id,\n\t\t\tresizing: true\n\t\t});\n\t\tlet newData = Object.assign({}, data);\n\t\tif (this.state.boxes[data.node.id].metadata) {\n\t\t\tnewData.metadata = this.state.boxes[data.node.id].metadata;\n\t\t}\n\n\t\tthis.props.onResizeStart && this.props.onResizeStart(e, newData);\n\n\t\t// Update starting positions so we can use it to update when group resize happens\n\t\tif (data.type && data.type === 'group') {\n\t\t\tthis.startingPositions = {};\n\t\t\tthis.state.activeBoxes.forEach(box => {\n\t\t\t\tthis.startingPositions[box] = this.state.boxes[box];\n\t\t\t});\n\t\t}\n\t}\n\n\tresizeHandler(e, data) {\n\t\tif (this.state.resizing) {\n\t\t\tlet newData = Object.assign({}, data);\n\t\t\tif (this.state.boxes[this.state.active].metadata) {\n\t\t\t\tnewData.metadata = this.state.boxes[this.state.active].metadata;\n\t\t\t}\n\n\t\t\tthis.props.onResize && this.props.onResize(e, newData);\n\t\t}\n\n\t\tlet boxes = null;\n\t\tlet guides = null;\n\t\tif (data.type && data.type === 'group') {\n\t\t\tboxes = {};\n\t\t\tconst boundingBox = this.getBoundingBoxElement();\n\t\t\tconst boundingBoxPosition = getOffsetCoordinates(boundingBox.current);\n\t\t\tfor (let box in this.state.boxes) {\n\t\t\t\tif (this.state.boxes.hasOwnProperty(box)) {\n\t\t\t\t\tif (this.state.activeBoxes.includes(box)) {\n\t\t\t\t\t\t// Adding bounding box's starting position\n\t\t\t\t\t\t// This is because it's added only to the group's box and not the individual members of the group\n\t\t\t\t\t\tboxes[box] = Object.assign({}, this.state.boxes[box], {\n\t\t\t\t\t\t\tx: boundingBoxPosition.x + this.startingPositions[box].x + data.deltaX,\n\t\t\t\t\t\t\ty: boundingBoxPosition.y + this.startingPositions[box].y + data.deltaY,\n\t\t\t\t\t\t\tleft: boundingBoxPosition.left + this.startingPositions[box].left + data.deltaX,\n\t\t\t\t\t\t\ttop: boundingBoxPosition.top + this.startingPositions[box].top + data.deltaY,\n\t\t\t\t\t\t\twidth: this.startingPositions[box].width + data.deltaW,\n\t\t\t\t\t\t\theight: this.startingPositions[box].height + data.deltaH\n\t\t\t\t\t\t});\n\t\t\t\t\t} else if (box === 'box-ms') {\n\t\t\t\t\t\tboxes[box] = Object.assign({}, data);\n\t\t\t\t\t\tdelete boxes[box].deltaX;\n\t\t\t\t\t\tdelete boxes[box].deltaY;\n\t\t\t\t\t\tdelete boxes[box].deltaW;\n\t\t\t\t\t\tdelete boxes[box].deltaH;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tboxes[box] = this.state.boxes[box];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tguides = Object.keys(this.state.guides).map(guide => {\n\t\t\t\tif (this.state.activeBoxes.includes(guide)) {\n\t\t\t\t\treturn Object.assign({}, this.state.guides[guide], {\n\t\t\t\t\t\tx: calculateGuidePositions(boxes[guide], 'x'),\n\t\t\t\t\t\ty: calculateGuidePositions(boxes[guide], 'y')\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tboxes = Object.assign({}, this.state.boxes, {\n\t\t\t\t[data.node.id]: Object.assign({}, this.state.boxes[data.node.id], {\n\t\t\t\t\tx: data.x,\n\t\t\t\t\ty: data.y,\n\t\t\t\t\tleft: data.left,\n\t\t\t\t\ttop: data.top,\n\t\t\t\t\twidth: data.width,\n\t\t\t\t\theight: data.height\n\t\t\t\t})\n\t\t\t});\n\t\t\tguides = Object.assign({}, this.state.guides, {\n\t\t\t\t[data.node.id]: Object.assign({}, this.state.guides[data.node.id], {\n\t\t\t\t\tx: calculateGuidePositions(boxes[data.node.id], 'x'),\n\t\t\t\t\ty: calculateGuidePositions(boxes[data.node.id], 'y')\n\t\t\t\t})\n\t\t\t});\n\t\t}\n\n\t\tthis.setState({\n\t\t\tboxes,\n\t\t\tguides\n\t\t});\n\t}\n\n\tresizeEndHandler(e, data) {\n\t\tif (this.state.resizing) {\n\t\t\tlet newData = Object.assign({}, data);\n\t\t\tif (this.state.boxes[this.state.active].metadata) {\n\t\t\t\tnewData.metadata = this.state.boxes[this.state.active].metadata;\n\t\t\t}\n\n\t\t\tif (data.type && data.type === 'group') {\n\t\t\t\tnewData.selections = this.state.activeBoxes.map(box => {\n\t\t\t\t\treturn Object.assign({}, this.state.boxes[box]);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthis.props.onResizeEnd && this.props.onResizeEnd(e, newData);\n\t\t}\n\n\t\tthis.setState({\n\t\t\tresizing: false,\n\t\t\tguidesActive: false\n\t\t});\n\t}\n\n\trotateStartHandler(e, data) {\n\t\tthis.setState({\n\t\t\tactive: data.node.id,\n\t\t\trotating: true\n\t\t});\n\t\tthis.props.onRotateStart && this.props.onRotateStart(e, data);\n\t}\n\n\trotateHandler(e, data) {\n\t\tconst boxes = Object.assign({}, this.state.boxes, {\n\t\t\t[this.state.active]: Object.assign({}, this.state.boxes[this.state.active], {\n\t\t\t\t...this.state.boxes[this.state.active],\n\t\t\t\tx: data.x,\n\t\t\t\ty: data.y,\n\t\t\t\trotateAngle: data.rotateAngle\n\t\t\t})\n\t\t});\n\n\t\tthis.setState({\n\t\t\tboxes\n\t\t});\n\n\t\tthis.props.onRotate && this.props.onRotate(e, data);\n\t}\n\n\trotateEndHandler(e, data) {\n\t\tlet newData = Object.assign({}, data);\n\t\tif (this.state.boxes[this.state.active].metadata) {\n\t\t\tnewData.metadata = this.state.boxes[this.state.active].metadata;\n\t\t}\n\t\tthis.props.onRotateEnd && this.props.onRotateEnd(e, newData);\n\t}\n\n\tkeyUpHandler(e, data) {\n\t\tlet newData = Object.assign({}, data);\n\t\tif (this.state.boxes[data.node.id].metadata) {\n\t\t\tnewData.metadata = this.state.boxes[data.node.id].metadata;\n\t\t}\n\n\t\tlet boxes = null;\n\t\tlet guides = null;\n\t\tif (data.type && data.type === 'group') {\n\t\t\tboxes = {};\n\t\t\tfor (let box in this.state.boxes) {\n\t\t\t\tif (this.state.boxes.hasOwnProperty(box)) {\n\t\t\t\t\tif (this.state.activeBoxes.includes(box)) {\n\t\t\t\t\t\tboxes[box] = Object.assign({}, this.state.boxes[box], {\n\t\t\t\t\t\t\tx: this.state.boxes[box].x + (data.changedValues.x || 0),\n\t\t\t\t\t\t\ty: this.state.boxes[box].y + (data.changedValues.y || 0),\n\t\t\t\t\t\t\tleft: this.state.boxes[box].left + (data.changedValues.left || 0),\n\t\t\t\t\t\t\ttop: this.state.boxes[box].top + (data.changedValues.top || 0),\n\t\t\t\t\t\t\theight: this.state.boxes[box].height + (data.changedValues.height || 0),\n\t\t\t\t\t\t\twidth: this.state.boxes[box].width + (data.changedValues.width || 0)\n\t\t\t\t\t\t});\n\t\t\t\t\t} else if (box === 'box-ms') {\n\t\t\t\t\t\tboxes[box] = Object.assign({}, data);\n\t\t\t\t\t\tdelete boxes[box].deltaX;\n\t\t\t\t\t\tdelete boxes[box].deltaY;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tboxes[box] = this.state.boxes[box];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tguides = Object.keys(this.state.guides).map(guide => {\n\t\t\t\tif (this.state.activeBoxes.includes(guide)) {\n\t\t\t\t\treturn Object.assign({}, this.state.guides[guide], {\n\t\t\t\t\t\tx: calculateGuidePositions(boxes[guide], 'x'),\n\t\t\t\t\t\ty: calculateGuidePositions(boxes[guide], 'y')\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\treturn this.state.guides[guide];\n\t\t\t});\n\t\t} else {\n\t\t\tboxes = Object.assign({}, this.state.boxes, {\n\t\t\t\t[data.node.id]: Object.assign({}, this.state.boxes[data.node.id], {\n\t\t\t\t\tx: data.x,\n\t\t\t\t\ty: data.y,\n\t\t\t\t\tleft: data.left,\n\t\t\t\t\ttop: data.top,\n\t\t\t\t\twidth: data.width,\n\t\t\t\t\theight: data.height\n\t\t\t\t})\n\t\t\t});\n\n\t\t\tguides = Object.assign({}, this.state.guides, {\n\t\t\t\t[data.node.id]: Object.assign({}, this.state.guides[data.node.id], {\n\t\t\t\t\tx: calculateGuidePositions(boxes[data.node.id], 'x'),\n\t\t\t\t\ty: calculateGuidePositions(boxes[data.node.id], 'y')\n\t\t\t\t})\n\t\t\t});\n\t\t}\n\n\t\tthis.setState({\n\t\t\tboxes,\n\t\t\tguides,\n\t\t\tresizing: false,\n\t\t\tguidesActive: false\n\t\t}, () => {\n\t\t\tif (data.type && data.type === 'group') {\n\t\t\t\tnewData.selections = this.state.activeBoxes.map(box => {\n\t\t\t\t\treturn Object.assign({}, this.state.boxes[box]);\n\t\t\t\t});\n\t\t\t}\n\t\n\t\t\tthis.props.onKeyUp && this.props.onKeyUp(e, newData);\n\t\t});\n\t}\n\n\tkeyEndHandler(e, data) {\n\t\tlet newData = Object.assign({}, data);\n\t\tif (this.state.boxes[this.state.active].metadata) {\n\t\t\tnewData.metadata = this.state.boxes[this.state.active].metadata;\n\t\t}\n\n\t\tif (data.type && data.type === 'group') {\n\t\t\tnewData.selections = this.state.activeBoxes.map(box => {\n\t\t\t\treturn Object.assign({}, this.state.boxes[box]);\n\t\t\t});\n\t\t}\n\n\t\tthis.props.onKeyEnd && this.props.onKeyEnd(e, newData);\n\t\t\n\n\t\tthis.setState({\n\t\t\tresizing: false,\n\t\t\tdragging: false,\n\t\t\tguidesActive: false\n\t\t});\n\t}\n\n\trender() {\n\t\tconst { active, boxes, activeBoxes, guides } = this.state;\n\t\tconst areMultipleBoxesSelected = activeBoxes.length > 1;\n\n\t\t// Create the draggable boxes from the position data\n\t\tconst draggableBoxes = Object.keys(boxes).map(box => {\n\t\t\tconst position = boxes[box];\n\t\t\tconst id = boxes[box].id || box;\n\t\t\tconst identifier = boxes[box].identifier; // option index for caption\n\t\t\tconst isLayerLocked = boxes[box].isLayerLocked; \n\t\t\tconst isSelected = (active === id || activeBoxes.includes(id));\n\t\t\treturn {\n\t\t\t\t\tif (this.props.preventShortcutEvents) {\n\t\t\t\t\t\tthis.props.setPreventShortcutEvents(false);\n\t\t\t\t\t}\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{(position.isWidthZero || position.isHeightZero) &&
}\n\t\t\t\t{<>\n\t\t\t\t\t{\n\t\t\t\t\t\t(isSelected && !areMultipleBoxesSelected) || (isSelected && position.type && position.type === 'group') ?\n\t\t\t\t\t\t(this.props.didDragOrResizeHappen) ?
\n\t\t\t\t\t\t\t{`${Math.round(position.x * xFactor)}, ${Math.round(position.y * yFactor)}`}\n\t\t\t\t\t\t :\n\t\t\t\t\t\t\tnull :null\n\t\t\t\t\t}\n\t\t\t\t\t{\n\t\t\t\t\t\t(isSelected && !areMultipleBoxesSelected) || (isSelected && position.type && position.type === 'group') ?\n\t\t\t\t\t\t(this.props.didDragOrResizeHappen) ?
\n\t\t\t\t\t\t\t{`${Math.round(position.width * xFactor)} x ${Math.round(position.height * yFactor)}`}
\n\t\t\t\t\t\t :\n\t\t\t\t\t\t\tnull :null\n\t\t\t\t\t}\n\t\t\t\t\t{\n\t\t\t\t\t\t(isSelected && !areMultipleBoxesSelected) || (position.type && position.type === 'group' && isSelected) ?\n\t\t\t\t\t\t\tRESIZE_CORNERS.filter(this.filterControls).map(handle => {\n\t\t\t\t\t\t\t\tlet visibleHandle = handle;\n\t\t\t\t\t\t\t\tconst additionalStyles = {};\n\t\t\t\t\t\t\t\tif (position.isHeightZero) {\n\t\t\t\t\t\t\t\t\tif (handle.includes('r')) {\n\t\t\t\t\t\t\t\t\t\tvisibleHandle = 'cr';\n\t\t\t\t\t\t\t\t\t} else if (handle.includes('l')) {\n\t\t\t\t\t\t\t\t\t\tvisibleHandle = 'cl';\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t// additionalStyles.bottom = 0;\n\t\t\t\t\t\t\t\t\tadditionalStyles.top = 0;\n\t\t\t\t\t\t\t\t} else if (position.isWidthZero) {\n\t\t\t\t\t\t\t\t\tif (handle.includes('t')) {\n\t\t\t\t\t\t\t\t\t\tvisibleHandle = 'ct';\n\t\t\t\t\t\t\t\t\t} else if (handle.includes('b')) {\n\t\t\t\t\t\t\t\t\t\tvisibleHandle = 'cb';\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t// additionalStyles.right = 0;\n\t\t\t\t\t\t\t\t\tadditionalStyles.left = 0;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tconst className = `${styles.resizeCorners} ${styles[`resize-${handle}`]} ` + `${dashedCentreNodes ? styles[`stretchable-resize-${handle}`] : null}`;\n\t\t\t\t\t\t\t\treturn
;\n\t\t\t\t\t\t\t}) :\n\t\t\t\t\t\t\tnull\n\t\t\t\t\t}\n\t\t\t\t\t{\n\t\t\t\t\t\tisSelected && !areMultipleBoxesSelected ?\n\t\t\t\t\t\t\tROTATE_HANDLES.filter(this.filterControls).map(handle => {\n\t\t\t\t\t\t\t\tconst className = `${styles.rotateHandle} ${styles[`rotate-${handle}`]}`;\n\t\t\t\t\t\t\t\treturn
;\n\t\t\t\t\t\t\t}) :\n\t\t\t\t\t\t\tnull\n\t\t\t\t\t}\n\t\t\t\t>}\n\t\t\t
\n\t\t}\n\n\t\treturn null;\n\t}\n}\n\nBox.propTypes = {\n\tareMultipleBoxesSelected: PropTypes.bool,\n\tboundToParent: PropTypes.bool,\n\tdrag: PropTypes.bool,\n\tgetBoundingBoxElement: PropTypes.func,\n\tid: PropTypes.string,\n\tisSelected: PropTypes.bool,\n\tkeybindings: PropTypes.bool,\n\tonDragStart: PropTypes.func,\n\tonDrag: PropTypes.func,\n\tonDragEnd: PropTypes.func,\n\tonKeyUp: PropTypes.func,\n\tonKeyEnd: PropTypes.func,\n\tonResizeStart: PropTypes.func,\n\tonResize: PropTypes.func,\n\tonResizeEnd: PropTypes.func,\n\tonRotateStart: PropTypes.func,\n\tonRotate: PropTypes.func,\n\tonRotateEnd: PropTypes.func,\n\tposition: PropTypes.object.isRequired,\n\tresize: PropTypes.bool,\n\tresolution: PropTypes.object,\n\trotate: PropTypes.bool\n};\n\nexport default Box;\n","import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport Box from './Box';\nimport {\n\tcalculateGuidePositions,\n\tgetMultipleSelectionCoordinates,\n\tgetOffsetCoordinates,\n\tproximityListener,\n\tgetGroupCoordinates,\n\tcheckGroupChildElementsLocked\n} from './utils/helpers'\nimport styles from './styles.scss';\nimport {GROUP_BOX_PREFIX} from './utils/constants';\nlet mousedown = false;\nlet last_mousex = 0;\nlet last_mousey = 0;\nlet posX = 0;\nlet posY = 0;\n// let rect2 = null;\n\nclass AlignmentGuides extends Component {\n\tconstructor(props) {\n\t\tsuper(props);\n\t\tthis.boundingBox = React.createRef();\n\t\tthis.state = {\n\t\t\tactive: '', // stores the active box to be shown on preview\n\t\t\tactiveBoxes: [], // store all captions box which are currently selected in multiple selection state\n\t\t\tboundingBox: null,\n\t\t\tboxes: {}, // store all data of each caption\n\t\t\tdragging: false,\n\t\t\tguides: {},\n\t\t\tguidesActive: false,\n\t\t\tisShiftKeyActive: false,\n\t\t\tmatch: {},\n\t\t\tresizing: false,\n\t\t\trotating: false,\n\t\t\tactiveBoxSnappedPosition: {},\n\t\t\tpreventShortcutEvents: false,\n\t\t\tactiveCaptionGroupCaptions: [], // this is to store all the captions selected while selecting 1 group or multiple groups\n\t\t\tcaptionGroupsToIndexMap:{} // we store all the group and its map to the caption index that are inside it as it's selection\n\t\t};\n\t\tthis.setShiftKeyState = this.setShiftKeyState.bind(this);\n\t\tthis.getBoundingBoxElement = this.getBoundingBoxElement.bind(this);\n\t\tthis.setDragOrResizeState = this.setDragOrResizeState.bind(this);\n\t\tthis.selectBox = this.selectBox.bind(this);\n\t\tthis.unSelectBox = this.unSelectBox.bind(this);\n\t\tthis.dragStartHandler = this.dragStartHandler.bind(this);\n\t\tthis.dragHandler = this.dragHandler.bind(this);\n\t\tthis.dragEndHandler = this.dragEndHandler.bind(this);\n\t\tthis.resizeStartHandler = this.resizeStartHandler.bind(this);\n\t\tthis.resizeHandler = this.resizeHandler.bind(this);\n\t\tthis.resizeEndHandler = this.resizeEndHandler.bind(this);\n\t\tthis.rotateStartHandler = this.rotateStartHandler.bind(this);\n\t\tthis.rotateHandler = this.rotateHandler.bind(this);\n\t\tthis.rotateEndHandler = this.rotateEndHandler.bind(this);\n\t\tthis.keyUpHandler = this.keyUpHandler.bind(this);\n\t\tthis.keyEndHandler = this.keyEndHandler.bind(this);\n\t\tthis.setPreventShortcutEvents = this.setPreventShortcutEvents.bind(this);\n\t\tthis.startingPositions = null;\n\t\tthis.didDragOrResizeHappen = false;\n\t\tthis.didResizeHappen = false;\n\t\tthis.didRotateHappen = false;\n\t\tthis.mouseDragHandler = this.mouseDragHandler.bind(this);\n\t\tthis.boxSelectByDrag = this.boxSelectByDrag.bind(this);\n\t\tthis.createRectByDrag = this.createRectByDrag.bind(this);\n\t\tthis.updateBoxAfterCrop = this.updateBoxAfterCrop.bind(this);\n\t\tthis.addGuidelinesForSnapping = this.addGuidelinesForSnapping.bind(this);\n\t\tthis.getReorderedBoxes = this.getReorderedBoxes.bind(this);\n\t}\n\n\tcomponentDidMount() {\n\t\t// Set the dimensions of the bounding box and the draggable boxes when the component mounts.\n\t\tif (this.boundingBox.current) {\n\t\t\tconst boundingBox = this.boundingBox.current.getBoundingClientRect().toJSON();\n\t\t\tconst boxes = {};\n\t\t\tconst guides = {};\n\t\t\tconst activeBoxes = [];\n\t\t\tlet active = '';\n\t\t\tconst captionGroupsToIndexMap = {};\n\n\t\t\t// Adding the guides for the bounding box to the guides object\n\t\t\tguides.boundingBox = {\n\t\t\t\tx: calculateGuidePositions(boundingBox, 'x').map(value => value - boundingBox.left),\n\t\t\t\ty: calculateGuidePositions(boundingBox, 'y').map(value => value - boundingBox.top)\n\t\t\t};\n\n\t\t\tthis.props.boxes.forEach((dimensions, index) => {\n\t\t\t\tboxes[`box${index}`] = Object.assign({}, dimensions, {\n\t\t\t\t\tisHeightZero: !isNaN(Number(dimensions?.height)) ? Math.round(dimensions?.height) <= 0 : undefined,\n\t\t\t\t\tisWidthZero: !isNaN(Number(dimensions?.width)) ? Math.round(dimensions?.width) <= 0 : undefined,\n\t\t\t\t});\n\t\t\t\tguides[`box${index}`] = {\n\t\t\t\t\tx: calculateGuidePositions(dimensions, 'x'),\n\t\t\t\t\ty: calculateGuidePositions(dimensions, 'y')\n\t\t\t\t};\n\t\t\t\tif (dimensions.active) {\n\t\t\t\t\tactiveBoxes.push(`box${index}`);\n\t\t\t\t}\n\n\t\t\t\tif (dimensions?.metadata?.url) {\n\t\t\t\t\tconst img = new Image();\n\t\t\t\t\timg.src = dimensions.metadata.url;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (activeBoxes.length > 1) {\n\t\t\t\tboxes['box-ms'] = getMultipleSelectionCoordinates(boxes, activeBoxes);\n\t\t\t\tboxes['box-ms'].type = 'group';\n\t\t\t\tboxes['box-ms'].zIndex = 12;\n\t\t\t\tconst selections = [];\n\t\t\t\tfor (let box in boxes) {\n\t\t\t\t\tif (boxes.hasOwnProperty(box) && activeBoxes.includes(box)) {\n\t\t\t\t\t\tselections.push(boxes[box]);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tboxes['box-ms'].selections = selections;\n\t\t\t\tactive = 'box-ms';\n\t\t\t} else if (activeBoxes.length === 1) {\n\t\t\t\tactive = activeBoxes[0];\n\t\t\t}\n\t\t\t// Checking if Groups are present and if the length of array of group > 0 then we create grouped boxes.\n\t\t\tif (this.props?.groups?.length > 0) {\n\t\t\t\t// for each group we are creating a new box starting with 'box-ms-'\n\t\t\t\tthis.props.groups.forEach((groupArray, index) => {\n\t\t\t\t\tboxes[`${GROUP_BOX_PREFIX}${index}`] = getGroupCoordinates(boxes, groupArray);\n\t\t\t\t\tboxes[`${GROUP_BOX_PREFIX}${index}`].type = 'group';\n\t\t\t\t\tboxes[`${GROUP_BOX_PREFIX}${index}`].zIndex = 12;\n\t\t\t\t\tconst selections = [];\n\t\t\t\t\tconst selectedIndexes = [];\n\t\t\t\t\tlet allElementsInsideGroupAreSelected = true;\n\t\t\t\t\t// Checking for all the boxes present inside that group and storing them in selections\n\t\t\t\t\tfor (let box in boxes) {\n\t\t\t\t\t\tif (boxes.hasOwnProperty(box) && groupArray.includes(boxes?.[box]?.metadata?.captionIndex)) {\n\t\t\t\t\t\t\tselections.push(boxes[box]);\n\t\t\t\t\t\t\tselectedIndexes.push(box);\n\t\t\t\t\t\t\tif (boxes[box].active !== true) {\n\t\t\t\t\t\t\t\tallElementsInsideGroupAreSelected = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (allElementsInsideGroupAreSelected) {\n\t\t\t\t\t\tselectedIndexes.forEach(val => {\n\t\t\t\t\t\t\tactiveBoxes.splice(activeBoxes.indexOf(val), 1);\n\t\t\t\t\t\t});\n\t\t\t\t\t\tactiveBoxes.push(`${GROUP_BOX_PREFIX}${index}`);\n\t\t\t\t\t}\n\t\t\t\t\tboxes[`${GROUP_BOX_PREFIX}${index}`].metadata = {type:'group'};\n\t\t\t\t\tboxes[`${GROUP_BOX_PREFIX}${index}`].selections = selections;\n\t\t\t\t\tboxes[`${GROUP_BOX_PREFIX}${index}`].identifier = `${GROUP_BOX_PREFIX}${index}`;\n\t\t\t\t\tboxes[`${GROUP_BOX_PREFIX}${index}`].isLayerLocked = checkGroupChildElementsLocked(selections);\n\t\t\t\t\t// storing all the indexes inside a particular group to map it later if we need\n\t\t\t\t\tcaptionGroupsToIndexMap[`${GROUP_BOX_PREFIX}${index}`] = groupArray;\n\t\t\t\t\t// active = `box-ms-${index}`;\n\t\t\t\t});\n\t\t\t\tdelete boxes['box-ms'];\n\t\t\t}\n\t\t\tif (activeBoxes.length > 1) {\n\t\t\t\tboxes['box-ms'] = getMultipleSelectionCoordinates(boxes, activeBoxes);\n\t\t\t\tboxes['box-ms'].type = 'group';\n\t\t\t\tboxes['box-ms'].zIndex = 12;\n\t\t\t\tconst selections = [];\n\t\t\t\tfor (let box in boxes) {\n\t\t\t\t\tif (boxes.hasOwnProperty(box) && activeBoxes.includes(box)) {\n\t\t\t\t\t\tselections.push(boxes[box]);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tboxes['box-ms'].selections = selections;\n\t\t\t\tactive = 'box-ms';\n\t\t\t} else if (activeBoxes.length === 1) {\n\t\t\t\tactive = activeBoxes[0];\n\t\t\t}\n\t\t\t// adding guidelines for snapping\n\t\t\tthis.addGuidelinesForSnapping(guides);\n\n\t\t\tdocument.addEventListener('click', this.unSelectBox);\n\t\t\twindow.addEventListener('blur', this.unSelectBox);\n\t\t\tdocument.addEventListener('keydown', this.setShiftKeyState);\n\t\t\tdocument.addEventListener('keydown', this.unSelectBox);\n\t\t\tdocument.addEventListener('keyup', this.setShiftKeyState);\n\t\t\tdocument.addEventListener('contextmenu', this.selectBox);\n\n\t\t\tthis.setState({\n\t\t\t\tboundingBox,\n\t\t\t\tboxes,\n\t\t\t\tguides,\n\t\t\t\tactiveBoxes,\n\t\t\t\tactive,\n\t\t\t\tcaptionGroupsToIndexMap,\n\t\t\t});\n\t\t}\n\t\tif (this.props.isStylingPanelEnabled) {\n\t\t\tthis.mouseDragHandler();\n\t\t}\n\t}\n\n\tcomponentWillUnmount() {\n\t\tdocument.removeEventListener('click', this.unSelectBox);\n\t\twindow.removeEventListener('blur', this.unSelectBox);\n\t\tdocument.removeEventListener('keydown', this.setShiftKeyState);\n\t\tdocument.removeEventListener('keydown', this.unSelectBox);\n\t\tdocument.removeEventListener('keyup', this.setShiftKeyState);\n\t\tdocument.removeEventListener('contextmenu', this.selectBox);\n\t}\n\n\tcomponentDidUpdate(prevProps, prevState) {\n\t\tconst captionGroupsToIndexMap = {};\n\t\tif (this.state.activeBoxes.length > 0) {\n\t\t\tconst activeBoxWithoutLock = this.state.activeBoxes.filter(activeBox => {\n\t\t\t\treturn !this.state.boxes[activeBox] || !this.state.boxes[activeBox].isLayerLocked;\n\t\t\t});\n\t\t\tif (JSON.stringify(this.state.activeBoxes) !== JSON.stringify(activeBoxWithoutLock)) {\n\t\t\t\tthis.setState({\n\t\t\t\t\tactiveBoxes: activeBoxWithoutLock\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (this.props?.groups !== prevProps.groups) {\n\t\t\tlet {boxes} = this.state;\n\t\t\tboxes = Object.fromEntries(\n\t\t\t\tObject.entries(boxes)\n\t\t\t\t\t.filter(([key]) => !key.startsWith(`${GROUP_BOX_PREFIX}`))\n\t\t\t);\n\t\t\tif (this.props?.groups?.length === 0) {\n\t\t\t\tthis.setState({\n\t\t\t\t\tboxes\n\t\t\t\t});\n\t\t\t} else if (this.props?.groups?.length > 0) {\n\t\t\t\tlet active = this.state.active;\n\t\t\t\tthis.props?.groups?.forEach((groupArray, index) => {\n\t\t\t\t\tboxes[`${GROUP_BOX_PREFIX}${index}`] = getGroupCoordinates(boxes, groupArray);\n\t\t\t\t\tboxes[`${GROUP_BOX_PREFIX}${index}`].type = 'group';\n\t\t\t\t\tboxes[`${GROUP_BOX_PREFIX}${index}`].zIndex = 12;\n\t\t\t\t\tconst selections = [];\n\t\t\t\t\tfor (let box in boxes) {\n\t\t\t\t\t\tif (boxes.hasOwnProperty(box) && groupArray.includes(boxes?.[box]?.metadata?.captionIndex)) {\n\t\t\t\t\t\t\tselections.push(boxes[box]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tboxes[`${GROUP_BOX_PREFIX}${index}`].metadata = {type:'group'};\n\t\t\t\t\tboxes[`${GROUP_BOX_PREFIX}${index}`].selections = selections;\n\t\t\t\t\tboxes[`${GROUP_BOX_PREFIX}${index}`].identifier = `${GROUP_BOX_PREFIX}${index}`;\n\t\t\t\t\tboxes[`${GROUP_BOX_PREFIX}${index}`].groupedCaptions = groupArray;\n\t\t\t\t\tboxes[`${GROUP_BOX_PREFIX}${index}`].isLayerLocked = checkGroupChildElementsLocked(selections);\n\t\t\t\t\tcaptionGroupsToIndexMap[`${GROUP_BOX_PREFIX}${index}`] = groupArray;\n\t\t\t\t\t// To check if we added new group, then we select it as active\n\t\t\t\t\tif (this.props.groups?.length > prevProps.groups?.length) {\n\t\t\t\t\t\tactive = `${GROUP_BOX_PREFIX}${index}`;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tdelete boxes['box-ms'];\n\t\t\t\t\n\t\t\t\tthis.setState({\n\t\t\t\t\tboxes,\n\t\t\t\t\tcaptionGroupsToIndexMap,\n\t\t\t\t\tactive\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// adding user guides for snapping\n\t\tif (\n\t\t\tthis.props.xFactor !== prevProps.xFactor ||\n\t\t\tthis.props.yFactor !== prevProps.yFactor ||\n\t\t\tthis.props.userXGuides !== prevProps.userXGuides ||\n\t\t\tthis.props.userYGuides !== prevProps.userYGuides\n\t\t) {\n\t\t\tconst guides = this.state.guides\n\t\t\tthis.addGuidelinesForSnapping(guides)\n\t\t\tthis.setState({\n\t\t\t\tguides,\n\t\t\t})\n\t\t}\n\t}\n\n\t// keeping the z-index of group box with the last element in group\n\tgetReorderedBoxes(boxes, captionGroupsToIndexMap) {\n\t\tconst selectionBoxesWithHigherIndex = {};\n\n\t\tconst reversedKeys = Object.keys(boxes).reverse();\n\t\tObject.keys(captionGroupsToIndexMap).forEach(group => {\n\t\t\tif (boxes[group]) {\n\t\t\t\tfor (let i=0; i