@ingcreators/annot-core 0.2.0 → 0.2.1
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/CHANGELOG.md +75 -0
- package/dist/xmp-bytes.js +265 -0
- package/package.json +5 -1
- package/styles/editor.css +6 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,80 @@
|
|
|
1
1
|
# @ingcreators/annot-core
|
|
2
2
|
|
|
3
|
+
## 0.2.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- f485646: **Expose `./xmp-bytes` subpath on the published tarball.**
|
|
8
|
+
The workspace `package.json#exports` declared
|
|
9
|
+
`"./xmp-bytes": "./src/xmp/xmp-bytes.ts"` from day one, but
|
|
10
|
+
`publishConfig.exports` only declared `.` + `./styles/*` —
|
|
11
|
+
so every workspace subpath (`./headless`, `./editor/*`,
|
|
12
|
+
`./xmp-bytes`, etc.) was stripped from the published
|
|
13
|
+
tarball.
|
|
14
|
+
|
|
15
|
+
This patch unblocks the `./xmp-bytes` subpath specifically.
|
|
16
|
+
`@ingcreators/annot-product-docs-astro@0.2.1`'s playwright
|
|
17
|
+
fixture imports `@ingcreators/annot-core/xmp-bytes` (via
|
|
18
|
+
the bundled `writePngWithTagsOnly` helper); without this
|
|
19
|
+
patch, any consumer doing
|
|
20
|
+
`import { test } from "@ingcreators/annot-product-docs-astro/playwright"`
|
|
21
|
+
hits `Package subpath './xmp-bytes' is not defined`.
|
|
22
|
+
|
|
23
|
+
## Fix
|
|
24
|
+
|
|
25
|
+
`vite.config.ts` switches to multi-entry library mode:
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
lib: {
|
|
29
|
+
entry: {
|
|
30
|
+
index: resolve(__dirname, "src/index.ts"),
|
|
31
|
+
"xmp-bytes": resolve(__dirname, "src/xmp/xmp-bytes.ts"),
|
|
32
|
+
},
|
|
33
|
+
formats: ["es"],
|
|
34
|
+
},
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`package.json#publishConfig.exports` gains the matching
|
|
38
|
+
`./xmp-bytes` entry:
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
"./xmp-bytes": {
|
|
42
|
+
"types": "./dist/xmp/xmp-bytes.d.ts",
|
|
43
|
+
"default": "./dist/xmp-bytes.js"
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Bundle landing in the tarball:
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
dist/xmp-bytes.js 7.55 kB │ gzip: 2.67 kB
|
|
51
|
+
dist/xmp/xmp-bytes.d.ts declarations colocated by the dts plugin
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Other subpaths still missing
|
|
55
|
+
|
|
56
|
+
The workspace `exports` map declares 17+ subpaths (`./headless`,
|
|
57
|
+
`./editor`, `./editor/*`, `./icons`, `./xmp`, `./zip`,
|
|
58
|
+
`./utils`, `./desktop-bridge`, `./storage`, `./encode/*`,
|
|
59
|
+
`./auto-capture-options`, …). Most are Tier C (browser-only)
|
|
60
|
+
and shouldn't ship as standalone published bundles — Tier C
|
|
61
|
+
code lives in `@ingcreators/annot-editor` / `-render` for
|
|
62
|
+
npm consumers. The few Tier A subpaths that DO make sense
|
|
63
|
+
on npm (`./headless`, `./storage`, `./utils`, `./zip`,
|
|
64
|
+
`./zip-bytes`) can ship in a separate follow-up patch
|
|
65
|
+
when a concrete downstream consumer needs them.
|
|
66
|
+
|
|
67
|
+
## After this PR republishes
|
|
68
|
+
|
|
69
|
+
`@ingcreators/annot-product-docs-astro` needs a `0.2.2`
|
|
70
|
+
republish that bumps its `@ingcreators/annot-core` dep
|
|
71
|
+
from `0.2.0` to `^0.2.1` so the playwright fixture can
|
|
72
|
+
finally resolve `./xmp-bytes` at consumer install time.
|
|
73
|
+
Once both land, the `examples/workflow-app/` tour can
|
|
74
|
+
migrate from the hybrid `captureScreen + page.screenshot`
|
|
75
|
+
pair to the unified `page.screenshot({ annot: { mdx } })`
|
|
76
|
+
single call.
|
|
77
|
+
|
|
3
78
|
## 0.2.0
|
|
4
79
|
|
|
5
80
|
### Minor Changes
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
//#region src/xmp/xmp-bytes.ts
|
|
2
|
+
var e = "annot", t = "https://ingcreators.com/annot/ns/1.0/", n = new TextEncoder().encode("http://ns.adobe.com/xap/1.0/\0"), r = new TextEncoder().encode("annot:OriginalImage\0"), i = new TextEncoder().encode("XML:com.adobe.xmp");
|
|
3
|
+
function a(n, r, i, a) {
|
|
4
|
+
let o = a && Object.keys(a).length > 0 ? JSON.stringify(a) : "";
|
|
5
|
+
return `<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
|
|
6
|
+
<x:xmpmeta xmlns:x="adobe:ns:meta/">
|
|
7
|
+
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
|
8
|
+
<rdf:Description rdf:about=""
|
|
9
|
+
xmlns:${e}="${t}">
|
|
10
|
+
<${e}:annotations><![CDATA[${n}]]></${e}:annotations>
|
|
11
|
+
<${e}:width>${r}</${e}:width>
|
|
12
|
+
<${e}:height>${i}</${e}:height>
|
|
13
|
+
<${e}:version>1.0</${e}:version>${o ? `\n <${e}:tags>${o}</${e}:tags>` : ""}
|
|
14
|
+
</rdf:Description>
|
|
15
|
+
</rdf:RDF>
|
|
16
|
+
</x:xmpmeta>
|
|
17
|
+
<?xpacket end="w"?>`;
|
|
18
|
+
}
|
|
19
|
+
function o(e) {
|
|
20
|
+
return new Uint8Array([e >> 8 & 255, e & 255]);
|
|
21
|
+
}
|
|
22
|
+
function s(e) {
|
|
23
|
+
return new Uint8Array([
|
|
24
|
+
e >> 24 & 255,
|
|
25
|
+
e >> 16 & 255,
|
|
26
|
+
e >> 8 & 255,
|
|
27
|
+
e & 255
|
|
28
|
+
]);
|
|
29
|
+
}
|
|
30
|
+
function c(e, t) {
|
|
31
|
+
return e[t] << 8 | e[t + 1];
|
|
32
|
+
}
|
|
33
|
+
function l(e, t) {
|
|
34
|
+
return (e[t] << 24 | e[t + 1] << 16 | e[t + 2] << 8 | e[t + 3]) >>> 0;
|
|
35
|
+
}
|
|
36
|
+
function u(...e) {
|
|
37
|
+
let t = 0;
|
|
38
|
+
for (let n of e) t += n.length;
|
|
39
|
+
let n = new Uint8Array(t), r = 0;
|
|
40
|
+
for (let t of e) n.set(t, r), r += t.length;
|
|
41
|
+
return n;
|
|
42
|
+
}
|
|
43
|
+
function d(e, t, n) {
|
|
44
|
+
if (t + n.length > e.length) return !1;
|
|
45
|
+
for (let r = 0; r < n.length; r++) if (e[t + r] !== n[r]) return !1;
|
|
46
|
+
return !0;
|
|
47
|
+
}
|
|
48
|
+
function f(e) {
|
|
49
|
+
let t = e.split(",")[1] || "", n = atob(t), r = new Uint8Array(n.length);
|
|
50
|
+
for (let e = 0; e < n.length; e++) r[e] = n.charCodeAt(e);
|
|
51
|
+
return r;
|
|
52
|
+
}
|
|
53
|
+
function p(e, t) {
|
|
54
|
+
let n = t.length + 2;
|
|
55
|
+
return u(new Uint8Array([255, e]), o(n), t);
|
|
56
|
+
}
|
|
57
|
+
function m(e) {
|
|
58
|
+
let t = 65533 - r.length - 4, n = Math.ceil(e.length / t), i = [];
|
|
59
|
+
for (let a = 0; a < n; a++) {
|
|
60
|
+
let s = a * t, c = Math.min(s + t, e.length), l = e.slice(s, c), d = u(r, o(a), o(n), l);
|
|
61
|
+
i.push(p(226, d));
|
|
62
|
+
}
|
|
63
|
+
return u(...i);
|
|
64
|
+
}
|
|
65
|
+
function h(e) {
|
|
66
|
+
let t = [e.slice(0, 2)], i = 2;
|
|
67
|
+
for (; i + 4 <= e.length && e[i] === 255;) {
|
|
68
|
+
let a = e[i + 1];
|
|
69
|
+
if (a === 217 || a === 218) return t.push(e.slice(i)), u(...t);
|
|
70
|
+
let o = c(e, i + 2), s = i + 2 + o;
|
|
71
|
+
if (s > e.length) break;
|
|
72
|
+
let l = a === 225 && d(e, i + 4, n), f = a === 226 && d(e, i + 4, r);
|
|
73
|
+
!l && !f && t.push(e.slice(i, s)), i = s;
|
|
74
|
+
}
|
|
75
|
+
return i < e.length && t.push(e.slice(i)), u(...t);
|
|
76
|
+
}
|
|
77
|
+
function g(e, t, r) {
|
|
78
|
+
let i = p(225, u(n, t)), a = m(r), o = h(e);
|
|
79
|
+
return u(o.slice(0, 2), i, a, o.slice(2));
|
|
80
|
+
}
|
|
81
|
+
var _ = (() => {
|
|
82
|
+
let e = new Uint32Array(256);
|
|
83
|
+
for (let t = 0; t < 256; t++) {
|
|
84
|
+
let n = t;
|
|
85
|
+
for (let e = 0; e < 8; e++) n & 1 ? n = 3988292384 ^ n >>> 1 : n >>>= 1;
|
|
86
|
+
e[t] = n;
|
|
87
|
+
}
|
|
88
|
+
return e;
|
|
89
|
+
})();
|
|
90
|
+
function v(e) {
|
|
91
|
+
let t = 4294967295;
|
|
92
|
+
for (let n = 0; n < e.length; n++) t = _[(t ^ e[n]) & 255] ^ t >>> 8;
|
|
93
|
+
return (t ^ 4294967295) >>> 0;
|
|
94
|
+
}
|
|
95
|
+
function y(e, t) {
|
|
96
|
+
let n = u(e, t), r = v(n);
|
|
97
|
+
return u(s(t.length), n, s(r));
|
|
98
|
+
}
|
|
99
|
+
function b(e) {
|
|
100
|
+
let t = u(i, new Uint8Array([
|
|
101
|
+
0,
|
|
102
|
+
0,
|
|
103
|
+
0,
|
|
104
|
+
0,
|
|
105
|
+
0
|
|
106
|
+
]), e);
|
|
107
|
+
return y(new TextEncoder().encode("iTXt"), t);
|
|
108
|
+
}
|
|
109
|
+
function x(e) {
|
|
110
|
+
let t = [e.slice(0, 8)], n = 8;
|
|
111
|
+
for (; n + 12 <= e.length;) {
|
|
112
|
+
let r = l(e, n), a = e.slice(n + 4, n + 8), o = n + 8, s = o + r + 4;
|
|
113
|
+
if (s > e.length) break;
|
|
114
|
+
let c = String.fromCharCode(...a);
|
|
115
|
+
!(c === "iTXt" && d(e, o, i)) && c !== "svGo" && t.push(e.slice(n, s)), n = s;
|
|
116
|
+
}
|
|
117
|
+
return u(...t);
|
|
118
|
+
}
|
|
119
|
+
function S(e, t, n) {
|
|
120
|
+
let r = b(t), i = y(new TextEncoder().encode("svGo"), n), a = x(e), o = a.length - 12;
|
|
121
|
+
return u(a.slice(0, o), r, i, a.slice(o));
|
|
122
|
+
}
|
|
123
|
+
function C(n) {
|
|
124
|
+
return `<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
|
|
125
|
+
<x:xmpmeta xmlns:x="adobe:ns:meta/">
|
|
126
|
+
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
|
127
|
+
<rdf:Description rdf:about=""
|
|
128
|
+
xmlns:${e}="${t}">
|
|
129
|
+
<${e}:tags>${JSON.stringify(n)}</${e}:tags>
|
|
130
|
+
</rdf:Description>
|
|
131
|
+
</rdf:RDF>
|
|
132
|
+
</x:xmpmeta>
|
|
133
|
+
<?xpacket end="w"?>`;
|
|
134
|
+
}
|
|
135
|
+
function w(e, t) {
|
|
136
|
+
if (!t || Object.keys(t).length === 0) return e;
|
|
137
|
+
let n = b(new TextEncoder().encode(C(t))), r = x(e), i = r.length - 12;
|
|
138
|
+
return u(r.slice(0, i), n, r.slice(i));
|
|
139
|
+
}
|
|
140
|
+
var T = [
|
|
141
|
+
"source",
|
|
142
|
+
"screen",
|
|
143
|
+
"capturedAt",
|
|
144
|
+
"commit"
|
|
145
|
+
];
|
|
146
|
+
function E(e) {
|
|
147
|
+
let t = a(e.annotationsSvg, e.width, e.height, e.tags), n = new TextEncoder().encode(t), r = typeof e.originalImage == "string" ? f(e.originalImage) : e.originalImage;
|
|
148
|
+
return S(e.renderedPng, n, r);
|
|
149
|
+
}
|
|
150
|
+
function D(e) {
|
|
151
|
+
return A(e) ? M(e) : null;
|
|
152
|
+
}
|
|
153
|
+
function O(e) {
|
|
154
|
+
return k(e) ? j(e) : A(e) ? M(e) : null;
|
|
155
|
+
}
|
|
156
|
+
function k(e) {
|
|
157
|
+
return e[0] === 255 && e[1] === 216;
|
|
158
|
+
}
|
|
159
|
+
function A(e) {
|
|
160
|
+
return e[0] === 137 && e[1] === 80 && e[2] === 78 && e[3] === 71;
|
|
161
|
+
}
|
|
162
|
+
function j(e) {
|
|
163
|
+
let t = F(e), n = I(e);
|
|
164
|
+
return t ? N(t, n) : null;
|
|
165
|
+
}
|
|
166
|
+
function M(e) {
|
|
167
|
+
let t = L(e), n = R(e);
|
|
168
|
+
return t ? N(t, n) : null;
|
|
169
|
+
}
|
|
170
|
+
function N(e, t) {
|
|
171
|
+
let n = P(e, "annotations");
|
|
172
|
+
if (!n) return null;
|
|
173
|
+
let r = n.replace(/^<!\[CDATA\[/, "").replace(/\]\]>$/, ""), i = Number.parseInt(P(e, "width") || "0", 10), a = Number.parseInt(P(e, "height") || "0", 10), o = "";
|
|
174
|
+
t && t.length > 0 && (o = `data:${t[0] === 137 && t[1] === 80 ? "image/png" : "image/jpeg"};base64,${z(t)}`);
|
|
175
|
+
let s = {}, c = P(e, "tags");
|
|
176
|
+
if (c) try {
|
|
177
|
+
s = JSON.parse(c);
|
|
178
|
+
} catch {}
|
|
179
|
+
return {
|
|
180
|
+
originalImageDataUrl: o,
|
|
181
|
+
annotationsSvg: r,
|
|
182
|
+
width: i,
|
|
183
|
+
height: a,
|
|
184
|
+
tags: s
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
function P(t, n) {
|
|
188
|
+
let r = `<${e}:${n}>`, i = `</${e}:${n}>`, a = t.indexOf(r);
|
|
189
|
+
if (a < 0) return null;
|
|
190
|
+
let o = t.indexOf(i, a);
|
|
191
|
+
return o < 0 ? null : t.substring(a + r.length, o);
|
|
192
|
+
}
|
|
193
|
+
function F(e) {
|
|
194
|
+
let t = 2;
|
|
195
|
+
for (; t + 4 <= e.length && e[t] === 255;) {
|
|
196
|
+
let r = e[t + 1];
|
|
197
|
+
if (r === 217 || r === 218) break;
|
|
198
|
+
let i = c(e, t + 2), a = t + 2 + i;
|
|
199
|
+
if (a > e.length) break;
|
|
200
|
+
if (r === 225 && d(e, t + 4, n)) {
|
|
201
|
+
let r = t + 4 + n.length;
|
|
202
|
+
return new TextDecoder().decode(e.slice(r, a));
|
|
203
|
+
}
|
|
204
|
+
t = a;
|
|
205
|
+
}
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
function I(e) {
|
|
209
|
+
let t = r.length, n = [], i = 2;
|
|
210
|
+
for (; i + 4 <= e.length && e[i] === 255;) {
|
|
211
|
+
let a = e[i + 1];
|
|
212
|
+
if (a === 217 || a === 218) break;
|
|
213
|
+
let o = c(e, i + 2), s = i + 2 + o;
|
|
214
|
+
if (s > e.length) break;
|
|
215
|
+
if (a === 226 && d(e, i + 4, r)) {
|
|
216
|
+
let r = i + 4 + t;
|
|
217
|
+
if (r + 4 <= s) {
|
|
218
|
+
let t = c(e, r), i = e.slice(r + 4, s);
|
|
219
|
+
n.push({
|
|
220
|
+
seq: t,
|
|
221
|
+
data: i
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
i = s;
|
|
226
|
+
}
|
|
227
|
+
return n.length === 0 ? null : (n.sort((e, t) => e.seq - t.seq), u(...n.map((e) => e.data)));
|
|
228
|
+
}
|
|
229
|
+
function L(e) {
|
|
230
|
+
let t = 8;
|
|
231
|
+
for (; t + 12 <= e.length;) {
|
|
232
|
+
let n = l(e, t), r = String.fromCharCode(e[t + 4], e[t + 5], e[t + 6], e[t + 7]), a = t + 8, o = a + n + 4;
|
|
233
|
+
if (o > e.length) break;
|
|
234
|
+
if (r === "iTXt" && d(e, a, i)) {
|
|
235
|
+
let t = a + i.length, r = 0, o = t;
|
|
236
|
+
for (let i = t; i < a + n; i++) if (e[i] === 0 && r++, r >= 4) {
|
|
237
|
+
o = i + 1;
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
return new TextDecoder().decode(e.slice(o, a + n));
|
|
241
|
+
}
|
|
242
|
+
t = o;
|
|
243
|
+
}
|
|
244
|
+
return null;
|
|
245
|
+
}
|
|
246
|
+
function R(e) {
|
|
247
|
+
let t = 8;
|
|
248
|
+
for (; t + 12 <= e.length;) {
|
|
249
|
+
let n = l(e, t), r = String.fromCharCode(e[t + 4], e[t + 5], e[t + 6], e[t + 7]), i = t + 8, a = i + n + 4;
|
|
250
|
+
if (a > e.length) break;
|
|
251
|
+
if (r === "svGo") return e.slice(i, i + n);
|
|
252
|
+
t = a;
|
|
253
|
+
}
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
function z(e) {
|
|
257
|
+
let t = 32768, n = "";
|
|
258
|
+
for (let r = 0; r < e.length; r += t) {
|
|
259
|
+
let i = e.subarray(r, Math.min(r + t, e.length));
|
|
260
|
+
n += String.fromCharCode.apply(null, i);
|
|
261
|
+
}
|
|
262
|
+
return btoa(n);
|
|
263
|
+
}
|
|
264
|
+
//#endregion
|
|
265
|
+
export { T as WELL_KNOWN_TAG_KEYS, a as buildXmp, C as buildXmpTagsOnly, E as createEditablePngBytes, f as dataUrlToUint8Array, O as readEditableImage, D as readEditablePngBytes, g as writeJpegWithMetadata, S as writePngWithMetadata, w as writePngWithTagsOnly };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ingcreators/annot-core",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Annot SDK — SVG-first screenshot annotation format, storage abstractions, and editor primitives. The foundation shared by the PWA, Chrome extension, Electron desktop, VSCode extension, and the headless annotator.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "ingcreators",
|
|
@@ -30,6 +30,10 @@
|
|
|
30
30
|
"types": "./dist/index.d.ts",
|
|
31
31
|
"default": "./dist/index.js"
|
|
32
32
|
},
|
|
33
|
+
"./xmp-bytes": {
|
|
34
|
+
"types": "./dist/xmp/xmp-bytes.d.ts",
|
|
35
|
+
"default": "./dist/xmp-bytes.js"
|
|
36
|
+
},
|
|
33
37
|
"./styles/*": "./styles/*"
|
|
34
38
|
},
|
|
35
39
|
"files": [
|
package/styles/editor.css
CHANGED
|
@@ -179,9 +179,12 @@ body {
|
|
|
179
179
|
|
|
180
180
|
/* The contentEditable overlay lives inside a `<foreignObject>` —
|
|
181
181
|
bring text selection back so the user can mark / replace runs
|
|
182
|
-
while editing.
|
|
183
|
-
|
|
184
|
-
[data-annot-shell-root]
|
|
182
|
+
while editing. Selectors ordered ascending-by-specificity so
|
|
183
|
+
Biome's `noDescendingSpecificity` rule is satisfied:
|
|
184
|
+
`[data-annot-shell-root]` is (0,2,1); `#svg-root` is (1,1,1).
|
|
185
|
+
Same applied rules either way. */
|
|
186
|
+
[data-annot-shell-root] foreignObject [contenteditable="true"],
|
|
187
|
+
#svg-root foreignObject [contenteditable="true"] {
|
|
185
188
|
user-select: text;
|
|
186
189
|
-webkit-user-select: text;
|
|
187
190
|
}
|