{
  "version": 3,
  "sources": ["../../../../src/lib/shapes/note/noteHelpers.ts"],
  "sourcesContent": ["import {\n\tEditor,\n\tIndexKey,\n\tTLNoteShape,\n\tTLShape,\n\tVec,\n\tcompact,\n\tcreateShapeId,\n\ttoRichText,\n} from '@tldraw/editor'\n\n/** @internal */\nexport const CLONE_HANDLE_MARGIN = 0\n/** @internal */\nexport const NOTE_ADJACENT_POSITION_SNAP_RADIUS = 10\n\nconst BASE_NOTE_POSITIONS = (editor: Editor, noteWidth: number, noteHeight: number) =>\n\t[\n\t\t[\n\t\t\t['a1' as IndexKey],\n\t\t\tnew Vec(noteWidth * 0.5, noteHeight * -0.5 - editor.options.adjacentShapeMargin),\n\t\t], // t\n\t\t[\n\t\t\t['a2' as IndexKey],\n\t\t\tnew Vec(noteWidth * 1.5 + editor.options.adjacentShapeMargin, noteHeight * 0.5),\n\t\t], // r\n\t\t[\n\t\t\t['a3' as IndexKey],\n\t\t\tnew Vec(noteWidth * 0.5, noteHeight * 1.5 + editor.options.adjacentShapeMargin),\n\t\t], // b\n\t\t[\n\t\t\t['a4' as IndexKey],\n\t\t\tnew Vec(noteWidth * -0.5 - editor.options.adjacentShapeMargin, noteHeight * 0.5),\n\t\t], // l\n\t] as const\n\nfunction getBaseAdjacentNotePositions(\n\teditor: Editor,\n\tscale: number,\n\tnoteWidth: number,\n\tnoteHeight: number\n) {\n\tif (scale === 1) return BASE_NOTE_POSITIONS(editor, noteWidth, noteHeight)\n\tconst w = noteWidth * scale\n\tconst h = noteHeight * scale\n\tconst m = editor.options.adjacentShapeMargin * scale\n\treturn [\n\t\t[['a1' as IndexKey], new Vec(w * 0.5, h * -0.5 - m)], // t\n\t\t[['a2' as IndexKey], new Vec(w * 1.5 + m, h * 0.5)], // r\n\t\t[['a3' as IndexKey], new Vec(w * 0.5, h * 1.5 + m)], // b\n\t\t[['a4' as IndexKey], new Vec(w * -0.5 - m, h * 0.5)], // l\n\t] as const\n}\n\n/** @internal */\nexport interface NoteAdjacentPositionsOpts {\n\tpagePoint: Vec\n\tpageRotation: number\n\tgrowY: number\n\textraHeight: number\n\tscale: number\n\tnoteWidth: number\n\tnoteHeight: number\n}\n\n/**\n * Get the adjacent positions for a particular note shape.\n *\n * @internal */\nexport function getNoteAdjacentPositions(\n\teditor: Editor,\n\topts: NoteAdjacentPositionsOpts\n): Record<IndexKey, Vec> {\n\tconst { pagePoint, pageRotation, growY, extraHeight, scale, noteWidth, noteHeight } = opts\n\treturn Object.fromEntries(\n\t\tgetBaseAdjacentNotePositions(editor, scale, noteWidth, noteHeight).map(([id, v], i) => {\n\t\t\tconst point = v.clone()\n\t\t\tif (i === 0 && extraHeight) {\n\t\t\t\t// apply top margin (the growY of the moving note shape)\n\t\t\t\tpoint.y -= extraHeight\n\t\t\t} else if (i === 2 && growY) {\n\t\t\t\t// apply bottom margin (the growY of this note shape)\n\t\t\t\tpoint.y += growY\n\t\t\t}\n\t\t\treturn [id, point.rot(pageRotation).add(pagePoint)]\n\t\t})\n\t)\n}\n\n/** @internal */\nexport interface AvailableNoteAdjacentPositionsOpts {\n\trotation: number\n\tscale: number\n\textraHeight: number\n\tnoteWidth: number\n\tnoteHeight: number\n}\n\n/**\n * Get all of the available note adjacent positions, excluding the selected shapes.\n *\n * @internal */\nexport function getAvailableNoteAdjacentPositions(\n\teditor: Editor,\n\topts: AvailableNoteAdjacentPositionsOpts\n) {\n\tconst { rotation, scale, extraHeight, noteWidth, noteHeight } = opts\n\tconst selectedShapeIds = new Set(editor.getSelectedShapeIds())\n\tconst minSize =\n\t\t(Math.max(noteWidth, noteHeight) + editor.options.adjacentShapeMargin + extraHeight) ** 2\n\tconst allCenters = new Map<TLNoteShape, Vec>()\n\tconst positions: (Vec | undefined)[] = []\n\n\t// Get all the positions that are adjacent to the selected note shapes\n\tfor (const shape of editor.getCurrentPageShapes()) {\n\t\tif (\n\t\t\t!editor.isShapeOfType(shape, 'note') ||\n\t\t\tscale !== shape.props.scale ||\n\t\t\tselectedShapeIds.has(shape.id)\n\t\t) {\n\t\t\tcontinue\n\t\t}\n\n\t\tconst transform = editor.getShapePageTransform(shape.id)!\n\n\t\t// If the note has a different rotation, we can't use its adjacent positions\n\t\tif (rotation !== transform.rotation()) continue\n\n\t\t// Save the unselected note shape's center\n\t\tallCenters.set(shape, editor.getShapePageBounds(shape)!.center)\n\n\t\t// And push its position to the positions array\n\t\tpositions.push(\n\t\t\t...Object.values(\n\t\t\t\tgetNoteAdjacentPositions(editor, {\n\t\t\t\t\tpagePoint: transform.point(),\n\t\t\t\t\tpageRotation: rotation,\n\t\t\t\t\tgrowY: shape.props.growY,\n\t\t\t\t\textraHeight,\n\t\t\t\t\tscale,\n\t\t\t\t\tnoteWidth,\n\t\t\t\t\tnoteHeight,\n\t\t\t\t})\n\t\t\t)\n\t\t)\n\t}\n\n\t// Remove positions that are inside of another note shape\n\tconst len = positions.length\n\tlet position: Vec | undefined\n\tfor (const [shape, center] of allCenters) {\n\t\tfor (let i = 0; i < len; i++) {\n\t\t\tposition = positions[i]\n\t\t\tif (!position) continue\n\t\t\tif (Vec.Dist2(center, position) > minSize) continue\n\t\t\tif (editor.isPointInShape(shape, position)) {\n\t\t\t\tpositions[i] = undefined\n\t\t\t}\n\t\t}\n\t}\n\n\treturn compact(positions)\n}\n\n/** @internal */\nexport interface NoteShapeForAdjacentPositionOpts {\n\tshape: TLNoteShape\n\tcenter: Vec\n\tpageRotation: number\n\tnoteWidth: number\n\tnoteHeight: number\n\tforceNew?: boolean\n}\n\n/**\n * For a particular adjacent note position, get the shape in that position or create a new one.\n *\n * @internal */\nexport function getNoteShapeForAdjacentPosition(\n\teditor: Editor,\n\topts: NoteShapeForAdjacentPositionOpts\n) {\n\tconst { shape, center, pageRotation, noteWidth, noteHeight, forceNew = false } = opts\n\t// There might already be a note in that position! If there is, we'll\n\t// select the next note and switch focus to it. If there's not, then\n\t// we'll create a new note in that position.\n\n\tlet nextNote: TLShape | undefined\n\n\t// Check the center of where a new note would be\n\t// Start from the top of the stack, and work our way down\n\tconst allShapesOnPage = editor.getCurrentPageShapesSorted()\n\n\tconst minDistance =\n\t\t(Math.max(noteWidth, noteHeight) + editor.options.adjacentShapeMargin ** 2) ** shape.props.scale\n\n\tfor (let i = allShapesOnPage.length - 1; i >= 0; i--) {\n\t\tconst otherNote = allShapesOnPage[i]\n\t\tif (otherNote.type === 'note' && otherNote.id !== shape.id) {\n\t\t\tconst otherBounds = editor.getShapePageBounds(otherNote)\n\t\t\tif (\n\t\t\t\totherBounds &&\n\t\t\t\tVec.Dist2(otherBounds.center, center) < minDistance &&\n\t\t\t\teditor.isPointInShape(otherNote, center)\n\t\t\t) {\n\t\t\t\tnextNote = otherNote\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\teditor.complete()\n\n\t// If we didn't find any in that position, then create a new one\n\tif (!nextNote || forceNew) {\n\t\teditor.markHistoryStoppingPoint('creating note shape')\n\t\tconst id = createShapeId()\n\n\t\t// We create it at the center first, so that it becomes\n\t\t// the child of whatever parent was at that center\n\t\teditor.createShape({\n\t\t\tid,\n\t\t\ttype: 'note',\n\t\t\tx: center.x,\n\t\t\ty: center.y,\n\t\t\trotation: pageRotation,\n\t\t\topacity: shape.opacity,\n\t\t\tprops: {\n\t\t\t\t// Use the props of the shape we're cloning\n\t\t\t\t...shape.props,\n\t\t\t\trichText: toRichText(''),\n\t\t\t\tgrowY: 0,\n\t\t\t\tfontSizeAdjustment: 1,\n\t\t\t\turl: '',\n\t\t\t\ttextFirstEditedBy: null,\n\t\t\t},\n\t\t})\n\n\t\t// Now we need to correct its location within its new parent\n\n\t\tconst createdShape = editor.getShape<TLNoteShape>(id)!\n\t\tif (!createdShape) return // may have hit max shapes\n\n\t\t// We need to put the page point in the same coordinate space as the newly created shape (i.e its parent's space)\n\t\tconst topLeft = editor.getPointInParentSpace(\n\t\t\tcreatedShape,\n\t\t\tVec.Sub(\n\t\t\t\tcenter,\n\t\t\t\tVec.Rot(new Vec(noteWidth / 2, noteHeight / 2).mul(createdShape.props.scale), pageRotation)\n\t\t\t)\n\t\t)\n\n\t\teditor.updateShape({\n\t\t\tid,\n\t\t\ttype: 'note',\n\t\t\tx: topLeft.x,\n\t\t\ty: topLeft.y,\n\t\t})\n\n\t\tnextNote = editor.getShape(id)!\n\t}\n\n\teditor.zoomToSelectionIfOffscreen(16, {\n\t\tanimation: {\n\t\t\tduration: editor.options.animationMediumMs,\n\t\t},\n\t\tinset: 0,\n\t})\n\treturn nextNote\n}\n"],
  "mappings": "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",
  "names": []
}
