schematex 0.2.0 → 0.2.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.
Files changed (200) hide show
  1. package/README.md +1 -1
  2. package/dist/ai/ai-sdk.cjs +85 -0
  3. package/dist/ai/ai-sdk.cjs.map +1 -0
  4. package/dist/ai/ai-sdk.d.cts +30 -0
  5. package/dist/ai/ai-sdk.d.ts +30 -0
  6. package/dist/ai/ai-sdk.js +83 -0
  7. package/dist/ai/ai-sdk.js.map +1 -0
  8. package/dist/ai/index.cjs +60 -0
  9. package/dist/ai/index.cjs.map +1 -0
  10. package/dist/ai/index.d.cts +155 -0
  11. package/dist/ai/index.d.ts +155 -0
  12. package/dist/ai/index.js +23 -0
  13. package/dist/ai/index.js.map +1 -0
  14. package/dist/browser.cjs +22 -21
  15. package/dist/browser.cjs.map +1 -1
  16. package/dist/browser.js +20 -19
  17. package/dist/browser.js.map +1 -1
  18. package/dist/{chunk-HLYA4QBB.js → chunk-2BM3HJSK.js} +545 -101
  19. package/dist/chunk-2BM3HJSK.js.map +1 -0
  20. package/dist/{chunk-ZO77FHBF.cjs → chunk-2JDVJRR3.cjs} +14 -6
  21. package/dist/chunk-2JDVJRR3.cjs.map +1 -0
  22. package/dist/{chunk-TIGP2OEJ.js → chunk-2VNMKOUO.js} +20 -5
  23. package/dist/chunk-2VNMKOUO.js.map +1 -0
  24. package/dist/{chunk-ULERCTGS.cjs → chunk-3YZ6FPQW.cjs} +36 -30
  25. package/dist/chunk-3YZ6FPQW.cjs.map +1 -0
  26. package/dist/{chunk-GEPBET4L.js → chunk-45KP67RR.js} +14 -6
  27. package/dist/chunk-45KP67RR.js.map +1 -0
  28. package/dist/chunk-4QP37LD3.js +1112 -0
  29. package/dist/chunk-4QP37LD3.js.map +1 -0
  30. package/dist/{chunk-HKRYKEOV.cjs → chunk-4S2WILLW.cjs} +4 -4
  31. package/dist/{chunk-HKRYKEOV.cjs.map → chunk-4S2WILLW.cjs.map} +1 -1
  32. package/dist/{chunk-IMHR3S5H.cjs → chunk-5AEN2PLB.cjs} +17 -9
  33. package/dist/chunk-5AEN2PLB.cjs.map +1 -0
  34. package/dist/{chunk-SPIW4VWP.js → chunk-5YYAYW67.js} +3 -3
  35. package/dist/{chunk-SPIW4VWP.js.map → chunk-5YYAYW67.js.map} +1 -1
  36. package/dist/{chunk-CEV3GZA3.cjs → chunk-6LZJTAA3.cjs} +552 -108
  37. package/dist/chunk-6LZJTAA3.cjs.map +1 -0
  38. package/dist/{chunk-IY52OWPG.cjs → chunk-A5D2IMOX.cjs} +18 -10
  39. package/dist/chunk-A5D2IMOX.cjs.map +1 -0
  40. package/dist/{chunk-AMP2FFES.cjs → chunk-B37IKTI7.cjs} +229 -52
  41. package/dist/chunk-B37IKTI7.cjs.map +1 -0
  42. package/dist/{chunk-LKHWBDWZ.cjs → chunk-B6INLQBU.cjs} +17 -11
  43. package/dist/chunk-B6INLQBU.cjs.map +1 -0
  44. package/dist/{chunk-DTMCQXXC.cjs → chunk-COLTVQWR.cjs} +184 -16
  45. package/dist/chunk-COLTVQWR.cjs.map +1 -0
  46. package/dist/{chunk-S6VPECM3.cjs → chunk-D7EHZFK4.cjs} +20 -5
  47. package/dist/chunk-D7EHZFK4.cjs.map +1 -0
  48. package/dist/chunk-DNZFOCV7.js +796 -0
  49. package/dist/chunk-DNZFOCV7.js.map +1 -0
  50. package/dist/{chunk-ZGKEFVJQ.cjs → chunk-E65ITQXV.cjs} +188 -32
  51. package/dist/chunk-E65ITQXV.cjs.map +1 -0
  52. package/dist/{chunk-7WXAAVR3.js → chunk-FCGHV6ZK.js} +17 -9
  53. package/dist/chunk-FCGHV6ZK.js.map +1 -0
  54. package/dist/{chunk-A74ZCP5I.js → chunk-FE6GAUNW.js} +36 -30
  55. package/dist/chunk-FE6GAUNW.js.map +1 -0
  56. package/dist/{chunk-MXJ6FHSY.js → chunk-JDTB7IKL.js} +3 -3
  57. package/dist/{chunk-MXJ6FHSY.js.map → chunk-JDTB7IKL.js.map} +1 -1
  58. package/dist/{chunk-RQX53J6M.js → chunk-LR4X4ZRG.js} +180 -24
  59. package/dist/chunk-LR4X4ZRG.js.map +1 -0
  60. package/dist/{chunk-MRGS54WN.js → chunk-M5B2UUNW.js} +3 -3
  61. package/dist/{chunk-MRGS54WN.js.map → chunk-M5B2UUNW.js.map} +1 -1
  62. package/dist/{chunk-LXNFVHDT.cjs → chunk-MCFQAUQV.cjs} +21 -13
  63. package/dist/chunk-MCFQAUQV.cjs.map +1 -0
  64. package/dist/chunk-MOU5QRZY.cjs +1121 -0
  65. package/dist/chunk-MOU5QRZY.cjs.map +1 -0
  66. package/dist/{chunk-TPA36ULU.js → chunk-OC22GGQN.js} +223 -46
  67. package/dist/chunk-OC22GGQN.js.map +1 -0
  68. package/dist/{chunk-2OIW3MAE.js → chunk-PGALHQFF.js} +3 -3
  69. package/dist/{chunk-2OIW3MAE.js.map → chunk-PGALHQFF.js.map} +1 -1
  70. package/dist/{chunk-3M7QWADF.cjs → chunk-QSQX77S2.cjs} +4 -4
  71. package/dist/{chunk-3M7QWADF.cjs.map → chunk-QSQX77S2.cjs.map} +1 -1
  72. package/dist/{chunk-VP54YPOX.cjs → chunk-QXIGHMH2.cjs} +498 -177
  73. package/dist/chunk-QXIGHMH2.cjs.map +1 -0
  74. package/dist/{chunk-YO4GU6JX.js → chunk-RP5UATRA.js} +175 -7
  75. package/dist/chunk-RP5UATRA.js.map +1 -0
  76. package/dist/{chunk-M6AMNXQ7.js → chunk-S3RBKJM5.js} +478 -157
  77. package/dist/chunk-S3RBKJM5.js.map +1 -0
  78. package/dist/{chunk-JZGFSRVT.js → chunk-SN7NTZI6.js} +9 -7
  79. package/dist/chunk-SN7NTZI6.js.map +1 -0
  80. package/dist/{chunk-L6IHSTPP.js → chunk-U6L3FAML.js} +16 -10
  81. package/dist/chunk-U6L3FAML.js.map +1 -0
  82. package/dist/{chunk-5SH5NUDW.js → chunk-UGCUNADI.js} +21 -13
  83. package/dist/chunk-UGCUNADI.js.map +1 -0
  84. package/dist/chunk-ULYRO2KY.cjs +800 -0
  85. package/dist/chunk-ULYRO2KY.cjs.map +1 -0
  86. package/dist/{chunk-4HPT4BOI.cjs → chunk-WYFXOXVK.cjs} +4 -4
  87. package/dist/{chunk-4HPT4BOI.cjs.map → chunk-WYFXOXVK.cjs.map} +1 -1
  88. package/dist/{chunk-YKO7DY2F.cjs → chunk-X7RPFTTR.cjs} +13 -13
  89. package/dist/{chunk-YKO7DY2F.cjs.map → chunk-X7RPFTTR.cjs.map} +1 -1
  90. package/dist/{chunk-4TS5NB7L.js → chunk-YQANC7HQ.js} +3 -3
  91. package/dist/{chunk-4TS5NB7L.js.map → chunk-YQANC7HQ.js.map} +1 -1
  92. package/dist/{chunk-HAIBAF6J.cjs → chunk-Z3DE6S64.cjs} +10 -8
  93. package/dist/chunk-Z3DE6S64.cjs.map +1 -0
  94. package/dist/{chunk-IQIJ6WW6.js → chunk-ZNDIGQJD.js} +15 -7
  95. package/dist/chunk-ZNDIGQJD.js.map +1 -0
  96. package/dist/{chunk-PIQG2Z5N.cjs → chunk-ZNOD4VZT.cjs} +4 -4
  97. package/dist/{chunk-PIQG2Z5N.cjs.map → chunk-ZNOD4VZT.cjs.map} +1 -1
  98. package/dist/diagrams/blockdiagram/index.cjs +5 -5
  99. package/dist/diagrams/blockdiagram/index.d.cts +1 -1
  100. package/dist/diagrams/blockdiagram/index.d.ts +1 -1
  101. package/dist/diagrams/blockdiagram/index.js +1 -1
  102. package/dist/diagrams/circuit/index.cjs +8 -8
  103. package/dist/diagrams/circuit/index.d.cts +1 -1
  104. package/dist/diagrams/circuit/index.d.ts +1 -1
  105. package/dist/diagrams/circuit/index.js +2 -2
  106. package/dist/diagrams/ecomap/index.cjs +8 -7
  107. package/dist/diagrams/ecomap/index.d.cts +2 -2
  108. package/dist/diagrams/ecomap/index.d.ts +2 -2
  109. package/dist/diagrams/ecomap/index.js +3 -2
  110. package/dist/diagrams/entity/index.cjs +6 -6
  111. package/dist/diagrams/entity/index.d.cts +1 -1
  112. package/dist/diagrams/entity/index.d.ts +1 -1
  113. package/dist/diagrams/entity/index.js +2 -2
  114. package/dist/diagrams/fishbone/index.cjs +8 -8
  115. package/dist/diagrams/fishbone/index.d.cts +1 -1
  116. package/dist/diagrams/fishbone/index.d.ts +1 -1
  117. package/dist/diagrams/fishbone/index.js +2 -2
  118. package/dist/diagrams/flowchart/index.cjs +8 -8
  119. package/dist/diagrams/flowchart/index.d.cts +2 -2
  120. package/dist/diagrams/flowchart/index.d.ts +2 -2
  121. package/dist/diagrams/flowchart/index.js +2 -2
  122. package/dist/diagrams/genogram/index.cjs +10 -9
  123. package/dist/diagrams/genogram/index.d.cts +1 -1
  124. package/dist/diagrams/genogram/index.d.ts +1 -1
  125. package/dist/diagrams/genogram/index.js +3 -2
  126. package/dist/diagrams/ladder/index.cjs +6 -6
  127. package/dist/diagrams/ladder/index.d.cts +1 -1
  128. package/dist/diagrams/ladder/index.d.ts +1 -1
  129. package/dist/diagrams/ladder/index.js +2 -2
  130. package/dist/diagrams/logic/index.cjs +6 -6
  131. package/dist/diagrams/logic/index.d.cts +1 -1
  132. package/dist/diagrams/logic/index.d.ts +1 -1
  133. package/dist/diagrams/logic/index.js +2 -2
  134. package/dist/diagrams/orgchart/index.cjs +7 -7
  135. package/dist/diagrams/orgchart/index.d.cts +5 -2
  136. package/dist/diagrams/orgchart/index.d.ts +5 -2
  137. package/dist/diagrams/orgchart/index.js +2 -2
  138. package/dist/diagrams/pedigree/index.cjs +8 -7
  139. package/dist/diagrams/pedigree/index.d.cts +1 -1
  140. package/dist/diagrams/pedigree/index.d.ts +1 -1
  141. package/dist/diagrams/pedigree/index.js +3 -2
  142. package/dist/diagrams/phylo/index.cjs +7 -7
  143. package/dist/diagrams/phylo/index.d.cts +1 -1
  144. package/dist/diagrams/phylo/index.d.ts +1 -1
  145. package/dist/diagrams/phylo/index.js +2 -2
  146. package/dist/diagrams/sld/index.cjs +6 -6
  147. package/dist/diagrams/sld/index.d.cts +1 -1
  148. package/dist/diagrams/sld/index.d.ts +1 -1
  149. package/dist/diagrams/sld/index.js +2 -2
  150. package/dist/diagrams/sociogram/index.cjs +7 -6
  151. package/dist/diagrams/sociogram/index.d.cts +2 -1
  152. package/dist/diagrams/sociogram/index.d.ts +2 -1
  153. package/dist/diagrams/sociogram/index.js +3 -2
  154. package/dist/diagrams/timing/index.cjs +4 -4
  155. package/dist/diagrams/timing/index.d.cts +1 -1
  156. package/dist/diagrams/timing/index.d.ts +1 -1
  157. package/dist/diagrams/timing/index.js +1 -1
  158. package/dist/diagrams/venn/index.cjs +9 -9
  159. package/dist/diagrams/venn/index.d.cts +1 -1
  160. package/dist/diagrams/venn/index.d.ts +1 -1
  161. package/dist/diagrams/venn/index.js +2 -2
  162. package/dist/{index-ga04CTBI.d.ts → index-C97K-kuw.d.ts} +1 -1
  163. package/dist/{index-SSGpCggE.d.cts → index-lsSaw3E0.d.cts} +1 -1
  164. package/dist/index.cjs +50 -49
  165. package/dist/index.d.cts +2 -2
  166. package/dist/index.d.ts +2 -2
  167. package/dist/index.js +19 -18
  168. package/dist/react.cjs +20 -19
  169. package/dist/react.cjs.map +1 -1
  170. package/dist/react.js +19 -18
  171. package/dist/react.js.map +1 -1
  172. package/dist/{types-BcPhMdHd.d.cts → types-C4LnMEcB.d.cts} +58 -4
  173. package/dist/{types-BcPhMdHd.d.ts → types-C4LnMEcB.d.ts} +58 -4
  174. package/package.json +30 -7
  175. package/dist/chunk-5SH5NUDW.js.map +0 -1
  176. package/dist/chunk-7WXAAVR3.js.map +0 -1
  177. package/dist/chunk-A74ZCP5I.js.map +0 -1
  178. package/dist/chunk-AMP2FFES.cjs.map +0 -1
  179. package/dist/chunk-CEV3GZA3.cjs.map +0 -1
  180. package/dist/chunk-DTMCQXXC.cjs.map +0 -1
  181. package/dist/chunk-GEPBET4L.js.map +0 -1
  182. package/dist/chunk-HAIBAF6J.cjs.map +0 -1
  183. package/dist/chunk-HLYA4QBB.js.map +0 -1
  184. package/dist/chunk-IMHR3S5H.cjs.map +0 -1
  185. package/dist/chunk-IQIJ6WW6.js.map +0 -1
  186. package/dist/chunk-IY52OWPG.cjs.map +0 -1
  187. package/dist/chunk-JZGFSRVT.js.map +0 -1
  188. package/dist/chunk-L6IHSTPP.js.map +0 -1
  189. package/dist/chunk-LKHWBDWZ.cjs.map +0 -1
  190. package/dist/chunk-LXNFVHDT.cjs.map +0 -1
  191. package/dist/chunk-M6AMNXQ7.js.map +0 -1
  192. package/dist/chunk-RQX53J6M.js.map +0 -1
  193. package/dist/chunk-S6VPECM3.cjs.map +0 -1
  194. package/dist/chunk-TIGP2OEJ.js.map +0 -1
  195. package/dist/chunk-TPA36ULU.js.map +0 -1
  196. package/dist/chunk-ULERCTGS.cjs.map +0 -1
  197. package/dist/chunk-VP54YPOX.cjs.map +0 -1
  198. package/dist/chunk-YO4GU6JX.js.map +0 -1
  199. package/dist/chunk-ZGKEFVJQ.cjs.map +0 -1
  200. package/dist/chunk-ZO77FHBF.cjs.map +0 -1
@@ -1,5 +1,6 @@
1
- import { resolveGenogramTheme, STROKE_WIDTH, cssCustomProperties } from './chunk-TIGP2OEJ.js';
2
- import { title, text, group, el, rect, pattern, path, circle, defs, polygon, line, desc, svgRoot } from './chunk-KLJEK547.js';
1
+ import { parseLegendDirective, applyLegendOverrides, renderLegend } from './chunk-DNZFOCV7.js';
2
+ import { resolveGenogramTheme, STROKE_WIDTH, cssCustomProperties } from './chunk-2VNMKOUO.js';
3
+ import { title, text, group, pattern, path, circle, el, defs, polygon, rect, line, desc, svgRoot } from './chunk-KLJEK547.js';
3
4
 
4
5
  // src/diagrams/genogram/parser.ts
5
6
  var ParseError = class extends Error {
@@ -108,6 +109,7 @@ function parseGenogram(text2) {
108
109
  const individualsMap = /* @__PURE__ */ new Map();
109
110
  const relationships = [];
110
111
  const childSpecialProps = /* @__PURE__ */ new Map();
112
+ const legendOverrides = {};
111
113
  skipBlankAndComments(state);
112
114
  while (state.currentLine < state.lines.length) {
113
115
  skipBlankAndComments(state);
@@ -118,6 +120,10 @@ function parseGenogram(text2) {
118
120
  state.currentLine++;
119
121
  continue;
120
122
  }
123
+ if (parseLegendDirective(trimmed, legendOverrides)) {
124
+ state.currentLine++;
125
+ continue;
126
+ }
121
127
  const emotionalMatch = detectEmotionalOp(trimmed);
122
128
  if (emotionalMatch) {
123
129
  const { leftId, emotionalType, rightId: emRightId, directional, label: emLabel } = emotionalMatch;
@@ -243,11 +249,13 @@ function parseGenogram(text2) {
243
249
  });
244
250
  }
245
251
  }
252
+ const hasLegendOverrides = Object.keys(legendOverrides).length > 0 && Object.values(legendOverrides).some((v) => v !== void 0);
246
253
  return {
247
254
  type: "genogram",
248
255
  individuals: Array.from(individualsMap.values()),
249
256
  relationships,
250
- metadata: Object.keys(metadata).length > 0 ? metadata : void 0
257
+ metadata: Object.keys(metadata).length > 0 ? metadata : void 0,
258
+ legendOverrides: hasLegendOverrides ? legendOverrides : void 0
251
259
  };
252
260
  }
253
261
  function currentLineText(state) {
@@ -1148,96 +1156,30 @@ function getRequiredDefs(individuals, includeArrowMarker = false) {
1148
1156
  }
1149
1157
  }
1150
1158
  const children = [];
1151
- if (neededFills.has("half-left")) {
1152
- children.push(
1153
- el("clipPath", { id: "schematex-genogram-clip-half-left-rect" }, [
1154
- rect({ x: "0", y: "0", width: "50%", height: "100%" })
1155
- ]),
1156
- el("clipPath", { id: "schematex-genogram-clip-half-left-circle" }, [
1157
- rect({ x: "-50", y: "-50", width: "50", height: "100" })
1158
- ])
1159
- );
1160
- }
1161
- if (neededFills.has("half-right")) {
1162
- children.push(
1163
- el("clipPath", { id: "schematex-genogram-clip-half-right-rect" }, [
1164
- rect({ x: "50%", y: "0", width: "50%", height: "100%" })
1165
- ]),
1166
- el("clipPath", { id: "schematex-genogram-clip-half-right-circle" }, [
1167
- rect({ x: "0", y: "-50", width: "50", height: "100" })
1168
- ])
1169
- );
1170
- }
1171
- if (neededFills.has("half-bottom")) {
1172
- children.push(
1173
- el("clipPath", { id: "schematex-genogram-clip-half-bottom-rect" }, [
1174
- rect({ x: "0", y: "50%", width: "100%", height: "50%" })
1175
- ]),
1176
- el("clipPath", { id: "schematex-genogram-clip-half-bottom-circle" }, [
1177
- rect({ x: "-50", y: "0", width: "100", height: "50" })
1178
- ])
1179
- );
1180
- }
1181
- if (neededFills.has("quarter")) {
1182
- children.push(
1183
- el("clipPath", { id: "schematex-genogram-clip-quarter-rect" }, [
1184
- rect({ x: "0", y: "0", width: "50%", height: "50%" })
1185
- ]),
1186
- el("clipPath", { id: "schematex-genogram-clip-quarter-circle" }, [
1187
- rect({ x: "-50", y: "-50", width: "50", height: "50" })
1188
- ])
1189
- );
1190
- }
1191
- if (neededFills.has("half-top")) {
1192
- children.push(
1193
- el("clipPath", { id: "schematex-genogram-clip-half-top-rect" }, [
1194
- rect({ x: "0", y: "0", width: "100%", height: "50%" })
1195
- ]),
1196
- el("clipPath", { id: "schematex-genogram-clip-half-top-circle" }, [
1197
- rect({ x: "-50", y: "-50", width: "100", height: "50" })
1198
- ])
1199
- );
1200
- }
1201
- if (neededFills.has("quad-tl")) {
1202
- children.push(
1203
- el("clipPath", { id: "schematex-genogram-clip-quad-tl-rect" }, [
1204
- rect({ x: "0", y: "0", width: "50%", height: "50%" })
1205
- ]),
1206
- el("clipPath", { id: "schematex-genogram-clip-quad-tl-circle" }, [
1207
- rect({ x: "-50", y: "-50", width: "50", height: "50" })
1208
- ])
1209
- );
1210
- }
1211
- if (neededFills.has("quad-tr")) {
1212
- children.push(
1213
- el("clipPath", { id: "schematex-genogram-clip-quad-tr-rect" }, [
1214
- rect({ x: "50%", y: "0", width: "50%", height: "50%" })
1215
- ]),
1216
- el("clipPath", { id: "schematex-genogram-clip-quad-tr-circle" }, [
1217
- rect({ x: "0", y: "-50", width: "50", height: "50" })
1218
- ])
1219
- );
1220
- }
1221
- if (neededFills.has("quad-bl")) {
1222
- children.push(
1223
- el("clipPath", { id: "schematex-genogram-clip-quad-bl-rect" }, [
1224
- rect({ x: "0", y: "50%", width: "50%", height: "50%" })
1225
- ]),
1226
- el("clipPath", { id: "schematex-genogram-clip-quad-bl-circle" }, [
1227
- rect({ x: "-50", y: "0", width: "50", height: "50" })
1228
- ])
1229
- );
1230
- }
1231
- if (neededFills.has("quad-br")) {
1159
+ function quadClips(suffix, x, y, w, h) {
1160
+ const r = rect({ x, y, width: w, height: h });
1232
1161
  children.push(
1233
- el("clipPath", { id: "schematex-genogram-clip-quad-br-rect" }, [
1234
- rect({ x: "50%", y: "50%", width: "50%", height: "50%" })
1235
- ]),
1236
- el("clipPath", { id: "schematex-genogram-clip-quad-br-circle" }, [
1237
- rect({ x: "0", y: "0", width: "50", height: "50" })
1238
- ])
1162
+ el(
1163
+ "clipPath",
1164
+ { id: `schematex-genogram-clip-${suffix}-rect`, clipPathUnits: "objectBoundingBox" },
1165
+ [r]
1166
+ ),
1167
+ el(
1168
+ "clipPath",
1169
+ { id: `schematex-genogram-clip-${suffix}-circle`, clipPathUnits: "objectBoundingBox" },
1170
+ [r]
1171
+ )
1239
1172
  );
1240
1173
  }
1174
+ if (neededFills.has("half-left")) quadClips("half-left", 0, 0, 0.5, 1);
1175
+ if (neededFills.has("half-right")) quadClips("half-right", 0.5, 0, 0.5, 1);
1176
+ if (neededFills.has("half-top")) quadClips("half-top", 0, 0, 1, 0.5);
1177
+ if (neededFills.has("half-bottom")) quadClips("half-bottom", 0, 0.5, 1, 0.5);
1178
+ if (neededFills.has("quarter")) quadClips("quarter", 0, 0, 0.5, 0.5);
1179
+ if (neededFills.has("quad-tl")) quadClips("quad-tl", 0, 0, 0.5, 0.5);
1180
+ if (neededFills.has("quad-tr")) quadClips("quad-tr", 0.5, 0, 0.5, 0.5);
1181
+ if (neededFills.has("quad-bl")) quadClips("quad-bl", 0, 0.5, 0.5, 0.5);
1182
+ if (neededFills.has("quad-br")) quadClips("quad-br", 0.5, 0.5, 0.5, 0.5);
1241
1183
  if (neededFills.has("striped")) {
1242
1184
  children.push(
1243
1185
  pattern(
@@ -1418,6 +1360,469 @@ function conditionFillElement(sex, half, cond) {
1418
1360
  }
1419
1361
  }
1420
1362
 
1363
+ // src/diagrams/genogram/legend.ts
1364
+ var EMOTIONAL_TYPES2 = /* @__PURE__ */ new Set([
1365
+ "harmony",
1366
+ "close",
1367
+ "bestfriends",
1368
+ "love",
1369
+ "inlove",
1370
+ "friendship",
1371
+ "hostile",
1372
+ "conflict",
1373
+ "enmity",
1374
+ "distant-hostile",
1375
+ "cutoff",
1376
+ "close-hostile",
1377
+ "fused",
1378
+ "fused-hostile",
1379
+ "distant",
1380
+ "normal",
1381
+ "nevermet",
1382
+ "abuse",
1383
+ "physical-abuse",
1384
+ "emotional-abuse",
1385
+ "sexual-abuse",
1386
+ "neglect",
1387
+ "manipulative",
1388
+ "controlling",
1389
+ "jealous",
1390
+ "focused",
1391
+ "focused-neg",
1392
+ "distrust",
1393
+ "admirer",
1394
+ "limerence"
1395
+ ]);
1396
+ var STRUCTURAL_TYPES = /* @__PURE__ */ new Set([
1397
+ "married",
1398
+ "divorced",
1399
+ "separated",
1400
+ "engaged",
1401
+ "cohabiting",
1402
+ "domestic-partnership",
1403
+ "consanguineous",
1404
+ "parent-child",
1405
+ "adopted",
1406
+ "foster",
1407
+ "twin-identical",
1408
+ "twin-fraternal"
1409
+ ]);
1410
+ var HERITAGE_PALETTE = [
1411
+ "#2563eb",
1412
+ "#059669",
1413
+ "#d97706",
1414
+ "#dc2626",
1415
+ "#7c3aed",
1416
+ "#0891b2",
1417
+ "#ca8a04",
1418
+ "#db2777"
1419
+ ];
1420
+ var SECTIONS = [
1421
+ { id: "symbols", title: "Symbols" },
1422
+ { id: "structural", title: "Structural" },
1423
+ { id: "relationships", title: "Relationships" },
1424
+ { id: "conditions", title: "Conditions" },
1425
+ { id: "heritage", title: "Heritage" },
1426
+ { id: "markers", title: "Markers" }
1427
+ ];
1428
+ function buildGenogramLegend(ast, theme) {
1429
+ const items = [];
1430
+ items.push(...buildSymbolItems(ast.individuals, theme));
1431
+ items.push(...buildStructuralItems(ast.relationships, theme));
1432
+ items.push(...buildRelationshipItems(ast.relationships));
1433
+ items.push(...buildConditionItems(ast.individuals));
1434
+ items.push(...buildHeritageItems(ast.individuals));
1435
+ items.push(...buildMarkerItems(ast.individuals, theme));
1436
+ return {
1437
+ mode: "auto",
1438
+ title: "Legend",
1439
+ position: "bottom-inline",
1440
+ columns: 1,
1441
+ sections: SECTIONS,
1442
+ items
1443
+ };
1444
+ }
1445
+ var OBVIOUS_SEX = /* @__PURE__ */ new Set(["male", "female"]);
1446
+ function buildSymbolItems(individuals, theme) {
1447
+ const items = [];
1448
+ const sexUsed = /* @__PURE__ */ new Set();
1449
+ const statusUsed = /* @__PURE__ */ new Set();
1450
+ for (const ind of individuals) {
1451
+ sexUsed.add(ind.sex);
1452
+ if (ind.status && ind.status !== "alive") statusUsed.add(ind.status);
1453
+ }
1454
+ const sexOrder = [
1455
+ "unknown",
1456
+ "other",
1457
+ "nonbinary",
1458
+ "intersex"
1459
+ ];
1460
+ for (const s of sexOrder) {
1461
+ if (!sexUsed.has(s)) continue;
1462
+ if (OBVIOUS_SEX.has(s)) continue;
1463
+ items.push({
1464
+ key: `sex.${s}`,
1465
+ label: sexLabel(s),
1466
+ kind: "shape",
1467
+ shape: sexShape(s),
1468
+ fill: theme ? sexFill(s, theme) : void 0,
1469
+ color: theme?.stroke,
1470
+ section: "symbols"
1471
+ });
1472
+ }
1473
+ const statusOrder = [
1474
+ "deceased",
1475
+ "stillborn",
1476
+ "miscarriage",
1477
+ "abortion",
1478
+ "pregnancy",
1479
+ "sab",
1480
+ "tab",
1481
+ "ectopic"
1482
+ ];
1483
+ for (const st of statusOrder) {
1484
+ if (!statusUsed.has(st)) continue;
1485
+ items.push({
1486
+ key: `status.${st}`,
1487
+ label: statusLabel(st),
1488
+ kind: "marker",
1489
+ marker: statusMarker(st),
1490
+ color: theme?.deceasedMark,
1491
+ section: "symbols"
1492
+ });
1493
+ }
1494
+ return items;
1495
+ }
1496
+ function sexFill(s, theme) {
1497
+ switch (s) {
1498
+ case "male":
1499
+ return theme.maleFill;
1500
+ case "female":
1501
+ return theme.femaleFill;
1502
+ default:
1503
+ return theme.unknownFill;
1504
+ }
1505
+ }
1506
+ function sexShape(s) {
1507
+ switch (s) {
1508
+ case "male":
1509
+ return "square";
1510
+ case "female":
1511
+ return "circle";
1512
+ case "unknown":
1513
+ return "diamond";
1514
+ case "other":
1515
+ case "nonbinary":
1516
+ return "diamond";
1517
+ case "intersex":
1518
+ return "diamond";
1519
+ default:
1520
+ return "square";
1521
+ }
1522
+ }
1523
+ function sexLabel(s) {
1524
+ switch (s) {
1525
+ case "male":
1526
+ return "Male";
1527
+ case "female":
1528
+ return "Female";
1529
+ case "unknown":
1530
+ return "Unknown";
1531
+ case "other":
1532
+ return "Other";
1533
+ case "nonbinary":
1534
+ return "Non-binary";
1535
+ case "intersex":
1536
+ return "Intersex";
1537
+ default:
1538
+ return s;
1539
+ }
1540
+ }
1541
+ function statusMarker(s) {
1542
+ switch (s) {
1543
+ case "deceased":
1544
+ case "stillborn":
1545
+ return "X";
1546
+ case "miscarriage":
1547
+ case "sab":
1548
+ case "tab":
1549
+ case "abortion":
1550
+ case "ectopic":
1551
+ return "slash";
1552
+ default:
1553
+ return "dot";
1554
+ }
1555
+ }
1556
+ function statusLabel(s) {
1557
+ switch (s) {
1558
+ case "deceased":
1559
+ return "Deceased";
1560
+ case "stillborn":
1561
+ return "Stillborn";
1562
+ case "miscarriage":
1563
+ return "Miscarriage";
1564
+ case "abortion":
1565
+ return "Abortion";
1566
+ case "pregnancy":
1567
+ return "Pregnancy";
1568
+ case "sab":
1569
+ return "Spontaneous abortion";
1570
+ case "tab":
1571
+ return "Therapeutic abortion";
1572
+ case "ectopic":
1573
+ return "Ectopic pregnancy";
1574
+ default:
1575
+ return s;
1576
+ }
1577
+ }
1578
+ var OBVIOUS_STRUCTURAL = /* @__PURE__ */ new Set([
1579
+ "married",
1580
+ // single horizontal line — universal McGoldrick
1581
+ "parent-child"
1582
+ // single vertical line — universal
1583
+ ]);
1584
+ function buildStructuralItems(rels, theme) {
1585
+ const used = /* @__PURE__ */ new Set();
1586
+ for (const r of rels) {
1587
+ if (STRUCTURAL_TYPES.has(r.type)) used.add(r.type);
1588
+ }
1589
+ const order = [
1590
+ "divorced",
1591
+ "separated",
1592
+ "engaged",
1593
+ "cohabiting",
1594
+ "domestic-partnership",
1595
+ "consanguineous",
1596
+ "adopted",
1597
+ "foster",
1598
+ "twin-identical",
1599
+ "twin-fraternal"
1600
+ ];
1601
+ const items = [];
1602
+ for (const t of order) {
1603
+ if (!used.has(t)) continue;
1604
+ if (OBVIOUS_STRUCTURAL.has(t)) continue;
1605
+ items.push(structuralItem(t, theme));
1606
+ }
1607
+ return items;
1608
+ }
1609
+ function structuralItem(t, theme) {
1610
+ const base = {
1611
+ key: t,
1612
+ label: humanize(t),
1613
+ kind: "line",
1614
+ color: theme?.stroke,
1615
+ section: "structural",
1616
+ pattern: "solid"
1617
+ };
1618
+ switch (t) {
1619
+ case "divorced":
1620
+ return { ...base, kind: "edge", marker: "X", pattern: "solid" };
1621
+ case "separated":
1622
+ return { ...base, kind: "edge", marker: "slash", pattern: "solid" };
1623
+ case "engaged":
1624
+ case "cohabiting":
1625
+ case "adopted":
1626
+ case "foster":
1627
+ return { ...base, pattern: "dashed" };
1628
+ case "consanguineous":
1629
+ return { ...base, pattern: "double" };
1630
+ case "twin-identical":
1631
+ case "twin-fraternal":
1632
+ return { ...base, pattern: "solid" };
1633
+ default:
1634
+ return base;
1635
+ }
1636
+ }
1637
+ function buildRelationshipItems(rels) {
1638
+ const used = /* @__PURE__ */ new Set();
1639
+ for (const r of rels) {
1640
+ if (EMOTIONAL_TYPES2.has(r.type)) used.add(r.type);
1641
+ }
1642
+ const order = [
1643
+ "harmony",
1644
+ "close",
1645
+ "bestfriends",
1646
+ "love",
1647
+ "inlove",
1648
+ "friendship",
1649
+ "hostile",
1650
+ "conflict",
1651
+ "enmity",
1652
+ "distant-hostile",
1653
+ "cutoff",
1654
+ "close-hostile",
1655
+ "fused",
1656
+ "fused-hostile",
1657
+ "distant",
1658
+ "normal",
1659
+ "nevermet",
1660
+ "abuse",
1661
+ "physical-abuse",
1662
+ "emotional-abuse",
1663
+ "sexual-abuse",
1664
+ "neglect",
1665
+ "manipulative",
1666
+ "controlling",
1667
+ "jealous",
1668
+ "focused",
1669
+ "focused-neg",
1670
+ "distrust",
1671
+ "admirer",
1672
+ "limerence"
1673
+ ];
1674
+ const items = [];
1675
+ for (const t of order) {
1676
+ if (!used.has(t)) continue;
1677
+ items.push({
1678
+ key: t,
1679
+ label: humanize(t),
1680
+ kind: "line",
1681
+ color: emotionalColor(t),
1682
+ pattern: emotionalPattern(t),
1683
+ strokeWidth: emotionalStrokeWidth(t),
1684
+ section: "relationships"
1685
+ });
1686
+ }
1687
+ return items;
1688
+ }
1689
+ function emotionalColor(t) {
1690
+ if (["harmony", "close", "bestfriends", "love", "inlove", "friendship"].includes(t)) return "#4caf50";
1691
+ if (["hostile", "conflict", "enmity", "distant-hostile", "cutoff"].includes(t)) return "#e53935";
1692
+ if (["close-hostile", "fused", "fused-hostile"].includes(t)) return "#9c27b0";
1693
+ if (["distant", "normal", "nevermet"].includes(t)) return "#9e9e9e";
1694
+ if (["abuse", "physical-abuse", "emotional-abuse", "sexual-abuse", "neglect"].includes(t)) return "#b71c1c";
1695
+ if (["manipulative", "controlling", "jealous"].includes(t)) return "#e65100";
1696
+ return "#1565c0";
1697
+ }
1698
+ function emotionalPattern(t) {
1699
+ if (["hostile", "conflict", "enmity", "distant-hostile", "close-hostile", "fused-hostile"].includes(t)) return "zigzag";
1700
+ if (["distant", "nevermet"].includes(t)) return "dashed";
1701
+ if (t === "cutoff") return "broken";
1702
+ return "solid";
1703
+ }
1704
+ function emotionalStrokeWidth(t) {
1705
+ if (["fused", "fused-hostile", "bestfriends"].includes(t)) return 4;
1706
+ if (["close", "close-hostile", "love", "inlove"].includes(t)) return 3;
1707
+ return 2;
1708
+ }
1709
+ function buildConditionItems(individuals) {
1710
+ const seen = /* @__PURE__ */ new Map();
1711
+ for (const ind of individuals) {
1712
+ if (!ind.conditions) continue;
1713
+ for (const c of ind.conditions) {
1714
+ if (seen.has(c.label)) continue;
1715
+ const color = c.color ?? defaultCategoryColor(c.category);
1716
+ const isFull = c.fill === "full";
1717
+ seen.set(c.label, {
1718
+ key: c.label,
1719
+ label: humanize(c.label),
1720
+ kind: isFull ? "fill" : "fill-pattern",
1721
+ color,
1722
+ shape: isFull ? void 0 : c.fill,
1723
+ section: "conditions"
1724
+ });
1725
+ }
1726
+ }
1727
+ return Array.from(seen.values());
1728
+ }
1729
+ function defaultCategoryColor(cat) {
1730
+ if (!cat) return "#9ca3af";
1731
+ const map = {
1732
+ cardiovascular: "#dc2626",
1733
+ cancer: "#a21caf",
1734
+ diabetes: "#d97706",
1735
+ "mental-health": "#2563eb",
1736
+ depression: "#1d4ed8",
1737
+ anxiety: "#0ea5e9",
1738
+ bipolar: "#6366f1",
1739
+ ptsd: "#475569",
1740
+ "substance-alcohol": "#92400e",
1741
+ "substance-drugs": "#7c2d12",
1742
+ "substance-tobacco": "#854d0e",
1743
+ neurological: "#7e22ce",
1744
+ respiratory: "#0891b2",
1745
+ autoimmune: "#be185d",
1746
+ genetic: "#0f766e",
1747
+ reproductive: "#db2777",
1748
+ "eating-disorder": "#9333ea",
1749
+ "learning-developmental": "#0369a1",
1750
+ kidney: "#b45309",
1751
+ "liver-gi": "#ca8a04",
1752
+ obesity: "#ea580c",
1753
+ other: "#9ca3af"
1754
+ };
1755
+ return map[cat] ?? "#9ca3af";
1756
+ }
1757
+ function buildHeritageItems(individuals) {
1758
+ const all = /* @__PURE__ */ new Set();
1759
+ for (const ind of individuals) {
1760
+ if (!ind.heritage) continue;
1761
+ for (const h of ind.heritage) all.add(h);
1762
+ }
1763
+ const ordered = Array.from(all).sort();
1764
+ return ordered.map((id, i) => ({
1765
+ key: id,
1766
+ label: humanize(id),
1767
+ kind: "fill",
1768
+ color: HERITAGE_PALETTE[i % HERITAGE_PALETTE.length],
1769
+ section: "heritage"
1770
+ }));
1771
+ }
1772
+ function buildMarkerItems(individuals, theme) {
1773
+ const used = /* @__PURE__ */ new Set();
1774
+ for (const ind of individuals) {
1775
+ if (!ind.markers) continue;
1776
+ for (const m of ind.markers) used.add(m);
1777
+ }
1778
+ const order = [
1779
+ "proband",
1780
+ "consultand",
1781
+ "evaluated",
1782
+ "index-person",
1783
+ "transgender",
1784
+ "no-children",
1785
+ "infertile"
1786
+ ];
1787
+ const items = [];
1788
+ for (const m of order) {
1789
+ if (!used.has(m)) continue;
1790
+ items.push(markerItem(m, theme));
1791
+ }
1792
+ return items;
1793
+ }
1794
+ function markerItem(m, theme) {
1795
+ switch (m) {
1796
+ case "proband":
1797
+ return { key: `marker.${m}`, label: "Proband (P)", kind: "marker", marker: "P", section: "markers" };
1798
+ case "consultand":
1799
+ return { key: `marker.${m}`, label: "Consultand (C)", kind: "marker", marker: "C", section: "markers" };
1800
+ case "evaluated":
1801
+ return { key: `marker.${m}`, label: "Evaluated (E)", kind: "marker", marker: "E", section: "markers" };
1802
+ case "index-person":
1803
+ return {
1804
+ key: `marker.${m}`,
1805
+ label: "Index person (focal subject)",
1806
+ kind: "shape",
1807
+ shape: "concentric-square",
1808
+ fill: "#fef3c7",
1809
+ color: theme?.stroke,
1810
+ section: "markers"
1811
+ };
1812
+ case "transgender":
1813
+ return { key: `marker.${m}`, label: "Transgender", kind: "marker", marker: "star", section: "markers" };
1814
+ case "no-children":
1815
+ return { key: `marker.${m}`, label: "No children (by choice)", kind: "marker", marker: "slash", section: "markers" };
1816
+ case "infertile":
1817
+ return { key: `marker.${m}`, label: "Infertile", kind: "marker", marker: "X", section: "markers" };
1818
+ default:
1819
+ return { key: `marker.${m}`, label: humanize(m), kind: "marker", marker: "dot", section: "markers" };
1820
+ }
1821
+ }
1822
+ function humanize(s) {
1823
+ return s.replace(/[-_]+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
1824
+ }
1825
+
1421
1826
  // src/diagrams/genogram/renderer.ts
1422
1827
  function renderGenogram(layout, config, ast) {
1423
1828
  const hasDirectional = layout.edges.some((e) => e.relationship.directional);
@@ -1444,8 +1849,9 @@ function renderGenogram(layout, config, ast) {
1444
1849
  defsStr,
1445
1850
  styleStr
1446
1851
  ];
1852
+ const chartContent = [];
1447
1853
  if (chartTitle) {
1448
- layers.push(
1854
+ chartContent.push(
1449
1855
  text(
1450
1856
  {
1451
1857
  x: layout.width / 2,
@@ -1460,17 +1866,54 @@ function renderGenogram(layout, config, ast) {
1460
1866
  )
1461
1867
  );
1462
1868
  }
1463
- const contentGroup = group(
1464
- { transform: titleHeight > 0 ? `translate(0, ${titleHeight})` : void 0 },
1465
- [edgeLayers, emotionalLayer, ...nodeLayers, labelLayer, edgeLabelLayer]
1869
+ chartContent.push(
1870
+ group(
1871
+ { transform: titleHeight > 0 ? `translate(0, ${titleHeight})` : void 0 },
1872
+ [edgeLayers, emotionalLayer, ...nodeLayers, labelLayer, edgeLabelLayer]
1873
+ )
1874
+ );
1875
+ let finalWidth = layout.width;
1876
+ let finalHeight = totalHeight;
1877
+ let legendSvg = "";
1878
+ if (ast) {
1879
+ const themeBase = resolveGenogramTheme(config.theme);
1880
+ const autoSpec = buildGenogramLegend(ast, themeBase);
1881
+ const finalSpec = applyLegendOverrides(autoSpec, ast.legendOverrides);
1882
+ if (finalSpec.mode === "on" && finalSpec.items.length > 0) {
1883
+ const { svg, bbox: lb } = renderLegend(
1884
+ finalSpec,
1885
+ {
1886
+ canvasWidth: layout.width,
1887
+ canvasHeight: totalHeight,
1888
+ padding: 16,
1889
+ titleHeight
1890
+ },
1891
+ themeBase,
1892
+ { fontFamily: config.fontFamily, fontSize: config.fontSize }
1893
+ );
1894
+ if (svg) {
1895
+ legendSvg = svg;
1896
+ const overflowX = lb.x + lb.w + 8;
1897
+ const overflowY = lb.y + lb.h + 8;
1898
+ if (overflowX > finalWidth) finalWidth = overflowX;
1899
+ if (overflowY > finalHeight) finalHeight = overflowY;
1900
+ }
1901
+ }
1902
+ }
1903
+ const chartXOffset = Math.max(0, (finalWidth - layout.width) / 2);
1904
+ layers.push(
1905
+ group(
1906
+ { transform: chartXOffset > 0 ? `translate(${chartXOffset}, 0)` : void 0 },
1907
+ chartContent
1908
+ )
1466
1909
  );
1467
- layers.push(contentGroup);
1910
+ if (legendSvg) layers.push(legendSvg);
1468
1911
  return svgRoot(
1469
1912
  {
1470
- viewBox: `0 0 ${layout.width} ${totalHeight}`,
1913
+ viewBox: `0 0 ${finalWidth} ${finalHeight}`,
1471
1914
  class: "schematex-diagram schematex-genogram",
1472
- width: layout.width,
1473
- height: totalHeight
1915
+ width: finalWidth,
1916
+ height: finalHeight
1474
1917
  },
1475
1918
  layers
1476
1919
  );
@@ -1491,7 +1934,8 @@ function buildStyles(config) {
1491
1934
  .schematex-genogram-edge-divorced .schematex-genogram-divorce-mark { stroke: ${t.neutral}; stroke-width: ${STROKE_WIDTH.normal}; }
1492
1935
  .schematex-genogram-edge-separated .schematex-genogram-separation-mark { stroke: ${t.neutral}; stroke-width: ${STROKE_WIDTH.normal}; }
1493
1936
  .schematex-genogram-deceased-mark { stroke: ${t.deceasedMark}; stroke-width: ${STROKE_WIDTH.normal}; stroke-linecap: round; }
1494
- .schematex-genogram-condition-fill { fill: ${t.conditionFill}; }
1937
+ /* Inline fill on each .schematex-genogram-condition-fill element comes from cond.color. The CSS only sets a default for elements that did not receive an inline fill attribute. */
1938
+ .schematex-genogram-condition-fill:not([fill]) { fill: ${t.conditionFill}; }
1495
1939
  .schematex-genogram-age { font-family: ${config.fontFamily}; fill: ${t.text}; pointer-events: none; }
1496
1940
  .schematex-genogram-title { fill: ${t.text}; }
1497
1941
  .schematex-genogram-edge-label { font-family: ${config.fontFamily}; fill: ${t.text}; }
@@ -1792,5 +2236,5 @@ var genogram = {
1792
2236
  };
1793
2237
 
1794
2238
  export { ParseError, genogram, getRequiredDefs, layoutGenogram, parseGenogram, renderGenogram, renderIndividualSymbol };
1795
- //# sourceMappingURL=chunk-HLYA4QBB.js.map
1796
- //# sourceMappingURL=chunk-HLYA4QBB.js.map
2239
+ //# sourceMappingURL=chunk-2BM3HJSK.js.map
2240
+ //# sourceMappingURL=chunk-2BM3HJSK.js.map