pptx-ts 0.0.1 → 4.0.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 +116 -269
- package/dist/autopage-odPz7zZO.js +536 -0
- package/dist/autopage-odPz7zZO.js.map +1 -0
- package/dist/binary-string-CKVAYI3M.js +24 -0
- package/dist/binary-string-CKVAYI3M.js.map +1 -0
- package/dist/body-insets-Dw_BeWD_.js +54 -0
- package/dist/body-insets-Dw_BeWD_.js.map +1 -0
- package/dist/browser.d.ts +29 -9
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +41 -14
- package/dist/browser.js.map +1 -1
- package/dist/clip-Bl01BPcN.d.ts +67 -0
- package/dist/clip-Bl01BPcN.d.ts.map +1 -0
- package/dist/diagnostics-D8ot4Ei7.d.ts +244 -0
- package/dist/diagnostics-D8ot4Ei7.d.ts.map +1 -0
- package/dist/embedded-fonts-DarT9aoa.d.ts +20 -0
- package/dist/embedded-fonts-DarT9aoa.d.ts.map +1 -0
- package/dist/entry-compose-DCnvBZz2.d.ts +1046 -0
- package/dist/entry-compose-DCnvBZz2.d.ts.map +1 -0
- package/dist/{enums-CvRYniUA.d.ts → enums-BUKTUB6V.d.ts} +21 -13
- package/dist/{enums-CvRYniUA.d.ts.map → enums-BUKTUB6V.d.ts.map} +1 -1
- package/dist/{errors-Bvln0H-7.js → errors-C4oENPcu.js} +92 -2
- package/dist/errors-C4oENPcu.js.map +1 -0
- package/dist/families.d.ts +260 -0
- package/dist/families.d.ts.map +1 -0
- package/dist/families.js +57 -0
- package/dist/families.js.map +1 -0
- package/dist/{fit-BKs0zxMI.js → fit-Cb7naFj6.js} +249 -167
- package/dist/fit-Cb7naFj6.js.map +1 -0
- package/dist/font-metrics-v5fn7s7e.d.ts +613 -0
- package/dist/font-metrics-v5fn7s7e.d.ts.map +1 -0
- package/dist/grid-DikTjFey.js +187 -0
- package/dist/grid-DikTjFey.js.map +1 -0
- package/dist/{html-dom-B0I0QSbU.js → html-dom-Iuog2wdK.js} +121 -91
- package/dist/html-dom-Iuog2wdK.js.map +1 -0
- package/dist/html.d.ts +6 -6
- package/dist/html.d.ts.map +1 -1
- package/dist/html.js +7 -6
- package/dist/html.js.map +1 -1
- package/dist/image-size-CvN2iCA4.js +1611 -0
- package/dist/image-size-CvN2iCA4.js.map +1 -0
- package/dist/index.d.ts +24 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +31 -11
- package/dist/index.js.map +1 -1
- package/dist/inspect.d.ts +40 -31
- package/dist/inspect.d.ts.map +1 -1
- package/dist/inspect.js +40 -48
- package/dist/inspect.js.map +1 -1
- package/dist/math.d.ts +7 -5
- package/dist/math.d.ts.map +1 -1
- package/dist/math.js +16 -7
- package/dist/math.js.map +1 -1
- package/dist/measure.d.ts +12 -225
- package/dist/measure.d.ts.map +1 -1
- package/dist/measure.js +3 -3
- package/dist/node.d.ts +22 -8
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +27 -7
- package/dist/node.js.map +1 -1
- package/dist/notes-Dh12JAbn.js +3264 -0
- package/dist/notes-Dh12JAbn.js.map +1 -0
- package/dist/options-internal-WqgMf720.js +43 -0
- package/dist/options-internal-WqgMf720.js.map +1 -0
- package/dist/{package-CaOLXSNi.d.ts → package-J49Ck6S2.d.ts} +27 -12
- package/dist/package-J49Ck6S2.d.ts.map +1 -0
- package/dist/playbtn-CUqQdoDf.js +22 -0
- package/dist/playbtn-CUqQdoDf.js.map +1 -0
- package/dist/{slide-js0QpRV-.d.ts → pres-C6qgOFAa.d.ts} +1021 -1370
- package/dist/pres-C6qgOFAa.d.ts.map +1 -0
- package/dist/{presentation-Cp7vzlAw.js → presentation-DGYlAWhl.js} +3208 -2727
- package/dist/presentation-DGYlAWhl.js.map +1 -0
- package/dist/{presentation-types-DP_8jog7.d.ts → presentation-types-8jLQHI4M.d.ts} +1070 -683
- package/dist/presentation-types-8jLQHI4M.d.ts.map +1 -0
- package/dist/read.d.ts +9 -9
- package/dist/read.d.ts.map +1 -1
- package/dist/read.js +4 -4
- package/dist/script.d.ts +80 -66
- package/dist/script.d.ts.map +1 -1
- package/dist/script.js +2399 -1139
- package/dist/script.js.map +1 -1
- package/dist/{shapes-BemroU-z.js → shapes-re0KyQk_.js} +2807 -1609
- package/dist/shapes-re0KyQk_.js.map +1 -0
- package/dist/slide-Dx2ZeVZ6.d.ts +1256 -0
- package/dist/slide-Dx2ZeVZ6.d.ts.map +1 -0
- package/dist/slide-size-BalTjFuv.js +88 -0
- package/dist/slide-size-BalTjFuv.js.map +1 -0
- package/dist/{units-internal-Dg95w_YD.js → table-cell-margins-EVg0EwxT.js} +235 -273
- package/dist/table-cell-margins-EVg0EwxT.js.map +1 -0
- package/dist/table-dom-BTDP3lEP.js +21 -0
- package/dist/table-dom-BTDP3lEP.js.map +1 -0
- package/dist/text-KnLOtEEu.js +3980 -0
- package/dist/text-KnLOtEEu.js.map +1 -0
- package/dist/text-anchor-CrYXAfUu.js +176 -0
- package/dist/text-anchor-CrYXAfUu.js.map +1 -0
- package/dist/transition-speed-kUEWDWTx.js +14 -0
- package/dist/transition-speed-kUEWDWTx.js.map +1 -0
- package/dist/units-internal-XJlf-hOl.js +649 -0
- package/dist/units-internal-XJlf-hOl.js.map +1 -0
- package/dist/zip-C0leZZMj.d.ts +67 -0
- package/dist/zip-C0leZZMj.d.ts.map +1 -0
- package/dist/zip-CKd8ihcf.js +177 -0
- package/dist/zip-CKd8ihcf.js.map +1 -0
- package/dist/zip.d.ts +3 -68
- package/dist/zip.js +3 -163
- package/dist/zoom-cX9sllpH.js +8865 -0
- package/dist/zoom-cX9sllpH.js.map +1 -0
- package/package.json +106 -19
- package/skills/ts-pptx-upstream/SKILL.md +58 -57
- package/dist/autopage-DkjYZUFD.js +0 -423
- package/dist/autopage-DkjYZUFD.js.map +0 -1
- package/dist/diagnostics-Du_s75MT.d.ts +0 -829
- package/dist/diagnostics-Du_s75MT.d.ts.map +0 -1
- package/dist/errors-Bvln0H-7.js.map +0 -1
- package/dist/errors-PflMPWBn.d.ts +0 -182
- package/dist/errors-PflMPWBn.d.ts.map +0 -1
- package/dist/fit-BKs0zxMI.js.map +0 -1
- package/dist/html-dom-B0I0QSbU.js.map +0 -1
- package/dist/namespaces-BVnNu7sg.js +0 -666
- package/dist/namespaces-BVnNu7sg.js.map +0 -1
- package/dist/notes-RLCwdlTE.js +0 -1703
- package/dist/notes-RLCwdlTE.js.map +0 -1
- package/dist/package-CaOLXSNi.d.ts.map +0 -1
- package/dist/pres-C5__xkDh.d.ts +0 -202
- package/dist/pres-C5__xkDh.d.ts.map +0 -1
- package/dist/presentation-Cp7vzlAw.js.map +0 -1
- package/dist/presentation-types-DP_8jog7.d.ts.map +0 -1
- package/dist/shapes-BemroU-z.js.map +0 -1
- package/dist/slide-js0QpRV-.d.ts.map +0 -1
- package/dist/text-CyetbF6p.js +0 -11278
- package/dist/text-CyetbF6p.js.map +0 -1
- package/dist/units-1kRzYShk.js +0 -231
- package/dist/units-1kRzYShk.js.map +0 -1
- package/dist/units-internal-Dg95w_YD.js.map +0 -1
- package/dist/zip.d.ts.map +0 -1
- package/dist/zip.js.map +0 -1
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { mn as imageFormatForExtension, pn as imageFormatForContentType } from "./image-size-CvN2iCA4.js";
|
|
2
|
+
//#region src/media/content-type.ts
|
|
3
|
+
/**
|
|
4
|
+
* OPC content types for embedded media parts, keyed by file extension.
|
|
5
|
+
*
|
|
6
|
+
* Both mappings reproduce what PowerPoint itself authors rather than the IANA-preferred
|
|
7
|
+
* spelling — a package that disagrees (e.g. `audio/mp3` for an `.mp3`) is the kind of thing
|
|
8
|
+
* PowerPoint offers to repair.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Map an image file extension to its OOXML content type, through the format registry in
|
|
12
|
+
* `media/image-formats.ts`. An extension the registry does not carry falls through to
|
|
13
|
+
* `image/<extn>`, which is right for any format whose content type is its extension.
|
|
14
|
+
* Only the content type is derived here; the file extension (used for the media Target
|
|
15
|
+
* filename) is left to the caller.
|
|
16
|
+
* @param {string} extn - image file extension (e.g. `png`, `jpg`, `emf`)
|
|
17
|
+
* @returns {string} OOXML content type (e.g. `image/png`, `image/x-emf`)
|
|
18
|
+
*/
|
|
19
|
+
function imageContentType(extn) {
|
|
20
|
+
return imageFormatForExtension(extn)?.contentType ?? "image/" + (extn || "").toLowerCase();
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The media type an inline payload states in its header, lower-cased, or `null` when it states none.
|
|
24
|
+
*
|
|
25
|
+
* Takes a `data:` URI or the same header without its `data:` scheme (`image/png;base64,…`), the
|
|
26
|
+
* two forms the definers accept. It is the one reading of that header: the patterns it replaces
|
|
27
|
+
* each stopped short somewhere, `image\/(\w+);` at `-`, `.` and `+`, so `data:image/x-emf;…` named
|
|
28
|
+
* no type and its EMF bytes were written into a `.png` part declared `image/png`.
|
|
29
|
+
* @param data - a `data:` URI, a header-first base64 payload, or anything else
|
|
30
|
+
* @returns the `type/subtype`, e.g. `image/x-emf`, or `null`
|
|
31
|
+
*/
|
|
32
|
+
function dataUriMediaType(data) {
|
|
33
|
+
return /^(?:data:)?([a-z]+\/[\w.+-]+)[;,]/i.exec(data || "")?.[1]?.toLowerCase() ?? null;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Resolve the file extension an embedded image part should carry, from the caller's source.
|
|
37
|
+
*
|
|
38
|
+
* A `data:` URI states its mime type outright, so it wins over `path`: the bytes are the thing
|
|
39
|
+
* being embedded, and a caller may supply them with no path at all (or with a path whose
|
|
40
|
+
* extension disagrees with the payload). The extension chosen here names the media part *and*,
|
|
41
|
+
* via {@link imageContentType}, decides the `<Default>` the package declares for it — so
|
|
42
|
+
* getting it from a placeholder path is how a deck ends up declaring `image/png` over SVG
|
|
43
|
+
* bytes, which is exactly the mismatch PowerPoint offers to "repair".
|
|
44
|
+
*
|
|
45
|
+
* A type the format registry carries names its part by the registry's extension (`image/x-emf` is
|
|
46
|
+
* `emf`, `image/svg+xml` is `svg`). Any other type names it by its subtype, so `image/jpg` keeps
|
|
47
|
+
* `jpg`. The result is always lower-cased, so a `data:image/PNG;` source names its part the same
|
|
48
|
+
* way a `photo.PNG` path does.
|
|
49
|
+
* @param {string} path - caller-supplied path/URL (may be empty); query and fragment are stripped
|
|
50
|
+
* @param {string} data - caller-supplied `data:`/base64 payload (may be empty)
|
|
51
|
+
* @returns {string} file extension, no dot (e.g. `png`, `jpeg`, `svg`)
|
|
52
|
+
*/
|
|
53
|
+
function imageExtensionForSource(path, data) {
|
|
54
|
+
const strPath = path || "";
|
|
55
|
+
const pathExtn = (((strPath.slice(strPath.lastIndexOf("/") + 1).split("?")[0] || "").split(".").pop() || "png").split("#")[0] || "png").toLowerCase();
|
|
56
|
+
const mime = dataUriMediaType(data);
|
|
57
|
+
if (mime?.startsWith("image/")) return imageFormatForContentType(mime)?.ext ?? mime.slice(6);
|
|
58
|
+
return pathExtn;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Map an audio content type's subtype back to the file extension a media part should use.
|
|
62
|
+
*
|
|
63
|
+
* Needed because a caller supplying sound bytes as a `data:` URI states a *content type*
|
|
64
|
+
* (`data:audio/x-wav;base64,…`), while the media part needs a *filename*. Taking the subtype
|
|
65
|
+
* verbatim produces `audio1.x-wav` — legal, since the package would then declare a matching
|
|
66
|
+
* `<Default Extension="x-wav"/>`, but a file type that does not exist and that no other tool
|
|
67
|
+
* recognises. `audio/x-wav` in particular is not an edge case: it is exactly what PowerPoint
|
|
68
|
+
* authors for an embedded transition sound, so it arrives on any deck read back in.
|
|
69
|
+
*
|
|
70
|
+
* Only the spellings that are *not* already an extension are listed; anything else (`ogg`,
|
|
71
|
+
* `flac`, `aac`, …) is its own extension and falls through. Read against {@link avContentType},
|
|
72
|
+
* which maps the same pairs in the other direction.
|
|
73
|
+
*/
|
|
74
|
+
function audioExtensionForSubtype(subtype) {
|
|
75
|
+
switch ((subtype || "").toLowerCase()) {
|
|
76
|
+
case "x-wav":
|
|
77
|
+
case "wave":
|
|
78
|
+
case "vnd.wave": return "wav";
|
|
79
|
+
case "mpeg": return "mp3";
|
|
80
|
+
case "x-ms-wma": return "wma";
|
|
81
|
+
case "mp4": return "m4a";
|
|
82
|
+
default: return (subtype || "").toLowerCase();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Resolve the OPC content type for an embedded audio/video part by file extension,
|
|
87
|
+
* matching what PowerPoint authors (e.g. `mp3` → `audio/mpeg`, not `audio/mp3`).
|
|
88
|
+
* The `mtype` disambiguates extensions Office maps differently per kind and seeds
|
|
89
|
+
* the `mtype/extn` fallback for anything unlisted.
|
|
90
|
+
* @param {string} extn - media file extension (no dot), case-insensitive
|
|
91
|
+
* @param {'audio' | 'video'} mtype - whether the item is audio or video
|
|
92
|
+
*/
|
|
93
|
+
function avContentType(extn, mtype) {
|
|
94
|
+
switch ((extn || "").toLowerCase()) {
|
|
95
|
+
case "mp4": return mtype === "audio" ? "audio/mp4" : "video/mp4";
|
|
96
|
+
case "m4v": return "video/mp4";
|
|
97
|
+
case "mov": return "video/quicktime";
|
|
98
|
+
case "avi": return "video/avi";
|
|
99
|
+
case "wmv": return "video/x-ms-wmv";
|
|
100
|
+
case "mpg":
|
|
101
|
+
case "mpeg": return mtype === "audio" ? "audio/mpeg" : "video/mpeg";
|
|
102
|
+
case "ogv": return "video/ogg";
|
|
103
|
+
case "webm": return "video/webm";
|
|
104
|
+
case "mp3": return "audio/mpeg";
|
|
105
|
+
case "m4a": return "audio/mp4";
|
|
106
|
+
case "wav": return "audio/x-wav";
|
|
107
|
+
case "wma": return "audio/x-ms-wma";
|
|
108
|
+
case "aac": return "audio/aac";
|
|
109
|
+
case "oga":
|
|
110
|
+
case "ogg": return "audio/ogg";
|
|
111
|
+
case "flac": return "audio/flac";
|
|
112
|
+
default: return mtype + "/" + (extn || "").toLowerCase();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* The extension an emitted *asset filename* should carry for a media content type, or `null`
|
|
117
|
+
* when nothing here names one and the caller should fall back to the source part's own suffix.
|
|
118
|
+
*
|
|
119
|
+
* This is the on-disk spelling, not the media part's: `image/jpeg` is `jpg` and `image/tiff` is
|
|
120
|
+
* `tif` here, because an asset directory is read by people and opened by desktop viewers. See the
|
|
121
|
+
* `filenameExt` column in `media/image-formats.ts`. Audio goes through {@link audioExtensionForSubtype}, which is
|
|
122
|
+
* already the one table for that direction.
|
|
123
|
+
*/
|
|
124
|
+
function assetFilenameExtension(contentType) {
|
|
125
|
+
const image = imageFormatForContentType(contentType);
|
|
126
|
+
if (image) return image.filenameExt;
|
|
127
|
+
const ct = (contentType || "").toLowerCase();
|
|
128
|
+
return ct.startsWith("audio/") ? audioExtensionForSubtype(ct.slice(6)) : null;
|
|
129
|
+
}
|
|
130
|
+
//#endregion
|
|
131
|
+
//#region src/ooxml/text-anchor.ts
|
|
132
|
+
/**
|
|
133
|
+
* Every `valign` the write API accepts, the anchor token it means, and the other spellings the
|
|
134
|
+
* definers between them have always taken.
|
|
135
|
+
*
|
|
136
|
+
* The three definers read `valign` three ways — `startsWith('b'|'m'|'t')`, a chain of
|
|
137
|
+
* `.replace('top','t')…` that let any other string through *verbatim* into `anchor=`, and a
|
|
138
|
+
* longer chain that also took `btm` and `center`. This table is the union of what they named;
|
|
139
|
+
* anything else is a warning and an omitted attribute rather than an invalid one.
|
|
140
|
+
*
|
|
141
|
+
* `valign` leads each row because it is the direction with a preferred answer: several spellings
|
|
142
|
+
* mean one anchor, and only one of them is what a generated script should write back.
|
|
143
|
+
*/
|
|
144
|
+
const VALIGN_TABLE = [
|
|
145
|
+
{
|
|
146
|
+
valign: "top",
|
|
147
|
+
anchor: "t",
|
|
148
|
+
aliases: ["t"]
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
valign: "middle",
|
|
152
|
+
anchor: "ctr",
|
|
153
|
+
aliases: [
|
|
154
|
+
"c",
|
|
155
|
+
"ctr",
|
|
156
|
+
"center",
|
|
157
|
+
"m"
|
|
158
|
+
]
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
valign: "bottom",
|
|
162
|
+
anchor: "b",
|
|
163
|
+
aliases: ["b", "btm"]
|
|
164
|
+
}
|
|
165
|
+
];
|
|
166
|
+
/** Every spelling of `valign` the definers accept, mapped to the one anchor token it means. */
|
|
167
|
+
const TEXT_ANCHOR_BY_VALIGN = Object.fromEntries(VALIGN_TABLE.flatMap((row) => [row.valign, ...row.aliases].map((spelling) => [spelling, row.anchor])));
|
|
168
|
+
/**
|
|
169
|
+
* An anchor token back to the `valign` a generated script writes — the preferred spelling of the
|
|
170
|
+
* row, never one of its aliases.
|
|
171
|
+
*/
|
|
172
|
+
const VALIGN_BY_ANCHOR = Object.fromEntries(VALIGN_TABLE.map((row) => [row.anchor, row.valign]));
|
|
173
|
+
//#endregion
|
|
174
|
+
export { avContentType as a, imageExtensionForSource as c, audioExtensionForSubtype as i, VALIGN_BY_ANCHOR as n, dataUriMediaType as o, assetFilenameExtension as r, imageContentType as s, TEXT_ANCHOR_BY_VALIGN as t };
|
|
175
|
+
|
|
176
|
+
//# sourceMappingURL=text-anchor-CrYXAfUu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-anchor-CrYXAfUu.js","names":[],"sources":["../src/media/content-type.ts","../src/ooxml/text-anchor.ts"],"sourcesContent":["/**\n * OPC content types for embedded media parts, keyed by file extension.\n *\n * Both mappings reproduce what PowerPoint itself authors rather than the IANA-preferred\n * spelling — a package that disagrees (e.g. `audio/mp3` for an `.mp3`) is the kind of thing\n * PowerPoint offers to repair.\n */\n\nimport { imageFormatForContentType, imageFormatForExtension } from './image-formats.js'\n\n/**\n * Map an image file extension to its OOXML content type, through the format registry in\n * `media/image-formats.ts`. An extension the registry does not carry falls through to\n * `image/<extn>`, which is right for any format whose content type is its extension.\n * Only the content type is derived here; the file extension (used for the media Target\n * filename) is left to the caller.\n * @param {string} extn - image file extension (e.g. `png`, `jpg`, `emf`)\n * @returns {string} OOXML content type (e.g. `image/png`, `image/x-emf`)\n */\nexport function imageContentType(extn: string): string {\n\treturn imageFormatForExtension(extn)?.contentType ?? 'image/' + (extn || '').toLowerCase()\n}\n\n/**\n * The media type an inline payload states in its header, lower-cased, or `null` when it states none.\n *\n * Takes a `data:` URI or the same header without its `data:` scheme (`image/png;base64,…`), the\n * two forms the definers accept. It is the one reading of that header: the patterns it replaces\n * each stopped short somewhere, `image\\/(\\w+);` at `-`, `.` and `+`, so `data:image/x-emf;…` named\n * no type and its EMF bytes were written into a `.png` part declared `image/png`.\n * @param data - a `data:` URI, a header-first base64 payload, or anything else\n * @returns the `type/subtype`, e.g. `image/x-emf`, or `null`\n */\nexport function dataUriMediaType(data: string): string | null {\n\tconst match = /^(?:data:)?([a-z]+\\/[\\w.+-]+)[;,]/i.exec(data || '')\n\treturn match?.[1]?.toLowerCase() ?? null\n}\n\n/**\n * Resolve the file extension an embedded image part should carry, from the caller's source.\n *\n * A `data:` URI states its mime type outright, so it wins over `path`: the bytes are the thing\n * being embedded, and a caller may supply them with no path at all (or with a path whose\n * extension disagrees with the payload). The extension chosen here names the media part *and*,\n * via {@link imageContentType}, decides the `<Default>` the package declares for it — so\n * getting it from a placeholder path is how a deck ends up declaring `image/png` over SVG\n * bytes, which is exactly the mismatch PowerPoint offers to \"repair\".\n *\n * A type the format registry carries names its part by the registry's extension (`image/x-emf` is\n * `emf`, `image/svg+xml` is `svg`). Any other type names it by its subtype, so `image/jpg` keeps\n * `jpg`. The result is always lower-cased, so a `data:image/PNG;` source names its part the same\n * way a `photo.PNG` path does.\n * @param {string} path - caller-supplied path/URL (may be empty); query and fragment are stripped\n * @param {string} data - caller-supplied `data:`/base64 payload (may be empty)\n * @returns {string} file extension, no dot (e.g. `png`, `jpeg`, `svg`)\n */\nexport function imageExtensionForSource(path: string, data: string): string {\n\t// NOTE: Split to address URLs with params (eg: `path/brent.jpg?someParam=true`)\n\tconst strPath = path || ''\n\tconst pathFile = strPath.slice(strPath.lastIndexOf('/') + 1).split('?')[0] || ''\n\tconst pathExtn = ((pathFile.split('.').pop() || 'png').split('#')[0] || 'png').toLowerCase()\n\n\tconst mime = dataUriMediaType(data)\n\tif (mime?.startsWith('image/')) return imageFormatForContentType(mime)?.ext ?? mime.slice('image/'.length)\n\treturn pathExtn\n}\n\n/**\n * Map an audio content type's subtype back to the file extension a media part should use.\n *\n * Needed because a caller supplying sound bytes as a `data:` URI states a *content type*\n * (`data:audio/x-wav;base64,…`), while the media part needs a *filename*. Taking the subtype\n * verbatim produces `audio1.x-wav` — legal, since the package would then declare a matching\n * `<Default Extension=\"x-wav\"/>`, but a file type that does not exist and that no other tool\n * recognises. `audio/x-wav` in particular is not an edge case: it is exactly what PowerPoint\n * authors for an embedded transition sound, so it arrives on any deck read back in.\n *\n * Only the spellings that are *not* already an extension are listed; anything else (`ogg`,\n * `flac`, `aac`, …) is its own extension and falls through. Read against {@link avContentType},\n * which maps the same pairs in the other direction.\n */\nexport function audioExtensionForSubtype(subtype: string): string {\n\tswitch ((subtype || '').toLowerCase()) {\n\t\tcase 'x-wav':\n\t\tcase 'wave':\n\t\tcase 'vnd.wave':\n\t\t\treturn 'wav'\n\t\tcase 'mpeg':\n\t\t\treturn 'mp3'\n\t\tcase 'x-ms-wma':\n\t\t\treturn 'wma'\n\t\tcase 'mp4':\n\t\t\treturn 'm4a'\n\t\tdefault:\n\t\t\treturn (subtype || '').toLowerCase()\n\t}\n}\n\n/**\n * Resolve the OPC content type for an embedded audio/video part by file extension,\n * matching what PowerPoint authors (e.g. `mp3` → `audio/mpeg`, not `audio/mp3`).\n * The `mtype` disambiguates extensions Office maps differently per kind and seeds\n * the `mtype/extn` fallback for anything unlisted.\n * @param {string} extn - media file extension (no dot), case-insensitive\n * @param {'audio' | 'video'} mtype - whether the item is audio or video\n */\nexport function avContentType(extn: string, mtype: 'audio' | 'video'): string {\n\tswitch ((extn || '').toLowerCase()) {\n\t\t// video\n\t\tcase 'mp4':\n\t\t\treturn mtype === 'audio' ? 'audio/mp4' : 'video/mp4'\n\t\tcase 'm4v':\n\t\t\treturn 'video/mp4'\n\t\tcase 'mov':\n\t\t\treturn 'video/quicktime'\n\t\tcase 'avi':\n\t\t\treturn 'video/avi'\n\t\tcase 'wmv':\n\t\t\treturn 'video/x-ms-wmv'\n\t\tcase 'mpg':\n\t\tcase 'mpeg':\n\t\t\treturn mtype === 'audio' ? 'audio/mpeg' : 'video/mpeg'\n\t\tcase 'ogv':\n\t\t\treturn 'video/ogg'\n\t\tcase 'webm':\n\t\t\treturn 'video/webm'\n\t\t// audio\n\t\tcase 'mp3':\n\t\t\treturn 'audio/mpeg'\n\t\tcase 'm4a':\n\t\t\treturn 'audio/mp4'\n\t\tcase 'wav':\n\t\t\treturn 'audio/x-wav' // PowerPoint authors the x- form (e.g. embedded transition sounds)\n\t\tcase 'wma':\n\t\t\treturn 'audio/x-ms-wma'\n\t\tcase 'aac':\n\t\t\treturn 'audio/aac'\n\t\tcase 'oga':\n\t\tcase 'ogg':\n\t\t\treturn 'audio/ogg'\n\t\tcase 'flac':\n\t\t\treturn 'audio/flac'\n\t\tdefault:\n\t\t\treturn mtype + '/' + (extn || '').toLowerCase()\n\t}\n}\n\n/**\n * The extension an emitted *asset filename* should carry for a media content type, or `null`\n * when nothing here names one and the caller should fall back to the source part's own suffix.\n *\n * This is the on-disk spelling, not the media part's: `image/jpeg` is `jpg` and `image/tiff` is\n * `tif` here, because an asset directory is read by people and opened by desktop viewers. See the\n * `filenameExt` column in `media/image-formats.ts`. Audio goes through {@link audioExtensionForSubtype}, which is\n * already the one table for that direction.\n */\nexport function assetFilenameExtension(contentType: string): string | null {\n\tconst image = imageFormatForContentType(contentType)\n\tif (image) return image.filenameExt\n\tconst ct = (contentType || '').toLowerCase()\n\treturn ct.startsWith('audio/') ? audioExtensionForSubtype(ct.slice('audio/'.length)) : null\n}\n","/**\n * `a:bodyPr/@anchor` and `a:tcPr/@anchor`, and the write API's `valign` on the other side of it.\n *\n * Two tables stated the same correspondence in opposite directions and could not see each other:\n * the emitters' spelling table in `gen/drawingml/text-body.ts`, and its hand-written inverse in\n * `script/from-read/values.ts`, which maps a read deck's anchor back to the `valign` a generated\n * script writes. `script/` cannot import `gen/` — it has no such import anywhere, deliberately —\n * so the inverse could not be derived where it stood, and a token added to one table would have\n * meant a script that reads an anchor it cannot write back.\n *\n * The correspondence itself is a fact about the format, so it lives here, as one table with both\n * directions derived from it.\n *\n * This module keeps `ooxml/`'s no-runtime-imports property: {@link TEXT_ANCHORS} is the schema's\n * own list from a module with none either, and the {@link TextAnchor} reference is type-only, so\n * it is erased. That reference is still a real check — it is what ties the enum the write API\n * exposes to the tokens named here.\n */\n\nimport type { TextAnchor } from '../enums.js'\nimport { TEXT_ANCHORS } from './st-enums.js'\n\n/**\n * The `ST_TextAnchoringType` tokens this library writes, checked against both the schema's list\n * and the public {@link TextAnchor} enum.\n *\n * `Extract` is that check twice over: a token here that is not in `ST_TextAnchoringType`, or not\n * in the enum, is dropped from the type and the table below stops compiling. Compile-time on\n * purpose — every value in the table is a literal, so a runtime check could never fail, and a\n * check that cannot fail is worse than none.\n *\n * The library writes three of the schema's five: `just` and `dist` are anchoring modes no\n * option surfaces.\n */\nexport type TextAnchorToken = Extract<`${TextAnchor}`, (typeof TEXT_ANCHORS)[number]>\n\n/**\n * Every `valign` the write API accepts, the anchor token it means, and the other spellings the\n * definers between them have always taken.\n *\n * The three definers read `valign` three ways — `startsWith('b'|'m'|'t')`, a chain of\n * `.replace('top','t')…` that let any other string through *verbatim* into `anchor=`, and a\n * longer chain that also took `btm` and `center`. This table is the union of what they named;\n * anything else is a warning and an omitted attribute rather than an invalid one.\n *\n * `valign` leads each row because it is the direction with a preferred answer: several spellings\n * mean one anchor, and only one of them is what a generated script should write back.\n */\nconst VALIGN_TABLE = [\n\t{ valign: 'top', anchor: 't', aliases: ['t'] },\n\t{ valign: 'middle', anchor: 'ctr', aliases: ['c', 'ctr', 'center', 'm'] },\n\t{ valign: 'bottom', anchor: 'b', aliases: ['b', 'btm'] },\n] as const satisfies ReadonlyArray<{ valign: string; anchor: TextAnchorToken; aliases: readonly string[] }>\n\n/** Every spelling of `valign` the definers accept, mapped to the one anchor token it means. */\nexport const TEXT_ANCHOR_BY_VALIGN: Readonly<Record<string, TextAnchorToken>> = Object.fromEntries(\n\tVALIGN_TABLE.flatMap((row) => [row.valign, ...row.aliases].map((spelling) => [spelling, row.anchor]))\n)\n\n/**\n * An anchor token back to the `valign` a generated script writes — the preferred spelling of the\n * row, never one of its aliases.\n */\nexport const VALIGN_BY_ANCHOR: Readonly<Record<string, string>> = Object.fromEntries(\n\tVALIGN_TABLE.map((row) => [row.anchor, row.valign])\n)\n"],"mappings":";;;;;;;;;;;;;;;;;;AAmBA,SAAgB,iBAAiB,MAAsB;CACtD,OAAO,wBAAwB,IAAI,CAAC,EAAE,eAAe,YAAY,QAAQ,GAAA,CAAI,YAAY;AAC1F;;;;;;;;;;;AAYA,SAAgB,iBAAiB,MAA6B;CAE7D,OADc,qCAAqC,KAAK,QAAQ,EACrD,CAAC,GAAG,EAAE,EAAE,YAAY,KAAK;AACrC;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,wBAAwB,MAAc,MAAsB;CAE3E,MAAM,UAAU,QAAQ;CAExB,MAAM,cADW,QAAQ,MAAM,QAAQ,YAAY,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,GAAA,CAClD,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK,MAAA,CAAO,MAAM,GAAG,CAAC,CAAC,MAAM,MAAA,CAAO,YAAY;CAE3F,MAAM,OAAO,iBAAiB,IAAI;CAClC,IAAI,MAAM,WAAW,QAAQ,GAAG,OAAO,0BAA0B,IAAI,CAAC,EAAE,OAAO,KAAK,MAAM,CAAe;CACzG,OAAO;AACR;;;;;;;;;;;;;;;AAgBA,SAAgB,yBAAyB,SAAyB;CACjE,SAAS,WAAW,GAAA,CAAI,YAAY,GAApC;EACC,KAAK;EACL,KAAK;EACL,KAAK,YACJ,OAAO;EACR,KAAK,QACJ,OAAO;EACR,KAAK,YACJ,OAAO;EACR,KAAK,OACJ,OAAO;EACR,SACC,QAAQ,WAAW,GAAA,CAAI,YAAY;CACrC;AACD;;;;;;;;;AAUA,SAAgB,cAAc,MAAc,OAAkC;CAC7E,SAAS,QAAQ,GAAA,CAAI,YAAY,GAAjC;EAEC,KAAK,OACJ,OAAO,UAAU,UAAU,cAAc;EAC1C,KAAK,OACJ,OAAO;EACR,KAAK,OACJ,OAAO;EACR,KAAK,OACJ,OAAO;EACR,KAAK,OACJ,OAAO;EACR,KAAK;EACL,KAAK,QACJ,OAAO,UAAU,UAAU,eAAe;EAC3C,KAAK,OACJ,OAAO;EACR,KAAK,QACJ,OAAO;EAER,KAAK,OACJ,OAAO;EACR,KAAK,OACJ,OAAO;EACR,KAAK,OACJ,OAAO;EACR,KAAK,OACJ,OAAO;EACR,KAAK,OACJ,OAAO;EACR,KAAK;EACL,KAAK,OACJ,OAAO;EACR,KAAK,QACJ,OAAO;EACR,SACC,OAAO,QAAQ,OAAO,QAAQ,GAAA,CAAI,YAAY;CAChD;AACD;;;;;;;;;;AAWA,SAAgB,uBAAuB,aAAoC;CAC1E,MAAM,QAAQ,0BAA0B,WAAW;CACnD,IAAI,OAAO,OAAO,MAAM;CACxB,MAAM,MAAM,eAAe,GAAA,CAAI,YAAY;CAC3C,OAAO,GAAG,WAAW,QAAQ,IAAI,yBAAyB,GAAG,MAAM,CAAe,CAAC,IAAI;AACxF;;;;;;;;;;;;;;;ACjHA,MAAM,eAAe;CACpB;EAAE,QAAQ;EAAO,QAAQ;EAAK,SAAS,CAAC,GAAG;CAAE;CAC7C;EAAE,QAAQ;EAAU,QAAQ;EAAO,SAAS;GAAC;GAAK;GAAO;GAAU;EAAG;CAAE;CACxE;EAAE,QAAQ;EAAU,QAAQ;EAAK,SAAS,CAAC,KAAK,KAAK;CAAE;AACxD;;AAGA,MAAa,wBAAmE,OAAO,YACtF,aAAa,SAAS,QAAQ,CAAC,IAAI,QAAQ,GAAG,IAAI,OAAO,CAAC,CAAC,KAAK,aAAa,CAAC,UAAU,IAAI,MAAM,CAAC,CAAC,CACrG;;;;;AAMA,MAAa,mBAAqD,OAAO,YACxE,aAAa,KAAK,QAAQ,CAAC,IAAI,QAAQ,IAAI,MAAM,CAAC,CACnD"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/ooxml/transition-speed.ts
|
|
2
|
+
/**
|
|
3
|
+
* Map an exact duration (ms) to the speed bucket it falls in.
|
|
4
|
+
* @param durationMs - the transition's duration, in milliseconds
|
|
5
|
+
*/
|
|
6
|
+
function transitionSpeedForDuration(durationMs) {
|
|
7
|
+
if (durationMs <= 500) return "fast";
|
|
8
|
+
if (durationMs <= 1e3) return "med";
|
|
9
|
+
return "slow";
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { transitionSpeedForDuration as t };
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=transition-speed-kUEWDWTx.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transition-speed-kUEWDWTx.js","names":[],"sources":["../src/ooxml/transition-speed.ts"],"sourcesContent":["/**\n * PowerPoint's coarse `p:transition/@spd` bucket for an exact duration.\n *\n * The write path (`gen/anim/transition.ts`) and the read model's transition setter\n * (`read/api/transition.ts`) each carried a byte-identical copy. A duration that lands in a\n * different bucket on the two sides would make a transition set through the read model differ\n * from the same transition authored fresh, so the boundaries live here once.\n *\n * This module keeps `ooxml/`'s no-runtime-imports property: the reference below is type-only.\n */\n\nimport type { TRANSITION_SPEEDS } from './st-enums.js'\n\n/** An `ST_TransitionSpeed` token. */\nexport type TransitionSpeedToken = (typeof TRANSITION_SPEEDS)[number]\n\n/**\n * Map an exact duration (ms) to the speed bucket it falls in.\n * @param durationMs - the transition's duration, in milliseconds\n */\nexport function transitionSpeedForDuration(durationMs: number): TransitionSpeedToken {\n\tif (durationMs <= 500) return 'fast'\n\tif (durationMs <= 1000) return 'med'\n\treturn 'slow'\n}\n"],"mappings":";;;;;AAoBA,SAAgB,2BAA2B,YAA0C;CACpF,IAAI,cAAc,KAAK,OAAO;CAC9B,IAAI,cAAc,KAAM,OAAO;CAC/B,OAAO;AACR"}
|