@wordinweb/agent 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.
- package/README.md +296 -0
- package/dist/chunk-E7AFDS2O.js +34056 -0
- package/dist/chunk-E7AFDS2O.js.map +1 -0
- package/dist/cli.d.ts +10 -0
- package/dist/cli.js +555 -0
- package/dist/cli.js.map +1 -0
- package/dist/dist-4GR64XSW.js +4326 -0
- package/dist/dist-4GR64XSW.js.map +1 -0
- package/dist/index.d.ts +3092 -0
- package/dist/index.js +124 -0
- package/dist/index.js.map +1 -0
- package/dist/wmf-KUCU4S75.js +193 -0
- package/dist/wmf-KUCU4S75.js.map +1 -0
- package/package.json +50 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AGENT_COMPOSE_SCHEMA,
|
|
3
|
+
AGENT_EDIT_CAPABILITIES,
|
|
4
|
+
AgentDocument,
|
|
5
|
+
DocxDocument,
|
|
6
|
+
agentCapabilities,
|
|
7
|
+
agentOperationSchema,
|
|
8
|
+
applyIntentScoped,
|
|
9
|
+
collaborativeAgentTarget,
|
|
10
|
+
resyncScope,
|
|
11
|
+
sha256Hex,
|
|
12
|
+
unionScopes,
|
|
13
|
+
validateAgentComposeRequest,
|
|
14
|
+
validateAgentOperationShape,
|
|
15
|
+
validateIntent
|
|
16
|
+
} from "./chunk-E7AFDS2O.js";
|
|
17
|
+
|
|
18
|
+
// src/session.ts
|
|
19
|
+
var LocalDocumentSession = class {
|
|
20
|
+
constructor(source) {
|
|
21
|
+
this.revision = 0;
|
|
22
|
+
this.renderRevision = 0;
|
|
23
|
+
this.clientSequence = 0;
|
|
24
|
+
this.dirtyScope = null;
|
|
25
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
26
|
+
this.uploadedMedia = /* @__PURE__ */ new Map();
|
|
27
|
+
this.allocIds = (count) => this.allocateIds(count);
|
|
28
|
+
this.takeRenderScope = () => {
|
|
29
|
+
const scope = this.dirtyScope;
|
|
30
|
+
this.dirtyScope = null;
|
|
31
|
+
return scope;
|
|
32
|
+
};
|
|
33
|
+
this.submit = (operation) => {
|
|
34
|
+
const intent = this.fullIntent(operation);
|
|
35
|
+
const error = validateIntent(intent);
|
|
36
|
+
if (error) throw new Error(error);
|
|
37
|
+
const ids = this.doc.enableStableIds();
|
|
38
|
+
const result = applyIntentScoped(this.doc, ids, intent);
|
|
39
|
+
if (!result.applied) throw new Error(`${operation.kind} could not apply to the referenced document state`);
|
|
40
|
+
resyncScope(this.doc, ids, result);
|
|
41
|
+
this.installUploadedImage(operation);
|
|
42
|
+
this.dirtyScope = unionScopes(this.dirtyScope, result);
|
|
43
|
+
this.revision++;
|
|
44
|
+
this.renderRevision++;
|
|
45
|
+
for (const listener of this.listeners) listener();
|
|
46
|
+
};
|
|
47
|
+
this.submitOp = (operation) => this.submit(operation);
|
|
48
|
+
/** Record an operation that DocxView already applied to this same object. */
|
|
49
|
+
this.submitPreApplied = (operation) => {
|
|
50
|
+
const error = validateIntent(this.fullIntent(operation));
|
|
51
|
+
if (error) throw new Error(error);
|
|
52
|
+
this.revision++;
|
|
53
|
+
};
|
|
54
|
+
this.doc = source instanceof DocxDocument ? source : DocxDocument.load(source);
|
|
55
|
+
this.nextId = this.doc.enableStableIds().nextId();
|
|
56
|
+
}
|
|
57
|
+
get version() {
|
|
58
|
+
return this.revision;
|
|
59
|
+
}
|
|
60
|
+
get renderSignal() {
|
|
61
|
+
return this.renderRevision;
|
|
62
|
+
}
|
|
63
|
+
getDocument() {
|
|
64
|
+
return this.doc;
|
|
65
|
+
}
|
|
66
|
+
getRevision() {
|
|
67
|
+
return this.revision;
|
|
68
|
+
}
|
|
69
|
+
getConnectionState() {
|
|
70
|
+
return "local";
|
|
71
|
+
}
|
|
72
|
+
allocateIds(count) {
|
|
73
|
+
if (!Number.isInteger(count) || count < 0) throw new Error("ID count must be a non-negative integer");
|
|
74
|
+
return Array.from({ length: count }, () => this.nextId++);
|
|
75
|
+
}
|
|
76
|
+
subscribe(listener) {
|
|
77
|
+
this.listeners.add(listener);
|
|
78
|
+
return () => this.listeners.delete(listener);
|
|
79
|
+
}
|
|
80
|
+
async uploadMedia(bytes) {
|
|
81
|
+
const blobSha = await sha256Hex(bytes);
|
|
82
|
+
this.uploadedMedia.set(blobSha, new Uint8Array(bytes));
|
|
83
|
+
return { blobSha, bytesLen: bytes.length };
|
|
84
|
+
}
|
|
85
|
+
fullIntent(operation) {
|
|
86
|
+
return { ...operation, clientId: "local-document-session", clientSeq: ++this.clientSequence, base: this.revision };
|
|
87
|
+
}
|
|
88
|
+
installUploadedImage(operation) {
|
|
89
|
+
if (operation.kind !== "insertImage") return;
|
|
90
|
+
const bytes = this.uploadedMedia.get(operation.blobSha);
|
|
91
|
+
if (!bytes) return;
|
|
92
|
+
for (const [part, metadata] of this.doc.pendingMedia) {
|
|
93
|
+
if (metadata.sha !== operation.blobSha) continue;
|
|
94
|
+
this.doc.installMedia(part, bytes);
|
|
95
|
+
this.uploadedMedia.delete(operation.blobSha);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
function localDocumentViewBinding(session) {
|
|
101
|
+
return {
|
|
102
|
+
subscribe: (listener) => session.subscribe(listener),
|
|
103
|
+
getSnapshot: () => session.renderSignal,
|
|
104
|
+
doc: session.doc,
|
|
105
|
+
submit: session.submitPreApplied,
|
|
106
|
+
submitOp: session.submitOp,
|
|
107
|
+
allocIds: session.allocIds,
|
|
108
|
+
uploadMedia: (bytes) => session.uploadMedia(bytes),
|
|
109
|
+
takeRenderScope: session.takeRenderScope
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
export {
|
|
113
|
+
AGENT_COMPOSE_SCHEMA,
|
|
114
|
+
AGENT_EDIT_CAPABILITIES,
|
|
115
|
+
AgentDocument,
|
|
116
|
+
LocalDocumentSession,
|
|
117
|
+
agentCapabilities,
|
|
118
|
+
agentOperationSchema,
|
|
119
|
+
collaborativeAgentTarget,
|
|
120
|
+
localDocumentViewBinding,
|
|
121
|
+
validateAgentComposeRequest,
|
|
122
|
+
validateAgentOperationShape
|
|
123
|
+
};
|
|
124
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/session.ts"],"sourcesContent":["import { DocxDocument, type XmlElement } from \"@wordinweb/core\";\nimport { applyIntentScoped, resyncScope, sha256Hex, unionScopes, type Intent, type IntentBody, type Scope } from \"@wordinweb/collab/client\";\nimport { validateIntent } from \"@wordinweb/collab/server\";\nimport type { AgentCollaborativeTarget } from \"./types.js\";\n\n/**\n * A canonical document session for one process. It lets a browser editor and\n * an AgentDocument share one DocxDocument without a server or a DOM dependency.\n */\nexport class LocalDocumentSession implements AgentCollaborativeTarget {\n readonly doc: DocxDocument;\n private revision = 0;\n private renderRevision = 0;\n private clientSequence = 0;\n private nextId: number;\n private dirtyScope: Scope | null = null;\n private readonly listeners = new Set<() => void>();\n private readonly uploadedMedia = new Map<string, Uint8Array>();\n\n constructor(source: ArrayBuffer | Uint8Array | DocxDocument) {\n this.doc = source instanceof DocxDocument ? source : DocxDocument.load(source);\n this.nextId = this.doc.enableStableIds().nextId();\n }\n\n get version(): number {\n return this.revision;\n }\n\n get renderSignal(): number {\n return this.renderRevision;\n }\n\n getDocument(): DocxDocument {\n return this.doc;\n }\n\n getRevision(): number {\n return this.revision;\n }\n\n getConnectionState(): \"local\" {\n return \"local\";\n }\n\n allocateIds(count: number): number[] {\n if (!Number.isInteger(count) || count < 0) throw new Error(\"ID count must be a non-negative integer\");\n return Array.from({ length: count }, () => this.nextId++);\n }\n\n allocIds = (count: number): number[] => this.allocateIds(count);\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n takeRenderScope = (): Scope | null => {\n const scope = this.dirtyScope;\n this.dirtyScope = null;\n return scope;\n };\n\n submit = (operation: IntentBody): void => {\n const intent = this.fullIntent(operation);\n const error = validateIntent(intent);\n if (error) throw new Error(error);\n const ids = this.doc.enableStableIds();\n const result = applyIntentScoped(this.doc, ids, intent);\n if (!result.applied) throw new Error(`${operation.kind} could not apply to the referenced document state`);\n resyncScope(this.doc, ids, result);\n this.installUploadedImage(operation);\n this.dirtyScope = unionScopes(this.dirtyScope, result);\n this.revision++;\n this.renderRevision++;\n for (const listener of this.listeners) listener();\n };\n\n submitOp = (operation: IntentBody): void => this.submit(operation);\n\n /** Record an operation that DocxView already applied to this same object. */\n submitPreApplied = (operation: IntentBody): void => {\n const error = validateIntent(this.fullIntent(operation));\n if (error) throw new Error(error);\n this.revision++;\n };\n\n async uploadMedia(bytes: Uint8Array): Promise<{ blobSha: string; bytesLen: number }> {\n const blobSha = await sha256Hex(bytes);\n this.uploadedMedia.set(blobSha, new Uint8Array(bytes));\n return { blobSha, bytesLen: bytes.length };\n }\n\n private fullIntent(operation: IntentBody): Intent {\n return { ...operation, clientId: \"local-document-session\", clientSeq: ++this.clientSequence, base: this.revision } as Intent;\n }\n\n private installUploadedImage(operation: IntentBody): void {\n if (operation.kind !== \"insertImage\") return;\n const bytes = this.uploadedMedia.get(operation.blobSha);\n if (!bytes) return;\n for (const [part, metadata] of this.doc.pendingMedia) {\n if (metadata.sha !== operation.blobSha) continue;\n this.doc.installMedia(part, bytes);\n this.uploadedMedia.delete(operation.blobSha);\n return;\n }\n }\n}\n\nexport interface LocalDocumentViewBinding {\n subscribe(listener: () => void): () => void;\n getSnapshot(): number;\n doc: DocxDocument;\n submit(operation: IntentBody): void;\n submitOp(operation: IntentBody): void;\n allocIds(count: number): number[];\n uploadMedia(bytes: Uint8Array): Promise<{ blobSha: string; bytesLen: number }>;\n takeRenderScope():\n | { kind: \"doc\" }\n | { kind: \"block\"; blocks: XmlElement[] }\n | { kind: \"split\"; before: XmlElement; after: XmlElement }\n | null;\n}\n\nexport function localDocumentViewBinding(session: LocalDocumentSession): LocalDocumentViewBinding {\n return {\n subscribe: (listener) => session.subscribe(listener),\n getSnapshot: () => session.renderSignal,\n doc: session.doc,\n submit: session.submitPreApplied,\n submitOp: session.submitOp,\n allocIds: session.allocIds,\n uploadMedia: (bytes) => session.uploadMedia(bytes),\n takeRenderScope: session.takeRenderScope,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
// ../core/src/render/wmf.ts
|
|
2
|
+
import * as WmfModule from "wmf";
|
|
3
|
+
var WMF = WmfModule.default ?? WmfModule;
|
|
4
|
+
var META_EOF = 0;
|
|
5
|
+
var META_SETBKCOLOR = 513;
|
|
6
|
+
var META_SETTEXTALIGN = 302;
|
|
7
|
+
var META_MOVETO = 532;
|
|
8
|
+
var META_LINETO = 531;
|
|
9
|
+
var META_POLYLINE = 805;
|
|
10
|
+
var META_ESCAPE = 1574;
|
|
11
|
+
var META_EXTTEXTOUT = 2610;
|
|
12
|
+
var PLACEABLE_KEY = 2596720087;
|
|
13
|
+
var SYMBOL_TEXT = {
|
|
14
|
+
p: "\u03C0",
|
|
15
|
+
"\xA5": "\u221E",
|
|
16
|
+
"\xB6": "\u2202",
|
|
17
|
+
\u00E5: "\u2211",
|
|
18
|
+
D: "\u0394"
|
|
19
|
+
};
|
|
20
|
+
function decodeWmfText(text, family) {
|
|
21
|
+
if (family === "Symbol") {
|
|
22
|
+
return { text: [...text].map((char) => SYMBOL_TEXT[char] ?? char).join(""), family };
|
|
23
|
+
}
|
|
24
|
+
if (family === "\xCB\xCE\xCC\xE5") {
|
|
25
|
+
return { text: text.replace(/£¨/g, "\uFF08").replace(/£©/g, "\uFF09"), family: "SimSun" };
|
|
26
|
+
}
|
|
27
|
+
return { text, family };
|
|
28
|
+
}
|
|
29
|
+
function record(fn, params) {
|
|
30
|
+
const length = 6 + params.length + (params.length & 1);
|
|
31
|
+
const out = new Uint8Array(length);
|
|
32
|
+
const view = new DataView(out.buffer);
|
|
33
|
+
view.setUint32(0, length / 2, true);
|
|
34
|
+
view.setUint16(4, fn, true);
|
|
35
|
+
out.set(params, 6);
|
|
36
|
+
return out;
|
|
37
|
+
}
|
|
38
|
+
function polyline(from, to) {
|
|
39
|
+
const params = new Uint8Array(10);
|
|
40
|
+
const view = new DataView(params.buffer);
|
|
41
|
+
view.setUint16(0, 2, true);
|
|
42
|
+
view.setInt16(2, from[0], true);
|
|
43
|
+
view.setInt16(4, from[1], true);
|
|
44
|
+
view.setInt16(6, to[0], true);
|
|
45
|
+
view.setInt16(8, to[1], true);
|
|
46
|
+
return record(META_POLYLINE, params);
|
|
47
|
+
}
|
|
48
|
+
function textRecord(char, x, y, advance) {
|
|
49
|
+
const params = new Uint8Array(12);
|
|
50
|
+
const view = new DataView(params.buffer);
|
|
51
|
+
view.setInt16(0, y, true);
|
|
52
|
+
view.setInt16(2, x, true);
|
|
53
|
+
view.setUint16(4, 1, true);
|
|
54
|
+
params[8] = char;
|
|
55
|
+
view.setInt16(10, advance, true);
|
|
56
|
+
return record(META_EXTTEXTOUT, params);
|
|
57
|
+
}
|
|
58
|
+
function isMathTypeEscape(bytes, offset, length) {
|
|
59
|
+
if (length < 18) return false;
|
|
60
|
+
const name = [77, 97, 116, 104, 84, 121, 112, 101];
|
|
61
|
+
return name.every((value, i) => bytes[offset + 10 + i] === value);
|
|
62
|
+
}
|
|
63
|
+
function hasMathTypeEscapes(bytes) {
|
|
64
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
65
|
+
let offset = 18;
|
|
66
|
+
while (offset + 6 <= bytes.length) {
|
|
67
|
+
const length = view.getUint32(offset, true) * 2;
|
|
68
|
+
if (length < 6 || offset + length > bytes.length) return false;
|
|
69
|
+
const fn = view.getUint16(offset + 4, true);
|
|
70
|
+
if (fn === META_ESCAPE && isMathTypeEscape(bytes, offset, length)) return true;
|
|
71
|
+
offset += length;
|
|
72
|
+
if (fn === META_EOF) break;
|
|
73
|
+
}
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
function prepareWmf(input) {
|
|
77
|
+
let bytes = input;
|
|
78
|
+
if (bytes.length >= 22 && new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(0, true) === PLACEABLE_KEY) {
|
|
79
|
+
bytes = bytes.subarray(22);
|
|
80
|
+
}
|
|
81
|
+
if (bytes.length < 18) return null;
|
|
82
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
83
|
+
const mathType = hasMathTypeEscapes(bytes);
|
|
84
|
+
const parts = [bytes.slice(0, 18)];
|
|
85
|
+
let offset = 18;
|
|
86
|
+
let textAlign = 0;
|
|
87
|
+
let current = [0, 0];
|
|
88
|
+
let maxRecordWords = 0;
|
|
89
|
+
const append = (part) => {
|
|
90
|
+
parts.push(part);
|
|
91
|
+
maxRecordWords = Math.max(maxRecordWords, part.length / 2);
|
|
92
|
+
};
|
|
93
|
+
while (offset + 6 <= bytes.length) {
|
|
94
|
+
const length = view.getUint32(offset, true) * 2;
|
|
95
|
+
if (length < 6 || offset + length > bytes.length) return null;
|
|
96
|
+
const fn = view.getUint16(offset + 4, true);
|
|
97
|
+
const params = offset + 6;
|
|
98
|
+
if (fn === META_SETTEXTALIGN) {
|
|
99
|
+
textAlign = view.getUint16(params, true);
|
|
100
|
+
append(bytes.slice(offset, offset + length));
|
|
101
|
+
} else if (fn === META_MOVETO) {
|
|
102
|
+
current = [view.getInt16(params + 2, true), view.getInt16(params, true)];
|
|
103
|
+
} else if (fn === META_LINETO) {
|
|
104
|
+
const next = [view.getInt16(params + 2, true), view.getInt16(params, true)];
|
|
105
|
+
append(polyline(current, next));
|
|
106
|
+
current = next;
|
|
107
|
+
} else if (fn === META_EXTTEXTOUT) {
|
|
108
|
+
const y = view.getInt16(params, true);
|
|
109
|
+
const x = view.getInt16(params + 2, true);
|
|
110
|
+
const count = view.getUint16(params + 4, true);
|
|
111
|
+
const options = view.getUint16(params + 6, true);
|
|
112
|
+
let charsAt = params + 8 + (options & 6 ? 8 : 0);
|
|
113
|
+
const advancesAt = charsAt + count + (count & 1);
|
|
114
|
+
const hasAdvances = options === 0 && advancesAt + count * 2 <= offset + length;
|
|
115
|
+
if (hasAdvances) {
|
|
116
|
+
let position = textAlign & 1 ? current : [x, y];
|
|
117
|
+
for (let i = 0; i < count; i++) {
|
|
118
|
+
const advance = view.getInt16(advancesAt + i * 2, true);
|
|
119
|
+
append(textRecord(bytes[charsAt + i], position[0], position[1], advance));
|
|
120
|
+
position = [position[0] + advance, position[1]];
|
|
121
|
+
}
|
|
122
|
+
if (textAlign & 1) current = position;
|
|
123
|
+
} else {
|
|
124
|
+
const copy = bytes.slice(offset, offset + length);
|
|
125
|
+
if (textAlign & 1) {
|
|
126
|
+
const copyView = new DataView(copy.buffer, copy.byteOffset, copy.byteLength);
|
|
127
|
+
copyView.setInt16(6, current[1], true);
|
|
128
|
+
copyView.setInt16(8, current[0], true);
|
|
129
|
+
}
|
|
130
|
+
append(copy);
|
|
131
|
+
}
|
|
132
|
+
} else if (fn === META_ESCAPE && mathType) {
|
|
133
|
+
} else if (fn !== META_SETBKCOLOR) {
|
|
134
|
+
append(bytes.slice(offset, offset + length));
|
|
135
|
+
}
|
|
136
|
+
offset += length;
|
|
137
|
+
if (fn === META_EOF) break;
|
|
138
|
+
}
|
|
139
|
+
const total = parts.reduce((sum, part) => sum + part.length, 0);
|
|
140
|
+
const out = new Uint8Array(total);
|
|
141
|
+
let at = 0;
|
|
142
|
+
for (const part of parts) {
|
|
143
|
+
out.set(part, at);
|
|
144
|
+
at += part.length;
|
|
145
|
+
}
|
|
146
|
+
const outView = new DataView(out.buffer);
|
|
147
|
+
outView.setUint32(6, total / 2, true);
|
|
148
|
+
outView.setUint32(12, maxRecordWords, true);
|
|
149
|
+
return out;
|
|
150
|
+
}
|
|
151
|
+
function renderWmf(bytes, width, height) {
|
|
152
|
+
var _a, _b;
|
|
153
|
+
try {
|
|
154
|
+
const prepared = prepareWmf(bytes);
|
|
155
|
+
if (!prepared) return null;
|
|
156
|
+
const [rawWidth, rawHeight] = WMF.image_size(prepared).map(Math.abs);
|
|
157
|
+
if (!rawWidth || !rawHeight) return null;
|
|
158
|
+
const scale = Math.max(1, window.devicePixelRatio || 1);
|
|
159
|
+
const canvas = document.createElement("canvas");
|
|
160
|
+
canvas.width = Math.max(1, Math.round(width * scale));
|
|
161
|
+
canvas.height = Math.max(1, Math.round(height * scale));
|
|
162
|
+
const ctx = canvas.getContext("2d");
|
|
163
|
+
if (!ctx) return null;
|
|
164
|
+
ctx.fillStyle = "#fff";
|
|
165
|
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
166
|
+
ctx.fillStyle = "#000";
|
|
167
|
+
ctx.scale(canvas.width / rawWidth, canvas.height / rawHeight);
|
|
168
|
+
const actions = WMF.get_actions(prepared);
|
|
169
|
+
for (const action of actions) {
|
|
170
|
+
if (!action.s) continue;
|
|
171
|
+
delete action.s.Extent;
|
|
172
|
+
if (action.t === "text" && action.v !== void 0 && action.s.Font) {
|
|
173
|
+
const decoded = decodeWmfText(action.v, action.s.Font.Name);
|
|
174
|
+
action.v = decoded.text;
|
|
175
|
+
action.s.Font.Name = decoded.family;
|
|
176
|
+
}
|
|
177
|
+
if (action.t === "poly") {
|
|
178
|
+
(_a = action.s).Pen ?? (_a.Pen = { Style: 0, Width: 1, Color: 0 });
|
|
179
|
+
(_b = action.s).Brush ?? (_b.Brush = { Style: 1, Color: 0 });
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
WMF.render_canvas(actions, canvas);
|
|
183
|
+
return canvas.toDataURL("image/png");
|
|
184
|
+
} catch {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
export {
|
|
189
|
+
decodeWmfText,
|
|
190
|
+
prepareWmf,
|
|
191
|
+
renderWmf
|
|
192
|
+
};
|
|
193
|
+
//# sourceMappingURL=wmf-KUCU4S75.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../core/src/render/wmf.ts"],"sourcesContent":["import * as WmfModule from \"wmf\";\n\nconst WMF = (WmfModule.default ?? WmfModule) as typeof WmfModule.default;\n\nconst META_EOF = 0x0000;\nconst META_SETBKCOLOR = 0x0201;\nconst META_SETTEXTALIGN = 0x012e;\nconst META_MOVETO = 0x0214;\nconst META_LINETO = 0x0213;\nconst META_POLYLINE = 0x0325;\nconst META_ESCAPE = 0x0626;\nconst META_EXTTEXTOUT = 0x0a32;\nconst PLACEABLE_KEY = 0x9ac6cdd7;\n\nconst SYMBOL_TEXT: Record<string, string> = {\n p: \"π\",\n \"¥\": \"∞\",\n \"¶\": \"∂\",\n å: \"∑\",\n D: \"Δ\",\n};\n\nexport function decodeWmfText(text: string, family: string): { text: string; family: string } {\n if (family === \"Symbol\") {\n return { text: [...text].map((char) => SYMBOL_TEXT[char] ?? char).join(\"\"), family };\n }\n if (family === \"ËÎÌå\") {\n return { text: text.replace(/£¨/g, \"(\").replace(/£©/g, \")\"), family: \"SimSun\" };\n }\n return { text, family };\n}\n\nfunction record(fn: number, params: Uint8Array): Uint8Array {\n const length = 6 + params.length + (params.length & 1);\n const out = new Uint8Array(length);\n const view = new DataView(out.buffer);\n view.setUint32(0, length / 2, true);\n view.setUint16(4, fn, true);\n out.set(params, 6);\n return out;\n}\n\nfunction polyline(from: [number, number], to: [number, number]): Uint8Array {\n const params = new Uint8Array(10);\n const view = new DataView(params.buffer);\n view.setUint16(0, 2, true);\n view.setInt16(2, from[0], true);\n view.setInt16(4, from[1], true);\n view.setInt16(6, to[0], true);\n view.setInt16(8, to[1], true);\n return record(META_POLYLINE, params);\n}\n\nfunction textRecord(char: number, x: number, y: number, advance: number): Uint8Array {\n const params = new Uint8Array(12);\n const view = new DataView(params.buffer);\n view.setInt16(0, y, true);\n view.setInt16(2, x, true);\n view.setUint16(4, 1, true);\n params[8] = char;\n view.setInt16(10, advance, true);\n return record(META_EXTTEXTOUT, params);\n}\n\nfunction isMathTypeEscape(bytes: Uint8Array, offset: number, length: number): boolean {\n if (length < 18) return false;\n const name = [0x4d, 0x61, 0x74, 0x68, 0x54, 0x79, 0x70, 0x65];\n return name.every((value, i) => bytes[offset + 10 + i] === value);\n}\n\nfunction hasMathTypeEscapes(bytes: Uint8Array): boolean {\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n let offset = 18;\n while (offset + 6 <= bytes.length) {\n const length = view.getUint32(offset, true) * 2;\n if (length < 6 || offset + length > bytes.length) return false;\n const fn = view.getUint16(offset + 4, true);\n if (fn === META_ESCAPE && isMathTypeEscape(bytes, offset, length)) return true;\n offset += length;\n if (fn === META_EOF) break;\n }\n return false;\n}\n\n/**\n * Make MathType's legacy WMF records consumable by the small `wmf` renderer.\n * MathType positions text through TA_UPDATECP + MOVETO and draws fraction bars\n * with LINETO. The dependency does not implement those records, so translate\n * them to the equivalent absolute EXTTEXTOUT and POLYLINE records first.\n */\nexport function prepareWmf(input: Uint8Array): Uint8Array | null {\n let bytes = input;\n if (bytes.length >= 22 && new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(0, true) === PLACEABLE_KEY) {\n bytes = bytes.subarray(22);\n }\n if (bytes.length < 18) return null;\n\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const mathType = hasMathTypeEscapes(bytes);\n const parts: Uint8Array[] = [bytes.slice(0, 18)];\n let offset = 18;\n let textAlign = 0;\n let current: [number, number] = [0, 0];\n let maxRecordWords = 0;\n\n const append = (part: Uint8Array) => {\n parts.push(part);\n maxRecordWords = Math.max(maxRecordWords, part.length / 2);\n };\n\n while (offset + 6 <= bytes.length) {\n const length = view.getUint32(offset, true) * 2;\n if (length < 6 || offset + length > bytes.length) return null;\n const fn = view.getUint16(offset + 4, true);\n const params = offset + 6;\n\n if (fn === META_SETTEXTALIGN) {\n textAlign = view.getUint16(params, true);\n append(bytes.slice(offset, offset + length));\n } else if (fn === META_MOVETO) {\n current = [view.getInt16(params + 2, true), view.getInt16(params, true)];\n } else if (fn === META_LINETO) {\n const next: [number, number] = [view.getInt16(params + 2, true), view.getInt16(params, true)];\n append(polyline(current, next));\n current = next;\n } else if (fn === META_EXTTEXTOUT) {\n const y = view.getInt16(params, true);\n const x = view.getInt16(params + 2, true);\n const count = view.getUint16(params + 4, true);\n const options = view.getUint16(params + 6, true);\n let charsAt = params + 8 + (options & 6 ? 8 : 0);\n const advancesAt = charsAt + count + (count & 1);\n const hasAdvances = options === 0 && advancesAt + count * 2 <= offset + length;\n\n if (hasAdvances) {\n let position: [number, number] = textAlign & 1 ? current : [x, y];\n for (let i = 0; i < count; i++) {\n const advance = view.getInt16(advancesAt + i * 2, true);\n append(textRecord(bytes[charsAt + i], position[0], position[1], advance));\n position = [position[0] + advance, position[1]];\n }\n if (textAlign & 1) current = position;\n } else {\n const copy = bytes.slice(offset, offset + length);\n if (textAlign & 1) {\n const copyView = new DataView(copy.buffer, copy.byteOffset, copy.byteLength);\n copyView.setInt16(6, current[1], true);\n copyView.setInt16(8, current[0], true);\n }\n append(copy);\n }\n } else if (fn === META_ESCAPE && mathType) {\n // MathType metadata is not a drawing command. The dependency otherwise\n // mistakes it for an embedded EMF comment and rejects the whole image.\n } else if (fn !== META_SETBKCOLOR) {\n append(bytes.slice(offset, offset + length));\n }\n\n offset += length;\n if (fn === META_EOF) break;\n }\n\n const total = parts.reduce((sum, part) => sum + part.length, 0);\n const out = new Uint8Array(total);\n let at = 0;\n for (const part of parts) {\n out.set(part, at);\n at += part.length;\n }\n const outView = new DataView(out.buffer);\n outView.setUint32(6, total / 2, true);\n outView.setUint32(12, maxRecordWords, true);\n return out;\n}\n\nexport function renderWmf(bytes: Uint8Array, width: number, height: number): string | null {\n try {\n const prepared = prepareWmf(bytes);\n if (!prepared) return null;\n const [rawWidth, rawHeight] = WMF.image_size(prepared).map(Math.abs);\n if (!rawWidth || !rawHeight) return null;\n\n const scale = Math.max(1, window.devicePixelRatio || 1);\n const canvas = document.createElement(\"canvas\");\n canvas.width = Math.max(1, Math.round(width * scale));\n canvas.height = Math.max(1, Math.round(height * scale));\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return null;\n ctx.fillStyle = \"#fff\";\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n ctx.fillStyle = \"#000\";\n ctx.scale(canvas.width / rawWidth, canvas.height / rawHeight);\n\n const actions = WMF.get_actions(prepared);\n for (const action of actions) {\n if (!action.s) continue;\n delete action.s.Extent;\n if (action.t === \"text\" && action.v !== undefined && action.s.Font) {\n const decoded = decodeWmfText(action.v, action.s.Font.Name);\n action.v = decoded.text;\n action.s.Font.Name = decoded.family;\n }\n if (action.t === \"poly\") {\n action.s.Pen ??= { Style: 0, Width: 1, Color: 0 };\n action.s.Brush ??= { Style: 1, Color: 0 };\n }\n }\n WMF.render_canvas(actions, canvas);\n return canvas.toDataURL(\"image/png\");\n } catch {\n return null;\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@wordinweb/agent",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Complete, schema-enforced DOCX creation, inspection, and editing tools for AI agents",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/theRealestAEP/wordinweb.git",
|
|
9
|
+
"directory": "packages/agent"
|
|
10
|
+
},
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"type": "module",
|
|
15
|
+
"main": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.js",
|
|
21
|
+
"default": "./dist/index.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"bin": {
|
|
25
|
+
"wordinweb-agent": "./dist/cli.js"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"README.md"
|
|
30
|
+
],
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsup",
|
|
33
|
+
"prepack": "npm run build && node ../../scripts/check-dts-selfcontained.mjs",
|
|
34
|
+
"test": "vitest run",
|
|
35
|
+
"test:watch": "vitest"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"cfb": "^1.2.2",
|
|
39
|
+
"fflate": "^0.8.2",
|
|
40
|
+
"wmf": "^1.0.2",
|
|
41
|
+
"ws": "^8.21.1"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@wordinweb/core": "0.1.0",
|
|
45
|
+
"@wordinweb/collab": "0.2.3",
|
|
46
|
+
"@types/node": "^22.0.0",
|
|
47
|
+
"@types/ws": "^8.18.1",
|
|
48
|
+
"vitest": "^2.1.0"
|
|
49
|
+
}
|
|
50
|
+
}
|