@sportsdataverse/sdvplot 0.0.0-stage → 0.1.0

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 (166) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +94 -0
  3. package/README.md +908 -2
  4. package/dist/_web-D7Aa5Rd8.d.ts +69 -0
  5. package/dist/aaf-GJ3SH34T.js +13 -0
  6. package/dist/aaf-HCYN5T6Y.js +37 -0
  7. package/dist/aaf-ZAE5KS2Y.js +13 -0
  8. package/dist/ahl-E66MDVCU.js +66 -0
  9. package/dist/ahl-NPQQWZEV.js +249 -0
  10. package/dist/ahl-QRDU73XX.js +309 -0
  11. package/dist/axis-CraWQRUJ.d.ts +49 -0
  12. package/dist/bins.d.ts +174 -0
  13. package/dist/bins.js +4 -0
  14. package/dist/bins.js.map +1 -0
  15. package/dist/cfb-F42SVS4X.js +5000 -0
  16. package/dist/cfb-P3SHEYRZ.js +692 -0
  17. package/dist/cfb-WXRZANLP.js +10226 -0
  18. package/dist/chartjs-surface.d.ts +42 -0
  19. package/dist/chartjs-surface.js +65 -0
  20. package/dist/chartjs-surface.js.map +1 -0
  21. package/dist/chartjs.d.ts +132 -0
  22. package/dist/chartjs.js +339 -0
  23. package/dist/chartjs.js.map +1 -0
  24. package/dist/chunk-4C3GX6QO.js +92 -0
  25. package/dist/chunk-4C3GX6QO.js.map +1 -0
  26. package/dist/chunk-C2CDY5OG.js +137 -0
  27. package/dist/chunk-C2CDY5OG.js.map +1 -0
  28. package/dist/chunk-E7G7VSLV.js +43 -0
  29. package/dist/chunk-E7G7VSLV.js.map +1 -0
  30. package/dist/chunk-J6R2LEJ7.js +58 -0
  31. package/dist/chunk-J6R2LEJ7.js.map +1 -0
  32. package/dist/chunk-JJFTD4VB.js +175 -0
  33. package/dist/chunk-JJFTD4VB.js.map +1 -0
  34. package/dist/chunk-KKH6ABMA.js +223 -0
  35. package/dist/chunk-KKH6ABMA.js.map +1 -0
  36. package/dist/chunk-NLPH2VZT.js +127 -0
  37. package/dist/chunk-NLPH2VZT.js.map +1 -0
  38. package/dist/chunk-OKEE4AH6.js +30 -0
  39. package/dist/chunk-OKEE4AH6.js.map +1 -0
  40. package/dist/chunk-QY65DUEF.js +306 -0
  41. package/dist/chunk-QY65DUEF.js.map +1 -0
  42. package/dist/chunk-RMT2GMFH.js +97 -0
  43. package/dist/chunk-RMT2GMFH.js.map +1 -0
  44. package/dist/chunk-SEBO35DV.js +76 -0
  45. package/dist/chunk-SEBO35DV.js.map +1 -0
  46. package/dist/chunk-TAXO3VXH.js +556 -0
  47. package/dist/chunk-TAXO3VXH.js.map +1 -0
  48. package/dist/chunk-TDNBAEQB.js +105 -0
  49. package/dist/chunk-TDNBAEQB.js.map +1 -0
  50. package/dist/cricket-KPCYG2HL.js +493 -0
  51. package/dist/cricket-NDXLE25B.js +116 -0
  52. package/dist/cricket-YUUF7P6M.js +160 -0
  53. package/dist/d3.d.ts +234 -0
  54. package/dist/d3.js +198 -0
  55. package/dist/d3.js.map +1 -0
  56. package/dist/echarts.d.ts +121 -0
  57. package/dist/echarts.js +228 -0
  58. package/dist/echarts.js.map +1 -0
  59. package/dist/echl-3CR4RGFC.js +241 -0
  60. package/dist/echl-NPC32C23.js +107 -0
  61. package/dist/echl-PI33DGJC.js +64 -0
  62. package/dist/export.d.ts +130 -0
  63. package/dist/export.js +258 -0
  64. package/dist/export.js.map +1 -0
  65. package/dist/headshots-B2J_LOO8.d.ts +40 -0
  66. package/dist/index.d.ts +182 -0
  67. package/dist/index.js +10 -0
  68. package/dist/index.js.map +1 -0
  69. package/dist/interact.d.ts +567 -0
  70. package/dist/interact.js +809 -0
  71. package/dist/interact.js.map +1 -0
  72. package/dist/marks-DH-tQIP-.d.ts +75 -0
  73. package/dist/mbb-3TRLVW3H.js +3619 -0
  74. package/dist/mbb-DQUHCHZP.js +5111 -0
  75. package/dist/mbb-PRAIO2P5.js +371 -0
  76. package/dist/milb-6IQ6NCEW.js +291 -0
  77. package/dist/milb-EYY5MD4T.js +1752 -0
  78. package/dist/milb-EYZ4SZLI.js +797 -0
  79. package/dist/mlb-4PBUJSVQ.js +35 -0
  80. package/dist/mlb-FHPY3GQJ.js +701 -0
  81. package/dist/mlb-REVGL3N2.js +665 -0
  82. package/dist/nba-ATT775GS.js +485 -0
  83. package/dist/nba-LKM4UHVU.js +482 -0
  84. package/dist/nba-YX7PXM3R.js +35 -0
  85. package/dist/nbagl-3WGZCZ4S.js +37 -0
  86. package/dist/nbagl-LP4XJRAL.js +229 -0
  87. package/dist/nbagl-VTTOU7LN.js +499 -0
  88. package/dist/ncaa_baseball-UV75LNVR.js +2670 -0
  89. package/dist/ncaa_baseball-VD5J5C72.js +419 -0
  90. package/dist/ncaa_baseball-YRBS32D6.js +4592 -0
  91. package/dist/ncaa_mhockey-IMYHS7QS.js +1033 -0
  92. package/dist/ncaa_mhockey-TXTKWHE3.js +115 -0
  93. package/dist/ncaa_mhockey-U3MFW5VT.js +663 -0
  94. package/dist/ncaa_softball-6WR6KS64.js +420 -0
  95. package/dist/ncaa_softball-RZCTIE56.js +2654 -0
  96. package/dist/ncaa_softball-VOD4PVGY.js +4599 -0
  97. package/dist/ncaa_whockey-6XXGUTBK.js +607 -0
  98. package/dist/ncaa_whockey-AKKYKY67.js +53 -0
  99. package/dist/ncaa_whockey-KBEKXFBB.js +293 -0
  100. package/dist/nfl-BDB2HYAR.js +625 -0
  101. package/dist/nfl-EHYHDLJD.js +37 -0
  102. package/dist/nfl-VF4NJCHY.js +514 -0
  103. package/dist/nfl_gsis-UY64JO37.js +4 -0
  104. package/dist/nhl-6WPHME7H.js +511 -0
  105. package/dist/nhl-EMIJFZHY.js +884 -0
  106. package/dist/nhl-ISFUKRFU.js +37 -0
  107. package/dist/ohl-2FEM554G.js +113 -0
  108. package/dist/ohl-C5Q4W6JB.js +32 -0
  109. package/dist/ohl-TQ4J46VC.js +66 -0
  110. package/dist/phf-H7POU2KW.js +32 -0
  111. package/dist/phf-K5IFMZUM.js +13 -0
  112. package/dist/phf-TWJI3BOW.js +20 -0
  113. package/dist/plot.d.ts +449 -0
  114. package/dist/plot.js +711 -0
  115. package/dist/plot.js.map +1 -0
  116. package/dist/plotly.d.ts +129 -0
  117. package/dist/plotly.js +360 -0
  118. package/dist/plotly.js.map +1 -0
  119. package/dist/pwhl-OX3BO4JI.js +53 -0
  120. package/dist/pwhl-W44OC3C6.js +17 -0
  121. package/dist/pwhl-ZJGG3H7W.js +23 -0
  122. package/dist/qmjhl-5HISEHLL.js +35 -0
  123. package/dist/qmjhl-DA3UHKE5.js +125 -0
  124. package/dist/qmjhl-YG4BOQPF.js +614 -0
  125. package/dist/react.d.ts +101 -0
  126. package/dist/react.js +164 -0
  127. package/dist/react.js.map +1 -0
  128. package/dist/resolve-CQW-jzvr.d.ts +28 -0
  129. package/dist/selection-D4T3PkRt.d.ts +140 -0
  130. package/dist/shots.d.ts +364 -0
  131. package/dist/shots.js +85 -0
  132. package/dist/shots.js.map +1 -0
  133. package/dist/soccer-7BH3ZLVL.js +7898 -0
  134. package/dist/soccer-MRU25OGE.js +2636 -0
  135. package/dist/soccer-PF4IPPVA.js +12342 -0
  136. package/dist/surfaces-ChaD9nei.d.ts +38 -0
  137. package/dist/testing.d.ts +75 -0
  138. package/dist/testing.js +240 -0
  139. package/dist/testing.js.map +1 -0
  140. package/dist/tiers-B6pUBPcE.d.ts +93 -0
  141. package/dist/types-C7n6gJF3.d.ts +62 -0
  142. package/dist/ufl-7VLZTLTT.js +143 -0
  143. package/dist/ufl-CCMBLPSW.js +100 -0
  144. package/dist/ufl-F2BJRXME.js +16 -0
  145. package/dist/usfl-4CR5RMZJ.js +32 -0
  146. package/dist/usfl-LD7HP2YK.js +14 -0
  147. package/dist/usfl-VU4YSJQD.js +19 -0
  148. package/dist/ushl-CPG2LB4L.js +73 -0
  149. package/dist/ushl-PQL6HJAD.js +88 -0
  150. package/dist/ushl-ZT2ATPHK.js +22 -0
  151. package/dist/vega.d.ts +85 -0
  152. package/dist/vega.js +362 -0
  153. package/dist/vega.js.map +1 -0
  154. package/dist/wbb-3KHCDYTK.js +5087 -0
  155. package/dist/wbb-BMX53Q3Q.js +369 -0
  156. package/dist/wbb-QNRN2CJJ.js +3620 -0
  157. package/dist/whl-4ATYZWUB.js +97 -0
  158. package/dist/whl-RVFPL6MH.js +79 -0
  159. package/dist/whl-Y7ASKYMM.js +28 -0
  160. package/dist/wnba-FWX5SFVI.js +232 -0
  161. package/dist/wnba-GX6HZR4B.js +220 -0
  162. package/dist/wnba-NTMWIPP6.js +20 -0
  163. package/dist/xfl-43R2JMJK.js +30 -0
  164. package/dist/xfl-H3BXQPZZ.js +16 -0
  165. package/dist/xfl-XON7A7FI.js +69 -0
  166. package/package.json +154 -3
package/dist/export.js ADDED
@@ -0,0 +1,258 @@
1
+ import { roundHalfEven, onColor } from './chunk-J6R2LEJ7.js';
2
+ import { InputError, OptionalDependencyError, warn, DownloadError } from './chunk-E7G7VSLV.js';
3
+
4
+ // src/export/index.ts
5
+ var GRAVITY = [
6
+ "center",
7
+ "north",
8
+ "south",
9
+ "east",
10
+ "west",
11
+ "northwest",
12
+ "northeast",
13
+ "southwest",
14
+ "southeast"
15
+ ];
16
+ function parseGravity(gravity) {
17
+ const g = String(gravity).toLowerCase();
18
+ const hit = GRAVITY.find((x) => x === g);
19
+ if (hit === void 0)
20
+ throw new InputError(`gravity must be one of ${GRAVITY.join(", ")}, got ${JSON.stringify(gravity)}`);
21
+ return hit;
22
+ }
23
+ function checkColor(name, value) {
24
+ if (!/^[#a-zA-Z0-9(),.%/ -]+$/.test(value))
25
+ throw new InputError(`${name} must be a CSS color, got ${JSON.stringify(value)}`);
26
+ return value;
27
+ }
28
+ var pyFloat = (s) => Number(typeof s === "string" ? s.replace(/(?<=\d)_(?=\d)/g, "") : s);
29
+ function parseAspect(aspect) {
30
+ let ratio = Number.NaN;
31
+ if (typeof aspect === "string" && /[:x]/.test(aspect)) {
32
+ const parts = aspect.split(/[:x]/);
33
+ if (parts.length === 2) ratio = pyFloat(parts[0]) / pyFloat(parts[1]);
34
+ } else if (typeof aspect === "number" || typeof aspect === "string") ratio = pyFloat(aspect);
35
+ if (!(ratio > 0 && Number.isFinite(ratio))) {
36
+ throw new InputError(
37
+ `aspect could not be read as a ratio: got ${String(aspect)}; use "1:1", "16:9", "4x5" or a number like 1.91`
38
+ );
39
+ }
40
+ return ratio;
41
+ }
42
+ function canvasFor(width, height, ratio) {
43
+ return width / height > ratio ? [width, roundHalfEven(width / ratio)] : [roundHalfEven(height * ratio), height];
44
+ }
45
+ function offsetFor(dx, dy, gravity) {
46
+ const x = gravity.endsWith("west") ? 0 : gravity.endsWith("east") ? dx : Math.floor(dx / 2);
47
+ const y = gravity.startsWith("north") ? 0 : gravity.startsWith("south") ? dy : Math.floor(dy / 2);
48
+ return [x, y];
49
+ }
50
+ var SVG_NS = "http://www.w3.org/2000/svg";
51
+ var XLINK_NS = "http://www.w3.org/1999/xlink";
52
+ var OPEN_TAG = /<svg\b[^>]*>/i;
53
+ var attrOf = (tag, name) => new RegExp(`\\s${name}=["']([^"']+)["']`, "i").exec(tag)?.[1];
54
+ var userUnits = (v) => Number(v?.trim().replace(/px$/i, "") || Number.NaN);
55
+ function svgSize(svg) {
56
+ const open = OPEN_TAG.exec(svg)?.[0];
57
+ if (!open) throw new InputError("socialCard: no <svg> root element");
58
+ const vb = attrOf(open, "viewBox");
59
+ const parts = vb?.trim().split(/[\s,]+/).map(Number);
60
+ const w = userUnits(attrOf(open, "width"));
61
+ const h = userUnits(attrOf(open, "height"));
62
+ const width = Number.isFinite(w) ? w : parts?.[2];
63
+ const height = Number.isFinite(h) ? h : parts?.[3];
64
+ if (width === void 0 || height === void 0 || !(width > 0) || !(height > 0)) {
65
+ throw new InputError("socialCard: the <svg> needs width/height attributes or a viewBox");
66
+ }
67
+ return { width, height, viewBox: vb ?? `0 0 ${width} ${height}` };
68
+ }
69
+ function socialCard(svg, { aspect = "1:1", padding = 60, background = "white", gravity = "center", color } = {}) {
70
+ const ratio = parseAspect(aspect);
71
+ const place = parseGravity(gravity);
72
+ checkColor("background", background);
73
+ if (color !== void 0) checkColor("color", color);
74
+ if (!(Number.isFinite(padding) && padding >= 0))
75
+ throw new InputError(`padding must be a non-negative number of pixels, got ${String(padding)}`);
76
+ const pad = Math.trunc(padding);
77
+ const { width, height, viewBox } = svgSize(svg);
78
+ const [cw, ch] = canvasFor(width + 2 * pad, height + 2 * pad, ratio);
79
+ const [ox, oy] = offsetFor(cw - (width + 2 * pad), ch - (height + 2 * pad), place);
80
+ const ink = color ?? (/^#(?:[0-9a-f]{3}){1,2}$/i.test(background) ? onColor(background) : void 0);
81
+ const open = OPEN_TAG.exec(svg)?.[0] ?? "<svg>";
82
+ const stripped = open.replace(/\s(?:x|y|width|height|viewBox)=["'][^"']*["']/gi, "");
83
+ const inner = svg.replace(
84
+ open,
85
+ () => stripped.replace(
86
+ /^<svg/i,
87
+ () => `<svg x="${ox + pad}" y="${oy + pad}" width="${width}" height="${height}" viewBox="${viewBox}"`
88
+ )
89
+ );
90
+ const inked = ink === void 0 ? "" : ` color="${ink}"`;
91
+ return `<svg xmlns="${SVG_NS}"${inked} width="${cw}" height="${ch}" viewBox="0 0 ${cw} ${ch}"><rect width="${cw}" height="${ch}" fill="${background}"/>${inner}</svg>`;
92
+ }
93
+ function peerMissing(e, name) {
94
+ const quoted = new RegExp(`['"]${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}['"]`);
95
+ return e instanceof Error && (/MODULE_NOT_FOUND/.test(String(e.code)) && quoted.test(e.message) || peerMissing(e.cause, name));
96
+ }
97
+ async function download(url) {
98
+ let r;
99
+ try {
100
+ r = await fetch(url);
101
+ if (r.ok) return new Uint8Array(await r.arrayBuffer());
102
+ } catch (e) {
103
+ throw Object.assign(new DownloadError(`toPNG could not download ${url}: ${String(e)}`, url), {
104
+ cause: e
105
+ });
106
+ }
107
+ throw new DownloadError(`toPNG could not download ${url}: it answered ${r.status}`, url, r.status);
108
+ }
109
+ var FETCH_LIMIT = 8;
110
+ async function mapLimit(xs, limit, fn) {
111
+ const out = new Array(xs.length);
112
+ let next = 0;
113
+ const worker = async () => {
114
+ while (next < xs.length) {
115
+ const i = next++;
116
+ try {
117
+ out[i] = await fn(xs[i]);
118
+ } catch (e) {
119
+ next = xs.length;
120
+ throw e;
121
+ }
122
+ }
123
+ };
124
+ await Promise.all(Array.from({ length: Math.min(limit, xs.length) }, worker));
125
+ return out;
126
+ }
127
+ var hrefAttr = (url) => {
128
+ const re = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
129
+ return new RegExp(`(href=)(["'])(?:${re(url)}|${re(url.replaceAll("&", "&amp;"))})\\2`, "g");
130
+ };
131
+ async function toPNG(svg, { width, scale = 1, background, color, images = "fetch", fonts = {} } = {}) {
132
+ if (!(Number.isFinite(scale) && scale > 0))
133
+ throw new InputError(`scale must be a positive number, got ${String(scale)}`);
134
+ if (width !== void 0 && !(Number.isFinite(width) && width > 0))
135
+ throw new InputError(`width must be a positive number of pixels, got ${String(width)}`);
136
+ if (background !== void 0) checkColor("background", background);
137
+ if (color !== void 0) checkColor("color", color);
138
+ if (images !== "fetch" && images !== "skip")
139
+ throw new InputError(`images must be "fetch" or "skip", got ${JSON.stringify(images)}`);
140
+ const font = await fontOptions(fonts);
141
+ let text = typeof svg === "string" ? svg : svg.outerHTML;
142
+ const mod = await import('@resvg/resvg-js').catch((e) => {
143
+ throw new OptionalDependencyError(
144
+ peerMissing(e, "@resvg/resvg-js") ? "toPNG needs the optional peer @resvg/resvg-js, which is not installed: pnpm add @resvg/resvg-js" : `toPNG could not load the optional peer @resvg/resvg-js (installed, but it failed to load): ${String(e)}`,
145
+ { cause: e }
146
+ );
147
+ });
148
+ const fitTo = width !== void 0 ? { mode: "width", value: Math.round(width * scale) } : { mode: "zoom", value: scale };
149
+ const opts = { fitTo, font, ...background !== void 0 && { background } };
150
+ const open = OPEN_TAG.exec(text)?.[0];
151
+ if (open !== void 0) {
152
+ let add = "";
153
+ if (!/\sxmlns=/i.test(open)) add += ` xmlns="${SVG_NS}"`;
154
+ if (/\sxlink:[\w-]+=/i.test(text) && !/\sxmlns:xlink=/i.test(open)) add += ` xmlns:xlink="${XLINK_NS}"`;
155
+ let ink = color;
156
+ if (ink === void 0 && background !== void 0 && !/\scolor=/i.test(open) && /currentcolor/i.test(text)) {
157
+ const p = new mod.Resvg(`<svg xmlns="${SVG_NS}" width="1" height="1"/>`, { background }).render().pixels;
158
+ ink = onColor(`#${[p[0], p[1], p[2]].map((v) => (v ?? 0).toString(16).padStart(2, "0")).join("")}`);
159
+ }
160
+ let tag = open;
161
+ if (ink !== void 0) {
162
+ tag = tag.replace(/\scolor=["'][^"']*["']/i, "");
163
+ add += ` color="${ink}"`;
164
+ }
165
+ text = text.replace(open, () => tag.replace(/^<svg/i, () => `<svg${add}`));
166
+ }
167
+ const probe = new mod.Resvg(text, NO_FONTS);
168
+ const hrefs = [...new Set(probe.imagesToResolve())];
169
+ let bodies = [];
170
+ if (hrefs.length > 0 && images === "skip") {
171
+ warn(
172
+ `toPNG:skip:${hrefs.join(" ")}`,
173
+ `toPNG left out ${hrefs.length} remote image(s): ${hrefs.join(", ")}`
174
+ );
175
+ } else if (hrefs.length > 0) {
176
+ bodies = await mapLimit(hrefs, FETCH_LIMIT, download);
177
+ const zoom = fitTo.mode === "width" ? fitTo.value / probe.width : scale;
178
+ const tags = text.match(/<image\b[^>]*>/gi) ?? [];
179
+ for (const [i, href] of hrefs.entries()) {
180
+ const b = bodies[i];
181
+ let uri = dataURI(b);
182
+ const re = hrefAttr(href);
183
+ const small = shrink(
184
+ mod,
185
+ uri,
186
+ tags.filter((t) => t.search(re) >= 0),
187
+ zoom
188
+ );
189
+ if (small !== void 0) uri = dataURI(small);
190
+ text = text.replace(re, (_m, attr, q) => `${attr}${q}${uri}${q}`);
191
+ }
192
+ }
193
+ const resvg = new mod.Resvg(text, opts);
194
+ if (bodies.length > 0) {
195
+ const left = new Set(resvg.imagesToResolve());
196
+ for (const [i, href] of hrefs.entries())
197
+ if (left.has(href)) resvg.resolveImage(href, Buffer.from(bodies[i]));
198
+ }
199
+ return new Uint8Array(resvg.render().asPng());
200
+ }
201
+ var NO_FONTS = { font: { loadSystemFonts: false } };
202
+ async function fontOptions(fonts) {
203
+ if (typeof fonts !== "object" || fonts === null || Array.isArray(fonts))
204
+ throw new InputError(
205
+ `fonts must be an object { files, defaultFamily, system }, got ${JSON.stringify(fonts)}`
206
+ );
207
+ const { files = [], defaultFamily, system = true } = fonts;
208
+ if (!Array.isArray(files) || files.some((f) => typeof f !== "string"))
209
+ throw new InputError(`fonts.files must be an array of font file paths, got ${JSON.stringify(files)}`);
210
+ if (defaultFamily !== void 0 && typeof defaultFamily !== "string")
211
+ throw new InputError(`fonts.defaultFamily must be a string, got ${JSON.stringify(defaultFamily)}`);
212
+ if (typeof system !== "boolean")
213
+ throw new InputError(`fonts.system must be a boolean, got ${JSON.stringify(system)}`);
214
+ if (files.length > 0) {
215
+ const { statSync } = await import('fs');
216
+ for (const f of files)
217
+ if (!statSync(f, { throwIfNoEntry: false })?.isFile())
218
+ throw new InputError(`fonts.files: no font file at ${JSON.stringify(f)}`);
219
+ }
220
+ return {
221
+ loadSystemFonts: system,
222
+ fontFiles: [...files],
223
+ ...defaultFamily !== void 0 && { defaultFontFamily: defaultFamily }
224
+ };
225
+ }
226
+ var OVERSAMPLE = 2;
227
+ function shrink(mod, uri, uses, zoom) {
228
+ if (uses.length < 2) return void 0;
229
+ let side = 0;
230
+ for (const tag of uses) {
231
+ const w2 = userUnits(attrOf(tag, "width"));
232
+ const h2 = userUnits(attrOf(tag, "height"));
233
+ if (!(w2 > 0 && h2 > 0)) return void 0;
234
+ side = Math.max(side, w2, h2);
235
+ }
236
+ const own = new mod.Resvg(
237
+ `<svg xmlns="${SVG_NS}" width="1" height="1"><image href="${uri}"/></svg>`,
238
+ NO_FONTS
239
+ ).getBBox();
240
+ const k = own ? Math.ceil(OVERSAMPLE * zoom * side) / Math.max(own.width, own.height) : 1;
241
+ if (!own || !(k < 1)) return void 0;
242
+ const [w, h] = [Math.max(1, Math.round(own.width * k)), Math.max(1, Math.round(own.height * k))];
243
+ return new mod.Resvg(
244
+ `<svg xmlns="${SVG_NS}" width="${w}" height="${h}"><image href="${uri}" width="${w}" height="${h}" preserveAspectRatio="none"/></svg>`,
245
+ NO_FONTS
246
+ ).render().asPng();
247
+ }
248
+ var dataURI = (b) => `data:${imageType(b)};base64,${Buffer.from(b).toString("base64")}`;
249
+ function imageType(b) {
250
+ if (new TextDecoder().decode(b.subarray(0, 64)).trimStart().startsWith("<")) return "image/svg+xml";
251
+ if (b[0] === 255 && b[1] === 216) return "image/jpeg";
252
+ if (b[0] === 71 && b[1] === 73 && b[2] === 70) return "image/gif";
253
+ return "image/png";
254
+ }
255
+
256
+ export { canvasFor, checkColor, offsetFor, parseAspect, parseGravity, peerMissing, socialCard, svgSize, toPNG };
257
+ //# sourceMappingURL=export.js.map
258
+ //# sourceMappingURL=export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/export/index.ts"],"names":["w","h"],"mappings":"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","file":"export.js","sourcesContent":["import { onColor, roundHalfEven } from \"../contrast.js\";\nimport { DownloadError, InputError, OptionalDependencyError, warn } from \"../errors.js\";\n\n/** A canvas ratio, width to height: `\"16:9\"`, `\"4x5\"`, a number such as 1.91, or a numeric string such as `\"1.91\"`. */\nexport type Aspect = \"1:1\" | \"16:9\" | \"4:5\" | \"9:16\" | \"1.91:1\" | number | (string & {});\n/** Where the figure sits on the canvas, as in ImageMagick (and sdvplot/sdvplotR `gt_social_crop`). */\nexport type Gravity =\n | \"center\"\n | \"north\"\n | \"south\"\n | \"east\"\n | \"west\"\n | \"northwest\"\n | \"northeast\"\n | \"southwest\"\n | \"southeast\";\n/** Options for {@link toPNG}. */\nexport interface ToPNGOptions {\n /** output width in CSS pixels, the height following (multiplied by `scale`); absent: the SVG's own size */\n width?: number;\n /** device-pixel multiplier, a positive number; default 1 */\n scale?: number;\n /** a color painted under transparent areas; absent: transparent */\n background?: string;\n /**\n * the root `color`, which `currentColor` (Plot's axes and text) resolves to; absent: the SVG's own root `color`, else\n * black or white, whichever contrasts more with `background` (black when there is no background)\n */\n color?: string;\n /**\n * remote `<image href=\"http(s)://…\">` (logos, headshots): `\"fetch\"` (default) downloads each once with the global\n * `fetch` and draws it, a failed download throwing `DownloadError`; `\"skip\"` leaves them out with one warning\n */\n images?: \"fetch\" | \"skip\";\n /**\n * the fonts `<text>` is drawn with. resvg draws text only in fonts it has loaded, and with none (a host without\n * system fonts: slim Docker images, minimal CI runners) every label renders as nothing, with no error. `files`: font\n * files (.ttf, .otf, .ttc) on disk to load, each checked to exist; `defaultFamily`: the family for text whose own\n * families are not loaded (absent: resvg's choice, the first font loaded); `system`: also load the system fonts,\n * default true. Absent: the system fonts only.\n */\n fonts?: { files?: readonly string[]; defaultFamily?: string; system?: boolean };\n}\n/** Options for {@link socialCard}; defaults are Python/R `gt_social_crop`'s. */\nexport interface SocialCardOptions {\n /** the canvas ratio; default `\"1:1\"` */\n aspect?: Aspect;\n /** pixels left around the figure before the canvas grows to the ratio (truncated to an integer); default 60 */\n padding?: number;\n /** the canvas color; default `\"white\"` */\n background?: string;\n /** where the padded figure sits on the canvas; default `\"center\"` */\n gravity?: Gravity;\n /**\n * the canvas root `color`, which the figure's `currentColor` (Plot's axes and text) inherits; absent: black or white,\n * whichever contrasts more with a hex `background` (none for a named background: give `color`, or a hex)\n */\n color?: string;\n}\n/** An SVG's size, from its `width`/`height` attributes or else its `viewBox`. */\nexport interface SvgSize {\n /** user units: the width attribute, else the viewBox width */\n width: number;\n /** user units: the height attribute, else the viewBox height */\n height: number;\n /** the root viewBox, else `0 0 width height` */\n viewBox: string;\n}\n\nconst GRAVITY: readonly Gravity[] = [\n \"center\",\n \"north\",\n \"south\",\n \"east\",\n \"west\",\n \"northwest\",\n \"northeast\",\n \"southwest\",\n \"southeast\",\n];\n/** Port of Python `_check_gravity`: one of the nine magick gravities, case-insensitive; anything else is an InputError. */\nexport function parseGravity(gravity: string): Gravity {\n const g = String(gravity).toLowerCase();\n const hit = GRAVITY.find((x) => x === g);\n if (hit === undefined)\n throw new InputError(`gravity must be one of ${GRAVITY.join(\", \")}, got ${JSON.stringify(gravity)}`);\n return hit;\n}\n/**\n * A CSS color written into markup: names, hex, rgb()/hsl() (with `/` alpha too); never a quote, angle bracket,\n * semicolon or equals sign.\n */\nexport function checkColor(name: string, value: string): string {\n if (!/^[#a-zA-Z0-9(),.%/ -]+$/.test(value))\n throw new InputError(`${name} must be a CSS color, got ${JSON.stringify(value)}`);\n return value;\n}\n\n/** Python `float()` of a string: an underscore is allowed only between two digits (\"1_0\" is 10). */\nconst pyFloat = (s: string | number): number =>\n Number(typeof s === \"string\" ? s.replace(/(?<=\\d)_(?=\\d)/g, \"\") : s);\n\n/** Port of Python `_ratio`: \"16:9\", \"4x5\" (exactly two parts) or a positive finite number, numeric strings included. */\nexport function parseAspect(aspect: Aspect): number {\n let ratio = Number.NaN;\n if (typeof aspect === \"string\" && /[:x]/.test(aspect)) {\n const parts = aspect.split(/[:x]/);\n if (parts.length === 2) ratio = pyFloat(parts[0] as string) / pyFloat(parts[1] as string); // Python `a, b = re.split(...)`\n } else if (typeof aspect === \"number\" || typeof aspect === \"string\") ratio = pyFloat(aspect); // Python float(\"1.91\")\n if (!(ratio > 0 && Number.isFinite(ratio))) {\n throw new InputError(\n `aspect could not be read as a ratio: got ${String(aspect)}; use \"1:1\", \"16:9\", \"4x5\" or a number like 1.91`,\n );\n }\n return ratio;\n}\n\n/** Port of Python `_canvas`: expand the short side until the ratio is met; never shrink. Rounds half to even (Python/R `round`). */\nexport function canvasFor(width: number, height: number, ratio: number): [number, number] {\n return width / height > ratio\n ? [width, roundHalfEven(width / ratio)]\n : [roundHalfEven(height * ratio), height];\n}\n\n/** Port of Python `_extent` placement: the offset of a figure with `dx`/`dy` spare pixels around it. */\nexport function offsetFor(dx: number, dy: number, gravity: Gravity): [number, number] {\n const x = gravity.endsWith(\"west\") ? 0 : gravity.endsWith(\"east\") ? dx : Math.floor(dx / 2);\n const y = gravity.startsWith(\"north\") ? 0 : gravity.startsWith(\"south\") ? dy : Math.floor(dy / 2);\n return [x, y];\n}\n\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\nconst XLINK_NS = \"http://www.w3.org/1999/xlink\";\nconst OPEN_TAG = /<svg\\b[^>]*>/i;\nconst attrOf = (tag: string, name: string): string | undefined =>\n new RegExp(`\\\\s${name}=[\"']([^\"']+)[\"']`, \"i\").exec(tag)?.[1];\n/** A plain or `px` length; a percent or relative unit (`em`) is NaN, so the size comes from the viewBox. */\nconst userUnits = (v: string | undefined): number => Number(v?.trim().replace(/px$/i, \"\") || Number.NaN);\n\n/**\n * The root `<svg>`'s size: `width`/`height` attributes in user units or px, else the viewBox's (D3 output often has\n * only a viewBox; a `100%` size is relative to a container a standalone SVG does not have).\n */\nexport function svgSize(svg: string): SvgSize {\n const open = OPEN_TAG.exec(svg)?.[0];\n if (!open) throw new InputError(\"socialCard: no <svg> root element\");\n const vb = attrOf(open, \"viewBox\");\n const parts = vb\n ?.trim()\n .split(/[\\s,]+/)\n .map(Number);\n const w = userUnits(attrOf(open, \"width\"));\n const h = userUnits(attrOf(open, \"height\"));\n const width = Number.isFinite(w) ? w : parts?.[2];\n const height = Number.isFinite(h) ? h : parts?.[3];\n if (width === undefined || height === undefined || !(width > 0) || !(height > 0)) {\n throw new InputError(\"socialCard: the <svg> needs width/height attributes or a viewBox\");\n }\n return { width, height, viewBox: vb ?? `0 0 ${width} ${height}` };\n}\n\n/**\n * Port of sdvplot/sdvplotR `gt_social_crop` framing for an SVG figure: pad, then extend the short side to the ratio\n * (the figure is never cropped). Arguments are checked in Python's order (ratio, gravity, background, padding) before\n * anything is built. A final rescale (`width=` in Python/R) is `toPNG(socialCard(svg), { width })`.\n */\nexport function socialCard(\n svg: string,\n { aspect = \"1:1\", padding = 60, background = \"white\", gravity = \"center\", color }: SocialCardOptions = {},\n): string {\n const ratio = parseAspect(aspect);\n const place = parseGravity(gravity);\n checkColor(\"background\", background);\n if (color !== undefined) checkColor(\"color\", color);\n if (!(Number.isFinite(padding) && padding >= 0))\n throw new InputError(`padding must be a non-negative number of pixels, got ${String(padding)}`);\n const pad = Math.trunc(padding); // Python _pixels: int(whitespace)\n const { width, height, viewBox } = svgSize(svg);\n const [cw, ch] = canvasFor(width + 2 * pad, height + 2 * pad, ratio);\n const [ox, oy] = offsetFor(cw - (width + 2 * pad), ch - (height + 2 * pad), place);\n // ponytail: contrast is judged for an opaque hex background only; a named one needs `color` (no CSS name table here)\n const ink = color ?? (/^#(?:[0-9a-f]{3}){1,2}$/i.test(background) ? onColor(background) : undefined);\n const open = OPEN_TAG.exec(svg)?.[0] ?? \"<svg>\";\n const stripped = open.replace(/\\s(?:x|y|width|height|viewBox)=[\"'][^\"']*[\"']/gi, \"\");\n // replacer functions: a `$&`, `$'` or `` $` `` in the figure's own attributes is text, not a replacement pattern\n const inner = svg.replace(open, () =>\n stripped.replace(\n /^<svg/i,\n () => `<svg x=\"${ox + pad}\" y=\"${oy + pad}\" width=\"${width}\" height=\"${height}\" viewBox=\"${viewBox}\"`,\n ),\n );\n const inked = ink === undefined ? \"\" : ` color=\"${ink}\"`;\n return `<svg xmlns=\"${SVG_NS}\"${inked} width=\"${cw}\" height=\"${ch}\" viewBox=\"0 0 ${cw} ${ch}\"><rect width=\"${cw}\" height=\"${ch}\" fill=\"${background}\"/>${inner}</svg>`;\n}\n\n/**\n * True when `e` is Node's \"cannot find\" (`ERR_MODULE_NOT_FOUND` / `MODULE_NOT_FOUND`) for the optional peer `name`\n * itself, on the error or under a loader's wrapper (vitest's mock error, say); a file missing inside an installed peer\n * is not.\n *\n * @example\n * ```ts\n * import { createRequire } from \"node:module\";\n * import { peerMissing } from \"@sportsdataverse/sdvplot/export\";\n *\n * // Node's resolver, asked for a package that is not installed, throws MODULE_NOT_FOUND naming it\n * const name = \"@sportsdataverse/no-such-peer\";\n * let error: unknown;\n * try {\n * createRequire(import.meta.url).resolve(name);\n * } catch (e) {\n * error = e;\n * }\n * peerMissing(error, name); // true; peerMissing(error, \"@resvg/resvg-js\") is false\n * ```\n */\nexport function peerMissing(e: unknown, name: string): boolean {\n const quoted = new RegExp(`['\"]${name.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")}['\"]`);\n return (\n e instanceof Error &&\n ((/MODULE_NOT_FOUND/.test(String((e as { code?: unknown }).code)) && quoted.test(e.message)) ||\n peerMissing(e.cause, name))\n );\n}\n\n/** The bytes at `url`; a network failure or a non-2xx answer is a DownloadError. */\nasync function download(url: string): Promise<Uint8Array> {\n let r: Response;\n try {\n r = await fetch(url);\n if (r.ok) return new Uint8Array(await r.arrayBuffer());\n } catch (e) {\n throw Object.assign(new DownloadError(`toPNG could not download ${url}: ${String(e)}`, url), {\n cause: e,\n });\n }\n throw new DownloadError(`toPNG could not download ${url}: it answered ${r.status}`, url, r.status);\n}\n\n/** At most this many image downloads in flight at once: a figure with hundreds of logos must not open hundreds of sockets. */\nconst FETCH_LIMIT = 8;\n\n/** `fn` over `xs` with at most `limit` calls in flight; results keep input order, and the first failure stops new calls. */\nasync function mapLimit<T, R>(xs: readonly T[], limit: number, fn: (x: T) => Promise<R>): Promise<R[]> {\n const out = new Array<R>(xs.length);\n let next = 0;\n const worker = async (): Promise<void> => {\n while (next < xs.length) {\n const i = next++;\n try {\n out[i] = await fn(xs[i] as T);\n } catch (e) {\n next = xs.length;\n throw e;\n }\n }\n };\n await Promise.all(Array.from({ length: Math.min(limit, xs.length) }, worker));\n return out;\n}\n\n/** `href=\"url\"` / `xlink:href='url'` attributes, the URL as written or with `&` escaped as `&amp;`. */\nconst hrefAttr = (url: string): RegExp => {\n const re = (s: string) => s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n return new RegExp(`(href=)([\"'])(?:${re(url)}|${re(url.replaceAll(\"&\", \"&amp;\"))})\\\\2`, \"g\");\n};\n\n/**\n * Rasterize an SVG with `@resvg/resvg-js` (optional peer; Node only). Throws OptionalDependencyError when it is missing.\n * An HTML-serialized figure (a DOM element or its `outerHTML`, as Observable Plot makes) gets the `xmlns` (and\n * `xmlns:xlink`) declarations it lacks. Remote images are downloaded and drawn unless `images` is `\"skip\"`. Text is\n * drawn in the system fonts; on a host without any, pass `fonts.files` or every label comes out blank.\n *\n * @example\n * ```ts\n * import { dirname, join } from \"node:path\";\n * import { fileURLToPath } from \"node:url\";\n * import { toPNG } from \"@sportsdataverse/sdvplot/export\";\n *\n * // any .ttf/.otf on disk; this one is Source Sans 3 (OFL) from the sdvplot-js repo's examples/fonts\n * const font = join(dirname(fileURLToPath(import.meta.url)), \"../../../../fonts/SourceSans3-Regular.ttf\");\n * const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"240\" height=\"60\"><text x=\"8\" y=\"42\" font-size=\"32\">Giants 27</text></svg>`;\n * // the same pixels with or without system fonts: only the given file is loaded\n * await toPNG(svg, { background: \"white\", fonts: { files: [font], system: false } });\n * ```\n */\nexport async function toPNG(\n svg: string | { outerHTML: string },\n { width, scale = 1, background, color, images = \"fetch\", fonts = {} }: ToPNGOptions = {},\n): Promise<Uint8Array> {\n if (!(Number.isFinite(scale) && scale > 0))\n throw new InputError(`scale must be a positive number, got ${String(scale)}`);\n if (width !== undefined && !(Number.isFinite(width) && width > 0))\n throw new InputError(`width must be a positive number of pixels, got ${String(width)}`);\n if (background !== undefined) checkColor(\"background\", background);\n if (color !== undefined) checkColor(\"color\", color);\n if (images !== \"fetch\" && images !== \"skip\")\n throw new InputError(`images must be \"fetch\" or \"skip\", got ${JSON.stringify(images)}`);\n const font = await fontOptions(fonts);\n let text = typeof svg === \"string\" ? svg : svg.outerHTML;\n const mod = await import(\"@resvg/resvg-js\").catch((e: unknown) => {\n throw new OptionalDependencyError(\n peerMissing(e, \"@resvg/resvg-js\")\n ? \"toPNG needs the optional peer @resvg/resvg-js, which is not installed: pnpm add @resvg/resvg-js\"\n : `toPNG could not load the optional peer @resvg/resvg-js (installed, but it failed to load): ${String(e)}`,\n { cause: e },\n );\n });\n const fitTo =\n width !== undefined\n ? { mode: \"width\" as const, value: Math.round(width * scale) }\n : { mode: \"zoom\" as const, value: scale };\n const opts = { fitTo, font, ...(background !== undefined && { background }) };\n\n const open = OPEN_TAG.exec(text)?.[0];\n if (open !== undefined) {\n let add = \"\";\n if (!/\\sxmlns=/i.test(open)) add += ` xmlns=\"${SVG_NS}\"`; // resvg parses XML; HTML serialization drops xmlns\n if (/\\sxlink:[\\w-]+=/i.test(text) && !/\\sxmlns:xlink=/i.test(open)) add += ` xmlns:xlink=\"${XLINK_NS}\"`;\n let ink = color;\n if (\n ink === undefined &&\n background !== undefined &&\n !/\\scolor=/i.test(open) &&\n /currentcolor/i.test(text)\n ) {\n // the background as resvg paints it (names and rgb() too): a 1x1 render\n // ponytail: pixels are premultiplied, so a translucent background is judged as if over black\n const p = new mod.Resvg(`<svg xmlns=\"${SVG_NS}\" width=\"1\" height=\"1\"/>`, { background }).render()\n .pixels;\n ink = onColor(`#${[p[0], p[1], p[2]].map((v) => (v ?? 0).toString(16).padStart(2, \"0\")).join(\"\")}`);\n }\n let tag = open;\n if (ink !== undefined) {\n tag = tag.replace(/\\scolor=[\"'][^\"']*[\"']/i, \"\"); // an explicit `color` option replaces the figure's own\n add += ` color=\"${ink}\"`;\n }\n text = text.replace(open, () => tag.replace(/^<svg/i, () => `<svg${add}`));\n }\n\n // the remote hrefs resvg cannot load itself, from a parse without the system-font scan (text does not change them)\n const probe = new mod.Resvg(text, NO_FONTS);\n const hrefs = [...new Set(probe.imagesToResolve())];\n let bodies: Uint8Array[] = [];\n if (hrefs.length > 0 && images === \"skip\") {\n warn(\n `toPNG:skip:${hrefs.join(\" \")}`,\n `toPNG left out ${hrefs.length} remote image(s): ${hrefs.join(\", \")}`,\n );\n } else if (hrefs.length > 0) {\n bodies = await mapLimit(hrefs, FETCH_LIMIT, download);\n const zoom = fitTo.mode === \"width\" ? fitTo.value / probe.width : scale;\n const tags = text.match(/<image\\b[^>]*>/gi) ?? [];\n // every image goes in as a data URI, so ONE Resvg draws them all: resolveImage costs ~150 ms a call\n for (const [i, href] of hrefs.entries()) {\n const b = bodies[i] as Uint8Array;\n let uri = dataURI(b);\n const re = hrefAttr(href);\n const small = shrink(\n mod,\n uri,\n tags.filter((t) => t.search(re) >= 0),\n zoom,\n );\n if (small !== undefined) uri = dataURI(small);\n text = text.replace(re, (_m, attr: string, q: string) => `${attr}${q}${uri}${q}`);\n }\n }\n const resvg = new mod.Resvg(text, opts);\n if (bodies.length > 0) {\n // an href escaped in a way hrefAttr does not match is still drawn, the slow way (resolveImage: raster only)\n const left = new Set(resvg.imagesToResolve());\n for (const [i, href] of hrefs.entries())\n if (left.has(href)) resvg.resolveImage(href, Buffer.from(bodies[i] as Uint8Array));\n }\n return new Uint8Array(resvg.render().asPng());\n}\n\nconst NO_FONTS = { font: { loadSystemFonts: false } };\n\n/** `fonts` as resvg's `font` option; a missing font file is an InputError (resvg would skip it, drawing no text). */\nasync function fontOptions(fonts: ToPNGOptions[\"fonts\"]) {\n if (typeof fonts !== \"object\" || fonts === null || Array.isArray(fonts))\n throw new InputError(\n `fonts must be an object { files, defaultFamily, system }, got ${JSON.stringify(fonts)}`,\n );\n const { files = [], defaultFamily, system = true } = fonts;\n if (!Array.isArray(files) || files.some((f) => typeof f !== \"string\"))\n throw new InputError(`fonts.files must be an array of font file paths, got ${JSON.stringify(files)}`);\n if (defaultFamily !== undefined && typeof defaultFamily !== \"string\")\n throw new InputError(`fonts.defaultFamily must be a string, got ${JSON.stringify(defaultFamily)}`);\n if (typeof system !== \"boolean\")\n throw new InputError(`fonts.system must be a boolean, got ${JSON.stringify(system)}`);\n if (files.length > 0) {\n const { statSync } = await import(\"node:fs\"); // ponytail: loaded only when files are given; /export is Node-only\n for (const f of files)\n if (!statSync(f, { throwIfNoEntry: false })?.isFile())\n throw new InputError(`fonts.files: no font file at ${JSON.stringify(f)}`);\n }\n return {\n loadSystemFonts: system,\n fontFiles: [...files],\n ...(defaultFamily !== undefined && { defaultFontFamily: defaultFamily }),\n };\n}\n/** A shared image's one raster is this many times its largest box: headroom for a transform that enlarges it. */\nconst OVERSAMPLE = 2;\n\n/**\n * resvg decodes an `<image>` per element, at the image's own size: 2000 uses of a 500 px logo held 2 GB for 6 s (a\n * `<use>` or resolveImage costs the same). An image used more than once is therefore drawn once, at OVERSAMPLE times its\n * largest box in output pixels, and every use inlines that small PNG. A single use keeps the original.\n */\nfunction shrink(\n mod: typeof import(\"@resvg/resvg-js\"),\n uri: string,\n uses: readonly string[],\n zoom: number,\n): Uint8Array | undefined {\n if (uses.length < 2) return undefined;\n let side = 0;\n for (const tag of uses) {\n const w = userUnits(attrOf(tag, \"width\"));\n const h = userUnits(attrOf(tag, \"height\"));\n // ponytail: a use without a numeric size (auto, %) keeps the full image, and its per-use decode\n if (!(w > 0 && h > 0)) return undefined;\n side = Math.max(side, w, h);\n }\n // the image's own size, read from its header (an image with no width/height is drawn at it)\n const own = new mod.Resvg(\n `<svg xmlns=\"${SVG_NS}\" width=\"1\" height=\"1\"><image href=\"${uri}\"/></svg>`,\n NO_FONTS,\n ).getBBox();\n const k = own ? Math.ceil(OVERSAMPLE * zoom * side) / Math.max(own.width, own.height) : 1;\n if (!own || !(k < 1)) return undefined;\n const [w, h] = [Math.max(1, Math.round(own.width * k)), Math.max(1, Math.round(own.height * k))];\n return new mod.Resvg(\n `<svg xmlns=\"${SVG_NS}\" width=\"${w}\" height=\"${h}\"><image href=\"${uri}\" width=\"${w}\" height=\"${h}\" preserveAspectRatio=\"none\"/></svg>`,\n NO_FONTS,\n )\n .render()\n .asPng();\n}\n\nconst dataURI = (b: Uint8Array): string => `data:${imageType(b)};base64,${Buffer.from(b).toString(\"base64\")}`;\n\n/** A downloaded image's data-URI type from its first bytes: SVG markup, JPEG, GIF, else PNG. */\nfunction imageType(b: Uint8Array): string {\n if (new TextDecoder().decode(b.subarray(0, 64)).trimStart().startsWith(\"<\")) return \"image/svg+xml\";\n if (b[0] === 0xff && b[1] === 0xd8) return \"image/jpeg\";\n if (b[0] === 0x47 && b[1] === 0x49 && b[2] === 0x46) return \"image/gif\";\n return \"image/png\";\n}\n"]}
@@ -0,0 +1,40 @@
1
+ import { V as Value } from './resolve-CQW-jzvr.js';
2
+ import { H as HeadshotIdSystem } from './types-C7n6gJF3.js';
3
+
4
+ /** Port of `_headshots.ESPN_HEADSHOT_LEAGUES`. */
5
+ declare const ESPN_HEADSHOT_LEAGUES: {
6
+ readonly nfl: "nfl";
7
+ readonly nba: "nba";
8
+ readonly wnba: "wnba";
9
+ readonly mlb: "mlb";
10
+ readonly nhl: "nhl";
11
+ readonly cfb: "college-football";
12
+ readonly mbb: "mens-college-basketball";
13
+ readonly wbb: "womens-college-basketball";
14
+ };
15
+ /** Leagues with ESPN headshots (gsis ids are nfl-only, and nfl is one of these). */
16
+ type EspnHeadshotLeague = keyof typeof ESPN_HEADSHOT_LEAGUES;
17
+ /** Width / height of a headshot image box (the ESPN combiner crop). */
18
+ declare const HEADSHOT_ASPECT: number;
19
+ declare function nbaHeadshotUrl(id: string | number): string;
20
+ declare function wnbaHeadshotUrl(id: string | number): string;
21
+ declare function mlbHeadshotUrl(id: string | number): string;
22
+ declare function nhlHeadshotUrl(id: string | number): string;
23
+ /** Loads the bundled nflverse gsis map (its own ~3 MB chunk, imported only on demand); required before `headshotUrl(…, { idSystem: "gsis" })`. Nothing is downloaded. */
24
+ declare function loadGsis(): Promise<void>;
25
+ /**
26
+ * Sync port of `_headshots.headshot_url`. ESPN ids need no data; gsis ids need `await loadGsis()` (or `preloadAll()`)
27
+ * first.
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * import { headshotUrl } from "@sportsdataverse/sdvplot";
32
+ *
33
+ * headshotUrl("3139477", "nfl"); // Patrick Mahomes, by ESPN athlete id
34
+ * ```
35
+ */
36
+ declare function headshotUrl(playerId: Value, league: EspnHeadshotLeague, { idSystem }?: {
37
+ idSystem?: HeadshotIdSystem;
38
+ }): string | undefined;
39
+
40
+ export { type EspnHeadshotLeague as E, HEADSHOT_ASPECT as H, ESPN_HEADSHOT_LEAGUES as a, nhlHeadshotUrl as b, headshotUrl as h, loadGsis as l, mlbHeadshotUrl as m, nbaHeadshotUrl as n, wnbaHeadshotUrl as w };
@@ -0,0 +1,182 @@
1
+ import { A as Alias, a as MarkRow, S as SeasonInput, L as League, b as LeagueData, c as Team } from './types-C7n6gJF3.js';
2
+ export { E as EXPLICIT_ONLY, H as HeadshotIdSystem, d as INDEX_VERSION, I as IdSystem, e as LEAGUES, M as MarkType, P as PRIORITY, T as TeamId, f as VARIANTS, V as Variant, W as Which } from './types-C7n6gJF3.js';
3
+ import { R as ResolveOptions, V as Value } from './resolve-CQW-jzvr.js';
4
+ export { a as Resolved, r as resolve, b as resolveSync, s as suggest } from './resolve-CQW-jzvr.js';
5
+ export { C as ColorOptions, a as ColorResult, L as LogoUrlOptions, S as SelectOptions, l as logoUrl, b as logoUrlSync, m as marks, p as palette, s as selectMark, c as selectMarkSync, t as teamColors, d as teamColorsSync } from './marks-DH-tQIP-.js';
6
+ export { K as Kind, b as PlaceOptions, P as Placement, c as TIERS_SUBTITLE, d as TIER_DESC, e as TIER_THEMES, a as TierRow, f as Tiers, T as TiersOptions, g as checkAlpha, h as checkHeight, p as place, i as placeSync, j as prepareTiers, w as wrapLabel } from './tiers-B6pUBPcE.js';
7
+ export { a as ESPN_HEADSHOT_LEAGUES, E as EspnHeadshotLeague, H as HEADSHOT_ASPECT, h as headshotUrl, l as loadGsis, m as mlbHeadshotUrl, n as nbaHeadshotUrl, b as nhlHeadshotUrl, w as wnbaHeadshotUrl } from './headshots-B2J_LOO8.js';
8
+ export { C as Cursor, R as RowFilter, b as SelectionPatch, a as SelectionState, S as SelectionStore, c as createSelection, f as focusIds, s as sameCursor, d as sameIds, t as toId } from './selection-D4T3PkRt.js';
9
+
10
+ declare const MANIFEST_URL = "https://sdv.nyc3.cdn.digitaloceanspaces.com/assets/public/manifest/marks.csv";
11
+ interface ManifestRow {
12
+ level: string;
13
+ league: string;
14
+ entity_id: string;
15
+ mark_type: string;
16
+ variant: string;
17
+ valid_from: string;
18
+ valid_to: string;
19
+ source: string;
20
+ sha256: string;
21
+ ext: string;
22
+ width: string;
23
+ height: string;
24
+ archive_url: string;
25
+ first_seen: string;
26
+ }
27
+ /** RFC 4180 over the whole text (quoted commas, doubled quotes, embedded newlines; CRLF or LF); rows keyed by header name. */
28
+ declare function parseManifestCsv(text: string): ManifestRow[];
29
+ /** Alias-mapped, safe-URL-filtered, ranked marks of one league; `archive_url` is derived, never copied. Not deduped. */
30
+ declare function manifestMarks(league: string, rows: readonly ManifestRow[], aliases: readonly Alias[]): MarkRow[];
31
+ declare function resetManifestCache(): void;
32
+ /** The CDN manifest, fetched once per process (a failure is not cached). */
33
+ declare function fetchManifest(o?: {
34
+ fetch?: typeof fetch;
35
+ }): Promise<ManifestRow[]>;
36
+
37
+ interface Rankable {
38
+ source_rank: number;
39
+ valid_from: number | null;
40
+ valid_to: number | null;
41
+ first_seen: string;
42
+ sha256: string;
43
+ }
44
+ /** Python `_ranked`: source_rank asc, open-ended (valid_to null) first, valid_to desc, first_seen desc, valid_from desc, sha256 asc; nulls last. */
45
+ declare function compareMarks(a: Rankable, b: Rankable): number;
46
+
47
+ declare class SdvplotError extends Error {
48
+ constructor(message: string, options?: ErrorOptions);
49
+ }
50
+ declare class InputError extends SdvplotError {
51
+ }
52
+ declare class UnresolvedTeamError extends SdvplotError {
53
+ }
54
+ declare class UnsupportedTargetError extends SdvplotError {
55
+ }
56
+ /** An optional peer dependency (resvg, playwright, react) is not installed. */
57
+ declare class OptionalDependencyError extends SdvplotError {
58
+ }
59
+ declare class OfflineError extends SdvplotError {
60
+ }
61
+ declare class DownloadError extends OfflineError {
62
+ readonly url: string;
63
+ readonly status?: number | undefined;
64
+ constructor(message: string, url: string, status?: number | undefined);
65
+ }
66
+ type WarningHandler = (message: string) => void;
67
+ declare function setWarningHandler(fn: WarningHandler | null): void;
68
+ declare function resetWarnings(): void;
69
+ /** One warning per `key` per process (spec §4.3): a 10k-row join must not print 10k lines. */
70
+ declare function warn(key: string, message: string): void;
71
+
72
+ /** Port of `_normalize.norm_value`: trimmed, accents + typographic punctuation folded, case-folded, integral numbers without ".0". */
73
+ declare function normValue(value: unknown): string | null;
74
+ declare function normSeason(value: SeasonInput, league?: League): number | null;
75
+
76
+ /**
77
+ * Load a league's bundled teams, aliases and marks (one code-split chunk; nothing is downloaded). Every `*Sync`
78
+ * function needs it first. Async throughout: an unknown league rejects (never throws synchronously); a failed chunk
79
+ * load can be retried.
80
+ *
81
+ * @example
82
+ * ```ts
83
+ * import { loadLeague } from "@sportsdataverse/sdvplot";
84
+ *
85
+ * const nfl = await loadLeague("nfl");
86
+ * nfl.teams.find((t) => t.abbr === "KC");
87
+ * ```
88
+ */
89
+ declare function loadLeague(league: League): Promise<LeagueData>;
90
+ /** Every league shard plus the gsis map, so every *Sync variant works afterwards. */
91
+ declare function preloadAll(): Promise<void>;
92
+ /** Port of `_index.season_bounds`: [first, last]; last = max(latest alias season, next year). */
93
+ declare function seasonBounds(league?: League): readonly [number, number] | null;
94
+ /**
95
+ * The latest season any dated alias of `league` names (the last relocation or rename the index records), or `null`
96
+ * when no alias is dated. It is not the current season: the NHL's is 1997. A value resolved without a season is
97
+ * matched at this season first.
98
+ */
99
+ declare const latestSeason: (league: League) => number | null;
100
+
101
+ /** All teams for one league, or every league (in `LEAGUES` order) when omitted. */
102
+ declare function teams(league?: League): Promise<readonly Team[]>;
103
+
104
+ /** Column form → `Row[]` (flat objects, one per index). Columns must be equal length; `{}` → `[]`. */
105
+ declare function rowsFrom(columns: Record<string, readonly unknown[]>): Record<string, unknown>[];
106
+
107
+ /** Options for {@link matchupColors}: the league, how to resolve the two teams, and the backgrounds. */
108
+ interface MatchupColorOptions extends ResolveOptions {
109
+ /** The league both teams belong to. */
110
+ league: League;
111
+ /** The background each theme's pair must read on; default `{ light: "#ffffff", dark: "#181a1b" }` (Game on Paper's pages). */
112
+ theme?: {
113
+ light?: string;
114
+ dark?: string;
115
+ };
116
+ }
117
+ /** One `[teamA, teamB]` colour pair per theme, as lowercase `#rrggbb`. */
118
+ interface MatchupColors {
119
+ /** The pair for a light background. */
120
+ light: [string, string];
121
+ /** The pair for a dark background. */
122
+ dark: [string, string];
123
+ }
124
+ /**
125
+ * {@link matchupColors} once the league is loaded (`loadLeague` or `preloadAll`).
126
+ *
127
+ * @example
128
+ * ```ts
129
+ * import { loadLeague, matchupColorsSync } from "@sportsdataverse/sdvplot";
130
+ *
131
+ * await loadLeague("cfb");
132
+ * matchupColorsSync("Alabama", "Georgia", { league: "cfb" });
133
+ * ```
134
+ */
135
+ declare function matchupColorsSync(teamA: Value, teamB: Value, opts: MatchupColorOptions): MatchupColors;
136
+ /**
137
+ * Two team colours that tell the teams apart on a chart: Game on Paper's "game colours" picker.
138
+ *
139
+ * @remarks
140
+ * One pair per theme, each the first candidate whose colours are at least 20 apart in CIEDE2000 and each
141
+ * at least 2.5:1 (WCAG) against that theme's background. Candidates, in order: both primaries, teamB's
142
+ * secondary, teamA's secondary, both secondaries; so a team keeps its primary whenever it works, and teamA
143
+ * (Game on Paper's home team) keeps it first. When no candidate works, an unreadable colour's L* moves just
144
+ * far enough to read; then both colours' L* move, least total movement first, until they separate; failing
145
+ * that, the widest readable separation found. A team with no colour gets `#2394fd`. Deterministic.
146
+ *
147
+ * @example
148
+ * ```ts
149
+ * import { matchupColors } from "@sportsdataverse/sdvplot";
150
+ *
151
+ * // two crimson teams; light: ["#9e1b32", "#2c2a29"] (Georgia's secondary), dark: ["#ffffff", "#ba0c2f"]
152
+ * // in a page, pick the pair for the theme:
153
+ * // const [alabama, georgia] = window.matchMedia("(prefers-color-scheme: dark)").matches ? dark : light;
154
+ * await matchupColors("Alabama", "Georgia", { league: "cfb" });
155
+ * ```
156
+ */
157
+ declare function matchupColors(teamA: Value, teamB: Value, opts: MatchupColorOptions): Promise<MatchupColors>;
158
+
159
+ /** A color as lowercase `#rrggbb`: accepts `#rgb`, `#rrggbb`, `#rgba`, `#rrggbbaa` (`#` optional). Transparency throws unless `dropAlpha`. */
160
+ declare function hex6(color: string, opts?: {
161
+ dropAlpha?: boolean;
162
+ }): string;
163
+ /** WCAG relative luminance, 0 (black) to 1 (white). */
164
+ declare function luminance(color: string): number;
165
+ /** WCAG contrast ratio, 1 (same) to 21 (black on white). */
166
+ declare function contrast(a: string, b: string): number;
167
+ /** Black or white, whichever reads better on `background`. */
168
+ declare function onColor(background: string): string;
169
+ /** The color `t` of the way from `a` to `b` in sRGB (`t` in [0, 1]). */
170
+ declare function mix(a: string, b: string, t: number): string;
171
+ /** The opaque `#rrggbb` a hex color shows as over `background`: a translucent color is alpha-composited onto it. */
172
+ declare function solid(color: string, background?: string): string;
173
+
174
+ declare function versions(): {
175
+ sdvplot: string;
176
+ index: string;
177
+ manifestLastModified: string;
178
+ };
179
+
180
+ declare const VERSION: string;
181
+
182
+ export { Alias, DownloadError, InputError, League, LeagueData, MANIFEST_URL, type ManifestRow, MarkRow, type MatchupColorOptions, type MatchupColors, OfflineError, OptionalDependencyError, type Rankable, ResolveOptions, SdvplotError, SeasonInput, Team, UnresolvedTeamError, UnsupportedTargetError, VERSION, Value, type WarningHandler, compareMarks, contrast, fetchManifest, hex6, latestSeason, loadLeague, luminance, manifestMarks, matchupColors, matchupColorsSync, mix, normSeason, normValue, onColor, parseManifestCsv, preloadAll, resetManifestCache, resetWarnings, rowsFrom, seasonBounds, setWarningHandler, solid, teams, versions, warn };
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ export { VERSION, matchupColors, matchupColorsSync, rowsFrom, teams, versions } from './chunk-JJFTD4VB.js';
2
+ export { TIERS_SUBTITLE, TIER_DESC, TIER_THEMES, prepareTiers, wrapLabel } from './chunk-NLPH2VZT.js';
3
+ export { createSelection, focusIds, sameCursor, sameIds, toId } from './chunk-4C3GX6QO.js';
4
+ export { checkAlpha, checkHeight, place, placeSync } from './chunk-RMT2GMFH.js';
5
+ export { MANIFEST_URL, compareMarks, fetchManifest, logoUrl, logoUrlSync, manifestMarks, marks, parseManifestCsv, resetManifestCache, selectMark, selectMarkSync } from './chunk-KKH6ABMA.js';
6
+ export { contrast, hex6, luminance, mix, onColor, solid } from './chunk-J6R2LEJ7.js';
7
+ export { ESPN_HEADSHOT_LEAGUES, EXPLICIT_ONLY, HEADSHOT_ASPECT, INDEX_VERSION, LEAGUES, PRIORITY, VARIANTS, headshotUrl, latestSeason, loadGsis, loadLeague, mlbHeadshotUrl, nbaHeadshotUrl, nhlHeadshotUrl, normSeason, normValue, palette, preloadAll, resolve, resolveSync, seasonBounds, suggest, teamColors, teamColorsSync, wnbaHeadshotUrl } from './chunk-TAXO3VXH.js';
8
+ export { DownloadError, InputError, OfflineError, OptionalDependencyError, SdvplotError, UnresolvedTeamError, UnsupportedTargetError, resetWarnings, setWarningHandler, warn } from './chunk-E7G7VSLV.js';
9
+ //# sourceMappingURL=index.js.map
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}