ooxml-core 0.20.0 → 0.21.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.
- package/README.md +21 -43
- package/dist/chart/axis-nice.d.ts +97 -0
- package/dist/chart/axis-nice.d.ts.map +1 -0
- package/dist/chart/histogram-binning.d.ts +40 -0
- package/dist/chart/histogram-binning.d.ts.map +1 -0
- package/dist/chart/index.cjs +167 -0
- package/dist/chart/index.d.ts +2 -0
- package/dist/chart/index.d.ts.map +1 -1
- package/dist/chart/index.mjs +162 -1
- package/dist/index.cjs +167 -0
- package/dist/index.mjs +167 -0
- package/dist/pptx/automation/index.cjs +1572 -863
- package/dist/pptx/automation/index.d.ts +4 -3
- package/dist/pptx/automation/index.d.ts.map +1 -1
- package/dist/pptx/automation/index.mjs +1572 -863
- package/dist/pptx/chunks/color-ref-BM66NGFP.d.ts +42 -0
- package/dist/pptx/chunks/color-ref-BM66NGFP.d.ts.map +1 -0
- package/dist/pptx/chunks/{index-D0yGoLyw.d.ts → index-CcQTCBnT.d.ts} +63 -479
- package/dist/pptx/chunks/index-CcQTCBnT.d.ts.map +1 -0
- package/dist/pptx/chunks/{index-BtBj3VG1.d.ts → index-DHoPgFcH.d.ts} +529 -11
- package/dist/pptx/chunks/index-DHoPgFcH.d.ts.map +1 -0
- package/dist/pptx/chunks/{text-operations-GuisjlbR.d.ts → text-operations-BzdehTeY.d.ts} +50 -51
- package/dist/pptx/chunks/text-operations-BzdehTeY.d.ts.map +1 -0
- package/dist/pptx/cli/index.cjs +1204 -489
- package/dist/pptx/cli/index.d.ts +1 -1
- package/dist/pptx/cli/index.mjs +1204 -489
- package/dist/pptx/converter/index.cjs +8 -5
- package/dist/pptx/converter/index.d.ts +1 -1
- package/dist/pptx/converter/index.mjs +8 -5
- package/dist/pptx/index.cjs +1699 -989
- package/dist/pptx/index.d.ts +5 -4
- package/dist/pptx/index.mjs +1698 -990
- package/dist/pptx/ui/index.cjs +510 -0
- package/dist/pptx/ui/index.d.ts +80 -0
- package/dist/pptx/ui/index.d.ts.map +1 -0
- package/dist/pptx/ui/index.mjs +499 -0
- package/package.json +15 -4
- package/dist/pptx/chunks/index-BtBj3VG1.d.ts.map +0 -1
- package/dist/pptx/chunks/index-D0yGoLyw.d.ts.map +0 -1
- package/dist/pptx/chunks/text-operations-GuisjlbR.d.ts.map +0 -1
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/color/color-primitives.ts
|
|
4
|
+
function clampUnitInterval(value) {
|
|
5
|
+
return Math.min(1, Math.max(0, value));
|
|
6
|
+
}
|
|
7
|
+
function normalizeHexColor(value, fallback = "#111827") {
|
|
8
|
+
if (!value || value === "transparent") {
|
|
9
|
+
return fallback;
|
|
10
|
+
}
|
|
11
|
+
const candidate = value.startsWith("#") ? value : `#${value}`;
|
|
12
|
+
return /^#[0-9A-Fa-f]{6}$/.test(candidate) ? candidate : fallback;
|
|
13
|
+
}
|
|
14
|
+
function hexToRgbChannels(color) {
|
|
15
|
+
const normalized = color.replace("#", "");
|
|
16
|
+
if (!/^[0-9a-fA-F]{6}$/.test(normalized)) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
r: Number.parseInt(normalized.slice(0, 2), 16),
|
|
21
|
+
g: Number.parseInt(normalized.slice(2, 4), 16),
|
|
22
|
+
b: Number.parseInt(normalized.slice(4, 6), 16)
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function percentDivisorFor(text) {
|
|
26
|
+
return text.endsWith("%") ? 100 : 1e5;
|
|
27
|
+
}
|
|
28
|
+
function parseOoxmlPercent(value) {
|
|
29
|
+
const text = String(value ?? "").trim();
|
|
30
|
+
const divisor = percentDivisorFor(text);
|
|
31
|
+
const magnitude = Number.parseFloat(divisor === 100 ? text.slice(0, -1) : text);
|
|
32
|
+
if (!Number.isFinite(magnitude)) {
|
|
33
|
+
return void 0;
|
|
34
|
+
}
|
|
35
|
+
return magnitude / divisor;
|
|
36
|
+
}
|
|
37
|
+
function parseDrawingPercent(value) {
|
|
38
|
+
const parsed = parseOoxmlPercent(value);
|
|
39
|
+
return parsed === void 0 ? void 0 : clampUnitInterval(parsed);
|
|
40
|
+
}
|
|
41
|
+
function toHex(value) {
|
|
42
|
+
return Math.min(255, Math.max(0, Math.round(value))).toString(16).padStart(2, "0").toUpperCase();
|
|
43
|
+
}
|
|
44
|
+
function rgbToHsl(r, g, b) {
|
|
45
|
+
const rN = r / 255;
|
|
46
|
+
const gN = g / 255;
|
|
47
|
+
const bN = b / 255;
|
|
48
|
+
const cMax = Math.max(rN, gN, bN);
|
|
49
|
+
const cMin = Math.min(rN, gN, bN);
|
|
50
|
+
const delta = cMax - cMin;
|
|
51
|
+
const l = (cMax + cMin) / 2;
|
|
52
|
+
let s = 0;
|
|
53
|
+
if (delta !== 0) {
|
|
54
|
+
s = delta / (1 - Math.abs(2 * l - 1));
|
|
55
|
+
}
|
|
56
|
+
let h = 0;
|
|
57
|
+
if (delta !== 0) {
|
|
58
|
+
if (cMax === rN) {
|
|
59
|
+
h = 60 * ((gN - bN) / delta % 6);
|
|
60
|
+
} else if (cMax === gN) {
|
|
61
|
+
h = 60 * ((bN - rN) / delta + 2);
|
|
62
|
+
} else {
|
|
63
|
+
h = 60 * ((rN - gN) / delta + 4);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (h < 0) {
|
|
67
|
+
h += 360;
|
|
68
|
+
}
|
|
69
|
+
return { h, s: clampUnitInterval(s), l: clampUnitInterval(l) };
|
|
70
|
+
}
|
|
71
|
+
function hslToRgb(h, s, l) {
|
|
72
|
+
const sC = clampUnitInterval(s);
|
|
73
|
+
const lC = clampUnitInterval(l);
|
|
74
|
+
const hN = (h % 360 + 360) % 360;
|
|
75
|
+
const c = (1 - Math.abs(2 * lC - 1)) * sC;
|
|
76
|
+
const x = c * (1 - Math.abs(hN / 60 % 2 - 1));
|
|
77
|
+
const m = lC - c / 2;
|
|
78
|
+
let rP = 0;
|
|
79
|
+
let gP = 0;
|
|
80
|
+
let bP = 0;
|
|
81
|
+
if (hN < 60) {
|
|
82
|
+
rP = c;
|
|
83
|
+
gP = x;
|
|
84
|
+
bP = 0;
|
|
85
|
+
} else if (hN < 120) {
|
|
86
|
+
rP = x;
|
|
87
|
+
gP = c;
|
|
88
|
+
bP = 0;
|
|
89
|
+
} else if (hN < 180) {
|
|
90
|
+
rP = 0;
|
|
91
|
+
gP = c;
|
|
92
|
+
bP = x;
|
|
93
|
+
} else if (hN < 240) {
|
|
94
|
+
rP = 0;
|
|
95
|
+
gP = x;
|
|
96
|
+
bP = c;
|
|
97
|
+
} else if (hN < 300) {
|
|
98
|
+
rP = x;
|
|
99
|
+
gP = 0;
|
|
100
|
+
bP = c;
|
|
101
|
+
} else {
|
|
102
|
+
rP = c;
|
|
103
|
+
gP = 0;
|
|
104
|
+
bP = x;
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
r: Math.round((rP + m) * 255),
|
|
108
|
+
g: Math.round((gP + m) * 255),
|
|
109
|
+
b: Math.round((bP + m) * 255)
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function parseDrawingFraction(value) {
|
|
113
|
+
return parseOoxmlPercent(value);
|
|
114
|
+
}
|
|
115
|
+
function parseDrawingHueDegrees(value) {
|
|
116
|
+
const parsed = Number.parseFloat(String(value ?? "").trim());
|
|
117
|
+
if (!Number.isFinite(parsed)) {
|
|
118
|
+
return void 0;
|
|
119
|
+
}
|
|
120
|
+
return parsed / 6e4;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// src/color/color-linear.ts
|
|
124
|
+
function srgb255ToLinear(channel) {
|
|
125
|
+
const c = clampUnitInterval(channel / 255);
|
|
126
|
+
return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
|
|
127
|
+
}
|
|
128
|
+
function linearToSrgb255(linear) {
|
|
129
|
+
const c = clampUnitInterval(linear);
|
|
130
|
+
return 255 * (c <= 31308e-7 ? c * 12.92 : 1.055 * c ** (1 / 2.4) - 0.055);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// src/pptx/core/color/color-transforms.ts
|
|
134
|
+
function applyDrawingColorTransforms(baseColor, colorNode) {
|
|
135
|
+
const rgb = hexToRgbChannels(baseColor);
|
|
136
|
+
if (!rgb) {
|
|
137
|
+
return baseColor;
|
|
138
|
+
}
|
|
139
|
+
let r = rgb.r;
|
|
140
|
+
let g = rgb.g;
|
|
141
|
+
let b = rgb.b;
|
|
142
|
+
const getVal = (key) => colorNode[key]?.["@_val"];
|
|
143
|
+
if (colorNode["a:gamma"] !== void 0) {
|
|
144
|
+
const out = applySrgbGammaEncode(r, g, b);
|
|
145
|
+
r = out.r;
|
|
146
|
+
g = out.g;
|
|
147
|
+
b = out.b;
|
|
148
|
+
}
|
|
149
|
+
if (colorNode["a:invGamma"] !== void 0) {
|
|
150
|
+
const out = applySrgbGammaDecode(r, g, b);
|
|
151
|
+
r = out.r;
|
|
152
|
+
g = out.g;
|
|
153
|
+
b = out.b;
|
|
154
|
+
}
|
|
155
|
+
if (colorNode["a:comp"] !== void 0) {
|
|
156
|
+
const hsl = rgbToHsl(r, g, b);
|
|
157
|
+
hsl.h = (hsl.h + 180) % 360;
|
|
158
|
+
const out = hslToRgb(hsl.h, hsl.s, hsl.l);
|
|
159
|
+
r = out.r;
|
|
160
|
+
g = out.g;
|
|
161
|
+
b = out.b;
|
|
162
|
+
}
|
|
163
|
+
if (colorNode["a:inv"] !== void 0) {
|
|
164
|
+
r = 255 - r;
|
|
165
|
+
g = 255 - g;
|
|
166
|
+
b = 255 - b;
|
|
167
|
+
}
|
|
168
|
+
if (colorNode["a:gray"] !== void 0) {
|
|
169
|
+
const gray = Math.round(0.299 * r + 0.587 * g + 0.114 * b);
|
|
170
|
+
r = gray;
|
|
171
|
+
g = gray;
|
|
172
|
+
b = gray;
|
|
173
|
+
}
|
|
174
|
+
const shade = parseDrawingPercent(getVal("a:shade"));
|
|
175
|
+
if (shade !== void 0) {
|
|
176
|
+
r = linearToSrgb255(srgb255ToLinear(r) * shade);
|
|
177
|
+
g = linearToSrgb255(srgb255ToLinear(g) * shade);
|
|
178
|
+
b = linearToSrgb255(srgb255ToLinear(b) * shade);
|
|
179
|
+
}
|
|
180
|
+
const tint = parseDrawingPercent(getVal("a:tint"));
|
|
181
|
+
if (tint !== void 0) {
|
|
182
|
+
r = linearToSrgb255(1 - (1 - srgb255ToLinear(r)) * tint);
|
|
183
|
+
g = linearToSrgb255(1 - (1 - srgb255ToLinear(g)) * tint);
|
|
184
|
+
b = linearToSrgb255(1 - (1 - srgb255ToLinear(b)) * tint);
|
|
185
|
+
}
|
|
186
|
+
const hslKeys = [
|
|
187
|
+
"a:hue",
|
|
188
|
+
"a:hueMod",
|
|
189
|
+
"a:hueOff",
|
|
190
|
+
"a:sat",
|
|
191
|
+
"a:satMod",
|
|
192
|
+
"a:satOff",
|
|
193
|
+
"a:lum",
|
|
194
|
+
"a:lumMod",
|
|
195
|
+
"a:lumOff"
|
|
196
|
+
];
|
|
197
|
+
const hasHsl = hslKeys.some((k) => colorNode[k] !== void 0);
|
|
198
|
+
if (hasHsl) {
|
|
199
|
+
const hsl = rgbToHsl(r, g, b);
|
|
200
|
+
const hueAbs = parseDrawingHueDegrees(getVal("a:hue"));
|
|
201
|
+
if (hueAbs !== void 0) {
|
|
202
|
+
hsl.h = (hueAbs % 360 + 360) % 360;
|
|
203
|
+
}
|
|
204
|
+
const hueMod = parseDrawingFraction(getVal("a:hueMod"));
|
|
205
|
+
if (hueMod !== void 0) {
|
|
206
|
+
hsl.h = (hsl.h * hueMod % 360 + 360) % 360;
|
|
207
|
+
}
|
|
208
|
+
const hueOff = parseDrawingHueDegrees(getVal("a:hueOff"));
|
|
209
|
+
if (hueOff !== void 0) {
|
|
210
|
+
hsl.h = ((hsl.h + hueOff) % 360 + 360) % 360;
|
|
211
|
+
}
|
|
212
|
+
const satAbs = parseDrawingFraction(getVal("a:sat"));
|
|
213
|
+
if (satAbs !== void 0) {
|
|
214
|
+
hsl.s = clampUnitInterval(satAbs);
|
|
215
|
+
}
|
|
216
|
+
const satMod = parseDrawingFraction(getVal("a:satMod"));
|
|
217
|
+
if (satMod !== void 0) {
|
|
218
|
+
hsl.s = clampUnitInterval(hsl.s * satMod);
|
|
219
|
+
}
|
|
220
|
+
const satOff = parseDrawingFraction(getVal("a:satOff"));
|
|
221
|
+
if (satOff !== void 0) {
|
|
222
|
+
hsl.s = clampUnitInterval(hsl.s + satOff);
|
|
223
|
+
}
|
|
224
|
+
const lumAbs = parseDrawingFraction(getVal("a:lum"));
|
|
225
|
+
if (lumAbs !== void 0) {
|
|
226
|
+
hsl.l = clampUnitInterval(lumAbs);
|
|
227
|
+
}
|
|
228
|
+
const lumMod = parseDrawingFraction(getVal("a:lumMod"));
|
|
229
|
+
if (lumMod !== void 0) {
|
|
230
|
+
hsl.l = clampUnitInterval(hsl.l * lumMod);
|
|
231
|
+
}
|
|
232
|
+
const lumOff = parseDrawingFraction(getVal("a:lumOff"));
|
|
233
|
+
if (lumOff !== void 0) {
|
|
234
|
+
hsl.l = clampUnitInterval(hsl.l + lumOff);
|
|
235
|
+
}
|
|
236
|
+
const out = hslToRgb(hsl.h, hsl.s, hsl.l);
|
|
237
|
+
r = out.r;
|
|
238
|
+
g = out.g;
|
|
239
|
+
b = out.b;
|
|
240
|
+
}
|
|
241
|
+
const redAbs = parseDrawingFraction(getVal("a:red"));
|
|
242
|
+
if (redAbs !== void 0) {
|
|
243
|
+
r = Math.round(clampUnitInterval(redAbs) * 255);
|
|
244
|
+
}
|
|
245
|
+
const redMod = parseDrawingFraction(getVal("a:redMod"));
|
|
246
|
+
if (redMod !== void 0) {
|
|
247
|
+
r = Math.min(255, Math.max(0, Math.round(r * redMod)));
|
|
248
|
+
}
|
|
249
|
+
const redOff = parseDrawingFraction(getVal("a:redOff"));
|
|
250
|
+
if (redOff !== void 0) {
|
|
251
|
+
r = Math.min(255, Math.max(0, Math.round(r + 255 * redOff)));
|
|
252
|
+
}
|
|
253
|
+
const greenAbs = parseDrawingFraction(getVal("a:green"));
|
|
254
|
+
if (greenAbs !== void 0) {
|
|
255
|
+
g = Math.round(clampUnitInterval(greenAbs) * 255);
|
|
256
|
+
}
|
|
257
|
+
const greenMod = parseDrawingFraction(getVal("a:greenMod"));
|
|
258
|
+
if (greenMod !== void 0) {
|
|
259
|
+
g = Math.min(255, Math.max(0, Math.round(g * greenMod)));
|
|
260
|
+
}
|
|
261
|
+
const greenOff = parseDrawingFraction(getVal("a:greenOff"));
|
|
262
|
+
if (greenOff !== void 0) {
|
|
263
|
+
g = Math.min(255, Math.max(0, Math.round(g + 255 * greenOff)));
|
|
264
|
+
}
|
|
265
|
+
const blueAbs = parseDrawingFraction(getVal("a:blue"));
|
|
266
|
+
if (blueAbs !== void 0) {
|
|
267
|
+
b = Math.round(clampUnitInterval(blueAbs) * 255);
|
|
268
|
+
}
|
|
269
|
+
const blueMod = parseDrawingFraction(getVal("a:blueMod"));
|
|
270
|
+
if (blueMod !== void 0) {
|
|
271
|
+
b = Math.min(255, Math.max(0, Math.round(b * blueMod)));
|
|
272
|
+
}
|
|
273
|
+
const blueOff = parseDrawingFraction(getVal("a:blueOff"));
|
|
274
|
+
if (blueOff !== void 0) {
|
|
275
|
+
b = Math.min(255, Math.max(0, Math.round(b + 255 * blueOff)));
|
|
276
|
+
}
|
|
277
|
+
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
|
278
|
+
}
|
|
279
|
+
function srgbEncodeChannel(channel) {
|
|
280
|
+
const linear = Math.min(1, Math.max(0, channel / 255));
|
|
281
|
+
const companded = linear <= 31308e-7 ? 12.92 * linear : 1.055 * linear ** (1 / 2.4) - 0.055;
|
|
282
|
+
return Math.min(255, Math.max(0, Math.round(companded * 255)));
|
|
283
|
+
}
|
|
284
|
+
function srgbDecodeChannel(channel) {
|
|
285
|
+
const companded = Math.min(1, Math.max(0, channel / 255));
|
|
286
|
+
const linear = companded <= 0.04045 ? companded / 12.92 : ((companded + 0.055) / 1.055) ** 2.4;
|
|
287
|
+
return Math.min(255, Math.max(0, Math.round(linear * 255)));
|
|
288
|
+
}
|
|
289
|
+
function applySrgbGammaEncode(r, g, b) {
|
|
290
|
+
return { r: srgbEncodeChannel(r), g: srgbEncodeChannel(g), b: srgbEncodeChannel(b) };
|
|
291
|
+
}
|
|
292
|
+
function applySrgbGammaDecode(r, g, b) {
|
|
293
|
+
return { r: srgbDecodeChannel(r), g: srgbDecodeChannel(g), b: srgbDecodeChannel(b) };
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// src/pptx/core/color/theme-color-ref.ts
|
|
297
|
+
var DEFAULT_ALIASES = {
|
|
298
|
+
bg1: "lt1",
|
|
299
|
+
tx1: "dk1",
|
|
300
|
+
bg2: "lt2",
|
|
301
|
+
tx2: "dk2"
|
|
302
|
+
};
|
|
303
|
+
function percentVal(fraction) {
|
|
304
|
+
return String(Math.round(fraction * 1e5));
|
|
305
|
+
}
|
|
306
|
+
function themeColorRefToXml(ref) {
|
|
307
|
+
const node = { "@_val": ref.scheme };
|
|
308
|
+
if (ref.tint !== void 0) {
|
|
309
|
+
node["a:tint"] = { "@_val": percentVal(ref.tint) };
|
|
310
|
+
}
|
|
311
|
+
if (ref.shade !== void 0) {
|
|
312
|
+
node["a:shade"] = { "@_val": percentVal(ref.shade) };
|
|
313
|
+
}
|
|
314
|
+
if (ref.lumMod !== void 0) {
|
|
315
|
+
node["a:lumMod"] = { "@_val": percentVal(ref.lumMod) };
|
|
316
|
+
}
|
|
317
|
+
if (ref.lumOff !== void 0) {
|
|
318
|
+
node["a:lumOff"] = { "@_val": percentVal(ref.lumOff) };
|
|
319
|
+
}
|
|
320
|
+
if (ref.alpha !== void 0) {
|
|
321
|
+
node["a:alpha"] = { "@_val": percentVal(ref.alpha) };
|
|
322
|
+
}
|
|
323
|
+
return node;
|
|
324
|
+
}
|
|
325
|
+
function resolveThemeColorRef(ref, themeColorMap) {
|
|
326
|
+
if (!themeColorMap) {
|
|
327
|
+
return void 0;
|
|
328
|
+
}
|
|
329
|
+
const base = themeColorMap[ref.scheme] ?? themeColorMap[DEFAULT_ALIASES[ref.scheme] ?? ""];
|
|
330
|
+
if (!base) {
|
|
331
|
+
return void 0;
|
|
332
|
+
}
|
|
333
|
+
const node = themeColorRefToXml(ref);
|
|
334
|
+
delete node["a:alpha"];
|
|
335
|
+
return normalizeHexColor(
|
|
336
|
+
applyDrawingColorTransforms(normalizeHexColor(base), node)
|
|
337
|
+
).toLowerCase();
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// src/pptx/core/types/color-ref.ts
|
|
341
|
+
var THEME_COLOR_PALETTE_COLUMNS = [
|
|
342
|
+
"bg1",
|
|
343
|
+
"tx1",
|
|
344
|
+
"bg2",
|
|
345
|
+
"tx2",
|
|
346
|
+
"accent1",
|
|
347
|
+
"accent2",
|
|
348
|
+
"accent3",
|
|
349
|
+
"accent4",
|
|
350
|
+
"accent5",
|
|
351
|
+
"accent6"
|
|
352
|
+
];
|
|
353
|
+
|
|
354
|
+
// src/pptx/ui/theme-color-swatches.ts
|
|
355
|
+
var COLUMN_LABELS = {
|
|
356
|
+
bg1: "Background 1",
|
|
357
|
+
tx1: "Text 1",
|
|
358
|
+
bg2: "Background 2",
|
|
359
|
+
tx2: "Text 2",
|
|
360
|
+
accent1: "Accent 1",
|
|
361
|
+
accent2: "Accent 2",
|
|
362
|
+
accent3: "Accent 3",
|
|
363
|
+
accent4: "Accent 4",
|
|
364
|
+
accent5: "Accent 5",
|
|
365
|
+
accent6: "Accent 6",
|
|
366
|
+
dk1: "Text 1",
|
|
367
|
+
lt1: "Background 1",
|
|
368
|
+
dk2: "Text 2",
|
|
369
|
+
lt2: "Background 2",
|
|
370
|
+
hlink: "Hyperlink",
|
|
371
|
+
folHlink: "Followed Hyperlink"
|
|
372
|
+
};
|
|
373
|
+
function lighter(percent) {
|
|
374
|
+
return { kind: "lighter", percent };
|
|
375
|
+
}
|
|
376
|
+
function darker(percent) {
|
|
377
|
+
return { kind: "darker", percent };
|
|
378
|
+
}
|
|
379
|
+
function themeColorVariantsForLuminance(l) {
|
|
380
|
+
if (l < 0.05) {
|
|
381
|
+
return [lighter(50), lighter(35), lighter(25), lighter(15), lighter(5)];
|
|
382
|
+
}
|
|
383
|
+
if (l < 0.25) {
|
|
384
|
+
return [lighter(90), lighter(75), lighter(50), lighter(25), lighter(10)];
|
|
385
|
+
}
|
|
386
|
+
if (l < 0.75) {
|
|
387
|
+
return [lighter(80), lighter(60), lighter(40), darker(25), darker(50)];
|
|
388
|
+
}
|
|
389
|
+
if (l < 0.95) {
|
|
390
|
+
return [darker(10), darker(25), darker(50), darker(75), darker(90)];
|
|
391
|
+
}
|
|
392
|
+
return [darker(5), darker(15), darker(25), darker(35), darker(50)];
|
|
393
|
+
}
|
|
394
|
+
function themeColorVariantToRef(scheme, variant) {
|
|
395
|
+
const fraction = variant.percent / 100;
|
|
396
|
+
const lumMod = Math.round((1 - fraction) * 1e5) / 1e5;
|
|
397
|
+
return variant.kind === "lighter" ? { scheme, lumMod, lumOff: fraction } : { scheme, lumMod };
|
|
398
|
+
}
|
|
399
|
+
function describeThemeColorSwatch(ref, variant) {
|
|
400
|
+
const column = COLUMN_LABELS[ref.scheme] ?? ref.scheme;
|
|
401
|
+
if (!variant) {
|
|
402
|
+
return column;
|
|
403
|
+
}
|
|
404
|
+
const word = variant.kind === "lighter" ? "Lighter" : "Darker";
|
|
405
|
+
return `${column}, ${word} ${variant.percent}%`;
|
|
406
|
+
}
|
|
407
|
+
function themeColorVariantOfRef(ref) {
|
|
408
|
+
if (ref.lumMod === void 0 || ref.tint !== void 0 || ref.shade !== void 0) {
|
|
409
|
+
return void 0;
|
|
410
|
+
}
|
|
411
|
+
const percent = Math.round((1 - ref.lumMod) * 100);
|
|
412
|
+
if (ref.lumOff !== void 0) {
|
|
413
|
+
return Math.round(ref.lumOff * 100) === percent ? lighter(percent) : void 0;
|
|
414
|
+
}
|
|
415
|
+
return darker(percent);
|
|
416
|
+
}
|
|
417
|
+
function buildThemeColorSwatchGrid(themeColorMap) {
|
|
418
|
+
if (!themeColorMap) {
|
|
419
|
+
return [];
|
|
420
|
+
}
|
|
421
|
+
const columns = [];
|
|
422
|
+
for (const scheme of THEME_COLOR_PALETTE_COLUMNS) {
|
|
423
|
+
const baseRef = { scheme };
|
|
424
|
+
const baseHex = resolveThemeColorRef(baseRef, themeColorMap);
|
|
425
|
+
const rgb = baseHex ? hexToRgbChannels(baseHex) : null;
|
|
426
|
+
if (!baseHex || !rgb) {
|
|
427
|
+
continue;
|
|
428
|
+
}
|
|
429
|
+
const { l } = rgbToHsl(rgb.r, rgb.g, rgb.b);
|
|
430
|
+
const variants = [];
|
|
431
|
+
for (const variant of themeColorVariantsForLuminance(l)) {
|
|
432
|
+
const ref = themeColorVariantToRef(scheme, variant);
|
|
433
|
+
const hex = resolveThemeColorRef(ref, themeColorMap);
|
|
434
|
+
if (hex) {
|
|
435
|
+
variants.push({ ref, hex, label: describeThemeColorSwatch(ref, variant), variant });
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
columns.push({
|
|
439
|
+
scheme,
|
|
440
|
+
base: {
|
|
441
|
+
ref: baseRef,
|
|
442
|
+
hex: baseHex,
|
|
443
|
+
label: describeThemeColorSwatch(baseRef, void 0),
|
|
444
|
+
variant: void 0
|
|
445
|
+
},
|
|
446
|
+
variants
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
return columns;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// src/pptx/ui/theme-color-picker-state.ts
|
|
453
|
+
function themeColorRefsEqual(a, b) {
|
|
454
|
+
if (!a || !b) {
|
|
455
|
+
return a === b;
|
|
456
|
+
}
|
|
457
|
+
return a.scheme === b.scheme && a.lumMod === b.lumMod && a.lumOff === b.lumOff && a.tint === b.tint && a.shade === b.shade;
|
|
458
|
+
}
|
|
459
|
+
function findSelectedThemeSwatch(columns, ref, hex) {
|
|
460
|
+
if (ref) {
|
|
461
|
+
for (const column of columns) {
|
|
462
|
+
const swatches = [column.base, ...column.variants];
|
|
463
|
+
const match = swatches.find((swatch) => themeColorRefsEqual(swatch.ref, ref));
|
|
464
|
+
if (match) {
|
|
465
|
+
return match;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
return void 0;
|
|
469
|
+
}
|
|
470
|
+
if (!hex) {
|
|
471
|
+
return void 0;
|
|
472
|
+
}
|
|
473
|
+
const normalized = hex.trim().toLowerCase();
|
|
474
|
+
for (const column of columns) {
|
|
475
|
+
const swatches = [column.base, ...column.variants];
|
|
476
|
+
const match = swatches.find((swatch) => swatch.hex.toLowerCase() === normalized);
|
|
477
|
+
if (match) {
|
|
478
|
+
return match;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
return void 0;
|
|
482
|
+
}
|
|
483
|
+
function themeSwatchCommit(swatch) {
|
|
484
|
+
return { hex: swatch.hex, ref: swatch.ref };
|
|
485
|
+
}
|
|
486
|
+
function customColorCommit(hex) {
|
|
487
|
+
return { hex, ref: void 0 };
|
|
488
|
+
}
|
|
489
|
+
function themeColorSwatchRows(columns) {
|
|
490
|
+
if (columns.length === 0) {
|
|
491
|
+
return [];
|
|
492
|
+
}
|
|
493
|
+
const variantRowCount = Math.max(...columns.map((column) => column.variants.length));
|
|
494
|
+
const rows = [columns.map((column) => column.base)];
|
|
495
|
+
for (let i = 0; i < variantRowCount; i++) {
|
|
496
|
+
rows.push(columns.map((column) => column.variants[i]));
|
|
497
|
+
}
|
|
498
|
+
return rows;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
exports.buildThemeColorSwatchGrid = buildThemeColorSwatchGrid;
|
|
502
|
+
exports.customColorCommit = customColorCommit;
|
|
503
|
+
exports.describeThemeColorSwatch = describeThemeColorSwatch;
|
|
504
|
+
exports.findSelectedThemeSwatch = findSelectedThemeSwatch;
|
|
505
|
+
exports.themeColorRefsEqual = themeColorRefsEqual;
|
|
506
|
+
exports.themeColorSwatchRows = themeColorSwatchRows;
|
|
507
|
+
exports.themeColorVariantOfRef = themeColorVariantOfRef;
|
|
508
|
+
exports.themeColorVariantToRef = themeColorVariantToRef;
|
|
509
|
+
exports.themeColorVariantsForLuminance = themeColorVariantsForLuminance;
|
|
510
|
+
exports.themeSwatchCommit = themeSwatchCommit;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { n as PptxThemeColorSchemeName, t as PptxThemeColorRef } from "../chunks/color-ref-BM66NGFP.js";
|
|
2
|
+
//#region src/pptx/ui/theme-color-swatches.d.ts
|
|
3
|
+
/** One swatch of the theme palette. */
|
|
4
|
+
export interface ThemeColorSwatch {
|
|
5
|
+
/** What the editor stores; serialises as `<a:schemeClr>`. */
|
|
6
|
+
readonly ref: PptxThemeColorRef;
|
|
7
|
+
/** Resolved `#rrggbb` for painting the swatch. */
|
|
8
|
+
readonly hex: string;
|
|
9
|
+
/** English label, e.g. "Accent 1, Lighter 80%" (for `title` / `aria-label`). */
|
|
10
|
+
readonly label: string;
|
|
11
|
+
/** Structured variant, for hosts that localise the label themselves. */
|
|
12
|
+
readonly variant: ThemeColorVariant | undefined;
|
|
13
|
+
}
|
|
14
|
+
/** A luminance variant of a base theme colour. */
|
|
15
|
+
export interface ThemeColorVariant {
|
|
16
|
+
readonly kind: 'lighter' | 'darker';
|
|
17
|
+
/** Whole percent as PowerPoint labels it (80 for "Lighter 80%"). */
|
|
18
|
+
readonly percent: number;
|
|
19
|
+
}
|
|
20
|
+
/** One palette column: the base swatch followed by its five variants. */
|
|
21
|
+
export interface ThemeColorSwatchColumn {
|
|
22
|
+
readonly scheme: PptxThemeColorSchemeName;
|
|
23
|
+
readonly base: ThemeColorSwatch;
|
|
24
|
+
readonly variants: readonly ThemeColorSwatch[];
|
|
25
|
+
}
|
|
26
|
+
/** The five variants PowerPoint shows under a base colour of luminance `l` (0..1). */
|
|
27
|
+
export declare function themeColorVariantsForLuminance(l: number): readonly ThemeColorVariant[];
|
|
28
|
+
/** The `lumMod`/`lumOff` pair a variant serialises as. */
|
|
29
|
+
export declare function themeColorVariantToRef(scheme: PptxThemeColorSchemeName, variant: ThemeColorVariant): PptxThemeColorRef;
|
|
30
|
+
/** Human label for a swatch: "Accent 1" or "Accent 1, Lighter 80%". */
|
|
31
|
+
export declare function describeThemeColorSwatch(ref: PptxThemeColorRef, variant: ThemeColorVariant | undefined): string;
|
|
32
|
+
/**
|
|
33
|
+
* Recover the PowerPoint variant a stored ref corresponds to, or `undefined`
|
|
34
|
+
* for a base colour or a ref whose transforms are not a plain lighter/darker step.
|
|
35
|
+
*/
|
|
36
|
+
export declare function themeColorVariantOfRef(ref: PptxThemeColorRef): ThemeColorVariant | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Build the palette for a deck's resolved theme colour map (`PptxData.themeColorMap`,
|
|
39
|
+
* which already applies the slide master's `p:clrMap` aliases). Columns whose
|
|
40
|
+
* base colour the map cannot resolve are skipped, so a partial map still yields
|
|
41
|
+
* a usable palette.
|
|
42
|
+
*/
|
|
43
|
+
export declare function buildThemeColorSwatchGrid(themeColorMap: Readonly<Record<string, string>> | undefined): readonly ThemeColorSwatchColumn[];
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/pptx/ui/theme-color-picker-state.d.ts
|
|
46
|
+
/** What a picker should write back to the model on a commit. */
|
|
47
|
+
export interface ThemeColorPickerCommit {
|
|
48
|
+
/** Resolved `#rrggbb`, always set so rendering keeps working. */
|
|
49
|
+
readonly hex: string;
|
|
50
|
+
/** The theme ref to store, or `undefined` to clear a previously-stored ref. */
|
|
51
|
+
readonly ref: PptxThemeColorRef | undefined;
|
|
52
|
+
}
|
|
53
|
+
/** Whether two refs describe the same `<a:schemeClr>` (same scheme + transforms). */
|
|
54
|
+
export declare function themeColorRefsEqual(a: PptxThemeColorRef | undefined, b: PptxThemeColorRef | undefined): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Find the swatch (base or variant, in any column) that matches the
|
|
57
|
+
* element's current colour, so the picker can highlight it.
|
|
58
|
+
*
|
|
59
|
+
* Prefers matching by `ref` (exact scheme + transform match) when the
|
|
60
|
+
* element carries one; falls back to matching by resolved hex (case
|
|
61
|
+
* insensitive) so a deck whose colour was never stored as a ref, but
|
|
62
|
+
* happens to equal a theme swatch's resolved value, still highlights.
|
|
63
|
+
*/
|
|
64
|
+
export declare function findSelectedThemeSwatch(columns: readonly ThemeColorSwatchColumn[], ref: PptxThemeColorRef | undefined, hex: string | undefined): ThemeColorSwatch | undefined;
|
|
65
|
+
/** Clicking a theme swatch commits both its resolved hex and its ref. */
|
|
66
|
+
export declare function themeSwatchCommit(swatch: ThemeColorSwatch): ThemeColorPickerCommit;
|
|
67
|
+
/**
|
|
68
|
+
* Typing a custom hex, using the native eyedropper, or picking a recent
|
|
69
|
+
* colour always clears the ref: none of those carry a theme identity.
|
|
70
|
+
*/
|
|
71
|
+
export declare function customColorCommit(hex: string): ThemeColorPickerCommit;
|
|
72
|
+
/**
|
|
73
|
+
* Lay the columns out as PowerPoint does: one row of base colours, then one
|
|
74
|
+
* row per luminance variant index (so column `i`'s "Lighter 80%" sits under
|
|
75
|
+
* column `i`'s base, matching the picker grid's visual columns). A column
|
|
76
|
+
* with fewer variants than the row index leaves that cell `undefined`.
|
|
77
|
+
*/
|
|
78
|
+
export declare function themeColorSwatchRows(columns: readonly ThemeColorSwatchColumn[]): readonly (readonly (ThemeColorSwatch | undefined)[])[];
|
|
79
|
+
//#endregion
|
|
80
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/pptx/ui/theme-color-swatches.ts","../../../src/pptx/ui/theme-color-picker-state.ts"],"mappings":";;;iBAyBiB;;WAEP,KAAK;;WAEL;;WAEA;;WAEA,SAAS;;;iBAIF;WACP;;WAEA;;;iBAIO;WACP,QAAQ;WACR,MAAM;WACN,mBAAmB;;;wBA+Bb,+BAA+B,qBAAqB;;wBAiBpD,uBACf,QAAQ,0BACR,SAAS,oBACP;;wBAOa,yBACf,KAAK,mBACL,SAAS;;;;;wBAcM,uBAAuB,KAAK,oBAAoB;;;;;;;wBAiBhD,0BACf,eAAe,SAAS,+CACb;;;;iBCvHK;;WAEP;;WAEA,KAAK;;;wBAIC,oBACf,GAAG,+BACH,GAAG;;;;;;;;;;wBAuBY,wBACf,kBAAkB,0BAClB,KAAK,+BACL,0BACE;;wBA0Ba,kBAAkB,QAAQ,mBAAmB;;;;;wBAQ7C,kBAAkB,cAAc;;;;;;;wBAUhC,qBACf,kBAAkB,+CACI"}
|