mixdog 1.2.5 → 1.2.6
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/package.json +1 -1
- package/scripts/lib/gate-scheduler.mjs +2 -2
- package/scripts/lib/run-node-tests.mjs +5 -14
- package/scripts/provider-pingpong-live.mjs +9 -9
- package/src/agents/advisor/AGENT.md +4 -4
- package/src/agents/advisor/agent.json +1 -1
- package/src/agents/reviewer/AGENT.md +2 -3
- package/src/agents/reviewer/agent.json +1 -1
- package/src/defaults/shipped-history.json +10 -0
- package/src/defaults/skills/browser-use/SKILL.md +2 -1
- package/src/defaults/skills/computer-use/SKILL.md +3 -1
- package/src/defaults/skills/visualize/SKILL.md +3 -2
- package/src/lib/rules-builder.cjs +1 -1
- package/src/output-styles/common.md +22 -6
- package/src/output-styles/detailed.md +7 -5
- package/src/output-styles/minimal.md +7 -3
- package/src/output-styles/simple.md +2 -3
- package/src/rules/agent/AGENT.md +3 -1
- package/src/rules/lead/LEAD.md +4 -3
- package/src/rules/shared/10-tool-workflow.md +2 -1
- package/src/rules/shared/60-verification.md +4 -5
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -1
- package/src/runtime/agent/orchestrator/config.mjs +6 -0
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +1 -1
- package/src/runtime/agent/orchestrator/internal-agents.mjs +10 -0
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +53 -60
- package/src/runtime/agent/orchestrator/mcp/client.mjs +7 -4
- package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +2 -3
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +40 -19
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +3 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-start.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +1 -2
- package/src/runtime/agent/orchestrator/providers/catalog-deadline.mjs +163 -0
- package/src/runtime/agent/orchestrator/providers/catalog-failures.mjs +34 -0
- package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +38 -14
- package/src/runtime/agent/orchestrator/providers/lib/oauth-page.mjs +100 -26
- package/src/runtime/agent/orchestrator/providers/lib/send-callbacks.mjs +24 -0
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +13 -0
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +49 -4
- package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +0 -7
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +5 -1
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +11 -2
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +45 -16
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-connect.mjs +196 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +74 -9
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +14 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth-login.mjs +194 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth-tokens.mjs +353 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +293 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-usage.mjs +33 -100
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +23 -14
- package/src/runtime/agent/orchestrator/providers/registry.mjs +41 -27
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +2 -3
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +3 -8
- package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +15 -3
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +74 -13
- package/src/runtime/agent/orchestrator/session/compact/forked-summary.mjs +102 -0
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +8 -2
- package/src/runtime/agent/orchestrator/session/compact/summary.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/lifecycle-scan.mjs +9 -0
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +39 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +9 -19
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +2 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +13 -5
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +10 -7
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +62 -22
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +23 -1
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +81 -34
- package/src/runtime/agent/orchestrator/session/manager.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/request-fork.mjs +47 -0
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +16 -1
- package/src/runtime/agent/orchestrator/session/side-question.mjs +5 -43
- package/src/runtime/agent/orchestrator/session/store/fs-probe.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +73 -6
- package/src/runtime/agent/orchestrator/session/store/load-session.mjs +40 -0
- package/src/runtime/agent/orchestrator/session/store/save-fault.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/store/session-paths.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-header.mjs +36 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +258 -43
- package/src/runtime/agent/orchestrator/session/store-record-strict-scan.mjs +306 -0
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +70 -21
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +46 -30
- package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +144 -45
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +32 -13
- package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +364 -38
- package/src/runtime/agent/orchestrator/session/store.mjs +9 -2
- package/src/runtime/agent/orchestrator/session/task-wait-control.mjs +43 -12
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +23 -6
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +12 -6
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +13 -7
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/bashism-rewrite.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/benign-exit.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +40 -7
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/deadline-plan.mjs +37 -34
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/inline-hoist.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +0 -4
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +6 -0
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +29 -27
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/find-files-tool.mjs +28 -11
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-policy.mjs +12 -3
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +203 -101
- package/src/runtime/agent/orchestrator/tools/builtin/git-repo-rw-lock.mjs +90 -41
- package/src/runtime/agent/orchestrator/tools/builtin/lib/list-helpers.mjs +17 -1
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-delivery.mjs +199 -0
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-task-output.mjs +165 -39
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +25 -13
- package/src/runtime/agent/orchestrator/tools/builtin/read-batch.mjs +7 -6
- package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +19 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-line-collector.mjs +5 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-render.mjs +25 -7
- package/src/runtime/agent/orchestrator/tools/builtin/read-special-files.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-render.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/builtin/search-glob-tool.mjs +12 -5
- package/src/runtime/agent/orchestrator/tools/builtin/search-grep-tool.mjs +61 -22
- package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +32 -8
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +193 -19
- package/src/runtime/agent/orchestrator/tools/builtin/shell-direct-exe.mjs +57 -7
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +119 -32
- package/src/runtime/agent/orchestrator/tools/builtin/shell-lossless-compact.mjs +26 -1
- package/src/runtime/agent/orchestrator/tools/builtin/shell-output.mjs +13 -28
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +90 -11
- package/src/runtime/agent/orchestrator/tools/builtin/wait-budgets.mjs +23 -0
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +54 -10
- package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +22 -28
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +11 -7
- package/src/runtime/agent/orchestrator/tools/destructive-warning.mjs +126 -9
- package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +15 -6
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +40 -2
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promotion-results.mjs +13 -3
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +35 -4
- package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +7 -2
- package/src/runtime/agent/orchestrator/tools/shell-powershell.mjs +39 -23
- package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
- package/src/runtime/attachments/office-extract.mjs +11 -9
- package/src/runtime/memory/lib/embedding-tokenizer.mjs +32 -18
- package/src/runtime/memory/lib/runtime-fetcher.mjs +1 -1
- package/src/runtime/memory/lib/tool-call-handler.mjs +7 -5
- package/src/runtime/office/authoring/pptx-script-normalize.mjs +11 -8
- package/src/runtime/office/core/tabular.mjs +1 -1
- package/src/runtime/office/design/library/design-template-inspect.mjs +7 -4
- package/src/runtime/office/portable/docx-formatting.mjs +1 -1
- package/src/runtime/office/portable/docx-runs.mjs +1 -1
- package/src/runtime/office/portable/docx-tracked-edits.mjs +2 -2
- package/src/runtime/office/portable/portable-docx-edits.mjs +11 -10
- package/src/runtime/office/portable/portable-docx-operations.mjs +21 -17
- package/src/runtime/office/portable/portable-docx-parts.mjs +15 -9
- package/src/runtime/office/portable/portable-docx-styles.mjs +4 -1
- package/src/runtime/office/portable/portable-docx-xml.mjs +9 -9
- package/src/runtime/office/portable/portable-opc.mjs +27 -13
- package/src/runtime/office/portable/portable-pivot.mjs +3 -3
- package/src/runtime/office/portable/portable-pptx-chart.mjs +3 -3
- package/src/runtime/office/portable/portable-pptx-charts.mjs +24 -18
- package/src/runtime/office/portable/portable-pptx-core.mjs +5 -5
- package/src/runtime/office/portable/portable-pptx-deck.mjs +8 -4
- package/src/runtime/office/portable/portable-pptx-package.mjs +7 -4
- package/src/runtime/office/portable/portable-pptx-shapes.mjs +18 -9
- package/src/runtime/office/portable/portable-sheet-parts.mjs +9 -3
- package/src/runtime/office/portable/portable-sheet-xml.mjs +5 -5
- package/src/runtime/office/portable/portable-xlsx-charts.mjs +4 -1
- package/src/runtime/office/portable/portable-xlsx-drawings.mjs +10 -6
- package/src/runtime/office/portable/portable-xlsx-operations.mjs +8 -5
- package/src/runtime/office/portable/portable-xlsx-pivot-ops.mjs +1 -1
- package/src/runtime/office/portable/portable-xlsx-reference-shift.mjs +11 -7
- package/src/runtime/office/portable/portable-xlsx-sheet-edits.mjs +6 -3
- package/src/runtime/office/portable/portable-xml.mjs +1 -1
- package/src/runtime/shared/atomic-file.mjs +22 -13
- package/src/runtime/shared/background-tasks.mjs +60 -20
- package/src/runtime/shared/child-spawn-gate.mjs +26 -16
- package/src/runtime/shared/config.mjs +0 -10
- package/src/runtime/shared/file-lock.mjs +7 -1
- package/src/runtime/shared/file-permissions-worker.mjs +38 -0
- package/src/runtime/shared/file-permissions.d.mts +19 -4
- package/src/runtime/shared/file-permissions.mjs +310 -4
- package/src/runtime/shared/git-runner-worker.mjs +6 -78
- package/src/runtime/shared/llm/http-agent.mjs +7 -3
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +10 -0
- package/src/runtime/shared/llm/usage-accounting.mjs +2 -0
- package/src/runtime/shared/llm/usage-ledger-import.mjs +32 -3
- package/src/runtime/shared/llm/usage-ledger-rollup.mjs +12 -5
- package/src/runtime/shared/llm/usage-ledger-worker.mjs +1 -1
- package/src/runtime/shared/llm/usage-ledger.mjs +20 -5
- package/src/runtime/shared/memory-snapshot.mjs +5 -1
- package/src/runtime/shared/notify-trace.mjs +8 -1
- package/src/runtime/shared/pristine-execution-contract.json +5 -1
- package/src/runtime/shared/process-runner-worker.mjs +7 -0
- package/src/runtime/shared/process-runner.mjs +38 -0
- package/src/runtime/shared/provider-accounts.mjs +2 -1
- package/src/runtime/shared/provider-api-key.mjs +0 -1
- package/src/runtime/shared/read-row-numbers.mjs +1 -1
- package/src/runtime/shared/resource-admission.mjs +60 -18
- package/src/runtime/shared/run-child.mjs +84 -0
- package/src/runtime/shared/session-activity-signal.mjs +23 -0
- package/src/runtime/shared/shell-output-summary.mjs +23 -0
- package/src/runtime/shared/singleton-owner.mjs +126 -42
- package/src/runtime/shared/tool-output-limit.mjs +4 -2
- package/src/runtime/shared/tool-output-marker.mjs +58 -0
- package/src/runtime/shared/user-data-guard.mjs +28 -9
- package/src/runtime/shared/worktrees/activity-gate.mjs +33 -8
- package/src/runtime/shared/worktrees/git-head.mjs +20 -2
- package/src/runtime/shared/worktrees/lock.mjs +3 -2
- package/src/runtime/terminal-bridge/tool-defs.mjs +1 -1
- package/src/runtime/tidy/runners/biome.mjs +3 -1
- package/src/runtime/tidy/shadow.mjs +2 -1
- package/src/runtime/web-search/index.mjs +5 -7
- package/src/runtime/web-search/lib/formatter.mjs +42 -6
- package/src/runtime/web-search/tool-defs.mjs +6 -1
- package/src/session-runtime/lifecycle/session-switch/context-switch.mjs +4 -3
- package/src/session-runtime/lifecycle/session-switch/resume.mjs +7 -4
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +3 -3
- package/src/session-runtime/lifecycle/shared.mjs +19 -2
- package/src/session-runtime/lifecycle/teardown/session-close.mjs +2 -0
- package/src/session-runtime/lifecycle/teardown.mjs +5 -2
- package/src/session-runtime/lifecycle-api.mjs +3 -1
- package/src/session-runtime/provider-auth/login.mjs +10 -6
- package/src/session-runtime/provider-auth/setup.mjs +19 -2
- package/src/session-runtime/provider-catalog-cache.mjs +101 -25
- package/src/session-runtime/provider-models/catalog-load.mjs +14 -3
- package/src/session-runtime/provider-models/row-hydration.mjs +4 -0
- package/src/session-runtime/provider-models.mjs +76 -10
- package/src/session-runtime/provider-readiness.mjs +4 -0
- package/src/session-runtime/services/agent-tool/close-flow.mjs +2 -1
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +10 -2
- package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +13 -4
- package/src/session-runtime/services/agent-tool/notify.mjs +15 -4
- package/src/session-runtime/services/agent-tool/restart-notify.mjs +134 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +24 -1
- package/src/session-runtime/services/agent-tool/spawn-flow/deferred-spawn.mjs +2 -1
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +4 -3
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +5 -1
- package/src/session-runtime/services/agent-tool/tag-registry/tag-lookup.mjs +8 -3
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +3 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +4 -0
- package/src/session-runtime/services/agent-tool/worker-index.mjs +44 -10
- package/src/session-runtime/services/agent-tool.mjs +20 -0
- package/src/session-runtime/services/provider-admin.mjs +92 -20
- package/src/session-runtime/services/usage-dashboard-model.mjs +2 -2
- package/src/session-runtime/services/usage-dashboard.mjs +27 -69
- package/src/session-runtime/turn/session-ops.mjs +2 -2
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
- package/src/session-runtime/usage-stats-api.mjs +6 -1
- package/src/standalone/channel-transport/http-routes.mjs +10 -9
- package/src/standalone/daemon-desktop-runtime.mjs +20 -7
- package/src/standalone/daemon-owner.mjs +117 -25
- package/src/standalone/daemon.mjs +43 -13
- package/src/standalone/session-call-cache.mjs +6 -0
- package/src/standalone/session-protocol.mjs +1 -1
- package/src/standalone/session-service/retention/busy.mjs +7 -2
- package/src/standalone/session-transport/routes.mjs +7 -6
- package/src/tui/app/model-options.mjs +39 -2
- package/src/tui/app/model-picker.mjs +16 -2
- package/src/tui/app/provider-setup-picker.mjs +1 -2
- package/src/tui/dist/index.mjs +385 -104
- package/src/tui/session/notice-text.mjs +0 -1
- package/src/tui/session/session-api/intake/submission.mjs +7 -13
- package/src/tui/session/session-api/integrations.mjs +1 -5
- package/src/tui/session/session-flow/drain.mjs +8 -0
- package/src/tui/session/session-flow/steering.mjs +46 -0
- package/src/tui/session/session-flow.mjs +2 -0
- package/src/tui/session/turn-stream.mjs +33 -0
- package/src/tui/session/turn.mjs +30 -3
- package/src/ui/statusline.mjs +1 -6
- package/src/ui/streaming-markdown-heal.mjs +24 -7
- package/src/vendor/statusline/bin/statusline-route.mjs +0 -1
- package/src/vendor/statusline/src/gateway/route-meta.mjs +0 -1
- package/src/workflows/default/WORKFLOW.md +9 -13
|
@@ -180,7 +180,7 @@ async function appendComment(zip, comments, op, text, thread = {}) {
|
|
|
180
180
|
const stamps = commentStamps();
|
|
181
181
|
zip.file(
|
|
182
182
|
comments.part,
|
|
183
|
-
comments.xml.replace('</w:comments>', `${commentEntryXml(id, op, text, stamps.local)}</w:comments>`)
|
|
183
|
+
comments.xml.replace('</w:comments>', () => `${commentEntryXml(id, op, text, stamps.local)}</w:comments>`)
|
|
184
184
|
);
|
|
185
185
|
await registerCommentThread(zip, { commentId: id, ...thread });
|
|
186
186
|
await registerCommentIdentity(zip, { commentId: id, date: stamps.utc });
|
|
@@ -363,7 +363,7 @@ export async function setDocxParagraphStyle(zip, op) {
|
|
|
363
363
|
let nextParagraph = paragraph.xml;
|
|
364
364
|
if (/<w:pPr(?:\s[^>]*)?>/.test(nextParagraph)) {
|
|
365
365
|
if (/<w:pStyle\b[^>]*\/>/.test(nextParagraph)) {
|
|
366
|
-
nextParagraph = nextParagraph.replace(/<w:pStyle\b[^>]*\/>/, `<w:pStyle w:val="${style}"/>`);
|
|
366
|
+
nextParagraph = nextParagraph.replace(/<w:pStyle\b[^>]*\/>/, () => `<w:pStyle w:val="${style}"/>`);
|
|
367
367
|
} else {
|
|
368
368
|
nextParagraph = nextParagraph.replace(/<w:pPr(?:\s[^>]*)?>/, (open) => `${open}<w:pStyle w:val="${style}"/>`);
|
|
369
369
|
}
|
|
@@ -412,17 +412,18 @@ export async function setDocxTableCell(zip, op, { tracking }) {
|
|
|
412
412
|
if (first) {
|
|
413
413
|
nextCell = cell[0].replace(
|
|
414
414
|
'</w:tc>',
|
|
415
|
-
|
|
415
|
+
() =>
|
|
416
|
+
`<w:p><w:ins ${revisionAttributes(id, op.author)}><w:r>` +
|
|
416
417
|
`${wordTextContent(op.text, { preserve: true })}</w:r></w:ins></w:p></w:tc>`
|
|
417
418
|
);
|
|
418
419
|
}
|
|
419
420
|
} else if (textNodes(cell[0], 'w:t').length) {
|
|
420
421
|
nextCell = withFirstRunText(cell[0], op.text);
|
|
421
422
|
} else {
|
|
422
|
-
nextCell = cell[0].replace('</w:tc>', `<w:p><w:r>${wordTextContent(op.text)}</w:r></w:p></w:tc>`);
|
|
423
|
+
nextCell = cell[0].replace('</w:tc>', () => `<w:p><w:r>${wordTextContent(op.text)}</w:r></w:p></w:tc>`);
|
|
423
424
|
}
|
|
424
|
-
const nextRow = row[0].replace(cell[0], nextCell);
|
|
425
|
-
const nextTable = table[0].replace(row[0], nextRow);
|
|
425
|
+
const nextRow = row[0].replace(cell[0], () => nextCell);
|
|
426
|
+
const nextTable = table[0].replace(row[0], () => nextRow);
|
|
426
427
|
zip.file(
|
|
427
428
|
DOCUMENT_PART,
|
|
428
429
|
`${current.slice(0, table.index)}${nextTable}${current.slice(table.index + table[0].length)}`
|
|
@@ -548,7 +549,7 @@ export async function editDocxTableRowsOrColumns(zip, op) {
|
|
|
548
549
|
const blank = blankTableCells(template[0]);
|
|
549
550
|
nextTable =
|
|
550
551
|
position > rows.length
|
|
551
|
-
? table[0].replace(/<\/w:tbl>$/, `${blank}</w:tbl>`)
|
|
552
|
+
? table[0].replace(/<\/w:tbl>$/, () => `${blank}</w:tbl>`)
|
|
552
553
|
: `${table[0].slice(0, template.index)}${blank}${table[0].slice(template.index)}`;
|
|
553
554
|
}
|
|
554
555
|
} else {
|
|
@@ -633,7 +634,7 @@ export async function addDocxHyperlink(zip, op) {
|
|
|
633
634
|
} else if (op.paragraph) {
|
|
634
635
|
const model = docxBodyModel(current);
|
|
635
636
|
const paragraph = bodyParagraphAt(model, op.paragraph);
|
|
636
|
-
const nextParagraph = paragraph.xml.replace(/<\/w:p>$/, `${link}</w:p>`);
|
|
637
|
+
const nextParagraph = paragraph.xml.replace(/<\/w:p>$/, () => `${link}</w:p>`);
|
|
637
638
|
current = replaceBodyParagraph(current, model, paragraph, nextParagraph);
|
|
638
639
|
anchor = 'paragraph';
|
|
639
640
|
} else {
|
|
@@ -788,7 +789,7 @@ export async function addDocxBookmark(zip, op) {
|
|
|
788
789
|
const opening = /^<w:p(?:\s[^>]*)?>(?:<w:pPr(?:\s[^>]*)?>[\s\S]*?<\/w:pPr>)?/.exec(paragraph.xml)?.[0] || '<w:p>';
|
|
789
790
|
const marked =
|
|
790
791
|
`${opening}<w:bookmarkStart w:id="${id}" w:name="${xmlEncode(name)}"/>` +
|
|
791
|
-
`${paragraph.xml.slice(opening.length)}`.replace(/<\/w:p>$/, `<w:bookmarkEnd w:id="${id}"/></w:p>`);
|
|
792
|
+
`${paragraph.xml.slice(opening.length)}`.replace(/<\/w:p>$/, () => `<w:bookmarkEnd w:id="${id}"/></w:p>`);
|
|
792
793
|
zip.file(DOCUMENT_PART, replaceBodyParagraph(current, model, paragraph, marked));
|
|
793
794
|
return { op: op.op, changed: true, name, bookmark: id };
|
|
794
795
|
}
|
|
@@ -837,7 +838,7 @@ export async function setDocxHeaderFooter(zip, op) {
|
|
|
837
838
|
|
|
838
839
|
// A separator says the number stands against the total ("3 / 12"): asked for with separator:' / ' and no
|
|
839
840
|
// includeTotal, the footer printed "3" alone. includeTotal:false still keeps the number alone.
|
|
840
|
-
|
|
841
|
+
function pageNumbersIncludeTotal(op) {
|
|
841
842
|
return op.includeTotal === true || (op.includeTotal !== false && Boolean(String(op.separator ?? '').trim()));
|
|
842
843
|
}
|
|
843
844
|
|
|
@@ -82,15 +82,15 @@ const PARAGRAPH_MARK_ID_OFFSET = 900;
|
|
|
82
82
|
// place ahead of the deletion that rejects it.
|
|
83
83
|
function withParagraphMarkRevision(paragraphXml, mark) {
|
|
84
84
|
if (!/<w:pPr(?:\s[^>]*)?>/.test(paragraphXml)) {
|
|
85
|
-
return paragraphXml.replace(/^(<w:p(?:\s[^>]*)?>)/, `$
|
|
85
|
+
return paragraphXml.replace(/^(<w:p(?:\s[^>]*)?>)/, (__m, __1) => `${__1}<w:pPr><w:rPr>${mark}</w:rPr></w:pPr>`);
|
|
86
86
|
}
|
|
87
87
|
if (/<w:rPr(?:\s[^>]*)?>[\s\S]*?<\/w:rPr>\s*<\/w:pPr>/.test(paragraphXml)) {
|
|
88
88
|
return paragraphXml.replace(
|
|
89
89
|
/(<w:rPr(?:\s[^>]*)?>)((?:<w:ins\b[^>]*\/>|<w:ins\b[^>]*>[\s\S]*?<\/w:ins>)?)/,
|
|
90
|
-
`$
|
|
90
|
+
(__m, __1, __2) => `${__1}${__2}${mark}`
|
|
91
91
|
);
|
|
92
92
|
}
|
|
93
|
-
return paragraphXml.replace(/<\/w:pPr>/, `<w:rPr>${mark}</w:rPr></w:pPr>`);
|
|
93
|
+
return paragraphXml.replace(/<\/w:pPr>/, () => `<w:rPr>${mark}</w:rPr></w:pPr>`);
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
export function docxTocEntries(documentXml, lower, upper, headingLevels = new Map()) {
|
|
@@ -328,7 +328,10 @@ export async function addDocxNote(zip, op) {
|
|
|
328
328
|
`<w:r><w:rPr><w:rStyle w:val="${definition.style}"/>${faces}<w:vertAlign w:val="superscript"/></w:rPr>` +
|
|
329
329
|
`<w:${definition.reference === 'w:footnoteReference' ? 'footnoteRef' : 'endnoteRef'}/></w:r>` +
|
|
330
330
|
`<w:r>${noteRun}<w:t xml:space="preserve"> ${xmlEncode(text)}</w:t></w:r></w:p></${definition.tag}>`;
|
|
331
|
-
zip.file(
|
|
331
|
+
zip.file(
|
|
332
|
+
definition.part,
|
|
333
|
+
definition.xml.replace(`</${definition.root}>`, () => `${entry}</${definition.root}>`)
|
|
334
|
+
);
|
|
332
335
|
// The mark belongs right after the phrase it cites; a phrase split across
|
|
333
336
|
// a tab, field, or drawing falls back to the end of its paragraph.
|
|
334
337
|
const mark =
|
|
@@ -336,7 +339,7 @@ export async function addDocxNote(zip, op) {
|
|
|
336
339
|
`<${definition.reference} w:id="${id}"/></w:r>`;
|
|
337
340
|
const cited = find ? wholeWordPhrase(paragraphTexts(paragraph.xml, 'w:t').join(''), find) : '';
|
|
338
341
|
const phrase = cited ? anchorPhraseInParagraph(paragraph.xml, cited, id, { start: '', end: mark }) : null;
|
|
339
|
-
const anchored = phrase || paragraph.xml.replace(/<\/w:p>$/, `${mark}</w:p>`);
|
|
342
|
+
const anchored = phrase || paragraph.xml.replace(/<\/w:p>$/, () => `${mark}</w:p>`);
|
|
340
343
|
const nextInner = `${model.body.inner.slice(0, paragraph.start)}${anchored}${model.body.inner.slice(paragraph.end)}`;
|
|
341
344
|
current = `${current.slice(0, model.body.start)}${nextInner}${current.slice(model.body.end)}`;
|
|
342
345
|
zip.file('word/document.xml', current);
|
|
@@ -388,7 +391,7 @@ export async function setDocxDocumentFont(zip, op) {
|
|
|
388
391
|
}
|
|
389
392
|
|
|
390
393
|
// The fields one style takes in define_styles: its face, size, weight, ink, and its paragraph's flow.
|
|
391
|
-
|
|
394
|
+
const DOCX_STYLE_FIELDS = Object.freeze([
|
|
392
395
|
'name',
|
|
393
396
|
'nameEastAsia',
|
|
394
397
|
'size',
|
|
@@ -608,7 +611,7 @@ export async function fitDocxTable(zip, op) {
|
|
|
608
611
|
let nextTable = grid
|
|
609
612
|
? table[0].replace(
|
|
610
613
|
grid[0],
|
|
611
|
-
`<w:tblGrid>${widths.map((width) => `<w:gridCol w:w="${width}"/>`).join('')}</w:tblGrid>`
|
|
614
|
+
() => `<w:tblGrid>${widths.map((width) => `<w:gridCol w:w="${width}"/>`).join('')}</w:tblGrid>`
|
|
612
615
|
)
|
|
613
616
|
: table[0];
|
|
614
617
|
const declared = `<w:tblW w:w="${usable}" w:type="dxa"/>`;
|
|
@@ -616,9 +619,9 @@ export async function fitDocxTable(zip, op) {
|
|
|
616
619
|
? wordTableProperties(op.properties)
|
|
617
620
|
: /<w:tblPr>([\s\S]*?)<\/w:tblPr>/.exec(nextTable)?.[1] || '';
|
|
618
621
|
if (/<w:tblW\b[^>]*\/>/.test(tableProperties)) {
|
|
619
|
-
tableProperties = tableProperties.replace(/<w:tblW\b[^>]*\/>/, declared);
|
|
622
|
+
tableProperties = tableProperties.replace(/<w:tblW\b[^>]*\/>/, () => declared);
|
|
620
623
|
} else if (/<w:tblStyle\b[^>]*\/>/.test(tableProperties)) {
|
|
621
|
-
tableProperties = tableProperties.replace(/(<w:tblStyle\b[^>]*\/>)/, `$
|
|
624
|
+
tableProperties = tableProperties.replace(/(<w:tblStyle\b[^>]*\/>)/, (__m, __1) => `${__1}${declared}`);
|
|
622
625
|
} else {
|
|
623
626
|
tableProperties = `${declared}${tableProperties}`;
|
|
624
627
|
}
|
|
@@ -640,7 +643,10 @@ function controlFilledWith(control, contentInner, text) {
|
|
|
640
643
|
? `${/^<w:p(?:\s[^>]*)?>(?:<w:pPr(?:\s[^>]*)?>[\s\S]*?<\/w:pPr>)?/.exec(firstParagraph)?.[0] || '<w:p>'}${run}</w:p>`
|
|
641
644
|
: run;
|
|
642
645
|
const cleaned = control.replace(/<w:showingPlcHdr\b[^>]*\/>/g, '');
|
|
643
|
-
return cleaned.replace(
|
|
646
|
+
return cleaned.replace(
|
|
647
|
+
/<w:sdtContent\b[^>]*>[\s\S]*?<\/w:sdtContent>/,
|
|
648
|
+
() => `<w:sdtContent>${paragraph}</w:sdtContent>`
|
|
649
|
+
);
|
|
644
650
|
}
|
|
645
651
|
|
|
646
652
|
/** Fills one named or numbered content control, in the body, a header, or a footer. */
|
|
@@ -712,8 +718,8 @@ function paragraphWithText(paragraph, op) {
|
|
|
712
718
|
if (!nodes.length) {
|
|
713
719
|
if (op.op === 'set_run_text') throw new Error(`DOCX paragraph ${op.paragraph} has no editable text`);
|
|
714
720
|
const run = `<w:r>${wordTextContent(op.text, { preserve: true })}</w:r>`;
|
|
715
|
-
if (/<\/w:p>\s*$/.test(paragraph.xml)) return paragraph.xml.replace(/<\/w:p>\s*$/, `${run}</w:p>`);
|
|
716
|
-
if (/\/>\s*$/.test(paragraph.xml)) return paragraph.xml.replace(/\/>\s*$/, `>${run}</w:p>`);
|
|
721
|
+
if (/<\/w:p>\s*$/.test(paragraph.xml)) return paragraph.xml.replace(/<\/w:p>\s*$/, () => `${run}</w:p>`);
|
|
722
|
+
if (/\/>\s*$/.test(paragraph.xml)) return paragraph.xml.replace(/\/>\s*$/, () => `>${run}</w:p>`);
|
|
717
723
|
throw new Error(`DOCX paragraph ${op.paragraph} is malformed`);
|
|
718
724
|
}
|
|
719
725
|
if (op.op === 'set_run_text') {
|
|
@@ -852,8 +858,7 @@ function mergedDocxTable({ table, rows, row, cells }, op) {
|
|
|
852
858
|
);
|
|
853
859
|
return `${rowXml.slice(0, joined[0].index)}${merged}${rowXml.slice(end)}`;
|
|
854
860
|
};
|
|
855
|
-
let nextTable = table[0].replace(
|
|
856
|
-
row[0],
|
|
861
|
+
let nextTable = table[0].replace(row[0], () =>
|
|
857
862
|
mergeRow(row[0], cells, `${gridSpan}${rowSpan > 1 ? '<w:vMerge w:val="restart"/>' : ''}`)
|
|
858
863
|
);
|
|
859
864
|
if (rowSpan > 1) {
|
|
@@ -862,8 +867,7 @@ function mergedDocxTable({ table, rows, row, cells }, op) {
|
|
|
862
867
|
if (!continuationRow) break;
|
|
863
868
|
const continuationCells = rowCellMatches(continuationRow[0]);
|
|
864
869
|
if (!continuationCells[first]) continue;
|
|
865
|
-
nextTable = nextTable.replace(
|
|
866
|
-
continuationRow[0],
|
|
870
|
+
nextTable = nextTable.replace(continuationRow[0], () =>
|
|
867
871
|
mergeRow(continuationRow[0], continuationCells, `${gridSpan}<w:vMerge/>`)
|
|
868
872
|
);
|
|
869
873
|
}
|
|
@@ -883,7 +887,7 @@ export async function styleOrMergeDocxTableCell(zip, op) {
|
|
|
883
887
|
if (!cell) throw missingDocxCellError(op, cells);
|
|
884
888
|
const nextTable =
|
|
885
889
|
op.op === 'set_table_cell_style'
|
|
886
|
-
? table[0].replace(cell[0], styledDocxCell(cell[0], op))
|
|
890
|
+
? table[0].replace(cell[0], () => styledDocxCell(cell[0], op))
|
|
887
891
|
: mergedDocxTable({ table, rows, row, cells }, op);
|
|
888
892
|
current = replaceDocxTable(current, table, nextTable);
|
|
889
893
|
zip.file('word/document.xml', current);
|
|
@@ -121,7 +121,7 @@ const sectionChildRank = (tag) => SECTION_CHILD_ORDER.indexOf(tag === 'footerRef
|
|
|
121
121
|
/** Replaces the section's own tag element, or writes it ahead of the first child the schema places after it. */
|
|
122
122
|
export function upsertSectionChild(sectionXml, tag, element) {
|
|
123
123
|
const pattern = new RegExp(`<w:${tag}\\b[^>]*\\/>`);
|
|
124
|
-
if (pattern.test(sectionXml)) return sectionXml.replace(pattern, element);
|
|
124
|
+
if (pattern.test(sectionXml)) return sectionXml.replace(pattern, () => element);
|
|
125
125
|
const rank = sectionChildRank(tag);
|
|
126
126
|
const children = /<w:(\w+)\b/g;
|
|
127
127
|
children.lastIndex = sectionXml.indexOf('>') + 1;
|
|
@@ -257,7 +257,11 @@ async function ensureNoteStyles(zip, definition) {
|
|
|
257
257
|
: `<w:style w:type="character" w:styleId="${definition.style}"><w:name w:val="${markName}"/><w:uiPriority w:val="99"/><w:unhideWhenUsed/>` +
|
|
258
258
|
'<w:rPr><w:vertAlign w:val="superscript"/></w:rPr></w:style>',
|
|
259
259
|
].join('');
|
|
260
|
-
if (additions)
|
|
260
|
+
if (additions)
|
|
261
|
+
zip.file(
|
|
262
|
+
part,
|
|
263
|
+
styles.replace('</w:styles>', () => `${additions}</w:styles>`)
|
|
264
|
+
);
|
|
261
265
|
}
|
|
262
266
|
|
|
263
267
|
// Word reads the separator notes (ids -1 and 0) before any real note: without
|
|
@@ -313,8 +317,8 @@ export async function registerCommentThread(zip, { commentId, parentId = 0, done
|
|
|
313
317
|
`${parentId ? ` w15:paraIdParent="${commentParagraphId(parentId)}"` : ''}` +
|
|
314
318
|
` w15:done="${done ? 1 : 0}"/>`;
|
|
315
319
|
const next = pattern.test(extended.xml)
|
|
316
|
-
? extended.xml.replace(pattern, entry)
|
|
317
|
-
: extended.xml.replace('</w15:commentsEx>', `${entry}</w15:commentsEx>`);
|
|
320
|
+
? extended.xml.replace(pattern, () => entry)
|
|
321
|
+
: extended.xml.replace('</w15:commentsEx>', () => `${entry}</w15:commentsEx>`);
|
|
318
322
|
zip.file(extended.part, next);
|
|
319
323
|
return paraId;
|
|
320
324
|
}
|
|
@@ -381,7 +385,8 @@ export async function registerCommentIdentity(zip, { commentId, date }) {
|
|
|
381
385
|
ids.part,
|
|
382
386
|
ids.xml.replace(
|
|
383
387
|
`</${COMMENT_SIDECARS.ids.root}>`,
|
|
384
|
-
|
|
388
|
+
() =>
|
|
389
|
+
`<w16cid:commentId w16cid:paraId="${paraId}" w16cid:durableId="${durableId}"/></${COMMENT_SIDECARS.ids.root}>`
|
|
385
390
|
)
|
|
386
391
|
);
|
|
387
392
|
}
|
|
@@ -391,7 +396,8 @@ export async function registerCommentIdentity(zip, { commentId, date }) {
|
|
|
391
396
|
extensible.part,
|
|
392
397
|
extensible.xml.replace(
|
|
393
398
|
`</${COMMENT_SIDECARS.extensible.root}>`,
|
|
394
|
-
|
|
399
|
+
() =>
|
|
400
|
+
`<w16cex:commentExtensible w16cex:durableId="${durableId}" w16cex:dateUtc="${xmlEncode(date)}"/></${COMMENT_SIDECARS.extensible.root}>`
|
|
395
401
|
)
|
|
396
402
|
);
|
|
397
403
|
}
|
|
@@ -435,7 +441,7 @@ export function anchorDocxComment(paragraphXml, id) {
|
|
|
435
441
|
const body = paragraphXml.slice(opening.length);
|
|
436
442
|
return `${opening}<w:commentRangeStart w:id="${id}"/>${body}`.replace(
|
|
437
443
|
/<\/w:p>$/,
|
|
438
|
-
`<w:commentRangeEnd w:id="${id}"/><w:r><w:commentReference w:id="${id}"/></w:r></w:p>`
|
|
444
|
+
() => `<w:commentRangeEnd w:id="${id}"/><w:r><w:commentReference w:id="${id}"/></w:r></w:p>`
|
|
439
445
|
);
|
|
440
446
|
}
|
|
441
447
|
|
|
@@ -511,7 +517,7 @@ export async function ensureDocxUpdateFields(zip) {
|
|
|
511
517
|
export function upsertSectionReference(sectionXml, tag, kind, relationshipId) {
|
|
512
518
|
const element = `<w:${tag} w:type="${kind}" r:id="${relationshipId}"/>`;
|
|
513
519
|
const pattern = new RegExp(`<w:${tag}\\b[^>]*\\bw:type="${kind}"[^>]*\\/>`);
|
|
514
|
-
if (pattern.test(sectionXml)) return sectionXml.replace(pattern, element);
|
|
520
|
+
if (pattern.test(sectionXml)) return sectionXml.replace(pattern, () => element);
|
|
515
521
|
const position = sectionXml.indexOf('>') + 1;
|
|
516
522
|
return `${sectionXml.slice(0, position)}${element}${sectionXml.slice(position)}`;
|
|
517
523
|
}
|
|
@@ -704,7 +710,7 @@ export async function ensureNumbering(zip, kind, { restart = false } = {}) {
|
|
|
704
710
|
: xml.indexOf('>', xml.indexOf('<w:numbering')) + 1;
|
|
705
711
|
next = `${xml.slice(0, position)}${numberingDefinition(abstractId, kind)}${xml.slice(position)}`;
|
|
706
712
|
}
|
|
707
|
-
next = next.replace('</w:numbering>', `${definition}</w:numbering>`);
|
|
713
|
+
next = next.replace('</w:numbering>', () => `${definition}</w:numbering>`);
|
|
708
714
|
zip.file(part, next);
|
|
709
715
|
return { xml: next, numId, created: true };
|
|
710
716
|
}
|
|
@@ -62,6 +62,9 @@ export async function documentStyleId(zip, requested, type = 'paragraph') {
|
|
|
62
62
|
return local ? `${open}${local.id}${close}` : whole;
|
|
63
63
|
}
|
|
64
64
|
);
|
|
65
|
-
zip.file(
|
|
65
|
+
zip.file(
|
|
66
|
+
STYLES_PART,
|
|
67
|
+
styles.replace('</w:styles>', () => `${definition}</w:styles>`)
|
|
68
|
+
);
|
|
66
69
|
return { id: borrowed.id, found: true };
|
|
67
70
|
}
|
|
@@ -188,8 +188,8 @@ export function justifyWordParagraphs(cellXml, justification) {
|
|
|
188
188
|
return cellXml.replace(/<w:p(?:\s[^>]*)?>[\s\S]*?<\/w:p>/g, (paragraph) => {
|
|
189
189
|
const stripped = paragraph.replace(/<w:jc\b[^>]*\/>/g, '');
|
|
190
190
|
return /<w:pPr(?:\s[^>]*)?>/.test(stripped)
|
|
191
|
-
? stripped.replace(/<\/w:pPr>/, `<w:jc w:val="${justification}"/></w:pPr>`)
|
|
192
|
-
: stripped.replace(/^(<w:p(?:\s[^>]*)?>)/, `$
|
|
191
|
+
? stripped.replace(/<\/w:pPr>/, () => `<w:jc w:val="${justification}"/></w:pPr>`)
|
|
192
|
+
: stripped.replace(/^(<w:p(?:\s[^>]*)?>)/, (__m, __1) => `${__1}<w:pPr><w:jc w:val="${justification}"/></w:pPr>`);
|
|
193
193
|
});
|
|
194
194
|
}
|
|
195
195
|
|
|
@@ -202,9 +202,9 @@ export function alignWordTableColumns(tableXml, columnAlignments = []) {
|
|
|
202
202
|
let nextRow = row[0];
|
|
203
203
|
rowCellMatches(row[0]).forEach((cell, column) => {
|
|
204
204
|
if (!justifications[column]) return;
|
|
205
|
-
nextRow = nextRow.replace(cell[0], justifyWordParagraphs(cell[0], justifications[column]));
|
|
205
|
+
nextRow = nextRow.replace(cell[0], () => justifyWordParagraphs(cell[0], justifications[column]));
|
|
206
206
|
});
|
|
207
|
-
next = next.replace(row[0], nextRow);
|
|
207
|
+
next = next.replace(row[0], () => nextRow);
|
|
208
208
|
}
|
|
209
209
|
return next;
|
|
210
210
|
}
|
|
@@ -302,7 +302,7 @@ function tableRowStyle(properties, row) {
|
|
|
302
302
|
// The last row is the total when totalRow is set: bold over a rule, so it reads as the sum of the rows above it and
|
|
303
303
|
// not as one more of them.
|
|
304
304
|
const isTotalRow = (properties, row, rows) => properties?.totalRow === true && rows > 1 && row === rows - 1;
|
|
305
|
-
|
|
305
|
+
const TOTAL_ROW_RULE = Object.freeze({ size: 8, color: '374151' });
|
|
306
306
|
|
|
307
307
|
// A row's weight: its own rowStyles bold when given, else the header's or the total's.
|
|
308
308
|
function rowBold(properties, row, rows, header) {
|
|
@@ -520,9 +520,9 @@ export function applyWordRunFormat(xml, runFormat) {
|
|
|
520
520
|
const opened = /<w:rPr(?:\s[^>]*)?>([\s\S]*?)<\/w:rPr>/.exec(run);
|
|
521
521
|
if (opened) {
|
|
522
522
|
const merged = mergeWordPropertyElements(opened[1], runFormat, RUN_PROPERTY_ORDER);
|
|
523
|
-
return run.replace(opened[0], `<w:rPr>${merged}</w:rPr>`);
|
|
523
|
+
return run.replace(opened[0], () => `<w:rPr>${merged}</w:rPr>`);
|
|
524
524
|
}
|
|
525
|
-
if (selfClosed) return run.replace(selfClosed[0], `<w:rPr>${runFormat}</w:rPr>`);
|
|
525
|
+
if (selfClosed) return run.replace(selfClosed[0], () => `<w:rPr>${runFormat}</w:rPr>`);
|
|
526
526
|
return run.replace(/<w:r(?:\s[^>]*)?>/, (open) => `${open}<w:rPr>${runFormat}</w:rPr>`);
|
|
527
527
|
});
|
|
528
528
|
}
|
|
@@ -598,7 +598,7 @@ export function rewriteTableColumns(tableXml, columnIndex, mode) {
|
|
|
598
598
|
} else {
|
|
599
599
|
columns.splice(columnIndex - 1, 0, columns[columnIndex - 1] || columns.at(-1) || '<w:gridCol/>');
|
|
600
600
|
}
|
|
601
|
-
next = next.replace(grid[0], `<w:tblGrid>${columns.join('')}</w:tblGrid>`);
|
|
601
|
+
next = next.replace(grid[0], () => `<w:tblGrid>${columns.join('')}</w:tblGrid>`);
|
|
602
602
|
}
|
|
603
603
|
return mapTableRows(next, (row) => {
|
|
604
604
|
const cells = tableRowCells(row);
|
|
@@ -749,7 +749,7 @@ export function replaceDocxTable(current, table, nextTable) {
|
|
|
749
749
|
|
|
750
750
|
export function replaceWordProperties(xml, owner, propertyTag, value) {
|
|
751
751
|
const pattern = new RegExp(`<w:${propertyTag}(?:\\s[^>]*)?>[\\s\\S]*?<\\/w:${propertyTag}>`);
|
|
752
|
-
if (pattern.test(xml)) return xml.replace(pattern, `<w:${propertyTag}>${value}</w:${propertyTag}>`);
|
|
752
|
+
if (pattern.test(xml)) return xml.replace(pattern, () => `<w:${propertyTag}>${value}</w:${propertyTag}>`);
|
|
753
753
|
return xml.replace(
|
|
754
754
|
new RegExp(`<w:${owner}(?:\\s[^>]*)?>`),
|
|
755
755
|
(open) => `${open}<w:${propertyTag}>${value}</w:${propertyTag}>`
|
|
@@ -206,7 +206,10 @@ export async function ensureContentTypeOverride(zip, part, type) {
|
|
|
206
206
|
const path = '[Content_Types].xml';
|
|
207
207
|
const xml = await zipText(zip, path);
|
|
208
208
|
if (xml.includes(`PartName="${part}"`)) return;
|
|
209
|
-
zip.file(
|
|
209
|
+
zip.file(
|
|
210
|
+
path,
|
|
211
|
+
xml.replace('</Types>', () => `<Override PartName="${part}" ContentType="${type}"/></Types>`)
|
|
212
|
+
);
|
|
210
213
|
}
|
|
211
214
|
|
|
212
215
|
export async function removeContentTypeOverride(zip, part) {
|
|
@@ -219,7 +222,10 @@ export async function ensureDefaultContentType(zip, extension, type) {
|
|
|
219
222
|
const path = '[Content_Types].xml';
|
|
220
223
|
const xml = await zipText(zip, path);
|
|
221
224
|
if (new RegExp(`<Default\\b[^>]*\\bExtension="${extension}"`, 'i').test(xml)) return;
|
|
222
|
-
zip.file(
|
|
225
|
+
zip.file(
|
|
226
|
+
path,
|
|
227
|
+
xml.replace(/<Types\b[^>]*>/, (__m) => `${__m}<Default Extension="${extension}" ContentType="${type}"/>`)
|
|
228
|
+
);
|
|
223
229
|
}
|
|
224
230
|
|
|
225
231
|
export async function addPackageRelationship(zip, relsPath, type, target, mode = '') {
|
|
@@ -237,7 +243,10 @@ export async function addPackageRelationship(zip, relsPath, type, target, mode =
|
|
|
237
243
|
const relationship =
|
|
238
244
|
`<Relationship Id="${id}" Type="${type}" Target="${xmlEncode(target)}"` +
|
|
239
245
|
`${mode ? ` TargetMode="${mode}"` : ''}/>`;
|
|
240
|
-
zip.file(
|
|
246
|
+
zip.file(
|
|
247
|
+
relsPath,
|
|
248
|
+
xml.replace('</Relationships>', () => `${relationship}</Relationships>`)
|
|
249
|
+
);
|
|
241
250
|
return id;
|
|
242
251
|
}
|
|
243
252
|
|
|
@@ -417,7 +426,9 @@ async function clonePartTree(zip, sourcePath, cache = new Map()) {
|
|
|
417
426
|
const cloned = await clonePartTree(zip, partFromTarget(directory, target), cache);
|
|
418
427
|
if (!cloned) continue;
|
|
419
428
|
const rewrittenTarget = absolute ? `/${cloned}` : posix.relative(posix.dirname(targetPath), cloned);
|
|
420
|
-
output = output.replace(block,
|
|
429
|
+
output = output.replace(block, () =>
|
|
430
|
+
block.replace(`Target="${raw}"`, () => `Target="${xmlEncode(rewrittenTarget)}"`)
|
|
431
|
+
);
|
|
421
432
|
}
|
|
422
433
|
zip.file(partRelationshipPath(targetPath), output);
|
|
423
434
|
return targetPath;
|
|
@@ -446,7 +457,9 @@ export async function cloneOwnedSlideParts(zip, relationshipsPath) {
|
|
|
446
457
|
if (!cloned) continue;
|
|
447
458
|
copied.push(cloned);
|
|
448
459
|
const rewrittenTarget = absolute ? `/${cloned}` : posix.relative(owner, cloned);
|
|
449
|
-
output = output.replace(block,
|
|
460
|
+
output = output.replace(block, () =>
|
|
461
|
+
block.replace(`Target="${raw}"`, () => `Target="${xmlEncode(rewrittenTarget)}"`)
|
|
462
|
+
);
|
|
450
463
|
}
|
|
451
464
|
if (copied.length) zip.file(relationshipsPath, output);
|
|
452
465
|
return copied;
|
|
@@ -468,9 +481,11 @@ async function remapLayoutRelationships(source, zip, { layoutPath, targetPath, m
|
|
|
468
481
|
? master
|
|
469
482
|
: await importPartTree(source, zip, resolved, cache);
|
|
470
483
|
if (!mapped) continue;
|
|
471
|
-
output = output.replace(
|
|
472
|
-
block
|
|
473
|
-
|
|
484
|
+
output = output.replace(block, () =>
|
|
485
|
+
block.replace(
|
|
486
|
+
/\bTarget="[^"]*"/,
|
|
487
|
+
() => `Target="${xmlEncode(posix.relative(posix.dirname(targetPath), mapped))}"`
|
|
488
|
+
)
|
|
474
489
|
);
|
|
475
490
|
}
|
|
476
491
|
zip.file(partRelationshipPath(targetPath), output);
|
|
@@ -490,8 +505,8 @@ async function registerLayoutOnMaster(zip, master, targetPath) {
|
|
|
490
505
|
zip.file(
|
|
491
506
|
master,
|
|
492
507
|
masterXml.includes('</p:sldLayoutIdLst>')
|
|
493
|
-
? masterXml.replace('</p:sldLayoutIdLst>', `${entry}</p:sldLayoutIdLst>`)
|
|
494
|
-
: masterXml.replace(/(<p:clrMap\b[^>]*\/>)/, `$
|
|
508
|
+
? masterXml.replace('</p:sldLayoutIdLst>', () => `${entry}</p:sldLayoutIdLst>`)
|
|
509
|
+
: masterXml.replace(/(<p:clrMap\b[^>]*\/>)/, (__m, __1) => `${__1}<p:sldLayoutIdLst>${entry}</p:sldLayoutIdLst>`)
|
|
495
510
|
);
|
|
496
511
|
}
|
|
497
512
|
|
|
@@ -548,9 +563,8 @@ export async function rewriteImportedRelationships(source, zip, sourceOwner, tar
|
|
|
548
563
|
} else {
|
|
549
564
|
mapped = await importPartTree(source, zip, resolved, cache);
|
|
550
565
|
}
|
|
551
|
-
output = output.replace(
|
|
552
|
-
block,
|
|
553
|
-
block.replace(/\bTarget="[^"]*"/, `Target="${xmlEncode(posix.relative(targetDirectory, mapped))}"`)
|
|
566
|
+
output = output.replace(block, () =>
|
|
567
|
+
block.replace(/\bTarget="[^"]*"/, () => `Target="${xmlEncode(posix.relative(targetDirectory, mapped))}"`)
|
|
554
568
|
);
|
|
555
569
|
}
|
|
556
570
|
return output;
|
|
@@ -321,12 +321,12 @@ export async function writePivotTable(
|
|
|
321
321
|
const cacheId = (workbook.match(/<pivotCache\b/g) || []).length + 1;
|
|
322
322
|
const entry = `<pivotCache cacheId="${cacheId}" r:id="${workbookRelationshipId}"/>`;
|
|
323
323
|
if (/<pivotCaches>/.test(workbook)) {
|
|
324
|
-
workbook = workbook.replace('</pivotCaches>', `${entry}</pivotCaches>`);
|
|
324
|
+
workbook = workbook.replace('</pivotCaches>', () => `${entry}</pivotCaches>`);
|
|
325
325
|
} else {
|
|
326
326
|
const block = `<pivotCaches>${entry}</pivotCaches>`;
|
|
327
327
|
workbook = /<calcPr\b[^>]*\/>/.test(workbook)
|
|
328
|
-
? workbook.replace(/(<calcPr\b[^>]*\/>)/, `$
|
|
329
|
-
: workbook.replace('</sheets>', `</sheets>${block}`);
|
|
328
|
+
? workbook.replace(/(<calcPr\b[^>]*\/>)/, (__m, __1) => `${__1}${block}`)
|
|
329
|
+
: workbook.replace('</sheets>', () => `</sheets>${block}`);
|
|
330
330
|
}
|
|
331
331
|
zip.file('xl/workbook.xml', workbook);
|
|
332
332
|
|
|
@@ -185,9 +185,9 @@ export async function writePresentationChart(zip, { chartPart, embeddingPart, ch
|
|
|
185
185
|
const id = /\bId="([^"]+)"/.exec(previous)?.[1] || `rId${Math.max(0, ...taken) + 1}`;
|
|
186
186
|
const relationship = `<Relationship Id="${id}" Type="${OFFICE_RELATIONSHIP_BASE}/package" Target="${target}"/>`;
|
|
187
187
|
let relationships = `${XML_HEADER}<Relationships xmlns="${PACKAGE_RELATIONSHIP_NS}">${relationship}</Relationships>`;
|
|
188
|
-
if (previous) relationships = existing.replace(previous, relationship);
|
|
188
|
+
if (previous) relationships = existing.replace(previous, () => relationship);
|
|
189
189
|
else if (existing.includes('</Relationships>'))
|
|
190
|
-
relationships = existing.replace('</Relationships>', `${relationship}</Relationships>`);
|
|
190
|
+
relationships = existing.replace('</Relationships>', () => `${relationship}</Relationships>`);
|
|
191
191
|
zip.file(relationshipsPath, relationships);
|
|
192
192
|
zip.file(chartPart, citeChartWorkbook(chart, id));
|
|
193
193
|
await ensureContentTypeOverride(zip, `/${chartPart}`, CHART_CONTENT_TYPE);
|
|
@@ -197,7 +197,7 @@ export async function writePresentationChart(zip, { chartPart, embeddingPart, ch
|
|
|
197
197
|
function citeChartWorkbook(chart, id) {
|
|
198
198
|
const text = String(chart);
|
|
199
199
|
if (/<c:externalData\b[^>]*\br:id="/.test(text)) {
|
|
200
|
-
return text.replace(/(<c:externalData\b[^>]*\br:id=")[^"]*(")/, `$
|
|
200
|
+
return text.replace(/(<c:externalData\b[^>]*\br:id=")[^"]*(")/, (__m, __1, __2) => `${__1}${id}${__2}`);
|
|
201
201
|
}
|
|
202
202
|
const cited = `<c:externalData r:id="${id}"><c:autoUpdate val="0"/></c:externalData>`;
|
|
203
203
|
const before = /<c:(?:printSettings|userShapes|extLst)\b|<\/c:chartSpace>/.exec(text);
|
|
@@ -103,9 +103,9 @@ function accentOnLastPoint(series, count) {
|
|
|
103
103
|
if (count !== previousCount && accents.length === 1 && pointAt(accents[0]) === previousCount - 1) {
|
|
104
104
|
// The accent and the point now last trade places; one past the new end is dropped by the caller.
|
|
105
105
|
const displaced = points.find((point) => pointAt(point) === count - 1);
|
|
106
|
-
const moved = (point, to) => point.replace(/<c:idx val="\d+"\/>/, `<c:idx val="${to}"/>`);
|
|
107
|
-
block = block.replace(accents[0], moved(accents[0], count - 1));
|
|
108
|
-
if (displaced) block = block.replace(displaced, moved(displaced, previousCount - 1));
|
|
106
|
+
const moved = (point, to) => point.replace(/<c:idx val="\d+"\/>/, () => `<c:idx val="${to}"/>`);
|
|
107
|
+
block = block.replace(accents[0], () => moved(accents[0], count - 1));
|
|
108
|
+
if (displaced) block = block.replace(displaced, () => moved(displaced, previousCount - 1));
|
|
109
109
|
}
|
|
110
110
|
return block;
|
|
111
111
|
}
|
|
@@ -132,7 +132,7 @@ function refreshChartDataInPlace(xml, categories, series, op) {
|
|
|
132
132
|
block = /<c:tx>\s*<c:v>/.test(block)
|
|
133
133
|
? block.replace(
|
|
134
134
|
/<c:tx>\s*<c:v>[\s\S]*?<\/c:v>\s*<\/c:tx>/,
|
|
135
|
-
`<c:tx><c:v>${xmlEncode(String(entry.name))}</c:v></c:tx>`
|
|
135
|
+
() => `<c:tx><c:v>${xmlEncode(String(entry.name))}</c:v></c:tx>`
|
|
136
136
|
)
|
|
137
137
|
: block.replace(
|
|
138
138
|
/(<c:tx>\s*<c:strRef>[\s\S]*?<c:strCache>)[\s\S]*?(<\/c:strCache>)/,
|
|
@@ -251,20 +251,20 @@ function withCategoryOrientation(xml, orientation) {
|
|
|
251
251
|
const element = `<c:orientation val="${orientation}"/>`;
|
|
252
252
|
let oriented;
|
|
253
253
|
if (/<c:orientation val="[^"]*"\/>/.test(categoryAxis)) {
|
|
254
|
-
oriented = categoryAxis.replace(/<c:orientation val="[^"]*"\/>/, element);
|
|
254
|
+
oriented = categoryAxis.replace(/<c:orientation val="[^"]*"\/>/, () => element);
|
|
255
255
|
} else if (categoryAxis.includes('<c:scaling/>')) {
|
|
256
|
-
oriented = categoryAxis.replace('<c:scaling/>', `<c:scaling>${element}</c:scaling>`);
|
|
256
|
+
oriented = categoryAxis.replace('<c:scaling/>', () => `<c:scaling>${element}</c:scaling>`);
|
|
257
257
|
} else {
|
|
258
|
-
oriented = categoryAxis.replace('<c:scaling>', `<c:scaling>${element}`);
|
|
258
|
+
oriented = categoryAxis.replace('<c:scaling>', () => `<c:scaling>${element}`);
|
|
259
259
|
}
|
|
260
260
|
const crosses = orientation === 'maxMin' ? 'max' : 'autoZero';
|
|
261
261
|
let crossed = valueAxis;
|
|
262
262
|
if (/<c:crosses val="[^"]*"\/>/.test(valueAxis)) {
|
|
263
|
-
crossed = valueAxis.replace(/<c:crosses val="[^"]*"\/>/, `<c:crosses val="${crosses}"/>`);
|
|
263
|
+
crossed = valueAxis.replace(/<c:crosses val="[^"]*"\/>/, () => `<c:crosses val="${crosses}"/>`);
|
|
264
264
|
} else if (!/<c:crossesAt\b/.test(valueAxis)) {
|
|
265
|
-
crossed = valueAxis.replace(/(<c:crossAx val="[^"]*"\/>)/, `$
|
|
265
|
+
crossed = valueAxis.replace(/(<c:crossAx val="[^"]*"\/>)/, (__m, __1) => `${__1}<c:crosses val="${crosses}"/>`);
|
|
266
266
|
}
|
|
267
|
-
return xml.replace(categoryAxis, oriented).replace(valueAxis, crossed);
|
|
267
|
+
return xml.replace(categoryAxis, () => oriented).replace(valueAxis, () => crossed);
|
|
268
268
|
}
|
|
269
269
|
|
|
270
270
|
// The new series carrying the colours the chart already had.
|
|
@@ -420,7 +420,7 @@ export async function handleSetChartAxis(context, op) {
|
|
|
420
420
|
const bounds =
|
|
421
421
|
`${op.maximum != null ? `<c:max val="${Number(op.maximum)}"/>` : ''}` +
|
|
422
422
|
`${op.minimum != null ? `<c:min val="${Number(op.minimum)}"/>` : ''}`;
|
|
423
|
-
return cleaned.replace('</c:scaling>', `${bounds}</c:scaling>`);
|
|
423
|
+
return cleaned.replace('</c:scaling>', () => `${bounds}</c:scaling>`);
|
|
424
424
|
});
|
|
425
425
|
}
|
|
426
426
|
if (op.numberFormat != null) {
|
|
@@ -471,7 +471,7 @@ export async function handleSetChartSeries(context, op) {
|
|
|
471
471
|
if (op.name != null) {
|
|
472
472
|
updated = updated.replace(
|
|
473
473
|
/(<c:tx>[\s\S]*?<c:strCache>[\s\S]*?<c:pt idx="0"><c:v>)[\s\S]*?(<\/c:v>)/,
|
|
474
|
-
`$
|
|
474
|
+
(__m, __1, __2) => `${__1}${xmlEncode(String(op.name))}${__2}`
|
|
475
475
|
);
|
|
476
476
|
}
|
|
477
477
|
if (Array.isArray(op.categories) && op.categories.length) {
|
|
@@ -482,9 +482,12 @@ export async function handleSetChartSeries(context, op) {
|
|
|
482
482
|
block
|
|
483
483
|
.replace(
|
|
484
484
|
/<c:strCache>[\s\S]*?<\/c:strCache>/,
|
|
485
|
-
`<c:strCache><c:ptCount val="${op.categories.length}"/>${points}</c:strCache>`
|
|
485
|
+
() => `<c:strCache><c:ptCount val="${op.categories.length}"/>${points}</c:strCache>`
|
|
486
|
+
)
|
|
487
|
+
.replace(
|
|
488
|
+
/(<c:f>[^<]*\$[A-Z]+\$\d+:\$[A-Z]+\$)\d+(<\/c:f>)/,
|
|
489
|
+
(__m, __1, __2) => `${__1}${op.categories.length + 1}${__2}`
|
|
486
490
|
)
|
|
487
|
-
.replace(/(<c:f>[^<]*\$[A-Z]+\$\d+:\$[A-Z]+\$)\d+(<\/c:f>)/, `$1${op.categories.length + 1}$2`)
|
|
488
491
|
);
|
|
489
492
|
}
|
|
490
493
|
if (Array.isArray(op.values) && op.values.length) {
|
|
@@ -499,10 +502,13 @@ export async function handleSetChartSeries(context, op) {
|
|
|
499
502
|
.replace(/<c:numCache>[\s\S]*?<\/c:numCache>/, (cache) =>
|
|
500
503
|
cache.replace(
|
|
501
504
|
/<c:ptCount val="\d+"\/>[\s\S]*?(?=<\/c:numCache>)/,
|
|
502
|
-
`<c:ptCount val="${op.values.length}"/>${points}`
|
|
505
|
+
() => `<c:ptCount val="${op.values.length}"/>${points}`
|
|
503
506
|
)
|
|
504
507
|
)
|
|
505
|
-
.replace(
|
|
508
|
+
.replace(
|
|
509
|
+
/(<c:f>[^<]*\$[A-Z]+\$\d+:\$[A-Z]+\$)\d+(<\/c:f>)/,
|
|
510
|
+
(__m, __1, __2) => `${__1}${op.values.length + 1}${__2}`
|
|
511
|
+
)
|
|
506
512
|
);
|
|
507
513
|
}
|
|
508
514
|
return updated;
|
|
@@ -575,7 +581,7 @@ export async function handleSetChartTrendlineOrSetChartErrorBars(context, op) {
|
|
|
575
581
|
const anchor = /<c:cat>/.exec(cleaned) || /<c:val>/.exec(cleaned);
|
|
576
582
|
return anchor
|
|
577
583
|
? `${cleaned.slice(0, anchor.index)}${element}${cleaned.slice(anchor.index)}`
|
|
578
|
-
: cleaned.replace('</c:ser>', `${element}</c:ser>`);
|
|
584
|
+
: cleaned.replace('</c:ser>', () => `${element}</c:ser>`);
|
|
579
585
|
});
|
|
580
586
|
if (!changed) throw new Error(`Chart has no series ${op.series ?? ''}`.trim());
|
|
581
587
|
zip.file(chart.part, next);
|
|
@@ -610,7 +616,7 @@ export async function handleSetChartDataLabels(context, op) {
|
|
|
610
616
|
const anchor = /<c:cat>/.exec(cleaned);
|
|
611
617
|
return anchor
|
|
612
618
|
? `${cleaned.slice(0, anchor.index)}${labels}${cleaned.slice(anchor.index)}`
|
|
613
|
-
: cleaned.replace('</c:ser>', `${labels}</c:ser>`);
|
|
619
|
+
: cleaned.replace('</c:ser>', () => `${labels}</c:ser>`);
|
|
614
620
|
});
|
|
615
621
|
if (!changed) throw new Error(`Chart has no series ${op.series ?? ''}`.trim());
|
|
616
622
|
zip.file(chart.part, next);
|
|
@@ -264,11 +264,11 @@ function setTableCellText(cell, text) {
|
|
|
264
264
|
`<a:t${/^\s|\s$/.test(value) ? ' xml:space="preserve"' : ''}>${xmlEncode(value)}</a:t></a:r>`;
|
|
265
265
|
const paragraph = /<a:p(?:\s[^>]*)?>[\s\S]*?<\/a:p>/.exec(cell);
|
|
266
266
|
if (paragraph) {
|
|
267
|
-
const replaced = paragraph[0].replace(/<\/a:p>$/, `${run}</a:p>`);
|
|
267
|
+
const replaced = paragraph[0].replace(/<\/a:p>$/, () => `${run}</a:p>`);
|
|
268
268
|
return `${cell.slice(0, paragraph.index)}${replaced}${cell.slice(paragraph.index + paragraph[0].length)}`;
|
|
269
269
|
}
|
|
270
270
|
if (!/<\/a:txBody>/.test(cell)) throw new Error('PPTX table cell has no text body');
|
|
271
|
-
return cell.replace('</a:txBody>', `<a:p>${run}</a:p></a:txBody>`);
|
|
271
|
+
return cell.replace('</a:txBody>', () => `<a:p>${run}</a:p></a:txBody>`);
|
|
272
272
|
}
|
|
273
273
|
|
|
274
274
|
export function setTableValues(shapeXml, values) {
|
|
@@ -399,7 +399,7 @@ export function writeShapeTree(slideXml, tree, shapes) {
|
|
|
399
399
|
|
|
400
400
|
export function appendSlideShape(xml, shape) {
|
|
401
401
|
if (!/<\/p:spTree>/.test(xml)) throw new Error('PPTX slide shape tree is missing');
|
|
402
|
-
return xml.replace('</p:spTree>', `${shape}</p:spTree>`);
|
|
402
|
+
return xml.replace('</p:spTree>', () => `${shape}</p:spTree>`);
|
|
403
403
|
}
|
|
404
404
|
|
|
405
405
|
export function setSlideBackground(xml, color) {
|
|
@@ -444,8 +444,8 @@ export function updateShapeGeometry(shape, properties) {
|
|
|
444
444
|
`<a:ext cx="${properties.width != null ? toEmu(properties.width) : Number(extent?.[1] || 1)}"` +
|
|
445
445
|
` cy="${properties.height != null ? toEmu(properties.height) : Number(extent?.[2] || 1)}"/></${frameTag}>`;
|
|
446
446
|
if (current) next = `${next.slice(0, current.index)}${frame}${next.slice(current.index + current[0].length)}`;
|
|
447
|
-
else if (frameTag === 'p:xfrm') next = next.replace('</p:nvGraphicFramePr>',
|
|
448
|
-
else next = next.replace(/<p:spPr(?:\s[^>]*)?>/,
|
|
447
|
+
else if (frameTag === 'p:xfrm') next = next.replace('</p:nvGraphicFramePr>', (__m) => `${__m}${frame}`);
|
|
448
|
+
else next = next.replace(/<p:spPr(?:\s[^>]*)?>/, (__m) => `${__m}${frame}`);
|
|
449
449
|
}
|
|
450
450
|
// A transparency alone keeps the fill's colour, as the Office backend's Fill.Transparency does; it was dropped here.
|
|
451
451
|
const fillColor =
|