{
  "version": 3,
  "sources": ["../../../../src/lib/shapes/frame/frameHelpers.ts"],
  "sourcesContent": ["import {\n\tBox,\n\tEditor,\n\tTLFrameShape,\n\tcanonicalizeRotation,\n\tlast,\n\ttoDomPrecision,\n} from '@tldraw/editor'\nimport { TLCreateTextJsxFromSpansOpts } from '../shared/createTextJsxFromSpans'\n\nexport function defaultEmptyAs(str: string, dflt: string) {\n\tif (str.match(/^\\s*$/)) {\n\t\treturn dflt\n\t}\n\treturn str\n}\n\nexport function getFrameHeadingSide(editor: Editor, shape: TLFrameShape): 0 | 1 | 2 | 3 {\n\tconst pageRotation = canonicalizeRotation(editor.getShapePageTransform(shape.id)!.rotation())\n\tconst offsetRotation = pageRotation + Math.PI / 4\n\tconst scaledRotation = (offsetRotation * (2 / Math.PI) + 4) % 4\n\treturn Math.floor(scaledRotation) as 0 | 1 | 2 | 3\n}\n\n/**\n * We use a weak map here to prevent re-measuring the text width of frames that haven't changed their names.\n * It's only really important for performance reasons while zooming in and out. The measured text size is\n * independent of the zoom level, so we can cache the expensive part (measurement) and apply those changes\n * using the zoom level.\n */\nconst measurementWeakmap = new WeakMap()\n\n/**\n * Get the frame heading info (size and text) for a frame shape.\n *\n * @param editor The editor instance.\n * @param shape The frame shape.\n * @param opts The text measurement options.\n *\n * @returns The frame heading's size (as a Box) and JSX text spans.\n */\nexport function getFrameHeadingSize(\n\teditor: Editor,\n\tshape: TLFrameShape,\n\topts: TLCreateTextJsxFromSpansOpts\n) {\n\tif (process.env.NODE_ENV === 'test') {\n\t\t// can't really measure text in tests\n\t\treturn new Box(0, -opts.height, shape.props.w, opts.height)\n\t}\n\n\tlet width = measurementWeakmap.get(shape.props)\n\tif (!width) {\n\t\tconst frameTitle = defaultEmptyAs(shape.props.name, 'Frame') + String.fromCharCode(8203)\n\t\tconst spans = editor.textMeasure.measureTextSpans(frameTitle, opts)\n\t\tconst firstSpan = spans[0]\n\t\tconst lastSpan = last(spans)!\n\n\t\twidth = lastSpan.box.w + lastSpan.box.x - firstSpan.box.x\n\t\tmeasurementWeakmap.set(shape.props, width)\n\t}\n\n\treturn new Box(0, -opts.height, width, opts.height)\n}\n\nexport function getFrameHeadingOpts(width: number, isSvg: boolean): TLCreateTextJsxFromSpansOpts {\n\treturn {\n\t\tfontSize: 12,\n\t\tfontFamily: isSvg ? 'Arial' : 'Inter, sans-serif',\n\t\ttextAlign: 'start' as const,\n\t\twidth: width,\n\t\theight: 24, // --frame-height\n\t\tpadding: 0,\n\t\tlineHeight: 1,\n\t\tfontStyle: 'normal',\n\t\tfontWeight: 'normal',\n\t\toverflow: 'truncate-ellipsis' as const,\n\t\tverticalTextAlign: 'middle' as const,\n\t\toffsetY: -(32 + 2), // --frame-minimum-height + (border width * 2)\n\t\toffsetX: 0,\n\t}\n}\n\nexport function getFrameHeadingTranslation(\n\tshape: TLFrameShape,\n\tside: 0 | 1 | 2 | 3,\n\tisSvg: boolean\n) {\n\tconst u = isSvg ? '' : 'px'\n\tconst r = isSvg ? '' : 'deg'\n\tlet labelTranslate: string\n\tswitch (side) {\n\t\tcase 0: // top\n\t\t\tlabelTranslate = ``\n\t\t\tbreak\n\t\tcase 3: // right\n\t\t\tlabelTranslate = `translate(${toDomPrecision(shape.props.w)}${u}, 0${u}) rotate(90${r})`\n\t\t\tbreak\n\t\tcase 2: // bottom\n\t\t\tlabelTranslate = `translate(${toDomPrecision(shape.props.w)}${u}, ${toDomPrecision(\n\t\t\t\tshape.props.h\n\t\t\t)}${u}) rotate(180${r})`\n\t\t\tbreak\n\t\tcase 1: // left\n\t\t\tlabelTranslate = `translate(0${u}, ${toDomPrecision(shape.props.h)}${u}) rotate(270${r})`\n\t\t\tbreak\n\t\tdefault:\n\t\t\tthrow Error('labelSide out of bounds')\n\t}\n\n\treturn labelTranslate\n}\n"],
  "mappings": "AAAA;AAAA,EACC;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AAGA,SAAS,eAAe,KAAa,MAAc;AACzD,MAAI,IAAI,MAAM,OAAO,GAAG;AACvB,WAAO;AAAA,EACR;AACA,SAAO;AACR;AAEO,SAAS,oBAAoB,QAAgB,OAAoC;AACvF,QAAM,eAAe,qBAAqB,OAAO,sBAAsB,MAAM,EAAE,EAAG,SAAS,CAAC;AAC5F,QAAM,iBAAiB,eAAe,KAAK,KAAK;AAChD,QAAM,kBAAkB,kBAAkB,IAAI,KAAK,MAAM,KAAK;AAC9D,SAAO,KAAK,MAAM,cAAc;AACjC;AAQA,MAAM,qBAAqB,oBAAI,QAAQ;AAWhC,SAAS,oBACf,QACA,OACA,MACC;AACD,MAAI,QAAQ,IAAI,aAAa,QAAQ;AAEpC,WAAO,IAAI,IAAI,GAAG,CAAC,KAAK,QAAQ,MAAM,MAAM,GAAG,KAAK,MAAM;AAAA,EAC3D;AAEA,MAAI,QAAQ,mBAAmB,IAAI,MAAM,KAAK;AAC9C,MAAI,CAAC,OAAO;AACX,UAAM,aAAa,eAAe,MAAM,MAAM,MAAM,OAAO,IAAI,OAAO,aAAa,IAAI;AACvF,UAAM,QAAQ,OAAO,YAAY,iBAAiB,YAAY,IAAI;AAClE,UAAM,YAAY,MAAM,CAAC;AACzB,UAAM,WAAW,KAAK,KAAK;AAE3B,YAAQ,SAAS,IAAI,IAAI,SAAS,IAAI,IAAI,UAAU,IAAI;AACxD,uBAAmB,IAAI,MAAM,OAAO,KAAK;AAAA,EAC1C;AAEA,SAAO,IAAI,IAAI,GAAG,CAAC,KAAK,QAAQ,OAAO,KAAK,MAAM;AACnD;AAEO,SAAS,oBAAoB,OAAe,OAA8C;AAChG,SAAO;AAAA,IACN,UAAU;AAAA,IACV,YAAY,QAAQ,UAAU;AAAA,IAC9B,WAAW;AAAA,IACX;AAAA,IACA,QAAQ;AAAA;AAAA,IACR,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,mBAAmB;AAAA,IACnB,SAAS,EAAE,KAAK;AAAA;AAAA,IAChB,SAAS;AAAA,EACV;AACD;AAEO,SAAS,2BACf,OACA,MACA,OACC;AACD,QAAM,IAAI,QAAQ,KAAK;AACvB,QAAM,IAAI,QAAQ,KAAK;AACvB,MAAI;AACJ,UAAQ,MAAM;AAAA,IACb,KAAK;AACJ,uBAAiB;AACjB;AAAA,IACD,KAAK;AACJ,uBAAiB,aAAa,eAAe,MAAM,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC;AACrF;AAAA,IACD,KAAK;AACJ,uBAAiB,aAAa,eAAe,MAAM,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK;AAAA,QACnE,MAAM,MAAM;AAAA,MACb,CAAC,GAAG,CAAC,eAAe,CAAC;AACrB;AAAA,IACD,KAAK;AACJ,uBAAiB,cAAc,CAAC,KAAK,eAAe,MAAM,MAAM,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC;AACtF;AAAA,IACD;AACC,YAAM,MAAM,yBAAyB;AAAA,EACvC;AAEA,SAAO;AACR;",
  "names": []
}
