gutterpress 0.11.23-alpha.2 → 0.11.23-alpha.4

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.
Files changed (82) hide show
  1. package/README.md +10 -13
  2. package/dist/{README-8ef336pp.md → README-syg2hn83.md} +13 -19
  3. package/dist/api/index.d.ts +1 -1
  4. package/dist/api/index.js +5 -5
  5. package/dist/{build-encgnv0c.js → build-c48eer6f.js} +8 -8
  6. package/dist/checks/asset/extensions.d.ts +1 -1
  7. package/dist/checks/asset/index.d.ts +0 -1
  8. package/dist/checks/policy.d.ts +5 -4
  9. package/dist/checks/source/config-file.d.ts +9 -6
  10. package/dist/checks/source/dangling-links.d.ts +1 -1
  11. package/dist/checks/types.d.ts +2 -2
  12. package/dist/{cli-pz4bn98t.js → cli-54xt7pjg.js} +19 -13
  13. package/dist/{index-2ppw6q9v.js → cli-5crpmz42.js} +80 -1
  14. package/dist/{cli-xq6djqbj.js → cli-93mkaw6v.js} +166 -308
  15. package/dist/{cli-evg8sbht.js → cli-d9mm3vvh.js} +7 -2
  16. package/dist/{cli-kh8v4vvw.js → cli-gnpea9dx.js} +1 -1
  17. package/dist/{cli-aqh6brew.js → cli-pspjxnc8.js} +1 -1
  18. package/dist/{cli-pwwfxdgb.js → cli-rqh295j9.js} +15 -21
  19. package/dist/{index-x3ema2w3.js → cli-y6d1arem.js} +321 -272
  20. package/dist/cli.js +12 -12
  21. package/dist/{doctor-5gtpgpd1.js → doctor-ptb346k8.js} +4 -3
  22. package/dist/engine/shared/gcpm-extract.d.ts +8 -0
  23. package/dist/engine/shared/print-area.d.ts +16 -4
  24. package/dist/{engine-mc5br8g8.js → engine-4rzdx6af.js} +1 -1
  25. package/dist/{engine-tn13gk0b.js → engine-6txhxmmv.js} +2 -2
  26. package/dist/{ext-wn2a5afq.js → ext-gy8szg3x.js} +8 -8
  27. package/dist/{extension-restore-s3x1618g.js → extension-restore-dymzcasz.js} +2 -2
  28. package/dist/{extension-restore-g8jnmmzq.js → extension-restore-m8tj43e7.js} +4 -4
  29. package/dist/{gutterpress-viewer-701vf4qp.js → gutterpress-viewer-mafsby5k.js} +9 -2
  30. package/dist/{cli-2ppw6q9v.js → index-5crpmz42.js} +80 -1
  31. package/dist/{index-0skhjx3e.js → index-5kh4c78h.js} +19 -13
  32. package/dist/{index-2bjcghze.js → index-8ywkd2sv.js} +15 -21
  33. package/dist/{index-j5z86r4a.js → index-ea94zbq4.js} +329 -488
  34. package/dist/{cli-sdmv4bba.js → index-kaks3mm2.js} +448 -156
  35. package/dist/{index-4x6y8krm.js → index-yc3xj266.js} +1 -1
  36. package/dist/index.js +6 -6
  37. package/dist/lib/build-preflight.d.ts +4 -10
  38. package/dist/lib/build-runner.d.ts +1 -1
  39. package/dist/lib/extension-manager.d.ts +8 -7
  40. package/dist/lib/extension-manifest.d.ts +1 -13
  41. package/dist/lib/ghostscript.d.ts +5 -2
  42. package/dist/lib/lint-rules.d.ts +5 -1
  43. package/dist/lib/manifest-config.d.ts +3 -2
  44. package/dist/lib/manifest-old-spellings.d.ts +64 -0
  45. package/dist/lib/manifest.d.ts +15 -1
  46. package/dist/lib/markdown/assemble.d.ts +4 -3
  47. package/dist/lib/markdown/chapter-id.d.ts +1 -1
  48. package/dist/lib/markdown/index.d.ts +1 -1
  49. package/dist/lib/markdown/table.d.ts +5 -3
  50. package/dist/lib/page-size.d.ts +45 -33
  51. package/dist/lib/pdf-inspect.d.ts +27 -0
  52. package/dist/lib/presets.d.ts +10 -8
  53. package/dist/lib/printsafe.d.ts +2 -1
  54. package/dist/lib/project-scaffold.d.ts +1 -1
  55. package/dist/lib/project-templates.d.ts +9 -0
  56. package/dist/lib/remote-auth/sync-messages.d.ts +2 -2
  57. package/dist/lib/targets.d.ts +4 -4
  58. package/dist/lib/validation-exec.d.ts +4 -4
  59. package/dist/manifest-2kc56wvw.yaml +22 -0
  60. package/dist/manifest-41ddzm13.yaml +18 -0
  61. package/dist/manifest-79zsgkpn.yaml +26 -0
  62. package/dist/manifest-sqzm4681.yaml +22 -0
  63. package/dist/{manifest.schema-t7nx2stg.json → manifest.schema-w86c1xw1.json} +30 -308
  64. package/dist/{new-mhs46pw3.js → new-t2t28ccb.js} +9 -15
  65. package/dist/{package-aenwjew3.json → package-awwkt7sa.json} +0 -1
  66. package/dist/{page-rules-nsj3aw42.css → page-rules-ytj9p04v.css} +12 -40
  67. package/dist/{pdf-inspect-wnw4za71.js → pdf-inspect-b3mf81ex.js} +3 -1
  68. package/dist/{plugin.test.js-xgxrd8hf.tpl → plugin.test.js-gxzqqfdh.tpl} +0 -1
  69. package/dist/{plugins-2cek4mz1.js → plugins-fec8t2bh.js} +1 -1
  70. package/dist/{plugins-1sxe0dkz.js → plugins-sqa4msdk.js} +3 -3
  71. package/dist/{preflight-3k2b1x8e.js → preflight-srq8fktp.js} +8 -8
  72. package/dist/preview/file-watcher.d.ts +1 -3
  73. package/dist/{preview-6p9v6rht.js → preview-zsp9hstd.js} +8 -8
  74. package/dist/{publish-qgsngy8s.js → publish-hhy31gr9.js} +8 -8
  75. package/dist/render.js +30 -562
  76. package/dist/schema/manifest.types.d.ts +60 -105
  77. package/dist/{tokens-7984461t.css → tokens-n82t4k9h.css} +12 -12
  78. package/dist/{validate-0v7xw6wa.js → validate-r9jdz85h.js} +8 -8
  79. package/package.json +1 -1
  80. package/dist/checks/asset/approved-fonts.d.ts +0 -3
  81. package/dist/manifest-eagfhba6.yaml +0 -19
  82. package/dist/manifest-n1gh3qw5.yaml +0 -9
package/README.md CHANGED
@@ -90,7 +90,7 @@ A Gutterpress project is a directory. The CLI doesn't impose much structure; the
90
90
  my-book/
91
91
  ├─ manifest.yaml ← optional but recommended; metadata + config
92
92
  ├─ chapter-01.md ← markdown files, processed in alphabetical order
93
- ├─ chapter-02.md (or in the order listed in manifest.yaml#source.files)
93
+ ├─ chapter-02.md (or in the order listed in manifest.yaml#chapters)
94
94
  ├─ css/ ← your stylesheets
95
95
  │ └─ print.css
96
96
  └─ images/ ← images referenced from markdown or CSS
@@ -123,10 +123,9 @@ preset: dtrpg
123
123
  styles:
124
124
  - css/print.css
125
125
 
126
- source:
127
- files:
128
- - chapter-01.md
129
- - chapter-02.md
126
+ chapters:
127
+ - chapter-01.md
128
+ - chapter-02.md
130
129
  ```
131
130
 
132
131
  The full configuration cascade is `CLI flags > manifest.yaml > preset defaults`. See the [configuration reference](https://github.com/dimm-city/gutterpress/blob/main/examples/gutterpress-user-guide/01-getting-started.md#manifest-configuration) for details.
@@ -163,7 +162,6 @@ gutterpress new <name> [--kind <id>] [options]
163
162
  --targets <ids> Publish targets recorded in the manifest (comma-separated: dtrpg, itch; or "none") — default: the preset's
164
163
  --page-width <pt> Trim width in points, 72pt = 1in (required with --preset custom; optional override otherwise)
165
164
  --page-height <pt> Trim height in points, 72pt = 1in (required with --preset custom; optional override otherwise)
166
- --page-tolerance <pt> Allowed trim deviation when validating a built PDF (default: 0.5)
167
165
  --git Initialise local version history (default: true; use --no-git to skip)
168
166
  --no-git
169
167
  ```
@@ -363,7 +361,7 @@ List, add, remove, enable, or disable the project's extensions. Markdown-it
363
361
  plugins, looks (stylesheets) and component libraries are all extensions — one
364
362
  `extensions:` list in `manifest.yaml`, in load order (see
365
363
  [Extensions](#extensions) below). These are the same shared-lib functions the
366
- desktop app's Look and Features views call, so an extension added from the
364
+ desktop app's Extensions tab calls, so an extension added from the
367
365
  terminal is the same entry the GUI shows.
368
366
 
369
367
  ```sh
@@ -460,7 +458,7 @@ never touched.
460
458
 
461
459
  ```sh
462
460
  gutterpress ext remove markdown-it-highlightjs ./my-book
463
- gutterpress ext remove ./extensions/zine ./my-book
461
+ gutterpress ext remove zine ./my-book
464
462
  ```
465
463
 
466
464
  #### `gutterpress ext enable` / `gutterpress ext disable`
@@ -475,8 +473,8 @@ gutterpress ext enable markdown-it-mark ./my-book
475
473
 
476
474
  #### `gutterpress ext search`
477
475
 
478
- Search **npm** for extensions — the same list the desktop app's Features view
479
- shows under "Find more on npm." Not project-scoped (no `dir` argument): it
476
+ Search **npm** for extensions — the same list the desktop app's Extensions tab
477
+ shows under *Search*. Not project-scoped (no `dir` argument): it
480
478
  queries the registry for packages tagged `gutterpress` (Gutterpress
481
479
  extensions: plugins, looks, component libraries) or `markdown-it-plugin` (the
482
480
  markdown-it ecosystem's own tag — those work in Gutterpress unchanged), and
@@ -521,7 +519,7 @@ extensions:
521
519
  # a feature bundled with Gutterpress — nothing to install, works offline
522
520
  - markdown-it-mark
523
521
  # a folder or plugin file, relative to manifest.yaml — referenced in place
524
- - ./extensions/clean-book
522
+ - ./extensions/house-look
525
523
  - ./plugins/my-custom-plugin.js
526
524
  # an npm package, pinned to the exact version `gutterpress ext add` installed
527
525
  - markdown-it-highlightjs@4.3.0
@@ -547,8 +545,7 @@ An extension folder (or npm package) describes itself in its **`package.json`**
547
545
  "gutterpress": {
548
546
  "styles": ["styles/plugin.css"],
549
547
  "snippets": "snippets",
550
- "components": "components.yaml",
551
- "tokensFile": "styles/tokens.css"
548
+ "components": "components.yaml"
552
549
  }
553
550
  }
554
551
  ```
@@ -17,7 +17,7 @@ arrangement of the files is the part worth keeping.
17
17
  ├── base.css element baseline. Bare p/h2/table/code.
18
18
  ├── components.css named components + their public tokens.
19
19
  ├── page-templates.css .page.* layouts — arrangement WITHIN a page.
20
- ├── page-rules.css @page geometry, margin boxes, running heads.
20
+ ├── page-rules.css @page margin boxes, running heads, named pages.
21
21
  └── book.css this book's overrides. Loads last.
22
22
  ```
23
23
 
@@ -64,7 +64,7 @@ instantly: **where does this rule go?**
64
64
  | what a plain paragraph or table looks like | `base.css` |
65
65
  | a named thing an author opts into | `components.css` |
66
66
  | how one page arranges its content | `page-templates.css` |
67
- | margins, folios, running heads | `page-rules.css` |
67
+ | folios, running heads, named pages | `page-rules.css` |
68
68
  | one chapter of one book | `book.css` |
69
69
 
70
70
  If a rule seems to belong in two of them, it is usually two rules.
@@ -156,23 +156,17 @@ author retypes must be found and replaced across every chapter when it
156
156
  changes. A variant expressed as a component name plus a CSS rule changes in
157
157
  one place, and chapters written afterwards get it for free.
158
158
 
159
- ### 4. `@page { size }` is not optional, and it must match the manifest
160
-
161
- `page-rules.css` opens by declaring the trim:
162
-
163
- ```css
164
- @page { size: 6in 9in; }
165
- ```
166
-
167
- That line is load-bearing in the most literal sense. With no `size:` anywhere
168
- in the book's CSS, Chromium falls back to US Letter and prints the whole book
169
- at the wrong trim, with no error — this is the one failure in the stack that
170
- costs money rather than time.
171
-
172
- The manifest's `preset:`/`page:` remains the source of truth: it is what
173
- `gutterpress validate` measures the produced PDF against, and what the publish
174
- targets check. The CSS line is the instruction that satisfies it. Change one,
175
- change the other — and let validate catch you when you forget.
159
+ ### 4. The page size and margins are the book's, not the look's
160
+
161
+ A look never declares `@page { size }` or `@page { margin }`. The book's
162
+ manifest records both (`preset:`, `page: width / height / margin`, which the
163
+ app edits under Setup > Book), and the build writes them as the `@page`
164
+ rule after every stylesheet, so a `size` in a look is ignored and reported by
165
+ the print-safety check, and a `margin` holds only until the author sets
166
+ margins in the app. `page-rules.css` owns what IS a look's: the margin boxes
167
+ (folios, running heads) and the named pages. Design them to sit in whatever
168
+ margin the book gives them — a folio at `@bottom-right` needs no particular
169
+ margin to work.
176
170
 
177
171
  ### 5. Keep the catalog honest
178
172
 
@@ -52,7 +52,7 @@ export type { ProjectStyle } from "../lib/style-resolver.ts";
52
52
  export { readManifestFields, setManifestFields, setActiveStyles, } from "../lib/manifest-config.ts";
53
53
  export type { ProjectConfigFields } from "../lib/manifest-config.ts";
54
54
  export { readPageSetup, setPageSetup } from "../lib/page-size.ts";
55
- export type { PageSetup, PageSizeChoice, PageSizePoints } from "../lib/page-size.ts";
55
+ export type { PageMargin, PageSetup, PageSetupChange, PageSizeChoice, PageSizePoints } from "../lib/page-size.ts";
56
56
  export { providerFor, restoreVersionWithBackup, isNoChangesError, countUnversionedChanges, whenGitIdle, AUTO_SNAPSHOT_MESSAGE, RESTORE_BACKUP_MESSAGE, HISTORY_PAGE_LIMIT, listLocalBranches, switchBranch, SWITCH_BRANCH_SNAPSHOT_MESSAGE, } from "../lib/source-provider.ts";
57
57
  export type { ListHistoryOptions, HistoryPage, UnversionedChanges, LocalBranches, SwitchBranchOptions, SwitchBranchResult, } from "../lib/source-provider.ts";
58
58
  export { describeVersions, listOnlineVersions, compareVersionFile, exportVersionTree, VERSION_CHANGES_SHOWN, } from "../lib/version-changes.ts";
package/dist/api/index.js CHANGED
@@ -101,7 +101,7 @@ import {
101
101
  substituteVariables,
102
102
  syncProject,
103
103
  testRemoteAccess
104
- } from "../index-j5z86r4a.js";
104
+ } from "../index-ea94zbq4.js";
105
105
  import {
106
106
  DEFAULT_NPM_REGISTRY,
107
107
  MANIFEST_FILENAMES,
@@ -130,7 +130,7 @@ import {
130
130
  setExtensionEnabled,
131
131
  updateExtensions,
132
132
  validateProjectExtensions
133
- } from "../index-x3ema2w3.js";
133
+ } from "../index-kaks3mm2.js";
134
134
  import {
135
135
  BUNDLED_EXTENSIONS,
136
136
  EXTENSION_MANIFEST_FILENAME,
@@ -145,13 +145,13 @@ import {
145
145
  pathEscapesFolder,
146
146
  readExtensionMeta,
147
147
  resolveExtension
148
- } from "../index-2bjcghze.js";
148
+ } from "../index-8ywkd2sv.js";
149
149
  import"../index-ht1bcqdd.js";
150
- import"../index-0skhjx3e.js";
150
+ import"../index-5kh4c78h.js";
151
151
  import {
152
152
  BuildError
153
153
  } from "../index-46ycxe6r.js";
154
- import"../index-2ppw6q9v.js";
154
+ import"../index-5crpmz42.js";
155
155
  import {
156
156
  DEFAULT_PRINT_OPTS,
157
157
  assertMilestone,
@@ -1,20 +1,20 @@
1
1
  import {
2
2
  runBuild,
3
3
  splitOutPath
4
- } from "./cli-xq6djqbj.js";
5
- import"./cli-evg8sbht.js";
4
+ } from "./cli-93mkaw6v.js";
5
+ import"./cli-d9mm3vvh.js";
6
6
  import"./cli-ht1bcqdd.js";
7
- import"./cli-pz4bn98t.js";
8
- import"./cli-2ppw6q9v.js";
7
+ import"./cli-54xt7pjg.js";
8
+ import"./cli-5crpmz42.js";
9
9
  import"./cli-eyyggect.js";
10
10
  import"./cli-asap4t1z.js";
11
11
  import"./cli-a35w7wzg.js";
12
12
  import"./cli-v5mp7a6q.js";
13
- import"./cli-sdmv4bba.js";
14
- import"./cli-pwwfxdgb.js";
13
+ import"./cli-y6d1arem.js";
14
+ import"./cli-rqh295j9.js";
15
15
  import {
16
16
  log
17
- } from "./cli-aqh6brew.js";
17
+ } from "./cli-pspjxnc8.js";
18
18
  import {
19
19
  UsageError,
20
20
  parseFormat,
@@ -22,7 +22,7 @@ import {
22
22
  rejectExtraPositionals,
23
23
  rejectUnknownFlags
24
24
  } from "./cli-d8xjns66.js";
25
- import"./cli-kh8v4vvw.js";
25
+ import"./cli-gnpea9dx.js";
26
26
  import {
27
27
  BuildError
28
28
  } from "./cli-46ycxe6r.js";
@@ -28,7 +28,7 @@ export declare const ALL_IMAGE_EXTS: readonly ["png", "jpg", "jpeg", "tiff", "ti
28
28
  * the run has no book to resolve them from (a `--pdf`-only run).
29
29
  */
30
30
  export declare function shippedImages(ctx: CheckContext, exts: readonly string[]): string[];
31
- /** Font file extensions shared by the approved-fonts and font-license checks. */
31
+ /** Font file extensions the font-license check looks for. */
32
32
  export declare const FONT_EXTS: readonly ["woff", "woff2", "otf", "ttf", "eot"];
33
33
  /**
34
34
  * Directories no asset scan should ever descend into, as glob patterns.
@@ -1,4 +1,3 @@
1
1
  import "./image-file-size";
2
2
  import "./image-alpha";
3
- import "./approved-fonts";
4
3
  import "./font-license";
@@ -11,10 +11,11 @@ export declare const INSPECT_FAILED_CODE = "inspect-failed";
11
11
  * Used by BOTH the runner (execution) and tool-check (tool probing) so the two
12
12
  * can never drift.
13
13
  *
14
- * Order: an explicit manifest disable wins first, then the check's own
15
- * declarative `enabledWhen(config)` predicate — the canonical, per-check way to
16
- * express a tool-specific config gate (e.g. `source.stylelint === false`)
17
- * instead of hard-coding special cases in the runner/tool-check.
14
+ * Order: a check's level `off` (preset, target, `checks:` or the CLI) wins
15
+ * first, then the check's own declarative `enabledWhen(config)` predicate —
16
+ * the canonical, per-check way to express a build-setting gate (e.g.
17
+ * `print.signature > 1`) instead of hard-coding special cases in the
18
+ * runner/tool-check.
18
19
  */
19
20
  export declare function isCheckEnabled(check: Check, config: ResolvedConfig): boolean;
20
21
  /** Selector inputs shared by check execution and tool probing. */
@@ -1,8 +1,11 @@
1
1
  /**
2
- * Locate a lint config file for a source check. An explicit relative path
3
- * (from the check's manifest config) wins when it exists; otherwise the first
4
- * of `names` found in the input dir is used. Returns null when nothing
5
- * matches. Shared by the markdownlint and htmlhint wrappers so their
6
- * config-discovery rules can never drift.
2
+ * Locate a lint config file for a source check by its usual name: the first
3
+ * of `names` in the book's folder, else in the folder above, and so on up to
4
+ * the repository the book lives in (the nearest folder with a `.git`), or the
5
+ * filesystem root when there is none. A book inside a larger repository
6
+ * therefore uses the repository's own `.markdownlint.jsonc`, as the linters'
7
+ * own command-line tools do. Returns null when nothing matches. Shared by the
8
+ * markdownlint, htmlhint and CSS-ownership checks so their config discovery
9
+ * can never drift.
7
10
  */
8
- export declare function findConfigFile(inputDir: string, names: readonly string[], explicit?: string | null): string | null;
11
+ export declare function findConfigFile(startDir: string, names: readonly string[]): string | null;
@@ -12,7 +12,7 @@ import type { Check } from "../types";
12
12
  * `source.links.local-refs` answers a different question — does the target
13
13
  * exist on disk — and a link can pass that while still being unopenable from
14
14
  * a PDF, which is why this is its own check (and can be switched off for an
15
- * HTML-only book via `validate.checks`).
15
+ * HTML-only book via `checks:` in the manifest).
16
16
  */
17
17
  declare const check: Check;
18
18
  export default check;
@@ -55,8 +55,8 @@ export interface Check {
55
55
  requiredTools?: string[];
56
56
  /**
57
57
  * Declarative enable gate driven by config (beyond the generic
58
- * `validate.checks[id]` enable/disable). Lets a check own a tool-specific
59
- * config switch — e.g. `source.stylelint === false` — so the runner and
58
+ * `checks: { <id>: off }`). Lets a check run only when a build setting it
59
+ * depends on is in effect — e.g. `print.signature > 1` — so the runner and
60
60
  * tool-check never need per-check special cases. Returning `false` disables
61
61
  * the check for enablement/tool-probing purposes.
62
62
  */
@@ -530,12 +530,18 @@ function parseMargin(value) {
530
530
  const d = parts[3] ?? b;
531
531
  return { top: a, right: b, bottom: c, left: d };
532
532
  }
533
+ var DEFAULT_PAGE_MARGIN_PT = 72;
533
534
  function resolvePage(model, ctx = {}) {
534
535
  const wanted = new Set(ctx.pseudos ?? []);
535
536
  const applicable = model.pageRules.filter((r) => r.name ? r.name === ctx.name : true).filter((r) => r.pseudos.every((p) => wanted.has(p))).sort((a, b) => specificity(a) - specificity(b));
536
537
  const decls = {};
537
538
  const marginBoxes = {};
538
- const margin = { top: 72, right: 72, bottom: 72, left: 72 };
539
+ const margin = {
540
+ top: DEFAULT_PAGE_MARGIN_PT,
541
+ right: DEFAULT_PAGE_MARGIN_PT,
542
+ bottom: DEFAULT_PAGE_MARGIN_PT,
543
+ left: DEFAULT_PAGE_MARGIN_PT
544
+ };
539
545
  for (const rule of applicable) {
540
546
  for (const [prop, value] of Object.entries(rule.decls)) {
541
547
  if (prop === "margin")
@@ -1134,7 +1140,7 @@ import { fileURLToPath } from "node:url";
1134
1140
  var favicon_default = "./favicon-272ga6y0.ico";
1135
1141
 
1136
1142
  // src/assets/manifest.schema.json
1137
- var manifest_schema_default = "./manifest.schema-t7nx2stg.json";
1143
+ var manifest_schema_default = "./manifest.schema-w86c1xw1.json";
1138
1144
 
1139
1145
  // src/assets/preview/scripts/preview-interface.js
1140
1146
  var preview_interface_default = "./preview-interface-nnmrxyqm.js";
@@ -1149,31 +1155,31 @@ var preview_shell_default = "./preview-shell-wk9k3gcd.js";
1149
1155
  var CGATS21_CRPC1_default = "./CGATS21_CRPC1-g0e3k7kr.icc";
1150
1156
 
1151
1157
  // src/assets/engine/gutterpress-viewer.js
1152
- var gutterpress_viewer_default = "./gutterpress-viewer-701vf4qp.js";
1158
+ var gutterpress_viewer_default = "./gutterpress-viewer-mafsby5k.js";
1153
1159
 
1154
1160
  // src/assets/engine/gutterpress-agent.js
1155
1161
  var gutterpress_agent_default = "./gutterpress-agent-d29ry3ak.js";
1156
1162
 
1157
1163
  // src/assets/templates/book/manifest.yaml
1158
- var manifest_default = "./manifest-n1gh3qw5.yaml";
1164
+ var manifest_default = "./manifest-41ddzm13.yaml";
1159
1165
 
1160
1166
  // src/assets/templates/book/chapter-01.md
1161
1167
  var chapter_01_default = "./chapter-01-gsbjt584.md";
1162
1168
 
1163
1169
  // src/assets/templates/zine/manifest.yaml
1164
- var manifest_default2 = "./manifest-n1gh3qw5.yaml";
1170
+ var manifest_default2 = "./manifest-sqzm4681.yaml";
1165
1171
 
1166
1172
  // src/assets/templates/zine/chapter-01.md
1167
1173
  var chapter_01_default2 = "./chapter-01-wgjfz4w6.md";
1168
1174
 
1169
1175
  // src/assets/templates/technical/manifest.yaml
1170
- var manifest_default3 = "./manifest-n1gh3qw5.yaml";
1176
+ var manifest_default3 = "./manifest-2kc56wvw.yaml";
1171
1177
 
1172
1178
  // src/assets/templates/technical/chapter-01.md
1173
1179
  var chapter_01_default3 = "./chapter-01-6fn9pvd0.md";
1174
1180
 
1175
1181
  // src/assets/templates/paper/manifest.yaml
1176
- var manifest_default4 = "./manifest-eagfhba6.yaml";
1182
+ var manifest_default4 = "./manifest-79zsgkpn.yaml";
1177
1183
 
1178
1184
  // src/assets/templates/paper/chapter-01.md
1179
1185
  var chapter_01_default4 = "./chapter-01-s71xrf5q.md";
@@ -1200,13 +1206,13 @@ var fixture_default = "./fixture-2qnyqgb5.md";
1200
1206
  var expected_default = "./expected-ycmacem8.html";
1201
1207
 
1202
1208
  // src/assets/extension-templates/plugin/test/plugin.test.js.tpl
1203
- var plugin_test_js_default = "./plugin.test.js-xgxrd8hf.tpl";
1209
+ var plugin_test_js_default = "./plugin.test.js-gxzqqfdh.tpl";
1204
1210
 
1205
1211
  // src/assets/extension-templates/look/package.json
1206
- var package_default2 = "./package-aenwjew3.json";
1212
+ var package_default2 = "./package-awwkt7sa.json";
1207
1213
 
1208
1214
  // src/assets/extension-templates/look/README.md
1209
- var README_default2 = "./README-8ef336pp.md";
1215
+ var README_default2 = "./README-syg2hn83.md";
1210
1216
 
1211
1217
  // src/assets/extension-templates/look/components.yaml
1212
1218
  var components_default = "./components-zzqdpt3m.yaml";
@@ -1215,7 +1221,7 @@ var components_default = "./components-zzqdpt3m.yaml";
1215
1221
  var callout_default = "./callout-hv56m16h.md";
1216
1222
 
1217
1223
  // src/assets/extension-templates/look/styles/tokens.css
1218
- var tokens_default = "./tokens-7984461t.css";
1224
+ var tokens_default = "./tokens-n82t4k9h.css";
1219
1225
 
1220
1226
  // src/assets/extension-templates/look/styles/base.css
1221
1227
  var base_default = "./base-ypqh9n7f.css";
@@ -1227,7 +1233,7 @@ var components_default2 = "./components-aam0fe2z.css";
1227
1233
  var page_templates_default = "./page-templates-tx9ryt19.css";
1228
1234
 
1229
1235
  // src/assets/extension-templates/look/styles/page-rules.css
1230
- var page_rules_default = "./page-rules-nsj3aw42.css";
1236
+ var page_rules_default = "./page-rules-ytj9p04v.css";
1231
1237
 
1232
1238
  // src/assets/extension-templates/look/styles/book.css
1233
1239
  var book_default = "./book-ted3tzrp.css";
@@ -2679,4 +2685,4 @@ ${lines.length ? lines.join(`
2679
2685
  `);
2680
2686
  }
2681
2687
 
2682
- export { lastPageMode, extract, resolvePage, getAssetPath, MARGIN_BOX_IGNORED_PROPERTIES, build };
2688
+ export { lastPageMode, DEFAULT_PAGE_MARGIN_PT, getAssetPath, MARGIN_BOX_IGNORED_PROPERTIES, build };
@@ -348,6 +348,85 @@ async function unsplittableTextReasons(pdfBytes, pages) {
348
348
  }
349
349
  return reasons;
350
350
  }
351
+ var FILL_PAINT_OPS = opSet(["fill", "eoFill", "fillStroke", "eoFillStroke", "closeFillStroke", "closeEOFillStroke"]);
352
+ var STROKE_PAINT_OPS = opSet(["stroke", "closeStroke", "fillStroke", "eoFillStroke", "closeFillStroke", "closeEOFillStroke"]);
353
+ var SLIVER_PT = 0.25;
354
+ async function pagesWithVisibleShadingPaints(pdfBytes, pages) {
355
+ const box = (b, m) => {
356
+ const xs = [];
357
+ const ys = [];
358
+ const corners = [[b[0], b[1]], [b[2], b[1]], [b[2], b[3]], [b[0], b[3]]];
359
+ for (const [x, y] of corners) {
360
+ xs.push(m[0] * x + m[2] * y + m[4]);
361
+ ys.push(m[1] * x + m[3] * y + m[5]);
362
+ }
363
+ return [Math.min(...xs), Math.min(...ys), Math.max(...xs), Math.max(...ys)];
364
+ };
365
+ const intersect = (a, b) => a ? [Math.max(a[0], b[0]), Math.max(a[1], b[1]), Math.min(a[2], b[2]), Math.min(a[3], b[3])] : b;
366
+ const visible = (b) => !b || b[2] - b[0] >= SLIVER_PT && b[3] - b[1] >= SLIVER_PT;
367
+ const doc = await getDocumentProxy(new Uint8Array(pdfBytes));
368
+ const out = [];
369
+ try {
370
+ for (const i of pages) {
371
+ const ops = await (await doc.getPage(i)).getOperatorList();
372
+ let ctm = [1, 0, 0, 1, 0, 0];
373
+ let clip = null;
374
+ let fillShading = false;
375
+ let strokeShading = false;
376
+ let pendingClip = false;
377
+ const stack = [];
378
+ let found = false;
379
+ for (let j = 0;j < ops.fnArray.length && !found; j++) {
380
+ const fn = ops.fnArray[j];
381
+ const args = ops.argsArray[j];
382
+ if (fn === OPS.save)
383
+ stack.push([ctm, clip, fillShading, strokeShading]);
384
+ else if (fn === OPS.restore || fn === OPS.paintFormXObjectEnd) {
385
+ const saved = stack.pop();
386
+ if (saved)
387
+ [ctm, clip, fillShading, strokeShading] = saved;
388
+ } else if (fn === OPS.transform)
389
+ ctm = multiply(ctm, args);
390
+ else if (fn === OPS.paintFormXObjectBegin) {
391
+ stack.push([ctm, clip, fillShading, strokeShading]);
392
+ if (Array.isArray(args[0]))
393
+ ctm = multiply(ctm, args[0]);
394
+ if (Array.isArray(args[1]))
395
+ clip = intersect(clip, box(args[1], ctm));
396
+ } else if (fn === OPS.setFillColorN)
397
+ fillShading = args[0] === "Shading";
398
+ else if (fn === OPS.setStrokeColorN)
399
+ strokeShading = args[0] === "Shading";
400
+ else if (FILL_COLOR_OPS.has(fn))
401
+ fillShading = false;
402
+ else if (STROKE_COLOR_OPS.has(fn))
403
+ strokeShading = false;
404
+ else if (fn === OPS.clip || fn === OPS.eoClip)
405
+ pendingClip = true;
406
+ else if (fn === OPS.constructPath) {
407
+ const paintOp = args[0];
408
+ const bounds = args[2] ? box(args[2], ctm) : null;
409
+ if (fillShading && FILL_PAINT_OPS.has(paintOp) && bounds)
410
+ found = visible(intersect(clip, bounds));
411
+ if (strokeShading && STROKE_PAINT_OPS.has(paintOp))
412
+ found = true;
413
+ if (pendingClip) {
414
+ clip = bounds ? intersect(clip, bounds) : [0, 0, 0, 0];
415
+ pendingClip = false;
416
+ }
417
+ } else if (fn === OPS.shadingFill)
418
+ found = visible(clip);
419
+ else if (SHOW_TEXT_OPS.has(fn) && fillShading)
420
+ found = true;
421
+ }
422
+ if (found)
423
+ out.push(i);
424
+ }
425
+ } finally {
426
+ await doc.destroy();
427
+ }
428
+ return out;
429
+ }
351
430
  function getImagePixelSize(page, name, timeoutMs = 2000) {
352
431
  return new Promise((resolve) => {
353
432
  let done = false;
@@ -435,4 +514,4 @@ async function isLoadable(doc) {
435
514
  }
436
515
  }
437
516
 
438
- export { DOC_CACHE_MAX, loadPdf, retainPdfCache, clearPdfCache, pendingGraceDestroyCount, getPageSize, getOutlineCount, getPageLabels, countLinkAnnotations, getTextPass, getOpPass, unsplittableTextReasons, pageHasMarks, getImageResolutions, isLoadable };
517
+ export { DOC_CACHE_MAX, loadPdf, retainPdfCache, clearPdfCache, pendingGraceDestroyCount, getPageSize, getOutlineCount, getPageLabels, countLinkAnnotations, getTextPass, getOpPass, unsplittableTextReasons, pagesWithVisibleShadingPaints, pageHasMarks, getImageResolutions, isLoadable };