@phin-tech/dottie 0.6.1 → 0.6.3

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.
package/dist/dottie.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! dottie.js 0.6.1 | Apache-2.0 | https://github.com/phin-tech/dottie */
1
+ /*! dottie.js 0.6.3 | Apache-2.0 | https://github.com/phin-tech/dottie */
2
2
  var __defProp = Object.defineProperty;
3
3
  var __defNormalProp = (obj, key, value2) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value: value2 }) : obj[key] = value2;
4
4
  var __publicField = (obj, key, value2) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value2);
@@ -13,7 +13,7 @@ var KNOWN_FIELDS = {
13
13
  symbol: ["id", "name", "width", "height", "layers", "elements", "timeline", "button", "params"],
14
14
  layer: ["id", "name", "visible", "locked"],
15
15
  rgba: ["r", "g", "b", "a"],
16
- style: ["stroke", "fill", "fillStyle", "strokeWidth", "dash", "roughness", "bowing", "fontSize", "gridSize", "opacity", "dashOffset"],
16
+ style: ["stroke", "fill", "fillStyle", "strokeWidth", "dash", "roughness", "bowing", "fontSize", "font", "gridSize", "opacity", "dashOffset", "textColor"],
17
17
  element: [
18
18
  "id",
19
19
  "kind",
@@ -54,7 +54,8 @@ var KNOWN_FIELDS = {
54
54
  extensionRef: ["id", "shape", "version", "params"],
55
55
  normalizedPoint: ["x", "y"],
56
56
  normalizedRect: ["x", "y", "width", "height"],
57
- connector: ["start", "end", "routing", "startHead", "endHead"],
57
+ connector: ["start", "end", "routing", "startHead", "endHead", "waypoints", "hops"],
58
+ waypoint: ["x", "y"],
58
59
  timeline: ["fps", "duration", "boil", "settle", "poster", "tracks", "camera", "markers"],
59
60
  track: ["element", "keys", "boil", "follow", "repeats", "march"],
60
61
  keyframe: ["t", "x", "y", "width", "height", "rotation", "strokeWidth", "stroke", "fill", "visible", "reveal", "opacity", "ease"],
@@ -133,9 +134,11 @@ var Reader = class {
133
134
  roughness: num(s.roughness) ?? 1,
134
135
  bowing: num(s.bowing) ?? 1,
135
136
  fontSize: num(s.fontSize) ?? 18,
137
+ font: str(s.font) || null,
136
138
  gridSize: num(s.gridSize) ?? null,
137
139
  opacity: num(s.opacity) ?? null,
138
- dashOffset: num(s.dashOffset) ?? null
140
+ dashOffset: num(s.dashOffset) ?? null,
141
+ textColor: rgba(s.textColor) ?? null
139
142
  };
140
143
  }
141
144
  endpoint(v) {
@@ -163,7 +166,12 @@ var Reader = class {
163
166
  end: this.endpoint(v.end),
164
167
  routing: routing && ["straight", "curved", "elbow"].includes(routing) ? routing : "straight",
165
168
  startHead: head(v.startHead, "none"),
166
- endHead: head(v.endHead, "arrow")
169
+ endHead: head(v.endHead, "arrow"),
170
+ waypoints: Array.isArray(v.waypoints) ? v.waypoints.filter(isObj).map((w) => {
171
+ this.fields(w, "waypoint");
172
+ return { x: num(w.x) ?? 0, y: num(w.y) ?? 0 };
173
+ }) : null,
174
+ hops: typeof v.hops === "boolean" ? v.hops : null
167
175
  };
168
176
  }
169
177
  image(v, table) {
@@ -440,8 +448,18 @@ function isAutomaticInk(c) {
440
448
  function cloneElement(e) {
441
449
  return {
442
450
  ...e,
443
- style: { ...e.style, stroke: { ...e.style.stroke }, fill: { ...e.style.fill } },
444
- connector: e.connector ? { ...e.connector, start: { ...e.connector.start }, end: { ...e.connector.end } } : null
451
+ style: {
452
+ ...e.style,
453
+ stroke: { ...e.style.stroke },
454
+ fill: { ...e.style.fill },
455
+ textColor: e.style.textColor ? { ...e.style.textColor } : null
456
+ },
457
+ connector: e.connector ? {
458
+ ...e.connector,
459
+ start: { ...e.connector.start },
460
+ end: { ...e.connector.end },
461
+ waypoints: e.connector.waypoints?.map((w) => ({ ...w })) ?? null
462
+ } : null
445
463
  };
446
464
  }
447
465
  function orderedElements(page) {
@@ -460,6 +478,159 @@ function elementIndex(page) {
460
478
  return m;
461
479
  }
462
480
 
481
+ // src/metrics.ts
482
+ var monoAdvance = 0.60205078125;
483
+ var monoAscent = 0.92822265625;
484
+ var monoDescent = 0.23583984375;
485
+ var families = { "Architects Daughter": { "faces": { "regular": { "ascent": 0.986328125, "descent": 0.4033203125, "k": {}, "leading": 0, "w": { " ": 400.39, "_": 686.52, "-": 310.55, "\u2013": 310.55, "\u2014": 411.13, ",": 177.73, ";": 124.02, ":": 166.99, "!": 134.77, "?": 505.86, ".": 140.63, "\u2026": 422.85, "\xB7": 140.63, "'": 162.11, "\u2018": 162.11, "\u2019": 162.11, '"': 236.33, "\u201C": 236.33, "\u201D": 236.33, "(": 297.85, ")": 351.56, "[": 424.8, "]": 541.02, "{": 352.54, "}": 478.52, "@": 1042.97, "*": 507.81, "/": 455.08, "\\": 501.95, "&": 669.92, "#": 637.7, "%": 518.55, "\u2022": 192.38, "`": 171.88, "^": 306.64, "\u2190": 1e3, "\u2192": 1e3, "\u2191": 645.02, "\u2193": 645.02, "+": 524.41, "\xD7": 470.7, "<": 475.59, "=": 492.19, ">": 471.68, "|": 145.51, "~": 444.34, "\u25E6": 578.13, "\u2610": 830.08, "\u2611": 830.08, "\u2713": 764.16, "$": 556.64, "0": 630.86, "1": 127.93, "2": 572.27, "3": 508.79, "4": 680.66, "5": 708.01, "6": 626.95, "7": 615.23, "8": 648.44, "9": 569.34, "a": 508.79, "A": 640.63, "b": 561.52, "B": 710.94, "c": 632.81, "C": 708.01, "d": 512.7, "D": 648.44, "e": 541.02, "E": 591.8, "\xE9": 541.02, "f": 593.75, "F": 692.38, "g": 515.63, "G": 692.38, "h": 495.12, "H": 605.47, "i": 151.37, "I": 151.37, "j": 177.73, "J": 529.3, "k": 614.26, "K": 605.47, "l": 157.23, "L": 692.38, "m": 778.32, "M": 827.15, "n": 500, "N": 626.95, "o": 562.5, "O": 669.92, "p": 556.64, "P": 637.7, "q": 513.67, "Q": 712.89, "r": 551.76, "R": 712.89, "s": 501.95, "S": 642.58, "t": 404.3, "T": 623.05, "u": 507.81, "U": 561.52, "v": 518.55, "V": 626.95, "w": 808.59, "W": 940.43, "x": 470.7, "X": 599.61, "y": 548.83, "Y": 534.18, "z": 495.12, "Z": 784.18 } } }, "fallback": { "\u2190": [0.966796875, 0.2109375, 0], "\u2192": [0.966796875, 0.2109375, 0], "\u2191": [0.966796875, 0.2109375, 0], "\u2193": [0.966796875, 0.2109375, 0], "\u25E6": [0.966796875, 0.2109375, 0], "\u2610": [0.66650390625, 0.25, 0.08349609375], "\u2611": [0.66650390625, 0.25, 0.08349609375], "\u2713": [0.966796875, 0.2109375, 0] } }, "Caveat": { "faces": { "bold": { "ascent": 0.9600067138671875, "descent": 0.3000030517578125, "k": { "AC": -20, "AE": -10, "AG": -10, "AH": -10, "AI": 10, "Aj": 10, "AJ": 10, "AL": -10, "AM": 10, "An": -10, "AO": -20, "AP": -10, "Aq": -10, "AQ": -20, "Ar": -10, "As": -10, "AS": -35, "AT": -50, "Au": -10, "AU": -20, "av": -20, "Av": -5, "AV": -40, "aw": -10, "AW": -20, "Ax": 10, "AX": -10, "ay": -20, "Ay": -10, "AY": -65, "Az": 20, "AZ": -10, "ba": -10, "bc": -10, "BC": -20, "bd": -10, "Bf": 10, "BF": -20, "Bg": 10, "bh": -5, "Bi": 10, "BI": -10, "bj": -5, "Bj": 10, "BJ": -10, "Bk": 10, "Bl": 10, "Bm": 10, "BP": -10, "BR": -10, "BS": -20, "BT": -40, "bu": -10, "BU": -20, "BV": -50, "BW": -50, "bx": -10, "Bx": 10, "BX": -40, "by": -10, "BY": -65, "Bz": 40, "BZ": -30, "CA": -20, "Cc": -5, "CC": -10, "Cd": -10, "CE": -10, "CG": -10, "Cj": 10, "CJ": -10, "CK": -10, "cl": 10, "Cl": 5, "Cn": -5, "CO": -10, "CP": -10, "CQ": -20, "Cs": -10, "CS": -10, "Ct": 10, "CT": -20, "Cu": -10, "CU": -10, "Cv": -20, "CV": -20, "cw": -10, "Cw": -10, "CW": -20, "Cx": 20, "CX": -30, "cy": -5, "CY": -35, "Cz": 20, "CZ": -40, "DA": -10, "Db": 10, "Dc": 10, "De": 10, "Df": 20, "DF": -10, "Dg": 10, "Dh": 10, "Di": 15, "DI": -10, "Dj": 5, "DJ": -10, "Dk": 10, "Dl": 10, "Dm": 20, "DM": -5, "dn": -10, "Do": 10, "Dp": 10, "Dq": 10, "Dr": 10, "Ds": 10, "dt": 10, "Dt": 20, "DT": -40, "du": -10, "Dv": 30, "DV": -30, "Dw": 20, "DW": -10, "Dx": 20, "DX": -50, "Dy": 10, "DY": -50, "Dz": 30, "DZ": -30, "EC": -10, "ED": -10, "EG": -10, "EJ": -10, "el": 10, "EO": -10, "EQ": -20, "ES": -40, "ET": -10, "EU": -20, "Ev": -10, "EV": -25, "Ew": -10, "EW": -30, "Ex": 10, "EX": -40, "Ey": -10, "EY": -50, "Ez": 20, "EZ": -20, "fa": -10, "Fa": -30, "FA": -40, "Fc": -20, "FC": -10, "Fd": -20, "FD": 20, "Fe": -15, "ff": 10, "Ff": 10, "FF": 20, "Fg": -10, "fh": 10, "Fh": 20, "fi": 10, "Fi": 10, "FI": 10, "fj": 10, "Fj": 10, "FJ": 20, "Fk": 10, "fl": 20, "Fl": 20, "FL": 10, "fm": 10, "FM": -10, "Fn": -20, "FN": 10, "Fo": -20, "FO": 10, "Fp": -10, "FP": -10, "Fq": -10, "FQ": 10, "Fr": -10, "FS": 10, "ft": 40, "Ft": 10, "FT": -30, "Fu": -10, "fv": 10, "Fv": 10, "FV": 10, "FW": 10, "fy": 10, "FY": 10, "Fz": 10, "FZ": -10, "GA": -10, "Gf": 10, "Gh": 10, "gi": 10, "Gi": 10, "GI": -10, "Gj": 10, "GJ": -10, "Gk": 10, "Gl": 10, "Gm": 10, "GM": -10, "GN": 10, "GP": -20, "GS": -10, "Gt": 10, "GU": -10, "Gv": 10, "GV": -10, "GW": -20, "Gx": 10, "GX": -40, "gy": 10, "GY": -40, "Gz": 10, "GZ": -20, "Hb": 10, "hf": -10, "Hf": 10, "hg": -20, "Hh": 10, "Hi": 10, "Hj": 20, "Hk": 10, "Hl": 10, "Hm": 10, "hq": -10, "hs": -10, "Ht": 20, "hv": -30, "Hv": 10, "hw": -15, "Hx": 20, "hy": -30, "Hy": 10, "Hz": 20, "Ia": -10, "IA": 10, "Ib": 10, "Ic": -10, "Id": -10, "ID": 30, "Ie": -10, "if": 10, "If": 20, "IF": 40, "Ig": -10, "Ih": 30, "Ii": 20, "II": 30, "Ij": 30, "IJ": 40, "Ik": 20, "IK": 10, "Il": 20, "IL": 10, "IM": 30, "In": -10, "IN": 20, "Io": -10, "Ip": 10, "Iq": -20, "Ir": -10, "IR": 10, "Is": -10, "It": 10, "Iu": -10, "IU": 10, "iv": 10, "Iv": -20, "IV": 30, "Iw": -25, "IW": 20, "Ix": 10, "IX": 10, "Iy": -10, "IY": 30, "Iz": 20, "IZ": 20, "Ja": -10, "Jb": 10, "Jc": -10, "Jd": -10, "Je": -10, "Jf": 10, "Jh": 10, "Ji": 10, "JI": -10, "Jj": 20, "JJ": 10, "Jk": 10, "Jl": 20, "Jn": -10, "Jo": -10, "JO": -10, "Jp": 10, "JP": -10, "Jq": -10, "JQ": -10, "JR": -10, "jt": 10, "Jt": 20, "JT": 10, "ju": -10, "Ju": -20, "JU": -10, "jx": 10, "JX": -25, "jy": 10, "JY": -20, "jz": 10, "Jz": 10, "JZ": -20, "Ka": -40, "kc": 20, "Kc": -40, "KC": -10, "Kd": -40, "KD": 10, "ke": 10, "Ke": -40, "kf": 20, "Kf": 10, "KF": 20, "Kg": -40, "KG": -10, "kh": 10, "Kh": 10, "ki": 10, "Ki": 10, "Kj": 40, "KJ": 20, "kk": 20, "Kk": 10, "kl": 20, "Kl": 10, "km": 10, "KM": 20, "Kn": -40, "ko": 10, "Ko": -50, "KO": -10, "Kp": 10, "Kq": -50, "kr": 10, "Ks": -40, "kt": 10, "Kt": 10, "KT": -10, "ku": 10, "Ku": -60, "kv": 10, "Kv": -30, "Kw": -40, "Kx": -10, "KX": -10, "ky": -10, "Ky": -30, "kz": 10, "Lb": -10, "LC": -20, "LE": -20, "Lf": 10, "Lg": -10, "LG": -20, "Lh": -10, "Li": 10, "LI": -40, "Lj": 20, "Lk": 10, "ll": 10, "Ll": 10, "LL": -20, "Ln": -20, "LO": -25, "Lp": 10, "Lq": -40, "LQ": -30, "Ls": -10, "LS": -65, "lt": 10, "Lt": -10, "LT": -70, "Lu": -40, "LU": -45, "Lv": -60, "LV": -70, "Lw": -40, "LW": -40, "Lx": 10, "Ly": -20, "LY": -90, "lz": 20, "Lz": 30, "LZ": -10, "Mb": 10, "md": 10, "Mf": 10, "Mh": 10, "Mi": 10, "MJ": 10, "Mk": 10, "Ml": 10, "mo": 20, "Mp": 10, "MP": -10, "Mq": -10, "MQ": -10, "MS": -20, "Mt": 20, "MT": -30, "Mu": -10, "MU": -20, "mv": -15, "Mv": 10, "MV": -20, "mw": -10, "MW": -30, "Mx": 10, "MX": -10, "my": -10, "My": -10, "MY": -50, "Mz": 10, "MZ": -10, "nb": -15, "Nb": 10, "Ne": 10, "Nf": 10, "Ng": 10, "Nh": 10, "Ni": 20, "Nj": 20, "Nk": 20, "Nl": 20, "Nm": 10, "Nq": 10, "ns": -5, "nt": -10, "Nt": 20, "nu": -10, "nv": -20, "Nv": 30, "nw": -20, "NW": -10, "Nx": 30, "NX": -20, "ny": -20, "Ny": 10, "NY": -20, "Nz": 40, "NZ": -10, "OA": -10, "OD": -10, "Of": 20, "Og": 20, "Oh": 10, "Oi": 20, "OI": -10, "oj": -5, "Oj": 20, "Ok": 10, "Ol": 20, "OL": 10, "Om": 20, "Oo": 10, "Op": 10, "Oq": 10, "OQ": 10, "Os": 10, "Ot": 20, "OT": -10, "ou": -10, "ov": 5, "Ov": 30, "OV": -10, "ow": -10, "Ow": 10, "OW": -10, "Ox": 30, "OX": -40, "oy": -10, "Oy": 20, "OY": -40, "Oz": 30, "OZ": -20, "Pa": -40, "PA": -40, "Pc": -30, "Pd": -40, "PD": -10, "Pe": -20, "Pf": 10, "Pg": -10, "Ph": 10, "Pi": 10, "PI": -10, "Pj": 20, "PJ": -10, "Pk": 10, "Pl": 10, "Pm": 10, "PM": -30, "pn": -10, "Pn": -10, "PN": -10, "Po": -30, "Pq": -30, "Ps": -20, "PS": 10, "Pt": 20, "pu": -10, "Pu": -30, "Pv": 10, "Px": 10, "PX": -35, "py": -10, "PY": -20, "Pz": 10, "PZ": -50, "Qb": 10, "Qf": 20, "Qg": 20, "qh": -10, "Qh": 10, "Qi": 20, "qj": 10, "Qj": 90, "QJ": 80, "Qk": 10, "Ql": 20, "Qm": 20, "qn": -10, "qo": -10, "Qp": 20, "Qt": 30, "QT": -10, "qu": -10, "Qv": 20, "QV": -10, "QW": -10, "Qx": 20, "QX": -20, "Qy": 50, "QY": -30, "Qz": 40, "QZ": -10, "ra": -5, "Ra": -10, "RA": -25, "RB": -10, "Rc": -10, "RC": -20, "Rd": -10, "RD": 10, "Re": -10, "RE": -20, "Rf": 20, "RF": 10, "Rg": -10, "RG": -10, "ri": 5, "RI": -10, "Rj": 30, "RJ": 30, "RL": -10, "RM": -20, "Rn": -10, "RN": 10, "Ro": -10, "RO": -10, "Rp": 20, "Rq": -30, "RQ": -10, "Rr": -10, "Rs": -10, "Rt": 10, "RT": -10, "Ru": -30, "RU": -20, "rv": 20, "RV": -10, "Rw": -10, "RW": -10, "Rx": 10, "RX": -20, "Ry": 10, "RY": -30, "Rz": 20, "RZ": -45, "Sa": -10, "Sb": 10, "Sc": -20, "Sd": -25, "SD": 20, "Se": -20, "SE": -10, "sf": 10, "Sf": 20, "SF": 30, "Sg": -20, "Sh": 20, "Si": 20, "SI": 10, "Sj": 30, "SJ": 30, "Sk": 10, "Sl": 20, "SL": 20, "Sn": -20, "SN": 10, "So": -10, "SO": 10, "Sq": -20, "Sr": -10, "Ss": -10, "st": 10, "St": 20, "Su": -20, "sv": 20, "Sv": -50, "SV": 20, "Sw": -30, "SW": 10, "sx": 15, "Sx": 10, "Sy": -15, "SY": 10, "sz": 20, "Sz": 20, "SZ": -10, "Ta": -90, "TA": -50, "Tc": -80, "TC": -10, "Td": -110, "TD": 10, "Te": -90, "TE": -10, "Tf": 20, "TF": 30, "Tg": -80, "TG": -10, "Th": 20, "ti": 5, "TI": 10, "Tj": 20, "Tk": 10, "Tl": 20, "Tm": -50, "TM": -30, "Tn": -90, "To": -90, "Tp": -80, "Tq": -120, "Tr": -80, "Ts": -80, "Tt": 10, "TT": -30, "Tu": -90, "tv": 10, "Tv": -70, "TV": 10, "Tw": -100, "tx": 20, "Tx": -60, "TX": -10, "Ty": -50, "tz": 30, "Tz": -40, "TZ": -10, "ub": -10, "Ub": 20, "UE": 10, "uf": 10, "Uf": 30, "UF": 10, "Ug": 10, "Uh": 30, "ui": 10, "Ui": 30, "Uj": 40, "uk": 10, "Uk": 20, "ul": 10, "Ul": 30, "Um": 30, "Up": 10, "UQ": 30, "Ur": 10, "UR": 10, "Us": 10, "Ut": 50, "UT": 20, "Uu": 10, "UU": 10, "Uv": 50, "UV": 10, "Uw": 10, "ux": 10, "Ux": 30, "UX": -10, "Uy": 10, "UY": -10, "uz": 30, "Uz": 30, "UZ": -10, "va": -10, "Va": -50, "VA": -55, "Vc": -30, "VC": -20, "Vd": -30, "Ve": -30, "VE": -20, "vf": 10, "VF": 10, "Vg": -30, "VG": -10, "vi": 10, "Vm": -10, "VM": -30, "Vn": -30, "VN": -10, "Vo": -30, "VO": -10, "Vp": -20, "VP": -20, "Vq": -30, "VQ": -10, "Vr": -20, "Vs": -30, "vt": 10, "VT": 20, "Vu": -30, "VU": -10, "vv": 20, "Vw": -30, "vx": 20, "VX": -20, "vy": 10, "VY": -10, "vz": 10, "VZ": -20, "WA": -20, "Wb": 20, "Wd": -10, "WD": 20, "We": 10, "Wf": 30, "WF": 20, "Wh": 30, "wi": 10, "Wi": 30, "WI": 10, "Wj": 40, "WJ": 20, "Wk": 20, "Wl": 40, "WL": 10, "Wm": 10, "WM": -10, "WS": 10, "Wt": 40, "WT": 30, "Wv": 30, "WV": 10, "wx": 10, "Wx": 20, "WX": -10, "Wy": 20, "WY": 10, "Wz": 30, "WZ": -10, "XA": -25, "XC": -20, "Xe": -10, "XE": -10, "xf": 10, "Xf": 10, "Xg": -10, "XG": -20, "xi": 10, "Xi": 10, "XI": -10, "Xj": 30, "xk": 10, "Xk": 10, "xl": 10, "Xl": 20, "Xm": 10, "XM": -25, "xn": -10, "XN": -10, "Xo": -10, "XO": -20, "xp": 10, "Xp": 10, "XP": -10, "xq": -10, "Xq": -40, "XQ": -25, "XS": -20, "xu": -5, "Xu": -30, "XU": -20, "xv": 10, "Xv": -20, "Xw": -30, "xx": 15, "Xx": 10, "XX": -30, "xy": -10, "Xy": -20, "XY": -20, "xz": 10, "Xz": 30, "ya": -10, "Ya": -70, "YA": -55, "Yc": -60, "YC": -30, "yd": -10, "Yd": -60, "YD": 10, "ye": 10, "Ye": -60, "YE": -30, "YF": 20, "Yg": -60, "YG": -30, "YH": -10, "YI": 10, "YJ": 10, "Ym": -30, "YM": -35, "yn": -10, "Yn": -60, "Yo": -60, "YO": -20, "Yp": -50, "YP": -10, "Yq": -60, "YQ": -10, "Yr": -60, "YR": -10, "Ys": -60, "YS": -10, "yt": 10, "YT": -15, "yu": -10, "Yu": -60, "yv": 10, "Yv": -20, "Yw": -50, "yx": 10, "Yx": -50, "YX": -30, "Yy": -40, "YY": -10, "Yz": -30, "YZ": -40, "Za": -20, "ZA": -20, "Zb": -10, "ZB": -10, "Zc": -10, "ZC": -20, "Zd": -30, "ZD": -10, "Ze": -40, "ZE": -20, "zf": 10, "Zg": -40, "ZG": -20, "zi": 10, "Zj": 10, "Zk": 10, "ZL": -10, "Zm": -10, "Zn": -50, "Zo": -30, "ZO": -30, "Zp": -10, "ZP": -10, "Zq": -50, "ZQ": -10, "Zr": -40, "ZR": -10, "Zs": -30, "ZS": -20, "zt": 10, "Zt": -10, "Zu": -30, "ZU": -10, "zv": 10, "Zv": -20, "Zw": -40, "ZW": -10, "zx": 10, "Zx": -10, "ZX": -10, "Zy": -30, "ZY": -20, "zz": 20, "Zz": 10, "ZZ": -10 }, "leading": 0, "w": { " ": 242, "_": 446, "-": 326, "\u2013": 446, "\u2014": 566, ",": 198, ";": 198, ":": 198, "!": 210, "?": 374, ".": 198, "\u2026": 594, "\xB7": 187, "'": 117, "\u2018": 117, "\u2019": 117, '"': 237, "\u201C": 267, "\u201D": 267, "(": 330, ")": 330, "[": 330, "]": 330, "{": 330, "}": 330, "@": 643, "*": 363, "/": 330, "\\": 330, "&": 564, "#": 559, "%": 600, "\u2022": 187, "`": 353, "^": 446, "\u2190": 1e3, "\u2192": 1e3, "\u2191": 722.66, "\u2193": 722.66, "+": 446, "\xD7": 446, "<": 446, "=": 446, ">": 446, "|": 330, "~": 446, "\u25E6": 608.4, "\u2610": 830.08, "\u2611": 830.08, "\u2713": 764.16, "$": 450, "0": 450, "1": 450, "2": 450, "3": 450, "4": 450, "5": 434, "6": 471, "7": 446, "8": 450, "9": 438, "a": 446, "A": 511, "b": 444, "B": 523, "c": 364, "C": 477, "d": 402, "D": 587, "e": 334, "E": 534, "\xE9": 325, "f": 300, "F": 466, "g": 364, "G": 494, "h": 473, "H": 574, "i": 196, "I": 409, "j": 213, "J": 315, "k": 374, "K": 508, "l": 178, "L": 426, "m": 569, "M": 729, "n": 459, "N": 619, "o": 362, "O": 505, "p": 378, "P": 468, "q": 377, "Q": 492, "r": 360, "R": 544, "s": 350, "S": 495, "t": 331, "T": 458, "u": 370, "U": 482, "v": 331, "V": 490, "w": 517, "W": 720, "x": 343, "X": 524, "y": 341, "Y": 504, "z": 315, "Z": 522 } }, "regular": { "ascent": 0.9600067138671875, "descent": 0.3000030517578125, "k": { "AC": -20, "AE": -10, "AG": -10, "AH": -10, "AI": 10, "Aj": 10, "AJ": 10, "AL": -10, "AM": 10, "An": -10, "AO": -20, "AP": -10, "Aq": -10, "AQ": -20, "Ar": -10, "As": -10, "AS": -35, "AT": -50, "Au": -10, "AU": -20, "av": -20, "Av": -5, "AV": -40, "aw": -10, "AW": -20, "Ax": 10, "AX": -10, "ay": -20, "Ay": -10, "AY": -65, "Az": 20, "AZ": -10, "ba": -10, "bc": -10, "BC": -20, "bd": -10, "Bf": 10, "BF": -20, "Bg": 10, "bh": -5, "Bi": 10, "BI": -10, "bj": -5, "Bj": 10, "BJ": -10, "Bk": 10, "Bl": 10, "Bm": 10, "BP": -10, "BR": -10, "BS": -20, "BT": -40, "bu": -10, "BU": -20, "BV": -50, "BW": -50, "bx": -10, "Bx": 10, "BX": -40, "by": -10, "BY": -65, "Bz": 40, "BZ": -30, "CA": -20, "Cc": -5, "CC": -10, "Cd": -10, "CE": -10, "CG": -10, "Cj": 10, "CJ": -10, "CK": -10, "cl": 10, "Cl": 5, "Cn": -5, "CO": -10, "CP": -10, "CQ": -20, "Cs": -10, "CS": -10, "Ct": 10, "CT": -20, "Cu": -10, "CU": -10, "Cv": -20, "CV": -20, "cw": -10, "Cw": -10, "CW": -20, "Cx": 20, "CX": -30, "cy": -5, "CY": -35, "Cz": 20, "CZ": -40, "DA": -10, "Db": 10, "Dc": 10, "De": 10, "Df": 20, "DF": -10, "Dg": 10, "Dh": 10, "Di": 15, "DI": -10, "Dj": 5, "DJ": -10, "Dk": 10, "Dl": 10, "Dm": 20, "DM": -5, "dn": -10, "Do": 10, "Dp": 10, "Dq": 10, "Dr": 10, "Ds": 10, "dt": 10, "Dt": 20, "DT": -40, "du": -10, "Dv": 30, "DV": -30, "Dw": 20, "DW": -10, "Dx": 20, "DX": -50, "Dy": 10, "DY": -50, "Dz": 30, "DZ": -30, "EC": -10, "ED": -10, "EG": -10, "EJ": -10, "el": 10, "EO": -10, "EQ": -20, "ES": -40, "ET": -10, "EU": -20, "Ev": -10, "EV": -25, "Ew": -10, "EW": -30, "Ex": 10, "EX": -40, "Ey": -10, "EY": -50, "Ez": 20, "EZ": -20, "fa": -10, "Fa": -30, "FA": -40, "Fc": -20, "FC": -10, "Fd": -20, "FD": 20, "Fe": -15, "ff": 10, "Ff": 10, "FF": 20, "Fg": -10, "fh": 10, "Fh": 20, "fi": 10, "Fi": 10, "FI": 10, "fj": 10, "Fj": 10, "FJ": 20, "Fk": 10, "fl": 20, "Fl": 20, "FL": 10, "fm": 10, "FM": -10, "Fn": -20, "FN": 10, "Fo": -20, "FO": 10, "Fp": -10, "FP": -10, "Fq": -10, "FQ": 10, "Fr": -10, "FS": 10, "ft": 40, "Ft": 10, "FT": -30, "Fu": -10, "fv": 10, "Fv": 10, "FV": 10, "FW": 10, "fy": 10, "FY": 10, "Fz": 10, "FZ": -10, "GA": -10, "Gf": 10, "Gh": 10, "gi": 10, "Gi": 10, "GI": -10, "Gj": 10, "GJ": -10, "Gk": 10, "Gl": 10, "Gm": 10, "GM": -10, "GN": 10, "GP": -20, "GS": -10, "Gt": 10, "GU": -10, "Gv": 10, "GV": -10, "GW": -20, "Gx": 10, "GX": -40, "gy": 10, "GY": -40, "Gz": 10, "GZ": -20, "Hb": 10, "hf": -10, "Hf": 10, "hg": -20, "Hh": 10, "Hi": 10, "Hj": 20, "Hk": 10, "Hl": 10, "Hm": 10, "hq": -10, "hs": -10, "Ht": 20, "hv": -30, "Hv": 10, "hw": -15, "Hx": 20, "hy": -30, "Hy": 10, "Hz": 20, "Ia": -10, "IA": 10, "Ib": 10, "Ic": -10, "Id": -10, "ID": 30, "Ie": -10, "if": 10, "If": 20, "IF": 40, "Ig": -10, "Ih": 30, "Ii": 20, "II": 30, "Ij": 30, "IJ": 40, "Ik": 20, "IK": 10, "Il": 20, "IL": 10, "IM": 30, "In": -10, "IN": 20, "Io": -10, "Ip": 10, "Iq": -20, "Ir": -10, "IR": 10, "Is": -10, "It": 10, "Iu": -10, "IU": 10, "iv": 10, "Iv": -20, "IV": 30, "Iw": -25, "IW": 20, "Ix": 10, "IX": 10, "Iy": -10, "IY": 30, "Iz": 20, "IZ": 20, "Ja": -10, "Jb": 10, "Jc": -10, "Jd": -10, "Je": -10, "Jf": 10, "Jh": 10, "Ji": 10, "JI": -10, "Jj": 20, "JJ": 10, "Jk": 10, "Jl": 20, "Jn": -10, "Jo": -10, "JO": -10, "Jp": 10, "JP": -10, "Jq": -10, "JQ": -10, "JR": -10, "jt": 10, "Jt": 20, "JT": 10, "ju": -10, "Ju": -20, "JU": -10, "jx": 10, "JX": -25, "jy": 10, "JY": -20, "jz": 10, "Jz": 10, "JZ": -20, "Ka": -40, "kc": 20, "Kc": -40, "KC": -10, "Kd": -40, "KD": 10, "ke": 10, "Ke": -40, "kf": 20, "Kf": 10, "KF": 20, "Kg": -40, "KG": -10, "kh": 10, "Kh": 10, "ki": 10, "Ki": 10, "Kj": 40, "KJ": 20, "kk": 20, "Kk": 10, "kl": 20, "Kl": 10, "km": 10, "KM": 20, "Kn": -40, "ko": 10, "Ko": -50, "KO": -10, "Kp": 10, "Kq": -50, "kr": 10, "Ks": -40, "kt": 10, "Kt": 10, "KT": -10, "ku": 10, "Ku": -60, "kv": 10, "Kv": -30, "Kw": -40, "Kx": -10, "KX": -10, "ky": -10, "Ky": -30, "kz": 10, "Lb": -10, "LC": -20, "LE": -20, "Lf": 10, "Lg": -10, "LG": -20, "Lh": -10, "Li": 10, "LI": -40, "Lj": 20, "Lk": 10, "ll": 10, "Ll": 10, "LL": -20, "Ln": -20, "LO": -25, "Lp": 10, "Lq": -40, "LQ": -30, "Ls": -10, "LS": -65, "lt": 10, "Lt": -10, "LT": -70, "Lu": -40, "LU": -45, "Lv": -60, "LV": -70, "Lw": -40, "LW": -40, "Lx": 10, "Ly": -20, "LY": -90, "lz": 20, "Lz": 30, "LZ": -10, "Mb": 10, "md": 10, "Mf": 10, "Mh": 10, "Mi": 10, "MJ": 10, "Mk": 10, "Ml": 10, "mo": 20, "Mp": 10, "MP": -10, "Mq": -10, "MQ": -10, "MS": -20, "Mt": 20, "MT": -30, "Mu": -10, "MU": -20, "mv": -15, "Mv": 10, "MV": -20, "mw": -10, "MW": -30, "Mx": 10, "MX": -10, "my": -10, "My": -10, "MY": -50, "Mz": 10, "MZ": -10, "nb": -15, "Nb": 10, "Ne": 10, "Nf": 10, "Ng": 10, "Nh": 10, "Ni": 20, "Nj": 20, "Nk": 20, "Nl": 20, "Nm": 10, "Nq": 10, "ns": -5, "nt": -10, "Nt": 20, "nu": -10, "nv": -20, "Nv": 30, "nw": -20, "NW": -10, "Nx": 30, "NX": -20, "ny": -20, "Ny": 10, "NY": -20, "Nz": 40, "NZ": -10, "OA": -10, "OD": -10, "Of": 20, "Og": 20, "Oh": 10, "Oi": 20, "OI": -10, "oj": -5, "Oj": 20, "Ok": 10, "Ol": 20, "OL": 10, "Om": 20, "Oo": 10, "Op": 10, "Oq": 10, "OQ": 10, "Os": 10, "Ot": 20, "OT": -10, "ou": -10, "ov": 5, "Ov": 30, "OV": -10, "ow": -10, "Ow": 10, "OW": -10, "Ox": 30, "OX": -40, "oy": -10, "Oy": 20, "OY": -40, "Oz": 30, "OZ": -20, "Pa": -40, "PA": -40, "Pc": -30, "Pd": -40, "PD": -10, "Pe": -20, "Pf": 10, "Pg": -10, "Ph": 10, "Pi": 10, "PI": -10, "Pj": 20, "PJ": -10, "Pk": 10, "Pl": 10, "Pm": 10, "PM": -30, "pn": -10, "Pn": -10, "PN": -10, "Po": -30, "Pq": -30, "Ps": -20, "PS": 10, "Pt": 20, "pu": -10, "Pu": -30, "Pv": 10, "Px": 10, "PX": -35, "py": -10, "PY": -20, "Pz": 10, "PZ": -50, "Qb": 10, "Qf": 20, "Qg": 20, "qh": -10, "Qh": 10, "Qi": 20, "qj": 10, "Qj": 90, "QJ": 80, "Qk": 10, "Ql": 20, "Qm": 20, "qn": -10, "qo": -10, "Qp": 20, "Qt": 30, "QT": -10, "qu": -10, "Qv": 20, "QV": -10, "QW": -10, "Qx": 20, "QX": -20, "Qy": 50, "QY": -30, "Qz": 40, "QZ": -10, "ra": -5, "Ra": -10, "RA": -25, "RB": -10, "Rc": -10, "RC": -20, "Rd": -10, "RD": 10, "Re": -10, "RE": -20, "Rf": 20, "RF": 10, "Rg": -10, "RG": -10, "ri": 5, "RI": -10, "Rj": 30, "RJ": 30, "RL": -10, "RM": -20, "Rn": -10, "RN": 10, "Ro": -10, "RO": -10, "Rp": 20, "Rq": -30, "RQ": -10, "Rr": -10, "Rs": -10, "Rt": 10, "RT": -10, "Ru": -30, "RU": -20, "rv": 20, "RV": -10, "Rw": -10, "RW": -10, "Rx": 10, "RX": -20, "Ry": 10, "RY": -30, "Rz": 20, "RZ": -45, "Sa": -10, "Sb": 10, "Sc": -20, "Sd": -25, "SD": 20, "Se": -20, "SE": -10, "sf": 10, "Sf": 20, "SF": 30, "Sg": -20, "Sh": 20, "Si": 20, "SI": 10, "Sj": 30, "SJ": 30, "Sk": 10, "Sl": 20, "SL": 20, "Sn": -20, "SN": 10, "So": -10, "SO": 10, "Sq": -20, "Sr": -10, "Ss": -10, "st": 10, "St": 20, "Su": -20, "sv": 20, "Sv": -50, "SV": 20, "Sw": -30, "SW": 10, "sx": 15, "Sx": 10, "Sy": -15, "SY": 10, "sz": 20, "Sz": 20, "SZ": -10, "Ta": -90, "TA": -50, "Tc": -80, "TC": -10, "Td": -110, "TD": 10, "Te": -90, "TE": -10, "Tf": 20, "TF": 30, "Tg": -80, "TG": -10, "Th": 20, "ti": 5, "TI": 10, "Tj": 20, "Tk": 10, "Tl": 20, "Tm": -50, "TM": -30, "Tn": -90, "To": -90, "Tp": -80, "Tq": -120, "Tr": -80, "Ts": -80, "Tt": 10, "TT": -30, "Tu": -90, "tv": 10, "Tv": -70, "TV": 10, "Tw": -100, "tx": 20, "Tx": -60, "TX": -10, "Ty": -50, "tz": 30, "Tz": -40, "TZ": -10, "ub": -10, "Ub": 20, "UE": 10, "uf": 10, "Uf": 30, "UF": 10, "Ug": 10, "Uh": 30, "ui": 10, "Ui": 30, "Uj": 40, "uk": 10, "Uk": 20, "ul": 10, "Ul": 30, "Um": 30, "Up": 10, "UQ": 30, "Ur": 10, "UR": 10, "Us": 10, "Ut": 50, "UT": 20, "Uu": 10, "UU": 10, "Uv": 50, "UV": 10, "Uw": 10, "ux": 10, "Ux": 30, "UX": -10, "Uy": 10, "UY": -10, "uz": 30, "Uz": 30, "UZ": -10, "va": -10, "Va": -50, "VA": -55, "Vc": -30, "VC": -20, "Vd": -30, "Ve": -30, "VE": -20, "vf": 10, "VF": 10, "Vg": -30, "VG": -10, "vi": 10, "Vm": -10, "VM": -30, "Vn": -30, "VN": -10, "Vo": -30, "VO": -10, "Vp": -20, "VP": -20, "Vq": -30, "VQ": -10, "Vr": -20, "Vs": -30, "vt": 10, "VT": 20, "Vu": -30, "VU": -10, "vv": 20, "Vw": -30, "vx": 20, "VX": -20, "vy": 10, "VY": -10, "vz": 10, "VZ": -20, "WA": -20, "Wb": 20, "Wd": -10, "WD": 20, "We": 10, "Wf": 30, "WF": 20, "Wh": 30, "wi": 10, "Wi": 30, "WI": 10, "Wj": 40, "WJ": 20, "Wk": 20, "Wl": 40, "WL": 10, "Wm": 10, "WM": -10, "WS": 10, "Wt": 40, "WT": 30, "Wv": 30, "WV": 10, "wx": 10, "Wx": 20, "WX": -10, "Wy": 20, "WY": 10, "Wz": 30, "WZ": -10, "XA": -25, "XC": -20, "Xe": -10, "XE": -10, "xf": 10, "Xf": 10, "Xg": -10, "XG": -20, "xi": 10, "Xi": 10, "XI": -10, "Xj": 30, "xk": 10, "Xk": 10, "xl": 10, "Xl": 20, "Xm": 10, "XM": -25, "xn": -10, "XN": -10, "Xo": -10, "XO": -20, "xp": 10, "Xp": 10, "XP": -10, "xq": -10, "Xq": -40, "XQ": -25, "XS": -20, "xu": -5, "Xu": -30, "XU": -20, "xv": 10, "Xv": -20, "Xw": -30, "xx": 15, "Xx": 10, "XX": -30, "xy": -10, "Xy": -20, "XY": -20, "xz": 10, "Xz": 30, "ya": -10, "Ya": -70, "YA": -55, "Yc": -60, "YC": -30, "yd": -10, "Yd": -60, "YD": 10, "ye": 10, "Ye": -60, "YE": -30, "YF": 20, "Yg": -60, "YG": -30, "YH": -10, "YI": 10, "YJ": 10, "Ym": -30, "YM": -35, "yn": -10, "Yn": -60, "Yo": -60, "YO": -20, "Yp": -50, "YP": -10, "Yq": -60, "YQ": -10, "Yr": -60, "YR": -10, "Ys": -60, "YS": -10, "yt": 10, "YT": -15, "yu": -10, "Yu": -60, "yv": 10, "Yv": -20, "Yw": -50, "yx": 10, "Yx": -50, "YX": -30, "Yy": -40, "YY": -10, "Yz": -30, "YZ": -40, "Za": -20, "ZA": -20, "Zb": -10, "ZB": -10, "Zc": -10, "ZC": -20, "Zd": -30, "ZD": -10, "Ze": -40, "ZE": -20, "zf": 10, "Zg": -40, "ZG": -20, "zi": 10, "Zj": 10, "Zk": 10, "ZL": -10, "Zm": -10, "Zn": -50, "Zo": -30, "ZO": -30, "Zp": -10, "ZP": -10, "Zq": -50, "ZQ": -10, "Zr": -40, "ZR": -10, "Zs": -30, "ZS": -20, "zt": 10, "Zt": -10, "Zu": -30, "ZU": -10, "zv": 10, "Zv": -20, "Zw": -40, "ZW": -10, "zx": 10, "Zx": -10, "ZX": -10, "Zy": -30, "ZY": -20, "zz": 20, "Zz": 10, "ZZ": -10 }, "leading": 0, "w": { " ": 242, "_": 446, "-": 326, "\u2013": 446, "\u2014": 566, ",": 198, ";": 198, ":": 198, "!": 210, "?": 374, ".": 198, "\u2026": 594, "\xB7": 187, "'": 117, "\u2018": 117, "\u2019": 117, '"': 237, "\u201C": 267, "\u201D": 267, "(": 330, ")": 330, "[": 330, "]": 330, "{": 330, "}": 330, "@": 643, "*": 363, "/": 330, "\\": 330, "&": 564, "#": 559, "%": 600, "\u2022": 187, "`": 353, "^": 446, "\u2190": 1e3, "\u2192": 1e3, "\u2191": 645.02, "\u2193": 645.02, "+": 446, "\xD7": 446, "<": 446, "=": 446, ">": 446, "|": 330, "~": 446, "\u25E6": 578.13, "\u2610": 830.08, "\u2611": 830.08, "\u2713": 764.16, "$": 450, "0": 450, "1": 450, "2": 450, "3": 450, "4": 450, "5": 450, "6": 450, "7": 450, "8": 450, "9": 450, "a": 437, "A": 502, "b": 435, "B": 520, "c": 355, "C": 472, "d": 393, "D": 578, "e": 325, "E": 529, "\xE9": 325, "f": 291, "F": 454, "g": 355, "G": 487, "h": 464, "H": 563, "i": 187, "I": 400, "j": 204, "J": 306, "k": 365, "K": 498, "l": 169, "L": 426, "m": 560, "M": 720, "n": 450, "N": 599, "o": 353, "O": 496, "p": 378, "P": 464, "q": 377, "Q": 502, "r": 360, "R": 537, "s": 341, "S": 486, "t": 331, "T": 458, "u": 370, "U": 482, "v": 331, "V": 490, "w": 517, "W": 720, "x": 343, "X": 524, "y": 341, "Y": 504, "z": 315, "Z": 522 } } }, "fallback": { "\u2190": [0.966796875, 0.2109375, 0], "\u2192": [0.966796875, 0.2109375, 0], "\u2191": [0.966796875, 0.2109375, 0], "\u2193": [0.966796875, 0.2109375, 0], "\u25E6": [0.966796875, 0.2109375, 0], "\u2610": [0.66650390625, 0.25, 0.08349609375], "\u2611": [0.66650390625, 0.25, 0.08349609375], "\u2713": [0.966796875, 0.2109375, 0] } }, "Helvetica Neue": { "faces": { "bold": { "ascent": 0.975006103515625, "descent": 0.2169952392578125, "k": { "\u2018\u2018": -95, "\u2019\u2019": -95, "\u2019s": -74, "\u2019t": -18, "A\u2019": -74, "AT": -92, "Av": -18, "AV": -46, "Aw": -18, "AW": -24, "Ay": -18, "AY": -74, "F,": -157, "F.": -157, "f\u2019": 18, "FA": -55, "ff": -30, "fi": 20, "fl": 20, "L\u2019": -74, "LT": -92, "LV": -92, "LW": -55, "Ly": -37, "LY": -111, "P,": -179, "P.": -179, "PA": -74, "r-": -55, "r,": -92, "r.": -92, "rc": -18, "rd": -18, "re": -18, "rg": -28, "rn": 18, "ro": -18, "rq": -18, "RT": -18, "RV": -18, "RW": -18, "RY": -37, "T-": -129, "T,": -111, "T;": -111, "T:": -111, "T.": -111, "Ta": -111, "TA": -92, "Tc": -111, "Te": -111, "To": -111, "Tr": -92, "Ts": -111, "Tu": -92, "Tw": -111, "Ty": -111, "V-": -55, "v,": -74, "V,": -129, "V;": -46, "V:": -46, "v.": -74, "V.": -129, "Va": -55, "VA": -46, "Ve": -55, "Vi": -18, "Vo": -55, "Vr": -37, "Vu": -37, "Vy": -18, "w,": -55, "W,": -74, "W;": -18, "W:": -18, "w.": -55, "W.": -74, "Wa": -37, "WA": -24, "We": -57, "Wo": -57, "Wr": -18, "Wu": -18, "Y-": -111, "y,": -74, "Y,": -139, "Y;": -92, "Y:": -92, "y.": -74, "Y.": -139, "Ya": -92, "YA": -74, "Ye": -111, "Yi": -37, "Yo": -111, "Yp": -74, "Yq": -92, "Yu": -74, "Yv": -55 }, "leading": 0.0290069580078125, "w": { " ": 278, "_": 500, "-": 407, "\u2013": 500, "\u2014": 1e3, ",": 278, ";": 278, ":": 278, "!": 278, "?": 556, ".": 278, "\u2026": 1e3, "\xB7": 278, "'": 278, "\u2018": 278, "\u2019": 278, '"': 463, "\u201C": 463, "\u201D": 463, "(": 296, ")": 296, "[": 333, "]": 333, "{": 333, "}": 333, "@": 800, "*": 407, "/": 371, "\\": 371, "&": 685, "#": 556, "%": 1e3, "\u2022": 350, "`": 259, "^": 600, "\u2190": 1e3, "\u2192": 1e3, "\u2191": 722.66, "\u2193": 722.66, "+": 600, "\xD7": 600, "<": 600, "=": 600, ">": 600, "|": 223, "~": 600, "\u25E6": 608.4, "\u2610": 830.08, "\u2611": 830.08, "\u2713": 764.16, "$": 556, "0": 556, "1": 556, "2": 556, "3": 556, "4": 556, "5": 556, "6": 556, "7": 556, "8": 556, "9": 556, "a": 574, "A": 685, "b": 611, "B": 704, "c": 574, "C": 741, "d": 611, "D": 741, "e": 574, "E": 648, "\xE9": 574, "f": 333, "F": 593, "g": 611, "G": 759, "h": 593, "H": 741, "i": 258, "I": 295, "j": 278, "J": 556, "k": 574, "K": 722, "l": 258, "L": 593, "m": 906, "M": 907, "n": 593, "N": 741, "o": 611, "O": 778, "p": 611, "P": 667, "q": 611, "Q": 778, "r": 389, "R": 722, "s": 537, "S": 649, "t": 352, "T": 611, "u": 593, "U": 741, "v": 520, "V": 630, "w": 814, "W": 944, "x": 537, "X": 667, "y": 519, "Y": 667, "z": 519, "Z": 648 } }, "boldItalic": { "ascent": 0.975006103515625, "descent": 0.2169952392578125, "k": { "\u2018\u2018": -95, "\u2019\u2019": -95, "\u2019s": -74, "\u2019t": -18, "A\u2019": -74, "AT": -92, "Av": -18, "AV": -46, "Aw": -18, "AW": -24, "Ay": -18, "AY": -74, "F,": -157, "F.": -157, "f\u2019": 18, "FA": -55, "ff": -68, "L\u2019": -74, "LT": -92, "LV": -92, "LW": -55, "Ly": -37, "LY": -111, "P,": -179, "P.": -179, "PA": -74, "r-": -55, "r,": -92, "r.": -92, "rc": -18, "rd": -18, "re": -18, "rg": -28, "rn": 18, "ro": -18, "rq": -18, "RT": -18, "RV": -18, "RW": -18, "RY": -37, "T-": -129, "T,": -111, "T;": -111, "T:": -111, "T.": -111, "Ta": -111, "TA": -92, "Tc": -111, "Te": -111, "To": -111, "Tr": -92, "Ts": -111, "Tu": -92, "Tw": -111, "Ty": -111, "V-": -55, "v,": -74, "V,": -129, "V;": -46, "V:": -46, "v.": -74, "V.": -129, "Va": -55, "VA": -46, "Ve": -55, "Vi": -18, "Vo": -55, "Vr": -37, "Vu": -37, "Vy": -18, "w,": -55, "W,": -74, "W;": -18, "W:": -18, "w.": -55, "W.": -74, "Wa": -37, "WA": -24, "We": -57, "Wo": -57, "Wr": -18, "Wu": -18, "Y-": -111, "y,": -74, "Y,": -139, "Y;": -92, "Y:": -92, "y.": -74, "Y.": -139, "Ya": -92, "YA": -74, "Ye": -111, "Yi": -37, "Yo": -111, "Yp": -74, "Yq": -92, "Yu": -74, "Yv": -55 }, "leading": 0.0290069580078125, "w": { " ": 278, "_": 500, "-": 407, "\u2013": 500, "\u2014": 1e3, ",": 278, ";": 278, ":": 278, "!": 296, "?": 574, ".": 278, "\u2026": 1e3, "\xB7": 278, "'": 278, "\u2018": 278, "\u2019": 278, '"': 481, "\u201C": 481, "\u201D": 481, "(": 296, ")": 296, "[": 333, "]": 333, "{": 333, "}": 333, "@": 800, "*": 407, "/": 389, "\\": 389, "&": 685, "#": 556, "%": 963, "\u2022": 350, "`": 259, "^": 600, "\u2190": 1e3, "\u2192": 1e3, "\u2191": 722.66, "\u2193": 722.66, "+": 600, "\xD7": 600, "<": 600, "=": 600, ">": 600, "|": 222, "~": 600, "\u25E6": 608.4, "\u2610": 830.08, "\u2611": 830.08, "\u2713": 764.16, "$": 556, "0": 556, "1": 556, "2": 556, "3": 556, "4": 556, "5": 556, "6": 556, "7": 556, "8": 556, "9": 556, "a": 574, "A": 685, "b": 611, "B": 722, "c": 556, "C": 741, "d": 611, "D": 741, "e": 574, "E": 667, "\xE9": 574, "f": 352, "F": 593, "g": 611, "G": 759, "h": 611, "H": 741, "i": 259, "I": 296, "j": 259, "J": 556, "k": 556, "K": 722, "l": 259, "L": 574, "m": 907, "M": 907, "n": 611, "N": 741, "o": 593, "O": 778, "p": 611, "P": 667, "q": 611, "Q": 778, "r": 389, "R": 722, "s": 519, "S": 648, "t": 370, "T": 611, "u": 611, "U": 741, "v": 519, "V": 630, "w": 815, "W": 944, "x": 519, "X": 667, "y": 519, "Y": 648, "z": 500, "Z": 648 } }, "italic": { "ascent": 0.957000732421875, "descent": 0.2129974365234375, "k": { "\u2018\u2018": -95, "\u2019\u2019": -95, "\u2019s": -74, "\u2019t": -18, "A\u2019": -74, "AT": -92, "Av": -18, "AV": -46, "Aw": -18, "AW": -24, "Ay": -18, "AY": -74, "F,": -157, "F.": -157, "f\u2019": 18, "FA": -55, "ff": -15, "fi": 1, "fl": 1, "L\u2019": -74, "LT": -92, "LV": -92, "LW": -55, "Ly": -37, "LY": -111, "P,": -179, "P.": -179, "PA": -74, "r-": -55, "r,": -92, "r.": -92, "rc": -18, "rd": -18, "re": -18, "rg": -28, "rn": 18, "ro": -18, "rq": -18, "RT": -18, "RV": -18, "RW": -18, "RY": -37, "T-": -129, "T,": -111, "T;": -111, "T:": -111, "T.": -111, "Ta": -111, "TA": -92, "Tc": -111, "Te": -111, "To": -111, "Tr": -92, "Ts": -111, "Tu": -92, "Tw": -111, "Ty": -111, "V-": -55, "v,": -74, "V,": -129, "V;": -46, "V:": -46, "v.": -74, "V.": -129, "Va": -55, "VA": -46, "Ve": -55, "Vi": -18, "Vo": -55, "Vr": -37, "Vu": -37, "Vy": -18, "w,": -55, "W,": -74, "W;": -18, "W:": -18, "w.": -55, "W.": -74, "Wa": -37, "WA": -24, "We": -57, "Wo": -57, "Wr": -18, "Wu": -18, "Y-": -111, "y,": -74, "Y,": -139, "Y;": -92, "Y:": -92, "y.": -74, "Y.": -139, "Ya": -92, "YA": -74, "Ye": -111, "Yi": -37, "Yo": -111, "Yp": -74, "Yq": -92, "Yu": -74, "Yv": -55 }, "leading": 0.0279998779296875, "w": { " ": 278, "_": 500, "-": 389, "\u2013": 500, "\u2014": 1e3, ",": 278, ";": 278, ":": 278, "!": 259, "?": 556, ".": 278, "\u2026": 1e3, "\xB7": 278, "'": 278, "\u2018": 278, "\u2019": 278, '"': 426, "\u201C": 426, "\u201D": 426, "(": 259, ")": 259, "[": 259, "]": 259, "{": 333, "}": 333, "@": 800, "*": 352, "/": 333, "\\": 333, "&": 630, "#": 556, "%": 926, "\u2022": 500, "`": 222, "^": 600, "\u2190": 1e3, "\u2192": 1e3, "\u2191": 645.02, "\u2193": 645.02, "+": 600, "\xD7": 600, "<": 600, "=": 600, ">": 600, "|": 222, "~": 600, "\u25E6": 578.13, "\u2610": 830.08, "\u2611": 830.08, "\u2713": 764.16, "$": 556, "0": 556, "1": 556, "2": 556, "3": 556, "4": 556, "5": 556, "6": 556, "7": 556, "8": 556, "9": 556, "a": 519, "A": 667, "b": 593, "B": 685, "c": 537, "C": 722, "d": 593, "D": 704, "e": 537, "E": 611, "\xE9": 537, "f": 296, "F": 574, "g": 574, "G": 759, "h": 556, "H": 722, "i": 222, "I": 259, "j": 222, "J": 519, "k": 481, "K": 667, "l": 222, "L": 556, "m": 852, "M": 870, "n": 556, "N": 722, "o": 574, "O": 759, "p": 593, "P": 648, "q": 593, "Q": 759, "r": 333, "R": 685, "s": 481, "S": 648, "t": 315, "T": 574, "u": 556, "U": 722, "v": 481, "V": 611, "w": 759, "W": 926, "x": 481, "X": 611, "y": 481, "Y": 611, "z": 444, "Z": 611 } }, "regular": { "ascent": 0.951995849609375, "descent": 0.2129974365234375, "k": { "\u2018\u2018": -95, "\u2019\u2019": -95, "\u2019s": -74, "\u2019t": -18, "A\u2019": -74, "AT": -92, "Av": -18, "AV": -46, "Aw": -18, "AW": -24, "Ay": -18, "AY": -74, "F,": -157, "F.": -157, "f\u2019": 18, "FA": -55, "ff": -15, "L\u2019": -74, "LT": -92, "LV": -92, "LW": -55, "Ly": -37, "LY": -111, "P,": -179, "P.": -179, "PA": -74, "r-": -55, "r,": -92, "r.": -92, "rc": -18, "rd": -18, "re": -18, "rg": -28, "rn": 18, "ro": -18, "rq": -18, "RT": -18, "RV": -18, "RW": -18, "RY": -37, "T-": -129, "T,": -111, "T;": -111, "T:": -111, "T.": -111, "Ta": -111, "TA": -92, "Tc": -111, "Te": -111, "To": -111, "Tr": -92, "Ts": -111, "Tu": -92, "Tw": -111, "Ty": -111, "V-": -55, "v,": -74, "V,": -129, "V;": -46, "V:": -46, "v.": -74, "V.": -129, "Va": -55, "VA": -46, "Ve": -55, "Vi": -18, "Vo": -55, "Vr": -37, "Vu": -37, "Vy": -18, "w,": -55, "W,": -74, "W;": -18, "W:": -18, "w.": -55, "W.": -74, "Wa": -37, "WA": -24, "We": -57, "Wo": -57, "Wr": -18, "Wu": -18, "Y-": -111, "y,": -74, "Y,": -139, "Y;": -92, "Y:": -92, "y.": -74, "Y.": -139, "Ya": -92, "YA": -74, "Ye": -111, "Yi": -37, "Yo": -111, "Yp": -74, "Yq": -92, "Yu": -74, "Yv": -55 }, "leading": 0.0279998779296875, "w": { " ": 278, "_": 500, "-": 389, "\u2013": 500, "\u2014": 1e3, ",": 278, ";": 278, ":": 278, "!": 259, "?": 556, ".": 278, "\u2026": 1e3, "\xB7": 278, "'": 278, "\u2018": 278, "\u2019": 278, '"': 426, "\u201C": 426, "\u201D": 426, "(": 259, ")": 259, "[": 259, "]": 259, "{": 333, "}": 333, "@": 800, "*": 352, "/": 333, "\\": 333, "&": 630, "#": 556, "%": 1e3, "\u2022": 350, "`": 222, "^": 600, "\u2190": 1e3, "\u2192": 1e3, "\u2191": 645.02, "\u2193": 645.02, "+": 600, "\xD7": 600, "<": 600, "=": 600, ">": 600, "|": 222, "~": 600, "\u25E6": 578.13, "\u2610": 830.08, "\u2611": 830.08, "\u2713": 764.16, "$": 556, "0": 556, "1": 556, "2": 556, "3": 556, "4": 556, "5": 556, "6": 556, "7": 556, "8": 556, "9": 556, "a": 537, "A": 648, "b": 593, "B": 685, "c": 537, "C": 722, "d": 593, "D": 704, "e": 537, "E": 611, "\xE9": 537, "f": 296, "F": 574, "g": 574, "G": 759, "h": 556, "H": 722, "i": 222, "I": 259, "j": 222, "J": 519, "k": 519, "K": 667, "l": 222, "L": 556, "m": 853, "M": 871, "n": 556, "N": 722, "o": 574, "O": 760, "p": 593, "P": 648, "q": 593, "Q": 760, "r": 333, "R": 685, "s": 500, "S": 648, "t": 315, "T": 574, "u": 556, "U": 722, "v": 500, "V": 611, "w": 758, "W": 926, "x": 518, "X": 611, "y": 500, "Y": 648, "z": 480, "Z": 611 } } }, "fallback": { "\u2190": [0.966796875, 0.2109375, 0], "\u2192": [0.966796875, 0.2109375, 0], "\u2191": [0.966796875, 0.2109375, 0], "\u2193": [0.966796875, 0.2109375, 0], "\u25E6": [0.966796875, 0.2109375, 0], "\u2610": [0.66650390625, 0.25, 0.08349609375], "\u2611": [0.66650390625, 0.25, 0.08349609375], "\u2713": [0.966796875, 0.2109375, 0] } }, "Patrick Hand": { "faces": { "regular": { "ascent": 1.0420074462890625, "descent": 0.3119964599609375, "k": {}, "leading": 0, "w": { " ": 230, "_": 571, "-": 404, "\u2013": 420, "\u2014": 648, ",": 202, ";": 232, ":": 232, "!": 247, "?": 368, ".": 214, "\u2026": 571, "\xB7": 200, "'": 164, "\u2018": 190, "\u2019": 220, '"': 303, "\u201C": 315, "\u201D": 303, "(": 334, ")": 364, "[": 303, "]": 296, "{": 339, "}": 328, "@": 550, "*": 404, "/": 423, "\\": 420, "&": 530, "#": 457, "%": 643, "\u2022": 352, "`": 220, "^": 370, "\u2190": 1e3, "\u2192": 1e3, "\u2191": 645.02, "\u2193": 645.02, "+": 480, "\xD7": 490, "<": 396, "=": 572, ">": 400, "|": 176, "~": 529, "\u25E6": 578.13, "\u2610": 830.08, "\u2611": 830.08, "\u2713": 764.16, "$": 507, "0": 448, "1": 363, "2": 468, "3": 448, "4": 375, "5": 423, "6": 399, "7": 495, "8": 433, "9": 367, "a": 392, "A": 488, "b": 412, "B": 507, "c": 388, "C": 548, "d": 390, "D": 475, "e": 398, "E": 442, "\xE9": 398, "f": 359, "F": 375, "g": 445, "G": 480, "h": 420, "H": 468, "i": 224, "I": 235, "j": 235, "J": 370, "k": 415, "K": 523, "l": 266, "L": 372, "m": 680, "M": 595, "n": 452, "N": 532, "o": 403, "O": 556, "p": 428, "P": 481, "q": 463, "Q": 655, "r": 385, "R": 454, "s": 385, "S": 459, "t": 344, "T": 468, "u": 400, "U": 550, "v": 400, "V": 562, "w": 463, "W": 616, "x": 448, "X": 601, "y": 423, "Y": 442, "z": 428, "Z": 507 } } }, "fallback": { "\u2190": [0.966796875, 0.2109375, 0], "\u2192": [0.966796875, 0.2109375, 0], "\u2191": [0.966796875, 0.2109375, 0], "\u2193": [0.966796875, 0.2109375, 0], "\u25E6": [0.966796875, 0.2109375, 0], "\u2610": [0.66650390625, 0.25, 0.08349609375], "\u2611": [0.66650390625, 0.25, 0.08349609375], "\u2713": [0.966796875, 0.2109375, 0] } } };
486
+
487
+ // src/text.ts
488
+ var DEFAULT_FAMILY = "Helvetica Neue";
489
+ var CSS_FALLBACK = "Helvetica Neue, Helvetica, Arial, sans-serif";
490
+ var BUNDLED_FONTS = Object.keys(families).filter((f) => f !== DEFAULT_FAMILY).sort();
491
+ function bundledFamily(font) {
492
+ if (!font) return null;
493
+ const lower = font.toLowerCase();
494
+ return BUNDLED_FONTS.find((f) => f.toLowerCase() === lower) ?? null;
495
+ }
496
+ function familyMetrics(font) {
497
+ return families[bundledFamily(font) ?? DEFAULT_FAMILY];
498
+ }
499
+ function faceOf(fam, bold, italic) {
500
+ const want = bold ? italic ? "boldItalic" : "bold" : italic ? "italic" : "regular";
501
+ return fam.faces[want] ? want : "regular";
502
+ }
503
+ function cssFamily(font) {
504
+ if (!font) return CSS_FALLBACK;
505
+ const name = [...bundledFamily(font) ?? font].filter((c) => !`"'<>&;{}\\`.includes(c)).join("");
506
+ if (name === "") return CSS_FALLBACK;
507
+ return `${/^[\p{L}\p{N} -]+$/u.test(name) ? name : `'${name}'`}, ${CSS_FALLBACK}`;
508
+ }
509
+ function measure(s, fontSize, face = "regular", font) {
510
+ const fam = familyMetrics(font);
511
+ const f = fam.faces[face] ?? fam.faces.regular;
512
+ const fallback = f.w["n"];
513
+ let w = 0;
514
+ let prev = "";
515
+ for (const ch of s) {
516
+ w += f.w[ch] ?? fallback;
517
+ if (prev) w += f.k[prev + ch] ?? 0;
518
+ prev = ch;
519
+ }
520
+ return w * fontSize / 1e3;
521
+ }
522
+ function lineHeights(fontSize, font) {
523
+ const m = familyMetrics(font).faces.regular;
524
+ const a = Math.round(m.ascent * fontSize), d = Math.round(m.descent * fontSize), l = Math.round(m.leading * fontSize);
525
+ return [a + Math.ceil(m.descent * fontSize - 1e-9), a + d + l];
526
+ }
527
+ function breaksAfter(ch, next) {
528
+ if (ch === " ") return true;
529
+ return (ch === "/" || ch === "-") && next !== "" && !/[\d\s/-]/.test(next);
530
+ }
531
+ function pieces(para) {
532
+ const chars = [...para];
533
+ const out = [];
534
+ let cur = "";
535
+ chars.forEach((ch, i) => {
536
+ cur += ch;
537
+ const next = chars[i + 1] ?? "";
538
+ if (breaksAfter(ch, next) && next !== " ") {
539
+ out.push(cur);
540
+ cur = "";
541
+ }
542
+ });
543
+ if (cur || out.length === 0) out.push(cur);
544
+ return out;
545
+ }
546
+ function wrap(s, fontSize, maxWidth, face = "regular", font) {
547
+ const width = (t) => measure(t, fontSize, face, font);
548
+ const out = [];
549
+ for (const para of s.split(/\r\n|\n|\r|\u2028|\u2029/)) {
550
+ let line2 = "";
551
+ for (const piece of pieces(para)) {
552
+ const candidate = line2 + piece;
553
+ if (line2 === "" || width(candidate.trimEnd()) <= maxWidth) {
554
+ line2 = candidate;
555
+ } else {
556
+ out.push(line2);
557
+ line2 = piece;
558
+ }
559
+ while (width(line2.trimEnd()) > maxWidth && [...line2.trimEnd()].length > 1) {
560
+ const chars = [...line2];
561
+ let n = chars.length - 1;
562
+ while (n > 1 && width(chars.slice(0, n).join("")) > maxWidth) n--;
563
+ out.push(chars.slice(0, n).join(""));
564
+ line2 = chars.slice(n).join("");
565
+ }
566
+ }
567
+ out.push(line2);
568
+ }
569
+ return out;
570
+ }
571
+ function textSize(s, fontSize, maxWidth, font) {
572
+ if (s === "") return { width: 0, height: 0 };
573
+ const lines = wrap(s, fontSize, maxWidth, "regular", font);
574
+ const width = Math.max(...lines.map((l) => measure(l.trimEnd(), fontSize, "regular", font)));
575
+ const [first, next] = lineHeights(fontSize, font);
576
+ return { width: Math.ceil(width - 1e-9), height: Math.ceil(first + next * (lines.length - 1) - 1e-9) };
577
+ }
578
+
579
+ // src/fonts.ts
580
+ var FACES = ["bold", "boldItalic", "italic", "regular"];
581
+ function fontFile(family, face) {
582
+ return `${family.toLowerCase().replaceAll(" ", "-")}-${face}.woff2`;
583
+ }
584
+ function fontFaces(family) {
585
+ return FACES.filter((f) => families[family]?.faces[f] !== void 0);
586
+ }
587
+ function usedFonts(page) {
588
+ const used = /* @__PURE__ */ new Set();
589
+ const add2 = (es) => {
590
+ for (const e of es) {
591
+ const b = bundledFamily(e.style.font);
592
+ if (b) used.add(b);
593
+ }
594
+ };
595
+ add2(page.elements);
596
+ for (const s of page.symbols ?? []) add2(s.elements);
597
+ return BUNDLED_FONTS.filter((f) => used.has(f));
598
+ }
599
+ function defaultBase() {
600
+ try {
601
+ const script = typeof document === "undefined" ? null : document.currentScript;
602
+ if (script?.src) return new URL("fonts/", script.src).href;
603
+ const here = import.meta.url;
604
+ return here ? new URL("fonts/", here).href : null;
605
+ } catch {
606
+ return null;
607
+ }
608
+ }
609
+ var base = defaultBase();
610
+ var added = /* @__PURE__ */ new Set();
611
+ function setFontBase(url) {
612
+ base = url.endsWith("/") ? url : `${url}/`;
613
+ }
614
+ function addFonts(fonts, data = {}) {
615
+ if (typeof document === "undefined" || typeof FontFace === "undefined" || !document.fonts) return;
616
+ for (const name of fonts) {
617
+ const family = bundledFamily(name);
618
+ if (!family || added.has(family)) continue;
619
+ const own = data[family];
620
+ if (!own && !base) continue;
621
+ added.add(family);
622
+ for (const face of fontFaces(family)) {
623
+ const encoded = own?.[face];
624
+ let source;
625
+ if (encoded) source = Uint8Array.from(atob(encoded), (c) => c.charCodeAt(0));
626
+ else if (!own) source = `url(${JSON.stringify(base + fontFile(family, face))}) format("woff2")`;
627
+ else continue;
628
+ const descriptors = { weight: face.startsWith("bold") ? "bold" : "normal", style: face === "italic" || face === "boldItalic" ? "italic" : "normal" };
629
+ document.fonts.add(new FontFace(family, source, descriptors));
630
+ }
631
+ }
632
+ }
633
+
463
634
  // src/path.ts
464
635
  var KAPPA = 0.5522847498307936;
465
636
  var Path = class _Path {
@@ -718,13 +889,19 @@ function rotatedBounds(e) {
718
889
  return { x, y, width: Math.max(...xs) - x, height: Math.max(...ys) - y };
719
890
  }
720
891
  function resolvingInk(e, ink) {
721
- if (!isAutomaticInk(e.style.stroke)) return e;
892
+ const text = e.style.textColor !== null && isAutomaticInk(e.style.textColor);
893
+ if (!isAutomaticInk(e.style.stroke) && !text) return e;
722
894
  const copy = cloneElement(e);
723
895
  const covers = e.style.fillStyle === "solid" || e.style.fillStyle === "grid";
724
896
  const onLightFill = covers && e.style.fill.a >= 0.5 && luminance(e.style.fill) > 0.5;
725
- copy.style.stroke = luminance(ink) > 0.5 && onLightFill ? { ...black } : { ...ink };
897
+ const resolved2 = luminance(ink) > 0.5 && onLightFill ? black : ink;
898
+ if (isAutomaticInk(e.style.stroke)) copy.style.stroke = { ...resolved2 };
899
+ if (text) copy.style.textColor = { ...resolved2 };
726
900
  return copy;
727
901
  }
902
+ function labelColor(e) {
903
+ return e.kind === "text" || e.kind === "note" ? e.style.stroke : e.style.textColor ?? e.style.stroke;
904
+ }
728
905
  function shapeContours(e) {
729
906
  if (e.kind !== "path" || !e.subpaths) return [];
730
907
  const out = [];
@@ -818,34 +995,93 @@ function resolve(ep, other, index) {
818
995
  function endpoints(e, index) {
819
996
  const c = e.connector;
820
997
  if (!c) return [{ x: 0, y: 0 }, { x: 0, y: 0 }];
821
- return [resolve(c.start, reference(c.end, index), index), resolve(c.end, reference(c.start, index), index)];
998
+ const w = c.waypoints ?? [];
999
+ return [
1000
+ resolve(c.start, w.length > 0 ? w[0] : reference(c.end, index), index),
1001
+ resolve(c.end, w.length > 0 ? w[w.length - 1] : reference(c.start, index), index)
1002
+ ];
822
1003
  }
823
1004
  function routePoints(r) {
824
1005
  if (r.kind === "polyline") return r.points;
825
- const out = [];
826
- for (let i = 0; i <= 24; i++) {
827
- const t = i / 24, u = 1 - t;
828
- out.push({
829
- x: u * u * u * r.a.x + 3 * u * u * t * r.b.x + 3 * u * t * t * r.c.x + t * t * t * r.d.x,
830
- y: u * u * u * r.a.y + 3 * u * u * t * r.b.y + 3 * u * t * t * r.c.y + t * t * t * r.d.y
831
- });
1006
+ const out = [], p = r.points;
1007
+ for (let s = 0; s < Math.floor((p.length - 1) / 3); s++) {
1008
+ const a = p[3 * s], b = p[3 * s + 1], c = p[3 * s + 2], d = p[3 * s + 3];
1009
+ for (let i = s === 0 ? 0 : 1; i <= 24; i++) {
1010
+ const t = i / 24, u = 1 - t;
1011
+ out.push({
1012
+ x: u * u * u * a.x + 3 * u * u * t * b.x + 3 * u * t * t * c.x + t * t * t * d.x,
1013
+ y: u * u * u * a.y + 3 * u * u * t * b.y + 3 * u * t * t * c.y + t * t * t * d.y
1014
+ });
1015
+ }
832
1016
  }
833
1017
  return out;
834
1018
  }
1019
+ var vertical = (p) => p === null ? null : p === "top" || p === "bottom";
1020
+ function simplified(pts) {
1021
+ const out = [];
1022
+ for (const q of pts) {
1023
+ const l = out[out.length - 1];
1024
+ if (l && Math.abs(l.x - q.x) < 0.5 && Math.abs(l.y - q.y) < 0.5) continue;
1025
+ if (out.length >= 2) {
1026
+ const p = out[out.length - 2], m = out[out.length - 1];
1027
+ if (Math.abs(p.x - m.x) < 0.5 && Math.abs(m.x - q.x) < 0.5 || Math.abs(p.y - m.y) < 0.5 && Math.abs(m.y - q.y) < 0.5) {
1028
+ out[out.length - 1] = q;
1029
+ continue;
1030
+ }
1031
+ }
1032
+ out.push(q);
1033
+ }
1034
+ return out.length >= 2 ? out : pts;
1035
+ }
1036
+ function routeThrough(p, c) {
1037
+ switch (c.routing) {
1038
+ case "straight":
1039
+ return { kind: "polyline", points: p };
1040
+ case "curved": {
1041
+ const out = [p[0]];
1042
+ for (let i = 0; i < p.length - 1; i++) {
1043
+ const p0 = p[Math.max(i - 1, 0)], p1 = p[i], p2 = p[i + 1], p3 = p[Math.min(i + 2, p.length - 1)];
1044
+ out.push({ x: p1.x + (p2.x - p0.x) / 6, y: p1.y + (p2.y - p0.y) / 6 });
1045
+ out.push({ x: p2.x - (p3.x - p1.x) / 6, y: p2.y - (p3.y - p1.y) / 6 });
1046
+ out.push(p2);
1047
+ }
1048
+ return { kind: "curve", points: out };
1049
+ }
1050
+ case "elbow": {
1051
+ const a = p[0], first = p[1];
1052
+ let goVertical = vertical(c.start.port) ?? Math.abs(first.y - a.y) > Math.abs(first.x - a.x);
1053
+ const endV = vertical(c.end.port);
1054
+ const out = [a];
1055
+ for (let i = 1; i < p.length; i++) {
1056
+ const q = p[i], cur = out[out.length - 1];
1057
+ const alignedX = Math.abs(cur.x - q.x) < 0.5, alignedY = Math.abs(cur.y - q.y) < 0.5;
1058
+ if (alignedX || alignedY) {
1059
+ out.push(q);
1060
+ if (alignedX !== alignedY) goVertical = !alignedX;
1061
+ continue;
1062
+ }
1063
+ const up = i === p.length - 1 && endV !== null ? !endV : goVertical;
1064
+ out.push(up ? { x: cur.x, y: q.y } : { x: q.x, y: cur.y }, q);
1065
+ goVertical = up;
1066
+ }
1067
+ return { kind: "polyline", points: simplified(out) };
1068
+ }
1069
+ }
1070
+ }
835
1071
  function route(e, index) {
836
1072
  const c = e.connector;
837
1073
  if (!c) return { kind: "polyline", points: [] };
838
1074
  const [a, b] = endpoints(e, index);
1075
+ if (c.waypoints && c.waypoints.length > 0) return routeThrough([a, ...c.waypoints.map((w) => ({ x: w.x, y: w.y })), b], c);
839
1076
  const dx = b.x - a.x, dy = b.y - a.y;
840
1077
  const horizontal = Math.abs(dx) >= Math.abs(dy);
841
1078
  switch (c.routing) {
842
1079
  case "straight":
843
1080
  return { kind: "polyline", points: [a, b] };
844
1081
  case "curved":
845
- if (horizontal) return { kind: "cubic", a, b: { x: a.x + dx / 2, y: a.y }, c: { x: b.x - dx / 2, y: b.y }, d: b };
846
- return { kind: "cubic", a, b: { x: a.x, y: a.y + dy / 2 }, c: { x: b.x, y: b.y - dy / 2 }, d: b };
1082
+ if (horizontal) return { kind: "curve", points: [a, { x: a.x + dx / 2, y: a.y }, { x: b.x - dx / 2, y: b.y }, b] };
1083
+ return { kind: "curve", points: [a, { x: a.x, y: a.y + dy / 2 }, { x: b.x, y: b.y - dy / 2 }, b] };
847
1084
  case "elbow": {
848
- const vertical = (p) => p === null ? null : p === "top" || p === "bottom";
849
1085
  const startV = vertical(c.start.port) ?? !horizontal;
850
1086
  const endV = vertical(c.end.port) ?? !horizontal;
851
1087
  if (startV && endV) {
@@ -1425,10 +1661,12 @@ function dashPattern(dash, width) {
1425
1661
  return [0.01, Math.max(5, width * 2.6)];
1426
1662
  }
1427
1663
  }
1428
- function connectorParts(e, index) {
1664
+ function connectorParts(e, index, page) {
1429
1665
  const c = e.connector;
1430
1666
  if (!c) return [new Path(), new Path()];
1431
1667
  const [a, b] = endpoints(e, index);
1668
+ const r = route(e, index);
1669
+ const hops = c.hops === true && page ? hopCrossings(e, r, page, index) : [];
1432
1670
  const key = [
1433
1671
  e.seed,
1434
1672
  e.style.roughness,
@@ -1442,28 +1680,166 @@ function connectorParts(e, index) {
1442
1680
  a.x,
1443
1681
  a.y,
1444
1682
  b.x,
1445
- b.y
1683
+ b.y,
1684
+ JSON.stringify(c.waypoints),
1685
+ JSON.stringify(hops)
1446
1686
  ].join("|");
1447
- return connectors.get(key, () => computeConnector(e, index));
1687
+ return connectors.get(key, () => computeConnector(e, r, hops));
1688
+ }
1689
+ function hopRadius(strokeWidth) {
1690
+ return Math.max(8, strokeWidth * 4);
1691
+ }
1692
+ function hopSamples(r) {
1693
+ const pts = r.points, out = [];
1694
+ if (r.kind === "polyline") {
1695
+ for (let i = 0; i < pts.length - 1; i++) out.push([pts[i], pts[i + 1]]);
1696
+ return out;
1697
+ }
1698
+ for (let s = 0; s < Math.floor((pts.length - 1) / 3); s++) {
1699
+ const seg = pts.slice(3 * s, 3 * s + 4), samples = [];
1700
+ for (let i = 0; i <= 24; i++) samples.push(cubicPoint(seg, i / 24));
1701
+ out.push(samples);
1702
+ }
1703
+ return out;
1704
+ }
1705
+ function runningLengths(samples) {
1706
+ const out = [0];
1707
+ for (let i = 1; i < samples.length; i++) out.push(out[i - 1] + Math.hypot(samples[i].x - samples[i - 1].x, samples[i].y - samples[i - 1].y));
1708
+ return out;
1448
1709
  }
1449
- function computeConnector(e, index) {
1710
+ function cubicPoint(p, t) {
1711
+ const u = 1 - t;
1712
+ return {
1713
+ x: u * u * u * p[0].x + 3 * u * u * t * p[1].x + 3 * u * t * t * p[2].x + t * t * t * p[3].x,
1714
+ y: u * u * u * p[0].y + 3 * u * u * t * p[1].y + 3 * u * t * t * p[2].y + t * t * t * p[3].y
1715
+ };
1716
+ }
1717
+ function subCubic(p, t0, t1) {
1718
+ const split = (q, t) => {
1719
+ const lerp = (a, b) => ({ x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t });
1720
+ const ab = lerp(q[0], q[1]), bc = lerp(q[1], q[2]), cd = lerp(q[2], q[3]);
1721
+ const abc = lerp(ab, bc), bcd = lerp(bc, cd), m = lerp(abc, bcd);
1722
+ return [[q[0], ab, abc, m], [m, bcd, cd, q[3]]];
1723
+ };
1724
+ const left = split(p, t1)[0];
1725
+ return t1 > 0 ? split(left, t0 / t1)[1] : [p[0], p[0], p[0], p[0]];
1726
+ }
1727
+ function hopCrossings(e, r, page, index) {
1728
+ const segments = hopSamples(r);
1729
+ if (segments.length === 0) return [];
1730
+ const visible = new Set(page.layers.filter((l) => l.visible).map((l) => l.id));
1731
+ const beneath = [];
1732
+ for (const o of orderedElements(page)) {
1733
+ if (o.id === e.id) break;
1734
+ if (o.kind !== "connector" || !visible.has(o.layerID)) continue;
1735
+ beneath.push(routePoints(route(o, index)));
1736
+ }
1737
+ const rad = hopRadius(e.style.strokeWidth);
1738
+ const out = [];
1739
+ for (const samples of segments) {
1740
+ const along = runningLengths(samples);
1741
+ const length = along[along.length - 1];
1742
+ const found = [];
1743
+ for (let i = 0; i < samples.length - 1; i++) {
1744
+ const p = samples[i], q = samples[i + 1];
1745
+ const dx = q.x - p.x, dy = q.y - p.y;
1746
+ for (const line2 of beneath) {
1747
+ for (let k = 0; k < line2.length - 1; k++) {
1748
+ const a = line2[k], b = line2[k + 1];
1749
+ const ex = b.x - a.x, ey = b.y - a.y;
1750
+ const det = dx * ey - dy * ex;
1751
+ if (Math.abs(det) < 1e-9) continue;
1752
+ const wx = a.x - p.x, wy = a.y - p.y;
1753
+ const t = (wx * ey - wy * ex) / det, s = (wx * dy - wy * dx) / det;
1754
+ if (t > 0 && t < 1 && s >= 0 && s <= 1) found.push(along[i] + t * (along[i + 1] - along[i]));
1755
+ }
1756
+ }
1757
+ }
1758
+ const kept = [];
1759
+ for (const at of found.sort((x, y) => x - y)) {
1760
+ if (at < rad + 2 || at > length - rad - 2) continue;
1761
+ if (kept.length > 0 && at - kept[kept.length - 1] < 2 * rad + 2) continue;
1762
+ kept.push(at);
1763
+ }
1764
+ out.push(kept);
1765
+ }
1766
+ return out;
1767
+ }
1768
+ function computeConnector(e, r, hops) {
1450
1769
  const c = e.connector;
1451
1770
  const rng = new SeededRNG(e.seed);
1452
1771
  const rough = e.style.roughness, bow = e.style.bowing;
1453
1772
  const path = new Path(), solid = new Path();
1454
- const r = route(e, index);
1773
+ const w = rough * 3;
1774
+ const j = () => rng.signed() * w;
1775
+ const hop = (s, t, u, rad2) => {
1776
+ let n = { x: u.y, y: -u.x };
1777
+ if (n.y > 1e-9 || Math.abs(n.y) <= 1e-9 && n.x > 0) n = { x: -n.x, y: -n.y };
1778
+ const k = rad2 * 0.5523;
1779
+ const m = { x: (s.x + t.x) / 2, y: (s.y + t.y) / 2 };
1780
+ const top = { x: m.x + n.x * rad2, y: m.y + n.y * rad2 };
1781
+ path.moveTo(s);
1782
+ const a1x = s.x + n.x * k + j(), a1y = s.y + n.y * k + j(), a2x = top.x - u.x * k + j(), a2y = top.y - u.y * k + j();
1783
+ path.curveTo(top, { x: a1x, y: a1y }, { x: a2x, y: a2y });
1784
+ const b1x = top.x + u.x * k + j(), b1y = top.y + u.y * k + j(), b2x = t.x + n.x * k + j(), b2y = t.y + n.y * k + j();
1785
+ path.curveTo(t, { x: b1x, y: b1y }, { x: b2x, y: b2y });
1786
+ };
1787
+ const rad = hopRadius(e.style.strokeWidth);
1455
1788
  if (r.kind === "polyline") {
1456
1789
  const pts2 = r.points;
1790
+ const straight = (p, q) => {
1791
+ if (rough <= 0) path.moveTo(p).lineTo(q);
1792
+ else line(p, q, rng, rough, bow, true, path);
1793
+ };
1457
1794
  for (let i = 0; i < Math.max(pts2.length - 1, 0); i++) {
1458
- if (rough <= 0) path.moveTo(pts2[i]).lineTo(pts2[i + 1]);
1459
- else line(pts2[i], pts2[i + 1], rng, rough, bow, true, path);
1795
+ const p = pts2[i], q = pts2[i + 1];
1796
+ const length = Math.hypot(q.x - p.x, q.y - p.y);
1797
+ const u = length > 0 ? { x: (q.x - p.x) / length, y: (q.y - p.y) / length } : { x: 0, y: 0 };
1798
+ const at = (d) => ({ x: p.x + u.x * d, y: p.y + u.y * d });
1799
+ let from = p;
1800
+ for (const d of i < hops.length ? hops[i] : []) {
1801
+ const s = at(d - rad), t = at(d + rad);
1802
+ straight(from, s);
1803
+ hop(s, t, u, rad);
1804
+ from = t;
1805
+ }
1806
+ straight(from, q);
1460
1807
  }
1461
1808
  } else {
1462
- path.moveTo(r.a);
1463
- const w = rough * 3;
1464
- const j = () => rng.signed() * w;
1465
- const c1x = r.b.x + j(), c1y = r.b.y + j(), c2x = r.c.x + j(), c2y = r.c.y + j();
1466
- path.curveTo(r.d, { x: c1x, y: c1y }, { x: c2x, y: c2y });
1809
+ const pts2 = r.points;
1810
+ const samples = hopSamples(r);
1811
+ path.moveTo(pts2[0]);
1812
+ for (let s = 0; s < Math.floor((pts2.length - 1) / 3); s++) {
1813
+ const b = pts2[3 * s + 1], c2 = pts2[3 * s + 2], d = pts2[3 * s + 3];
1814
+ const c1x = b.x + j(), c1y = b.y + j(), c2x = c2.x + j(), c2y = c2.y + j();
1815
+ const here = s < hops.length ? hops[s] : [];
1816
+ if (here.length === 0) {
1817
+ path.curveTo(d, { x: c1x, y: c1y }, { x: c2x, y: c2y });
1818
+ continue;
1819
+ }
1820
+ const cubic = [pts2[3 * s], { x: c1x, y: c1y }, { x: c2x, y: c2y }, d];
1821
+ const along = runningLengths(samples[s]);
1822
+ const param = (at) => {
1823
+ let i = 0;
1824
+ while (i < along.length - 2 && along[i + 1] < at) i++;
1825
+ const span = along[i + 1] - along[i];
1826
+ return (i + (span > 0 ? (at - along[i]) / span : 0)) / 24;
1827
+ };
1828
+ let from = 0;
1829
+ for (const at of here) {
1830
+ const t0 = param(at - rad), t1 = param(at + rad);
1831
+ const piece = subCubic(cubic, from, t0);
1832
+ if (s > 0 || from > 0) path.moveTo(piece[0]);
1833
+ path.curveTo(piece[3], piece[1], piece[2]);
1834
+ const a = cubicPoint(cubic, t0), z = cubicPoint(cubic, t1);
1835
+ const width = Math.hypot(z.x - a.x, z.y - a.y);
1836
+ const u = width > 0 ? { x: (z.x - a.x) / width, y: (z.y - a.y) / width } : { x: 0, y: 0 };
1837
+ hop(a, z, u, width / 2);
1838
+ from = t1;
1839
+ }
1840
+ const rest = subCubic(cubic, from, 1);
1841
+ path.moveTo(rest[0]).curveTo(rest[3], rest[1], rest[2]);
1842
+ }
1467
1843
  }
1468
1844
  const pts = routePoints(r);
1469
1845
  const size = Math.max(10, e.style.strokeWidth * 5);
@@ -1485,10 +1861,10 @@ function computeConnector(e, index) {
1485
1861
  solid.moveTo(tip).lineTo(w1).lineTo(w2).close();
1486
1862
  break;
1487
1863
  case "dot": {
1488
- const rad = size * 0.32;
1864
+ const rad2 = size * 0.32;
1489
1865
  const ang = Math.atan2(tip.y - from.y, tip.x - from.x);
1490
- const cx = tip.x - rad * Math.cos(ang), cy = tip.y - rad * Math.sin(ang);
1491
- solid.addEllipse({ x: cx - rad, y: cy - rad, width: 2 * rad, height: 2 * rad });
1866
+ const cx = tip.x - rad2 * Math.cos(ang), cy = tip.y - rad2 * Math.sin(ang);
1867
+ solid.addEllipse({ x: cx - rad2, y: cy - rad2, width: 2 * rad2, height: 2 * rad2 });
1492
1868
  break;
1493
1869
  }
1494
1870
  case "bar": {
@@ -1568,7 +1944,7 @@ function localTime(track, t) {
1568
1944
  }
1569
1945
  return t;
1570
1946
  }
1571
- function value(track, t, get, base, lerp) {
1947
+ function value(track, t, get, base2, lerp) {
1572
1948
  t = localTime(track, t);
1573
1949
  let before, after;
1574
1950
  for (const k of track.keys) {
@@ -1579,7 +1955,7 @@ function value(track, t, get, base, lerp) {
1579
1955
  break;
1580
1956
  }
1581
1957
  }
1582
- if (!before && !after) return base;
1958
+ if (!before && !after) return base2;
1583
1959
  if (before && !after) return get(before);
1584
1960
  if (!before && after) return get(after);
1585
1961
  const b = before, a = after;
@@ -1594,8 +1970,8 @@ var lerpColor = (a, b, u) => ({
1594
1970
  b: mix01(a.b, b.b, u),
1595
1971
  a: mix01(a.a, b.a, u)
1596
1972
  });
1597
- function num2(track, t, p, base) {
1598
- return value(track, t, (k) => k[p], base, lerpNum);
1973
+ function num2(track, t, p, base2) {
1974
+ return value(track, t, (k) => k[p], base2, lerpNum);
1599
1975
  }
1600
1976
  function isChanging(track, t) {
1601
1977
  t = localTime(track, t);
@@ -1955,7 +2331,12 @@ function placed(inner, instance, symbol) {
1955
2331
  const q = point(p);
1956
2332
  return { elementID: null, port: p.port, x: q.x, y: q.y };
1957
2333
  };
1958
- e.connector = { ...inner.connector, start: end(inner.connector.start), end: end(inner.connector.end) };
2334
+ e.connector = {
2335
+ ...inner.connector,
2336
+ start: end(inner.connector.start),
2337
+ end: end(inner.connector.end),
2338
+ waypoints: inner.connector.waypoints?.map(point) ?? null
2339
+ };
1959
2340
  }
1960
2341
  return e;
1961
2342
  }
@@ -2060,25 +2441,6 @@ var CLICK_STYLE = `
2060
2441
  .dottie-b:active .dottie-d, .dottie-b.dottie-press .dottie-d { display: inline; }
2061
2442
  `;
2062
2443
 
2063
- // src/metrics.ts
2064
- var ascent = 0.951995849609375;
2065
- var descent = 0.2129974365234375;
2066
- var leading = 0.0279998779296875;
2067
- var boldAscent = 0.975006103515625;
2068
- var boldDescent = 0.2169952392578125;
2069
- var boldLeading = 0.0290069580078125;
2070
- var italicAscent = 0.957000732421875;
2071
- var italicDescent = 0.2129974365234375;
2072
- var italicLeading = 0.0279998779296875;
2073
- var boldItalicAscent = 0.975006103515625;
2074
- var boldItalicDescent = 0.2169952392578125;
2075
- var boldItalicLeading = 0.0290069580078125;
2076
- var monoAdvance = 0.60205078125;
2077
- var monoAscent = 0.92822265625;
2078
- var monoDescent = 0.23583984375;
2079
- var fonts = { "bold": { "k": { "\u2018\u2018": -95, "\u2019\u2019": -95, "\u2019s": -74, "\u2019t": -18, "A\u2019": -74, "AT": -92, "Av": -18, "AV": -46, "Aw": -18, "AW": -24, "Ay": -18, "AY": -74, "F,": -157, "F.": -157, "f\u2019": 18, "FA": -55, "ff": -30, "fi": 20, "fl": 20, "L\u2019": -74, "LT": -92, "LV": -92, "LW": -55, "Ly": -37, "LY": -111, "P,": -179, "P.": -179, "PA": -74, "r-": -55, "r,": -92, "r.": -92, "rc": -18, "rd": -18, "re": -18, "rg": -28, "rn": 18, "ro": -18, "rq": -18, "RT": -18, "RV": -18, "RW": -18, "RY": -37, "T-": -129, "T,": -111, "T;": -111, "T:": -111, "T.": -111, "Ta": -111, "TA": -92, "Tc": -111, "Te": -111, "To": -111, "Tr": -92, "Ts": -111, "Tu": -92, "Tw": -111, "Ty": -111, "V-": -55, "v,": -74, "V,": -129, "V;": -46, "V:": -46, "v.": -74, "V.": -129, "Va": -55, "VA": -46, "Ve": -55, "Vi": -18, "Vo": -55, "Vr": -37, "Vu": -37, "Vy": -18, "w,": -55, "W,": -74, "W;": -18, "W:": -18, "w.": -55, "W.": -74, "Wa": -37, "WA": -24, "We": -57, "Wo": -57, "Wr": -18, "Wu": -18, "Y-": -111, "y,": -74, "Y,": -139, "Y;": -92, "Y:": -92, "y.": -74, "Y.": -139, "Ya": -92, "YA": -74, "Ye": -111, "Yi": -37, "Yo": -111, "Yp": -74, "Yq": -92, "Yu": -74, "Yv": -55 }, "w": { " ": 278, "_": 500, "-": 407, "\u2013": 500, "\u2014": 1e3, ",": 278, ";": 278, ":": 278, "!": 278, "?": 556, ".": 278, "\u2026": 1e3, "\xB7": 278, "'": 278, "\u2018": 278, "\u2019": 278, '"': 463, "\u201C": 463, "\u201D": 463, "(": 296, ")": 296, "[": 333, "]": 333, "{": 333, "}": 333, "@": 800, "*": 407, "/": 371, "\\": 371, "&": 685, "#": 556, "%": 1e3, "\u2022": 350, "`": 259, "^": 600, "\u2190": 1e3, "\u2192": 1e3, "\u2191": 722.66, "\u2193": 722.66, "+": 600, "\xD7": 600, "<": 600, "=": 600, ">": 600, "|": 223, "~": 600, "\u25E6": 608.4, "\u2610": 830.08, "\u2611": 830.08, "\u2713": 764.16, "$": 556, "0": 556, "1": 556, "2": 556, "3": 556, "4": 556, "5": 556, "6": 556, "7": 556, "8": 556, "9": 556, "a": 574, "A": 685, "b": 611, "B": 704, "c": 574, "C": 741, "d": 611, "D": 741, "e": 574, "E": 648, "\xE9": 574, "f": 333, "F": 593, "g": 611, "G": 759, "h": 593, "H": 741, "i": 258, "I": 295, "j": 278, "J": 556, "k": 574, "K": 722, "l": 258, "L": 593, "m": 906, "M": 907, "n": 593, "N": 741, "o": 611, "O": 778, "p": 611, "P": 667, "q": 611, "Q": 778, "r": 389, "R": 722, "s": 537, "S": 649, "t": 352, "T": 611, "u": 593, "U": 741, "v": 520, "V": 630, "w": 814, "W": 944, "x": 537, "X": 667, "y": 519, "Y": 667, "z": 519, "Z": 648 } }, "boldItalic": { "k": { "\u2018\u2018": -95, "\u2019\u2019": -95, "\u2019s": -74, "\u2019t": -18, "A\u2019": -74, "AT": -92, "Av": -18, "AV": -46, "Aw": -18, "AW": -24, "Ay": -18, "AY": -74, "F,": -157, "F.": -157, "f\u2019": 18, "FA": -55, "ff": -68, "L\u2019": -74, "LT": -92, "LV": -92, "LW": -55, "Ly": -37, "LY": -111, "P,": -179, "P.": -179, "PA": -74, "r-": -55, "r,": -92, "r.": -92, "rc": -18, "rd": -18, "re": -18, "rg": -28, "rn": 18, "ro": -18, "rq": -18, "RT": -18, "RV": -18, "RW": -18, "RY": -37, "T-": -129, "T,": -111, "T;": -111, "T:": -111, "T.": -111, "Ta": -111, "TA": -92, "Tc": -111, "Te": -111, "To": -111, "Tr": -92, "Ts": -111, "Tu": -92, "Tw": -111, "Ty": -111, "V-": -55, "v,": -74, "V,": -129, "V;": -46, "V:": -46, "v.": -74, "V.": -129, "Va": -55, "VA": -46, "Ve": -55, "Vi": -18, "Vo": -55, "Vr": -37, "Vu": -37, "Vy": -18, "w,": -55, "W,": -74, "W;": -18, "W:": -18, "w.": -55, "W.": -74, "Wa": -37, "WA": -24, "We": -57, "Wo": -57, "Wr": -18, "Wu": -18, "Y-": -111, "y,": -74, "Y,": -139, "Y;": -92, "Y:": -92, "y.": -74, "Y.": -139, "Ya": -92, "YA": -74, "Ye": -111, "Yi": -37, "Yo": -111, "Yp": -74, "Yq": -92, "Yu": -74, "Yv": -55 }, "w": { " ": 278, "_": 500, "-": 407, "\u2013": 500, "\u2014": 1e3, ",": 278, ";": 278, ":": 278, "!": 296, "?": 574, ".": 278, "\u2026": 1e3, "\xB7": 278, "'": 278, "\u2018": 278, "\u2019": 278, '"': 481, "\u201C": 481, "\u201D": 481, "(": 296, ")": 296, "[": 333, "]": 333, "{": 333, "}": 333, "@": 800, "*": 407, "/": 389, "\\": 389, "&": 685, "#": 556, "%": 963, "\u2022": 350, "`": 259, "^": 600, "\u2190": 1e3, "\u2192": 1e3, "\u2191": 722.66, "\u2193": 722.66, "+": 600, "\xD7": 600, "<": 600, "=": 600, ">": 600, "|": 222, "~": 600, "\u25E6": 608.4, "\u2610": 830.08, "\u2611": 830.08, "\u2713": 764.16, "$": 556, "0": 556, "1": 556, "2": 556, "3": 556, "4": 556, "5": 556, "6": 556, "7": 556, "8": 556, "9": 556, "a": 574, "A": 685, "b": 611, "B": 722, "c": 556, "C": 741, "d": 611, "D": 741, "e": 574, "E": 667, "\xE9": 574, "f": 352, "F": 593, "g": 611, "G": 759, "h": 611, "H": 741, "i": 259, "I": 296, "j": 259, "J": 556, "k": 556, "K": 722, "l": 259, "L": 574, "m": 907, "M": 907, "n": 611, "N": 741, "o": 593, "O": 778, "p": 611, "P": 667, "q": 611, "Q": 778, "r": 389, "R": 722, "s": 519, "S": 648, "t": 370, "T": 611, "u": 611, "U": 741, "v": 519, "V": 630, "w": 815, "W": 944, "x": 519, "X": 667, "y": 519, "Y": 648, "z": 500, "Z": 648 } }, "italic": { "k": { "\u2018\u2018": -95, "\u2019\u2019": -95, "\u2019s": -74, "\u2019t": -18, "A\u2019": -74, "AT": -92, "Av": -18, "AV": -46, "Aw": -18, "AW": -24, "Ay": -18, "AY": -74, "F,": -157, "F.": -157, "f\u2019": 18, "FA": -55, "ff": -15, "fi": 1, "fl": 1, "L\u2019": -74, "LT": -92, "LV": -92, "LW": -55, "Ly": -37, "LY": -111, "P,": -179, "P.": -179, "PA": -74, "r-": -55, "r,": -92, "r.": -92, "rc": -18, "rd": -18, "re": -18, "rg": -28, "rn": 18, "ro": -18, "rq": -18, "RT": -18, "RV": -18, "RW": -18, "RY": -37, "T-": -129, "T,": -111, "T;": -111, "T:": -111, "T.": -111, "Ta": -111, "TA": -92, "Tc": -111, "Te": -111, "To": -111, "Tr": -92, "Ts": -111, "Tu": -92, "Tw": -111, "Ty": -111, "V-": -55, "v,": -74, "V,": -129, "V;": -46, "V:": -46, "v.": -74, "V.": -129, "Va": -55, "VA": -46, "Ve": -55, "Vi": -18, "Vo": -55, "Vr": -37, "Vu": -37, "Vy": -18, "w,": -55, "W,": -74, "W;": -18, "W:": -18, "w.": -55, "W.": -74, "Wa": -37, "WA": -24, "We": -57, "Wo": -57, "Wr": -18, "Wu": -18, "Y-": -111, "y,": -74, "Y,": -139, "Y;": -92, "Y:": -92, "y.": -74, "Y.": -139, "Ya": -92, "YA": -74, "Ye": -111, "Yi": -37, "Yo": -111, "Yp": -74, "Yq": -92, "Yu": -74, "Yv": -55 }, "w": { " ": 278, "_": 500, "-": 389, "\u2013": 500, "\u2014": 1e3, ",": 278, ";": 278, ":": 278, "!": 259, "?": 556, ".": 278, "\u2026": 1e3, "\xB7": 278, "'": 278, "\u2018": 278, "\u2019": 278, '"': 426, "\u201C": 426, "\u201D": 426, "(": 259, ")": 259, "[": 259, "]": 259, "{": 333, "}": 333, "@": 800, "*": 352, "/": 333, "\\": 333, "&": 630, "#": 556, "%": 926, "\u2022": 500, "`": 222, "^": 600, "\u2190": 1e3, "\u2192": 1e3, "\u2191": 645.02, "\u2193": 645.02, "+": 600, "\xD7": 600, "<": 600, "=": 600, ">": 600, "|": 222, "~": 600, "\u25E6": 578.13, "\u2610": 830.08, "\u2611": 830.08, "\u2713": 764.16, "$": 556, "0": 556, "1": 556, "2": 556, "3": 556, "4": 556, "5": 556, "6": 556, "7": 556, "8": 556, "9": 556, "a": 519, "A": 667, "b": 593, "B": 685, "c": 537, "C": 722, "d": 593, "D": 704, "e": 537, "E": 611, "\xE9": 537, "f": 296, "F": 574, "g": 574, "G": 759, "h": 556, "H": 722, "i": 222, "I": 259, "j": 222, "J": 519, "k": 481, "K": 667, "l": 222, "L": 556, "m": 852, "M": 870, "n": 556, "N": 722, "o": 574, "O": 759, "p": 593, "P": 648, "q": 593, "Q": 759, "r": 333, "R": 685, "s": 481, "S": 648, "t": 315, "T": 574, "u": 556, "U": 722, "v": 481, "V": 611, "w": 759, "W": 926, "x": 481, "X": 611, "y": 481, "Y": 611, "z": 444, "Z": 611 } }, "regular": { "k": { "\u2018\u2018": -95, "\u2019\u2019": -95, "\u2019s": -74, "\u2019t": -18, "A\u2019": -74, "AT": -92, "Av": -18, "AV": -46, "Aw": -18, "AW": -24, "Ay": -18, "AY": -74, "F,": -157, "F.": -157, "f\u2019": 18, "FA": -55, "ff": -15, "L\u2019": -74, "LT": -92, "LV": -92, "LW": -55, "Ly": -37, "LY": -111, "P,": -179, "P.": -179, "PA": -74, "r-": -55, "r,": -92, "r.": -92, "rc": -18, "rd": -18, "re": -18, "rg": -28, "rn": 18, "ro": -18, "rq": -18, "RT": -18, "RV": -18, "RW": -18, "RY": -37, "T-": -129, "T,": -111, "T;": -111, "T:": -111, "T.": -111, "Ta": -111, "TA": -92, "Tc": -111, "Te": -111, "To": -111, "Tr": -92, "Ts": -111, "Tu": -92, "Tw": -111, "Ty": -111, "V-": -55, "v,": -74, "V,": -129, "V;": -46, "V:": -46, "v.": -74, "V.": -129, "Va": -55, "VA": -46, "Ve": -55, "Vi": -18, "Vo": -55, "Vr": -37, "Vu": -37, "Vy": -18, "w,": -55, "W,": -74, "W;": -18, "W:": -18, "w.": -55, "W.": -74, "Wa": -37, "WA": -24, "We": -57, "Wo": -57, "Wr": -18, "Wu": -18, "Y-": -111, "y,": -74, "Y,": -139, "Y;": -92, "Y:": -92, "y.": -74, "Y.": -139, "Ya": -92, "YA": -74, "Ye": -111, "Yi": -37, "Yo": -111, "Yp": -74, "Yq": -92, "Yu": -74, "Yv": -55 }, "w": { " ": 278, "_": 500, "-": 389, "\u2013": 500, "\u2014": 1e3, ",": 278, ";": 278, ":": 278, "!": 259, "?": 556, ".": 278, "\u2026": 1e3, "\xB7": 278, "'": 278, "\u2018": 278, "\u2019": 278, '"': 426, "\u201C": 426, "\u201D": 426, "(": 259, ")": 259, "[": 259, "]": 259, "{": 333, "}": 333, "@": 800, "*": 352, "/": 333, "\\": 333, "&": 630, "#": 556, "%": 1e3, "\u2022": 350, "`": 222, "^": 600, "\u2190": 1e3, "\u2192": 1e3, "\u2191": 645.02, "\u2193": 645.02, "+": 600, "\xD7": 600, "<": 600, "=": 600, ">": 600, "|": 222, "~": 600, "\u25E6": 578.13, "\u2610": 830.08, "\u2611": 830.08, "\u2713": 764.16, "$": 556, "0": 556, "1": 556, "2": 556, "3": 556, "4": 556, "5": 556, "6": 556, "7": 556, "8": 556, "9": 556, "a": 537, "A": 648, "b": 593, "B": 685, "c": 537, "C": 722, "d": 593, "D": 704, "e": 537, "E": 611, "\xE9": 537, "f": 296, "F": 574, "g": 574, "G": 759, "h": 556, "H": 722, "i": 222, "I": 259, "j": 222, "J": 519, "k": 519, "K": 667, "l": 222, "L": 556, "m": 853, "M": 871, "n": 556, "N": 722, "o": 574, "O": 760, "p": 593, "P": 648, "q": 593, "Q": 760, "r": 333, "R": 685, "s": 500, "S": 648, "t": 315, "T": 574, "u": 556, "U": 722, "v": 500, "V": 611, "w": 758, "W": 926, "x": 518, "X": 611, "y": 500, "Y": 648, "z": 480, "Z": 611 } } };
2080
- var fallbackMetrics = { "\u2190": [0.966796875, 0.2109375, 0], "\u2192": [0.966796875, 0.2109375, 0], "\u2191": [0.966796875, 0.2109375, 0], "\u2193": [0.966796875, 0.2109375, 0], "\u25E6": [0.966796875, 0.2109375, 0], "\u2610": [0.66650390625, 0.25, 0.08349609375], "\u2611": [0.66650390625, 0.25, 0.08349609375], "\u2713": [0.966796875, 0.2109375, 0] };
2081
-
2082
2444
  // src/svg-util.ts
2083
2445
  function color(c) {
2084
2446
  const h = (v) => Math.round(Math.min(Math.max(v, 0), 1) * 255).toString(16).padStart(2, "0");
@@ -2088,74 +2450,6 @@ function escapeXML(s) {
2088
2450
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
2089
2451
  }
2090
2452
 
2091
- // src/text.ts
2092
- function measure(s, fontSize, face2 = "regular") {
2093
- const f = fonts[face2];
2094
- const fallback = f.w["n"];
2095
- let w = 0;
2096
- let prev = "";
2097
- for (const ch of s) {
2098
- w += f.w[ch] ?? fallback;
2099
- if (prev) w += f.k[prev + ch] ?? 0;
2100
- prev = ch;
2101
- }
2102
- return w * fontSize / 1e3;
2103
- }
2104
- function lineHeights(fontSize) {
2105
- const a = Math.round(ascent * fontSize), d = Math.round(descent * fontSize), l = Math.round(leading * fontSize);
2106
- return [a + d, a + d + l];
2107
- }
2108
- function breaksAfter(ch, next) {
2109
- if (ch === " ") return true;
2110
- return (ch === "/" || ch === "-") && next !== "" && !/[\d\s/-]/.test(next);
2111
- }
2112
- function pieces(para) {
2113
- const chars = [...para];
2114
- const out = [];
2115
- let cur = "";
2116
- chars.forEach((ch, i) => {
2117
- cur += ch;
2118
- const next = chars[i + 1] ?? "";
2119
- if (breaksAfter(ch, next) && next !== " ") {
2120
- out.push(cur);
2121
- cur = "";
2122
- }
2123
- });
2124
- if (cur || out.length === 0) out.push(cur);
2125
- return out;
2126
- }
2127
- function wrap(s, fontSize, maxWidth, face2 = "regular") {
2128
- const out = [];
2129
- for (const para of s.split(/\r\n|\n|\r|\u2028|\u2029/)) {
2130
- let line2 = "";
2131
- for (const piece of pieces(para)) {
2132
- const candidate = line2 + piece;
2133
- if (line2 === "" || measure(candidate.trimEnd(), fontSize, face2) <= maxWidth) {
2134
- line2 = candidate;
2135
- } else {
2136
- out.push(line2);
2137
- line2 = piece;
2138
- }
2139
- while (measure(line2.trimEnd(), fontSize, face2) > maxWidth && [...line2.trimEnd()].length > 1) {
2140
- const chars = [...line2];
2141
- let n = chars.length - 1;
2142
- while (n > 1 && measure(chars.slice(0, n).join(""), fontSize, face2) > maxWidth) n--;
2143
- out.push(chars.slice(0, n).join(""));
2144
- line2 = chars.slice(n).join("");
2145
- }
2146
- }
2147
- out.push(line2);
2148
- }
2149
- return out;
2150
- }
2151
- function textSize(s, fontSize, maxWidth) {
2152
- if (s === "") return { width: 0, height: 0 };
2153
- const lines = wrap(s, fontSize, maxWidth);
2154
- const width = Math.max(...lines.map((l) => measure(l.trimEnd(), fontSize)));
2155
- const [first, next] = lineHeights(fontSize);
2156
- return { width: Math.ceil(width - 1e-9), height: Math.ceil(first + next * (lines.length - 1) - 1e-9) };
2157
- }
2158
-
2159
2453
  // src/note.ts
2160
2454
  var PADDING = 12;
2161
2455
  var SEP = "\u2028";
@@ -2411,35 +2705,36 @@ function underlineBareURLs(runs) {
2411
2705
  return out;
2412
2706
  });
2413
2707
  }
2414
- function face(r) {
2415
- return r.bold ? r.italic ? "boldItalic" : "bold" : r.italic ? "italic" : "regular";
2708
+ function famOf(r, fam) {
2709
+ return r.mono ? families[DEFAULT_FAMILY] : fam;
2416
2710
  }
2417
- function charWidth(ch, r) {
2418
- if (r.mono && fallbackMetrics[ch] === void 0) return monoAdvance * r.size;
2419
- const f = fonts[face(r)];
2420
- return (f.w[ch] ?? fonts.regular.w[ch] ?? f.w["n"]) * r.size / 1e3;
2711
+ function charWidth(ch, r, fam) {
2712
+ const f = famOf(r, fam);
2713
+ if (r.mono && f.fallback[ch] === void 0) return monoAdvance * r.size;
2714
+ const face = f.faces[faceOf(f, r.bold, r.italic)];
2715
+ return (face.w[ch] ?? f.faces.regular.w[ch] ?? face.w["n"]) * r.size / 1e3;
2421
2716
  }
2422
- function kern(a, b, r) {
2717
+ function kern(a, b, r, fam) {
2423
2718
  if (r.mono) return 0;
2424
- return (fonts[face(r)].k[a + b] ?? 0) * r.size / 1e3;
2719
+ return (fam.faces[faceOf(fam, r.bold, r.italic)].k[a + b] ?? 0) * r.size / 1e3;
2425
2720
  }
2426
- function metrics(ch, r) {
2427
- const fb = fallbackMetrics[ch];
2721
+ function metrics(ch, r, fam) {
2722
+ const fb = famOf(r, fam).fallback[ch];
2428
2723
  if (fb) return [fb[0] * r.size, fb[1] * r.size, fb[2] * r.size];
2429
2724
  if (r.mono) return [monoAscent * r.size, monoDescent * r.size, 0];
2430
- if (r.bold && r.italic) return [boldItalicAscent * r.size, boldItalicDescent * r.size, boldItalicLeading * r.size];
2431
- if (r.bold) return [boldAscent * r.size, boldDescent * r.size, boldLeading * r.size];
2432
- if (r.italic) return [italicAscent * r.size, italicDescent * r.size, italicLeading * r.size];
2433
- return [ascent * r.size, descent * r.size, leading * r.size];
2725
+ const m = fam.faces[faceOf(fam, r.bold, r.italic)];
2726
+ return [m.ascent * r.size, m.descent * r.size, m.leading * r.size];
2434
2727
  }
2435
2728
  var Builder = class {
2436
- constructor(fontSize, width) {
2729
+ constructor(fontSize, width, fam) {
2437
2730
  __publicField(this, "paras", []);
2438
2731
  __publicField(this, "nextSpacing", null);
2439
2732
  __publicField(this, "fontSize");
2440
2733
  __publicField(this, "width");
2734
+ __publicField(this, "fam");
2441
2735
  this.fontSize = fontSize;
2442
2736
  this.width = width;
2737
+ this.fam = fam;
2443
2738
  }
2444
2739
  get gap() {
2445
2740
  return this.fontSize * 0.5;
@@ -2447,13 +2742,13 @@ var Builder = class {
2447
2742
  spacing(normal) {
2448
2743
  return this.paras.length === 0 ? 0 : this.nextSpacing ?? normal;
2449
2744
  }
2450
- run(i, size, alpha, base = {}) {
2745
+ run(i, size, alpha, base2 = {}) {
2451
2746
  const mono = !!i.mono;
2452
2747
  return {
2453
2748
  text: i.text,
2454
2749
  size: mono ? size * 0.9 : size,
2455
- bold: !!(i.bold || base.bold),
2456
- italic: !!(i.italic || base.italic),
2750
+ bold: !!(i.bold || base2.bold),
2751
+ italic: !!(i.italic || base2.italic),
2457
2752
  mono,
2458
2753
  strike: !!i.strike,
2459
2754
  underline: !!i.link,
@@ -2486,7 +2781,7 @@ var Builder = class {
2486
2781
  break;
2487
2782
  case "list": {
2488
2783
  const markers = b.items.map((it, i) => it.checkbox === true ? "\u2611" : it.checkbox === false ? "\u2610" : b.ordered !== null ? `${b.ordered + i}.` : ctx.listDepth % 2 === 0 ? "\u2022" : "\u25E6");
2489
- const plain = (s) => measureRun({ text: s, size: this.fontSize, bold: false, italic: false, mono: false, strike: false, underline: false, alpha: 1 });
2784
+ const plain = (s) => measureRun({ text: s, size: this.fontSize, bold: false, italic: false, mono: false, strike: false, underline: false, alpha: 1 }, this.fam);
2490
2785
  const widest = Math.max(0, ...markers.map(plain));
2491
2786
  const hang = ctx.indent + Math.max(widest + this.fontSize * 0.45, this.fontSize * 1.2);
2492
2787
  b.items.forEach((item, i) => {
@@ -2531,7 +2826,7 @@ var Builder = class {
2531
2826
  const widths = (size2) => {
2532
2827
  const w2 = new Array(columns).fill(0);
2533
2828
  for (const row of rows) row.cells.forEach((c, i) => {
2534
- if (i < columns) w2[i] = Math.max(w2[i], cell(c, row.header, size2).reduce((s, r) => s + measureRun(r), 0));
2829
+ if (i < columns) w2[i] = Math.max(w2[i], cell(c, row.header, size2).reduce((s, r) => s + measureRun(r, this.fam), 0));
2535
2830
  });
2536
2831
  return w2;
2537
2832
  };
@@ -2575,17 +2870,17 @@ var Builder = class {
2575
2870
  });
2576
2871
  }
2577
2872
  };
2578
- function measureRun(r) {
2873
+ function measureRun(r, fam) {
2579
2874
  let w = 0, prev = "";
2580
2875
  for (const ch of r.text) {
2581
- w += charWidth(ch, r);
2582
- if (prev) w += kern(prev, ch, r);
2876
+ w += charWidth(ch, r, fam);
2877
+ if (prev) w += kern(prev, ch, r, fam);
2583
2878
  prev = ch;
2584
2879
  }
2585
2880
  return w;
2586
2881
  }
2587
2882
  var TAB_INTERVAL = 28;
2588
- function layoutLines(paras, width, height, fontSize) {
2883
+ function layoutLines(paras, width, height, fontSize, fam) {
2589
2884
  const lines = [];
2590
2885
  let baseline = 0;
2591
2886
  let prev = null;
@@ -2619,7 +2914,7 @@ function layoutLines(paras, width, height, fontSize) {
2619
2914
  let seg = 0, prevCh = "";
2620
2915
  for (let q = end + 1; q < chars.length && chars[q].ch !== " " && chars[q].ch !== "\n" && chars[q].ch !== SEP; q++) {
2621
2916
  const rr = runs[chars[q].run];
2622
- seg += charWidth(chars[q].ch, rr) + (prevCh ? kern(prevCh, chars[q].ch, rr) : 0);
2917
+ seg += charWidth(chars[q].ch, rr, fam) + (prevCh ? kern(prevCh, chars[q].ch, rr, fam) : 0);
2623
2918
  prevCh = chars[q].ch;
2624
2919
  }
2625
2920
  tx = Math.max(x, stop.align === "right" ? stop.x - seg : stop.x - seg / 2);
@@ -2630,12 +2925,12 @@ function layoutLines(paras, width, height, fontSize) {
2630
2925
  continue;
2631
2926
  }
2632
2927
  const prevGlyph = glyphs[glyphs.length - 1];
2633
- const kx = prevGlyph && prevGlyph.run === run && prevGlyph.ch !== " " ? kern(prevGlyph.ch, ch, r) : 0;
2928
+ const kx = prevGlyph && prevGlyph.run === run && prevGlyph.ch !== " " ? kern(prevGlyph.ch, ch, r, fam) : 0;
2634
2929
  if (prevGlyph) {
2635
2930
  prevGlyph.w += kx;
2636
2931
  x += kx;
2637
2932
  }
2638
- const w = charWidth(ch, r);
2933
+ const w = charWidth(ch, r, fam);
2639
2934
  if (ch !== " " && x + w > maxX2 + 0.01 && glyphs.some((g) => g.ch !== " ")) {
2640
2935
  if (lastSpace >= 0) {
2641
2936
  glyphs.length = lastSpace + 1;
@@ -2650,17 +2945,17 @@ function layoutLines(paras, width, height, fontSize) {
2650
2945
  }
2651
2946
  if (glyphs.length === 0 && end === k && k < chars.length) {
2652
2947
  const { ch, run } = chars[k];
2653
- glyphs.push({ ch, run, x: start, w: charWidth(ch, runs[run]) });
2948
+ glyphs.push({ ch, run, x: start, w: charWidth(ch, runs[run], fam) });
2654
2949
  end = k + 1;
2655
2950
  }
2656
2951
  let asc = 0, desc = 0, lead = 0;
2657
2952
  for (const g of glyphs) {
2658
- const [a, d, l] = metrics(g.ch, runs[g.run]);
2953
+ const [a, d, l] = metrics(g.ch, runs[g.run], fam);
2659
2954
  asc = Math.max(asc, a);
2660
2955
  desc = Math.max(desc, d);
2661
2956
  lead = Math.max(lead, l);
2662
2957
  }
2663
- if (glyphs.length === 0) [asc, desc, lead] = metrics(" ", runs[0] ?? { text: " ", size: fontSize, bold: false, italic: false, mono: false, strike: false, underline: false, alpha: 1 });
2958
+ if (glyphs.length === 0) [asc, desc, lead] = metrics(" ", runs[0] ?? { text: " ", size: fontSize, bold: false, italic: false, mono: false, strike: false, underline: false, alpha: 1 }, fam);
2664
2959
  baseline = prev ? baseline + Math.round(prev.desc) + Math.round(prev.lead) + (firstLine ? p.spacing : 0) + Math.round(asc) : Math.round(asc);
2665
2960
  if (baseline + desc > height + 0.5) return;
2666
2961
  const line2 = { glyphs, asc, desc, lead, baseline, para: p, first: firstLine };
@@ -2679,9 +2974,10 @@ function layoutLines(paras, width, height, fontSize) {
2679
2974
  function noteMarkup(source, e) {
2680
2975
  const rect2 = textRect({ x: e.x, y: e.y, width: e.width, height: e.height });
2681
2976
  if (!(rect2.width > 1 && rect2.height > 1)) return "";
2682
- const b = new Builder(e.style.fontSize, rect2.width);
2977
+ const fam = familyMetrics(e.style.font);
2978
+ const b = new Builder(e.style.fontSize, rect2.width, fam);
2683
2979
  for (const block of parseBlocks(source)) b.block(block, { indent: 0, marker: null, quote: null, listDepth: 0 });
2684
- const lines = layoutLines(b.paras, rect2.width, rect2.height, e.style.fontSize);
2980
+ const lines = layoutLines(b.paras, rect2.width, rect2.height, e.style.fontSize, fam);
2685
2981
  const ink = color(e.style.stroke);
2686
2982
  let s = "";
2687
2983
  const marks = [];
@@ -2700,8 +2996,8 @@ function noteMarkup(source, e) {
2700
2996
  const r = gs[i].r;
2701
2997
  let j = i;
2702
2998
  let text = "";
2703
- const font = fontOf(gs[i].ch);
2704
- while (j < gs.length && sameStyle(gs[j].r, r) && gs[j].ch !== " " && fontOf(gs[j].ch) === font) {
2999
+ const font = fontOf(gs[i].ch, famOf(r, fam));
3000
+ while (j < gs.length && sameStyle(gs[j].r, r) && gs[j].ch !== " " && fontOf(gs[j].ch, famOf(r, fam)) === font) {
2705
3001
  text += gs[j].ch;
2706
3002
  j++;
2707
3003
  }
@@ -2709,20 +3005,21 @@ function noteMarkup(source, e) {
2709
3005
  if (shown.trim() !== "") {
2710
3006
  let a = `font-size="${fmt(r.size)}"`;
2711
3007
  if (r.mono) a += ` font-family="Menlo, Consolas, monospace"`;
2712
- if (r.bold) a += ` font-weight="bold"`;
2713
- if (r.italic) a += ` font-style="italic"`;
3008
+ const face = r.mono ? "regular" : faceOf(fam, r.bold, r.italic);
3009
+ if (r.mono ? r.bold : face === "bold" || face === "boldItalic") a += ` font-weight="bold"`;
3010
+ if (r.mono ? r.italic : face === "italic" || face === "boldItalic") a += ` font-style="italic"`;
2714
3011
  if (r.underline) a += ` text-decoration="underline"`;
2715
3012
  if (r.alpha < 1) a += ` fill-opacity="${fmt(r.alpha * e.style.stroke.a)}"`;
2716
3013
  spans += `<tspan x="${fmt(rect2.x + gs[i].x)}" ${a}>${escapeXML(shown)}</tspan>`;
2717
3014
  }
2718
3015
  if (r.strike && j > i) {
2719
- const y = l.baseline - metrics(gs[i].ch, r)[0] * 0.32;
3016
+ const y = l.baseline - metrics(gs[i].ch, r, fam)[0] * 0.32;
2720
3017
  marks.push([rect2.x + gs[i].x, rect2.y + y, rect2.x + gs[j - 1].x + gs[j - 1].w, rect2.y + y]);
2721
3018
  }
2722
3019
  if (j === i) j++;
2723
3020
  i = j;
2724
3021
  }
2725
- if (spans) s += `<text y="${fmt(rect2.y + l.baseline)}" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" fill="${ink}" xml:space="preserve">${spans}</text>
3022
+ if (spans) s += `<text y="${fmt(rect2.y + l.baseline)}" font-family="${cssFamily(e.style.font)}" fill="${ink}" xml:space="preserve">${spans}</text>
2726
3023
  `;
2727
3024
  }
2728
3025
  const width = fmt(Math.max(1, e.style.fontSize / 14));
@@ -2732,8 +3029,8 @@ function noteMarkup(source, e) {
2732
3029
  }
2733
3030
  return s;
2734
3031
  }
2735
- function fontOf(ch) {
2736
- return fallbackMetrics[ch] ? `fb:${ch}` : "";
3032
+ function fontOf(ch, fam) {
3033
+ return fam.fallback[ch] ? `fb:${ch}` : "";
2737
3034
  }
2738
3035
  function sameStyle(a, b) {
2739
3036
  return a === b || a.size === b.size && a.bold === b.bold && a.italic === b.italic && a.mono === b.mono && a.strike === b.strike && a.underline === b.underline && a.alpha === b.alpha;
@@ -2815,7 +3112,7 @@ function svgParts(page, background, fixed, links = false) {
2815
3112
  if (!visible.has(e.layerID)) continue;
2816
3113
  const alpha = Math.min(Math.max(e.style.opacity ?? 1, 0), 1);
2817
3114
  if (alpha <= 0) continue;
2818
- let body = svgElement(e, index, bg);
3115
+ let body = svgElement(e, index, bg, d);
2819
3116
  if (angle(e) !== 0 && e.kind !== "connector") {
2820
3117
  body = `<g transform="rotate(${fmt(angle(e) * 180 / Math.PI)} ${fmt(midX(frame(e)))} ${fmt(midY(frame(e)))})">
2821
3118
  ${body}</g>
@@ -2839,7 +3136,7 @@ function svg(page, background = { r: 1, g: 1, b: 1, a: 1 }, fixed) {
2839
3136
  function labelRect(e, index) {
2840
3137
  const m = midpoint(e, index);
2841
3138
  const text = e.text ?? "";
2842
- const size = textSize(text === "" ? "Label" : text, e.style.fontSize, 200);
3139
+ const size = textSize(text === "" ? "Label" : text, e.style.fontSize, 200, e.style.font);
2843
3140
  const w = Math.max(size.width + 12, 44), h = size.height + 6;
2844
3141
  return { x: m.x - w / 2, y: m.y - h / 2, width: w, height: h };
2845
3142
  }
@@ -2850,7 +3147,7 @@ function typed(s, progress) {
2850
3147
  function revealProgress(e) {
2851
3148
  return e.reveal !== null && e.reveal < 1 ? Math.max(0, e.reveal) : null;
2852
3149
  }
2853
- function svgElement(e, index, labelBackground) {
3150
+ function svgElement(e, index, labelBackground, page) {
2854
3151
  const stroke = color(e.style.stroke);
2855
3152
  let strokeAttrs = `stroke="${stroke}" stroke-width="${fmt(e.style.strokeWidth)}" stroke-linecap="round" stroke-linejoin="round"`;
2856
3153
  const dash = dashPattern(e.style.dash, e.style.strokeWidth);
@@ -2861,7 +3158,7 @@ function svgElement(e, index, labelBackground) {
2861
3158
  if (r !== null) {
2862
3159
  if (e.kind === "text") text = typed(text ?? "", r);
2863
3160
  else if (e.kind === "connector") {
2864
- return `<path d="${connectorParts(e, index)[0].trimmed(r).data()}" fill="none" ${strokeAttrs}/>
3161
+ return `<path d="${connectorParts(e, index, page)[0].trimmed(r).data()}" fill="none" ${strokeAttrs}/>
2865
3162
  `;
2866
3163
  } else {
2867
3164
  return `<path d="${outline(e).trimmed(r).data()}" fill="none" ${strokeAttrs}/>
@@ -2870,7 +3167,7 @@ function svgElement(e, index, labelBackground) {
2870
3167
  }
2871
3168
  switch (e.kind) {
2872
3169
  case "connector": {
2873
- const [line2, filled2] = connectorParts(e, index);
3170
+ const [line2, filled2] = connectorParts(e, index, page);
2874
3171
  let s = `<path d="${line2.data()}" fill="none" ${strokeAttrs}/>
2875
3172
  `;
2876
3173
  if (!filled2.isEmpty) s += `<path d="${filled2.data()}" fill="${stroke}" stroke="none"/>
@@ -2953,7 +3250,7 @@ function textElement(text, f, e, centered) {
2953
3250
  const total = lineHeight * lines.length;
2954
3251
  const x = centered ? midX(f) : f.x;
2955
3252
  const top = centered ? midY(f) - total / 2 : f.y;
2956
- let s = `<text x="${fmt(x)}" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="${fmt(size)}" fill="${color(e.style.stroke)}"${centered ? ` text-anchor="middle"` : ""}>`;
3253
+ let s = `<text x="${fmt(x)}" font-family="${cssFamily(e.style.font)}" font-size="${fmt(size)}" fill="${color(labelColor(e))}"${centered ? ` text-anchor="middle"` : ""}>`;
2957
3254
  lines.forEach((line2, i) => {
2958
3255
  s += `<tspan x="${fmt(x)}" y="${fmt(top + lineHeight * (i + 0.8))}">${escapeXML(line2)}</tspan>`;
2959
3256
  });
@@ -3020,6 +3317,7 @@ var Playback = class {
3020
3317
  __publicField(this, "frame", -1);
3021
3318
  __publicField(this, "onFrame", null);
3022
3319
  this.page = options.clean ? withRoughness(page, 0) : page;
3320
+ addFonts(usedFonts(this.page));
3023
3321
  this.plan = plan(this.page);
3024
3322
  this.clicks = clickTargets(page, options.file);
3025
3323
  const table = symbolTable(this.page);
@@ -3181,16 +3479,16 @@ var Playback = class {
3181
3479
  const s = keys.map((k) => m2.get(k) ?? "").join("");
3182
3480
  return s === "" ? null : s;
3183
3481
  };
3184
- const base = join(normal) ?? "";
3482
+ const base2 = join(normal) ?? "";
3185
3483
  const instance = pose.elements.find((e) => e.id === o && e.kind === "symbol");
3186
3484
  const overLook = instance ? join(over) : join(hover);
3187
3485
  const downLook = instance ? join(down) : null;
3188
- const shownOver = overLook !== null && overLook !== base ? overLook : null;
3189
- const shownDown = downLook !== null && downLook !== (overLook ?? base) ? downLook : null;
3190
- if (!instance && shownOver === null) return { key: o, markup: base, button: false };
3486
+ const shownOver = overLook !== null && overLook !== base2 ? overLook : null;
3487
+ const shownDown = downLook !== null && downLook !== (overLook ?? base2) ? downLook : null;
3488
+ if (!instance && shownOver === null) return { key: o, markup: base2, button: false };
3191
3489
  const still2 = instance ? ` pointer-events="none"` : "";
3192
3490
  let m = `<g class="dottie-n"${still2}>
3193
- ${base}</g>
3491
+ ${base2}</g>
3194
3492
  `;
3195
3493
  if (shownOver !== null) m += `<g class="dottie-h"${still2}>
3196
3494
  ${shownOver}</g>
@@ -3601,6 +3899,7 @@ function inspectFrame(page, t) {
3601
3899
  d.strokeWidth = r4(e.style.strokeWidth);
3602
3900
  d.stroke = rgba2(e.style.stroke);
3603
3901
  d.fill = rgba2(e.style.fill);
3902
+ if (e.style.textColor !== null) d.textColor = rgba2(e.style.textColor);
3604
3903
  if (e.kind === "connector") {
3605
3904
  const [a, b] = endpoints(e, index);
3606
3905
  d.start = pt(a);
@@ -3644,9 +3943,10 @@ function render(source, options = {}) {
3644
3943
  function isFile(v) {
3645
3944
  return typeof v === "object" && v !== null && Array.isArray(v.pages) && Array.isArray(v.warnings);
3646
3945
  }
3647
- var VERSION = "0.6.1";
3946
+ var VERSION = "0.6.3";
3648
3947
  export {
3649
3948
  BOIL_DRAWINGS,
3949
+ BUNDLED_FONTS,
3650
3950
  DottieFormatError,
3651
3951
  DottiePlayer,
3652
3952
  KINDS,
@@ -3656,6 +3956,7 @@ export {
3656
3956
  Playback,
3657
3957
  SUPPORTED_VERSION,
3658
3958
  VERSION,
3959
+ addFonts,
3659
3960
  allowedURL,
3660
3961
  black,
3661
3962
  bounds,
@@ -3667,6 +3968,8 @@ export {
3667
3968
  cloneElement,
3668
3969
  definePlayer,
3669
3970
  elementIndex,
3971
+ fontFaces,
3972
+ fontFile,
3670
3973
  frameTimes,
3671
3974
  inkOnDark,
3672
3975
  inspect,
@@ -3685,6 +3988,7 @@ export {
3685
3988
  sameColor,
3686
3989
  sampleTimes,
3687
3990
  sceneAt,
3991
+ setFontBase,
3688
3992
  stableSortBy,
3689
3993
  still,
3690
3994
  svg,
@@ -3692,6 +3996,7 @@ export {
3692
3996
  themeNamed,
3693
3997
  themes,
3694
3998
  transientElements,
3999
+ usedFonts,
3695
4000
  webLink,
3696
4001
  withRoughness
3697
4002
  };