meadow-integration 1.0.40 → 1.0.42

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 (75) hide show
  1. package/BUILDING-AND-PUBLISHING.md +2 -2
  2. package/Dockerfile +1 -1
  3. package/README.md +27 -8
  4. package/docs/README.md +1 -1
  5. package/docs/_brand.json +18 -0
  6. package/docs/_cover.md +1 -1
  7. package/docs/_topbar.md +1 -1
  8. package/docs/_version.json +3 -3
  9. package/docs/architecture.md +14 -225
  10. package/docs/data-clone/configuration.md +9 -1
  11. package/docs/data-clone/diagrams/architecture-diagram.excalidraw +1756 -0
  12. package/docs/data-clone/diagrams/architecture-diagram.mmd +8 -0
  13. package/docs/data-clone/diagrams/architecture-diagram.svg +2 -0
  14. package/docs/data-clone/overview.md +2 -32
  15. package/docs/diagrams/configuration-cascade-2.excalidraw +831 -0
  16. package/docs/diagrams/configuration-cascade-2.mmd +8 -0
  17. package/docs/diagrams/configuration-cascade-2.svg +2 -0
  18. package/docs/diagrams/configuration-cascade.excalidraw +831 -0
  19. package/docs/diagrams/configuration-cascade.mmd +8 -0
  20. package/docs/diagrams/configuration-cascade.svg +2 -0
  21. package/docs/diagrams/data-synchronization-pipeline.excalidraw +3278 -0
  22. package/docs/diagrams/data-synchronization-pipeline.mmd +42 -0
  23. package/docs/diagrams/data-synchronization-pipeline.svg +2 -0
  24. package/docs/diagrams/data-transformation-pipeline.excalidraw +2929 -0
  25. package/docs/diagrams/data-transformation-pipeline.mmd +31 -0
  26. package/docs/diagrams/data-transformation-pipeline.svg +2 -0
  27. package/docs/diagrams/docker-deployment.excalidraw +1963 -0
  28. package/docs/diagrams/docker-deployment.mmd +23 -0
  29. package/docs/diagrams/docker-deployment.svg +2 -0
  30. package/docs/diagrams/high-level-system-architecture.excalidraw +5752 -0
  31. package/docs/diagrams/high-level-system-architecture.mmd +66 -0
  32. package/docs/diagrams/high-level-system-architecture.svg +2 -0
  33. package/docs/diagrams/module-structure.excalidraw +15206 -0
  34. package/docs/diagrams/module-structure.mmd +56 -0
  35. package/docs/diagrams/module-structure.svg +2 -0
  36. package/docs/diagrams/sync-mode-comparison.excalidraw +3660 -0
  37. package/docs/diagrams/sync-mode-comparison.mmd +33 -0
  38. package/docs/diagrams/sync-mode-comparison.svg +2 -0
  39. package/docs/implementation-reference.md +2 -58
  40. package/docs/index.html +6 -7
  41. package/docs/retold-catalog.json +388 -279
  42. package/docs/retold-keyword-index.json +24887 -16186
  43. package/example-applications/mapping-demo/README.md +2 -10
  44. package/example-applications/mapping-demo/diagrams/architecture.excalidraw +1866 -0
  45. package/example-applications/mapping-demo/diagrams/architecture.mmd +8 -0
  46. package/example-applications/mapping-demo/diagrams/architecture.svg +2 -0
  47. package/example-applications/mapping-demo/package.json +22 -1
  48. package/example-applications/mapping-demo/server.js +28 -0
  49. package/example-applications/mapping-demo/source/MappingDemoApp.js +42 -3
  50. package/example-applications/mapping-demo/source/MappingDemoBrand.js +17 -0
  51. package/example-applications/mapping-demo/web/favicons/apple-touch-icon.png +0 -0
  52. package/example-applications/mapping-demo/web/favicons/favicon-16.png +0 -0
  53. package/example-applications/mapping-demo/web/favicons/favicon-192.png +0 -0
  54. package/example-applications/mapping-demo/web/favicons/favicon-32.png +0 -0
  55. package/example-applications/mapping-demo/web/favicons/favicon-48.png +0 -0
  56. package/example-applications/mapping-demo/web/favicons/favicon-512.png +0 -0
  57. package/example-applications/mapping-demo/web/favicons/favicon-64.png +0 -0
  58. package/example-applications/mapping-demo/web/favicons/favicon-dark.svg +30 -0
  59. package/example-applications/mapping-demo/web/favicons/favicon-light.svg +30 -0
  60. package/example-applications/mapping-demo/web/favicons/favicon.svg +30 -0
  61. package/example-applications/mapping-demo/web/index.html +40 -26
  62. package/example-applications/mapping-demo/web/mapping-demo-editor.js +3267 -398
  63. package/example-applications/mapping-demo/web/mapping-demo-editor.js.map +1 -1
  64. package/example-applications/mapping-demo/web/mapping-demo-editor.min.js +34 -1
  65. package/example-applications/mapping-demo/web/mapping-demo-editor.min.js.map +1 -1
  66. package/example-applications/mapping-demo/web/pict.min.js +2 -2
  67. package/package.json +10 -7
  68. package/source/services/clone/Meadow-Service-DeleteCursorStore.js +105 -0
  69. package/source/services/clone/Meadow-Service-Sync-Entity-OngoingEventualConsistency.js +327 -92
  70. package/source/services/clone/Meadow-Service-Sync.js +2 -0
  71. package/source/views/PictView-MeadowMappingEditor.js +30 -30
  72. package/test/Meadow-Integration-BisectionSync_test.js +15 -5
  73. package/test/Meadow-Integration-NewStrategies_test.js +15 -5
  74. package/test/Meadow-Integration-OngoingEventualConsistencyDeleteCursor_test.js +228 -0
  75. package/test/Meadow-Integration-OngoingEventualConsistencyDeleteSync_test.js +311 -0
@@ -0,0 +1,8 @@
1
+ server.js
2
+ ├── SQLite (in-memory) ← meadow-connection-sqlite
3
+ ├── Meadow DAL (Book entity) ← meadow + inline schema
4
+ ├── meadow-endpoints (Book) ← auto-generates /1.0/Book(s) REST routes
5
+ ├── Demo pipeline endpoints ← /1.0/Demo/*
6
+ │ ├── TabularTransform ← parse + map = comprehension
7
+ │ └── IntegrationAdapter ← comprehension → upsert via REST
8
+ └── Static web UI ← web/index.html
@@ -0,0 +1,2 @@
1
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 773 293" width="773" height="293"><!-- svg-source:excalidraw --><metadata><!-- payload-type:application/vnd.excalidraw+json --><!-- payload-version:2 --><!-- payload-start -->eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO1dXXPbNlx1MDAxNn3Pr+BoX9JtZeObQGb2wU7sbXaTblx1MDAxYqfb/Zg+0Fx1MDAxMiyxpkiVouN4O33t887+xP6SXHUwMDA1aUmgKagkJMpBUtgzXHUwMDFlXHUwMDBiXHUwMDA0qUvwXHUwMDFj3otzL8Gfnlx1MDAwNMGguJvLwbNgIN+PoiRcdTAwMWXn0e3gi7L9ncxcdTAwMTdxlqpNqPq8yG7yUdVzWlx1MDAxNPNnx8dcdTAwMTCFR0D9wmc0JFx1MDAxMN7vJVx1MDAxMzmTabFQ/f6tPlx1MDAwN8FP1V+1JVx1MDAxZZf7Xlx1MDAxNcOrLFx1MDAxOVx1MDAwZovocshcdTAwMTGvdqo2r8zI5aiI0klcIvWm96pcdTAwMWTy9ce70iS2/nhcdTAwMWKPi2nZXHUwMDAzrJumMp5MXHUwMDBi1aZ3uj/ks0B3Wlx1MDAxNHl2LZ9nSZaX3/uH54JcdTAwMDF0rr/1Mlx1MDAxYV1P8uwmXHUwMDFk6z7np+fh2Znuc1x1MDAxNSfJRXFXXHUwMDFkWVxykFx1MDAxYb5B4/jfraw7Yo0t2/ZTXzmZpnJRXHUwMDBlITii6/ZsXHUwMDFljeLirjpTfVx1MDAxNqWF85fjary/13bl0Uy+LFx1MDAwNzy9SZL6odPx8tCr66KHXHUwMDFlL1t+1oZKWVx1MDAxZUNdp3VTXHUwMDAzXHUwMDE19bavsrTCXHUwMDA3gpBcdTAwMTJcdTAwMWGCUFtcdTAwMTkvXihgXHUwMDE01dGuomQh9SiXJp3VQKNP4mY+ju53gSFcdTAwMDeEXG5cdTAwMDApR3pAkji9bp5hko2uXHLfXHUwMDEyp2NZomhcdTAwMTCBwZPaOW5cdTAwMDHnZTa+21x1MDAwN51cdTAwMThuolNsolx1MDAxM0JcdTAwMGbPXuAprOCJMVxuhUDIQXTCXHUwMDE2dKZq3IZgXHUwMDEzloV8XzxEJFx0XHUwMDFm3i9ccoiEeFx1MDAxM5Ko5ztmkUfpYlx1MDAxZeVq/HaC5Vx1MDAwZaCEh4Lkg1xyS+yFdtiDWHBMuPrrXGb4KuiUIypzZezRXHUwMDBmi9p1ytLiXCL+T0VcdTAwMWHwoPU8msVJObD0wXFOknhSnv8gkVe1662OW8QquFhvLrK53jpSx4viVOabo5/l8SROo+Ttdlx1MDAxYqObXCJ7I1x1MDAxN/dWXHUwMDE2+Y2sj4H8cn2rPaqNjuZcdTAwMWJq4ZtMLofvhnCTcOXBXHUwMDFmXHUwMDEyXHUwMDBlPXRcdTAwMDF0k3CG+Fx1MDAwNGuj2unGT8LzXHUwMDEw7Um3aTSa3uRyu1x1MDAxZsCNLVx1MDAxZthcdTAwMGaYSIfFXHUwMDA2wVriXHUwMDExJkJBnYxHsFx1MDAxZdF5XHUwMDE211x1MDAwM+fyR/9cdTAwMTdoYFRcdTAwMWbW/3//RXtvTHX3J43dXHUwMDA2SbQonmezWVxcqJP7urRhY9iLKC9Olc1xOmluk+l4y5Zqr5M8z26nMtq4xmq/rdvmWXI3qa5pNWrtXHUwMDE0ne5EUaZv3WufqKOgNUc1ajxFLSiqjexA0Vx1MDAxMEKCMVx1MDAxNi4ylFx1MDAxY4ihXHUwMDFha43un1x1MDAxYUNcdTAwMTW45f2UinDUeUpFNVx1MDAxNip/aiCrvrB6SqW7tbNcdTAwMTWewnOE/ZRqc0qlLpRVWFx1MDAwYkumYerknIq2zfhLeFbTfiM8N91cYmtFplx1MDAwMZg2gV5cdTAwMDdcXH4oL/KYPkTNk2xASCCHQEDGXHUwMDFjxCA7kFx1MDAwZqH13rStN9i99yfsnipNxVx1MDAxMD9uairhQ02FbmrQXGLqLrtpKr1w/+PWVLAl71x1MDAwNUOIXHUwMDAz7o7vWUkqXHUwMDE337yKXHUwMDBiXHUwMDE5PI3T4UzOsvzuM4e1ld8ydj+RJWxxwKNZ0Y1/uHaNt3heRFxyKkstLHmkKdzHTkBiQ0A114OYXHUwMDEx7M7kbUXAX3/5bzBT/iG7XHUwMDFkKiakaqKhzFx1MDAxZS5+TFx1MDAxNNKNVKzN/z8gXHUwMDE1u5m9XHUwMDFmKXkn5bNTPNyQVfimW/TKZ18hMbXKxEKBMFx1MDAxMJxcdTAwMDN3fKNGoPDKZ1x1MDAxZsrnLlx1MDAxNIVA3+C99Nk7R61SglxmMaZ4SlxcnLaeeOmzL+mTku7VJFxy6VNcdTAwMTjI6qXPQ0mf6kLZ0Fc5WEJcdTAwMTTVXFyk72ln5dOIzlbl01x1MDAwMEyvfPbhQiixqyrhKFx1MDAxNJxwSFx1MDAxY1x1MDAwNOFzL306654q6dNcdTAwMTBAtkqfYrO6XHUwMDA1cS997lx1MDAxZjvaXHUwMDExn1x0gVx0dqmUcaW8vK7ki+DFyavg6WmWXVx1MDAwN+pb1di5LIC2m7yf4vKig1xm2omLTVx1MDAxOdTghlGtXHUwMDAy2cugO0/kQFx1MDAxZGWtXjjERFxiKqjLOmjweVx1MDAxMKclWoPFaCpn0Uehgm43ej9GnnXSQHGXyLgpsFx1MDAxOOqtvVxi2ld6XCKkdbS1ztBCXHUwMDEyQlx1MDAwMlx1MDAxYyq51lxiPD9QcPw700B3oij25Z9cdTAwMDekqFx1MDAxZckurlx1MDAxMzHBIXWRoX/2XHUwMDEyaG/Vn4zuKoFC5Ms/l62PUv7JrDysgEJcdTAwMTBcbrGL/P2ye/WnXHSerVx1MDAxYahcdJleXHUwMDA07WX6xex8XGJcdTAwMDCEc1xmqItcIuhLL4I666AqXHUwMDEx1Fx1MDAxMEG2iqDQsFxiXHUwMDAxXG5ccuT3Kqhl9GjJfFwiWEhcdTAwMTByKH5cXFx0L8sqLoXVe9rfK4suq6CtXHUwMDE27ye5/KWDXGLaiYtNXHUwMDEx1OSHMTcsuuBVUFsyhnWUtZORYshcdTAwMThyyFxy11XQXHUwMDEyvcOJVFRQR19cdTAwMDTH8FxiXHUwMDFjl1x1MDAwMH+6+Cx4c3bxNlDDoTY4Lotan8V+pP1rJ52UdImem1wijOFcdTAwMTlcbq+T9ibCWOUv1Fx1MDAxZFx1MDAxNTNOmTvJRI3AV14n7UMn3Ymioa9cdTAwMTU9IEW1L+9U6IPVL3XzOfnXXindUyldrYtHmGGJpy1CKWmwlfmF8e5bXHUwMDFmRye18rBcYlx1MDAxM1x1MDAxY1x1MDAxMuxkrehXndfF21x1MDAwN52hX1x1MDAxOO9R4WnlXShBXHUwMDEwcUFcXFxmXHUwMDAw/9ZlYTxDeNMu4jFDKaNcdTAwMTfx+tBccqzAh1x1MDAwMFxmXHUwMDA14MShR9VWusFcdTAwMGI5y4J5PJdVXHTSWlx1MDAxOXNYxGu1eD894OtcdTAwMGVcIl4nLm6IeMww10BexOuBjFbr+XBRanjCQUG9VL8quauE+PFcdTAwMWZcdTAwMWTX6YyW7se9b1q4l0dxMqSmNWLbZ/qGqn4vxvXFQGg1VYCQXHUwMDAzXG5cdTAwMTF2cs3KN16N21+NezfsVG5CPUfv21x1MDAxZoGjSNhxXHUwMDE0YFx1MDAwMiCiTqpxXHUwMDE3nqN9KOa7cFx1MDAxNFx1MDAwMV9ZfECO2inmXHUwMDAwsJBTXHUwMDEwupOO1lx1MDAxY33rXHUwMDE1875qizHvLkryRlx1MDAwNafwtcXL1sdcdTAwMTAlMbdysoKFmFwiN1x1MDAxZm3/tnNtsVx1MDAxMZ6bjkS0I9PXXHUwMDE297PCnaU4iVx1MDAxMUHEoSUmNVxi/+5Li531T1VWwlx1MDAxMEJuKqFcdTAwMTA00lx1MDAxMsKQx6096O3TXHUwMDEyu8aPdsyH5Vx1MDAwNI9cdTAwMTDqoFx1MDAxNPo2urxJovxtecGusnzmcD5iu6n7iaHfdUhEdKLfRlwiwuB5Uagx4Fx1MDAxM1x1MDAxMTvTz+7FXHUwMDAygnJcdTAwMDCdKpmoZ1wi1IVayODzYFx1MDAxNs2DP1x1MDAwNaNsNs/lVKbVWZnY6E5mopPl+5HzXHUwMDFmXTJcdTAwMTVsp0xcdTAwMDUyPHnjVdC+XmlnlytEXGZBXGK4Q6s/a1xi/tOLoH0kKlhcdTAwMTeKNkXQblx1MDAxNIU24aun6IqixM6LUkRDxSknS/v/9Vx1MDAxOFx1MDAxY4X80+bodDeOXHUwMDEyX9p/QI5avcVcdTAwMDRcdTAwMTJcdTAwMGVcdTAwMThcdTAwMGZDJ5OJ0YE4+jtMVHDc/Vx1MDAxNXiNRFx1MDAwNcJ+Iehl66O8Vlx1MDAxY9s52Vx1MDAxMFx0ijl26MFXTeDLzplcbiM+WzNcdTAwMTUmaPpMRVx1MDAxZm6EYys3XCLCci1y5JBeokE48plcbmdcdTAwMWRUlakwxJDtmYr6UrP+NXh9XHUwMDA2kHbMp4QhhDh2x/2slNKXaSEneVS+xOpkXHUwMDFjzVx1MDAwYpk7nKr4LWP300PHXHUwMDFkklx1MDAxNZ1cdTAwMTjYTFaYnC82XHUwMDA1hj5ZYctAq/fgIcBoWa1cdTAwMDLdy1x1MDAxNZaS/1x1MDAwM5E/+PWX/1x1MDAwNTfzhaJN8C6OqlVDXHUwMDFjT1lY2L9cdTAwMWZRZaflTsJd8lx1MDAxNoaHXHK9KNpXTVx1MDAwZrCbrymyXHUwMDEyTJx82vXKa6J9aKI7UTT0xdtcdTAwMDekqFVIy1x1MDAwNFx1MDAxMiys1124Q9GJl0R7q91cdTAwMTbdJdHGutCI+drtZeuj1G5cdTAwMGI7XHUwMDE3XHUwMDBiIIchXHUwMDA1TuY0pt2Lt034bF1cdTAwMTjaXHUwMDA0TS+J9uJFhF1mXHJAXHUwMDAxXHUwMDAwRE5mv2OviTrroSpN1Fx1MDAxMEO2rimDTItwUdMyXHUwMDE2Xlx1MDAxMrV8+M8uXHUwMDE5wlx1MDAwNFx1MDAwMy5VvazkmItcIiriUXArL4Nva0vDOyeGbrFzP3nlh1x1MDAwZTpoJ9Zt6KDGYNCUifA6qCXtrHRQ5XBcdTAwMTmBor7ihSvEK3VEhebjXG6NR9Niljguem4zdj9cbl4vKfhk6a1cdTAwMDfRfF5yXa6nXHUwMDAzXG5A8bhxL7pvK+RcXI9E1fQ6XHUwMDFiy7M0ukyaXHUwMDAzP3hcdTAwMTfL29O22dPymr2+SYr4QqFkVOZeqolJaV91myjJJJdNP/9cdTAwMWaog0qPIn0=<!-- payload-end --><pict-renderer-graph:source xmlns:pict-renderer-graph="https://fable-retold.github.io/pict-renderer-graph/ns/v1"><![CDATA[{"type":"filetree","mermaid":"server.js\n├── SQLite (in-memory) ← meadow-connection-sqlite\n├── Meadow DAL (Book entity) ← meadow + inline schema\n├── meadow-endpoints (Book) ← auto-generates /1.0/Book(s) REST routes\n├── Demo pipeline endpoints ← /1.0/Demo/*\n│ ├── TabularTransform ← parse + map = comprehension\n│ └── IntegrationAdapter ← comprehension → upsert via REST\n└── Static web UI ← web/index.html\n","style":"notebook"}]]></pict-renderer-graph:source></metadata><defs><style class="style-fonts">
2
+ @font-face { font-family: Excalifont; src: url(data:font/woff2;base64,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); }</style></defs><g stroke-linecap="round" transform="translate(10 15) rotate(0 5 4)"><path d="M2 0 C4.57 0.03, 6.11 0.12, 8 0 C8.17 1.32, 8.54 2.13, 10 2 C9.71 3.58, 10.15 4.86, 10 6 C9.58 8.04, 9.8 8.56, 8 8 C5.42 8.55, 4.17 8.56, 2 8 C-1.15 6.73, -0.44 8.76, 0 6 C-0.35 5.24, -0.15 4.17, 0 2 C-1.85 2.32, 0.44 -1.38, 2 0" stroke="none" stroke-width="0" fill="var(--diagram-paper, #FBF7EE)"/><path d="M2 0 C3.21 0, 4.54 0.07, 8 0 M2 0 C3.22 -0.02, 4.53 0.03, 8 0 M8 0 C9.29 0.04, 10.43 1.04, 10 2 M8 0 C9.64 -0.54, 10.26 0.86, 10 2 M10 2 C9.93 3.24, 10 4.37, 10 6 M10 2 C9.95 3.26, 9.98 4.58, 10 6 M10 6 C9.74 6.93, 9.03 8.41, 8 8 M10 6 C10.51 7.11, 9.27 8.38, 8 8 M8 8 C5.87 8.1, 3.42 7.86, 2 8 M8 8 C6.2 7.96, 4.46 7.97, 2 8 M2 8 C0.59 7.99, 0.12 7.05, 0 6 M2 8 C0.68 8.38, 0.26 7.13, 0 6 M0 6 C0.07 4.93, 0.1 3.8, 0 2 M0 6 C-0.01 4.96, 0.02 3.82, 0 2 M0 2 C-0.27 0.43, 1 -0.23, 2 0 M0 2 C-0.18 0.32, 0.63 -0.52, 2 0" stroke="var(--diagram-accent, #C9602F)" stroke-width="1.6" fill="none"/></g><g stroke-linecap="round" transform="translate(10 20) rotate(0 9.5 5.5)"><path d="M2.75 0 C8.66 -1.11, 12.7 -0.42, 16.25 0 C16.43 1.83, 19.89 2.35, 19 2.75 C18.84 3.98, 19.22 6.84, 19 8.25 C19.36 10.62, 17.75 12.48, 16.25 11 C12.92 10.86, 8.92 10.41, 2.75 11 C-0.54 10.21, 1.87 10.81, 0 8.25 C-0.3 7.16, 0.52 5.2, 0 2.75 C1.53 0.03, 2.37 0.44, 2.75 0" stroke="none" stroke-width="0" fill="var(--diagram-paper, #FBF7EE)"/><path d="M2.75 0 C5.28 -0.16, 8.07 0.05, 16.25 0 M2.75 0 C6.67 0.03, 10.51 0.01, 16.25 0 M16.25 0 C18.21 -0.32, 19.15 1.2, 19 2.75 M16.25 0 C17.86 0.17, 19.5 0.97, 19 2.75 M19 2.75 C19.12 4.57, 18.92 6.15, 19 8.25 M19 2.75 C18.97 4.48, 19.06 6.21, 19 8.25 M19 8.25 C19.39 9.78, 18.41 11.48, 16.25 11 M19 8.25 C18.51 10.45, 17.68 11.01, 16.25 11 M16.25 11 C11.08 10.84, 5.35 11, 2.75 11 M16.25 11 C12.12 10.86, 7.65 11.12, 2.75 11 M2.75 11 C0.87 11.42, -0.42 10.44, 0 8.25 M2.75 11 C0.81 10.81, 0.22 10.48, 0 8.25 M0 8.25 C-0.09 6.15, 0.09 4.3, 0 2.75 M0 8.25 C0 6.37, -0.01 4.44, 0 2.75 M0 2.75 C0.34 0.68, 1.36 -0.06, 2.75 0 M0 2.75 C0.24 0.63, 0.56 -0.53, 2.75 0" stroke="var(--diagram-accent, #C9602F)" stroke-width="1.6" fill="none"/></g><g transform="translate(39 10) rotate(0 56.5 14)"><text x="0" y="17.619999999999997" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="var(--diagram-accent, #C9602F)" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">server.js</text></g><g stroke-linecap="round"><g transform="translate(20 40) rotate(0 -0.09199490329848992 17.5)"><path d="M0 0 C-0.52 7.02, 0.13 14.61, 0 35 M0 0 C-0.04 7.93, -0.13 15.57, 0 35" stroke="var(--diagram-deemphasis, #8A7F72)" stroke-width="1.3" fill="none"/></g></g><mask/><g stroke-linecap="round"><g transform="translate(20 58) rotate(0 8 0.003770379375282573)"><path d="M0 0 C3.41 -0.22, 6.12 0.24, 16 0 M0 0 C4.52 0.18, 9.45 -0.07, 16 0" stroke="var(--diagram-deemphasis, #8A7F72)" stroke-width="1.3" fill="none"/></g></g><mask/><g stroke-linecap="round" transform="translate(42 48) rotate(0 7.5 9.5)"><path d="M3.75 0 C4.97 0.04, 6.66 -0.04, 11.25 0 C14.6 -1.2, 15.59 -1.35, 15 3.75 C15.23 4.84, 13.97 10.32, 15 15.25 C13.95 18.25, 15.3 17.19, 11.25 19 C8.6 19.74, 7.16 19.1, 3.75 19 C0.58 20.74, -2.09 20.31, 0 15.25 C0.38 12.47, 0.17 11.05, 0 3.75 C-0.98 0.18, 0.53 -2.17, 3.75 0" stroke="none" stroke-width="0" fill="var(--diagram-paper, #FBF7EE)"/><path d="M3.75 0 C5.12 -0.29, 6.76 -0.28, 11.25 0 M3.75 0 C5.92 -0.01, 8.45 -0.16, 11.25 0 M11.25 0 C14.09 0.54, 15.82 0.45, 15 3.75 M11.25 0 C14.49 0.71, 14.15 1.09, 15 3.75 M15 3.75 C14.65 6.11, 14.93 8.89, 15 15.25 M15 3.75 C14.83 7.96, 15.19 11.84, 15 15.25 M15 15.25 C15.48 17.5, 13.41 19.42, 11.25 19 M15 15.25 C13.85 17.94, 12.73 19.9, 11.25 19 M11.25 19 C8.87 18.83, 5.69 19.17, 3.75 19 M11.25 19 C9.51 19.15, 8.01 19.02, 3.75 19 M3.75 19 C1.52 18.72, 0.65 17.91, 0 15.25 M3.75 19 C1.98 18.21, -0.49 16.79, 0 15.25 M0 15.25 C-0.43 11.99, 0.44 10.06, 0 3.75 M0 15.25 C0.07 12.67, -0.16 10.14, 0 3.75 M0 3.75 C0.06 1.39, 0.33 -0.2, 3.75 0 M0 3.75 C-1.15 2.36, 0.6 -0.88, 3.75 0" stroke="var(--diagram-ink, #1B1F23)" stroke-width="1.6" fill="none"/></g><g stroke-linecap="round"><g transform="translate(52 48) rotate(0 2.5 2.5)"><path d="M0 0 C1.01 1.01, 2.02 2.02, 5 5 M0 0 C1.87 1.87, 3.73 3.73, 5 5 M5 5 C3.15 5, 1.31 5, 0 5 M5 5 C3.69 5, 2.39 5, 0 5 M0 5 C0 3.95, 0 2.89, 0 0 M0 5 C0 3.2, 0 1.41, 0 0" stroke="var(--diagram-ink, #1B1F23)" stroke-width="1.3" fill="none"/></g></g><mask/><g transform="translate(69 45) rotate(0 108.5 14)"><text x="0" y="17.619999999999997" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="var(--diagram-ink, #1B1F23)" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">SQLite (in-memory)</text></g><g transform="translate(374 48) rotate(0 125 11)"><text x="0" y="14.096" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="16px" fill="var(--diagram-deemphasis, #8A7F72)" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">← meadow-connection-sqlite</text></g><g stroke-linecap="round"><g transform="translate(20 75) rotate(0 0.02450433774991545 17.5)"><path d="M0 0 C-0.27 6.94, -0.03 13.83, 0 35 M0 0 C0.28 13.26, 0.18 26.3, 0 35" stroke="var(--diagram-deemphasis, #8A7F72)" stroke-width="1.3" fill="none"/></g></g><mask/><g stroke-linecap="round"><g transform="translate(20 93) rotate(0 8 0.029607386739996855)"><path d="M0 0 C3.53 -0.28, 6.71 0.42, 16 0 M0 0 C3.93 -0.19, 7.69 0.04, 16 0" stroke="var(--diagram-deemphasis, #8A7F72)" stroke-width="1.3" fill="none"/></g></g><mask/><g stroke-linecap="round" transform="translate(42 83) rotate(0 7.5 9.5)"><path d="M3.75 0 C5.63 0.55, 8.18 0.64, 11.25 0 C16.09 -0.6, 15.16 1.72, 15 3.75 C16.3 6.26, 15.67 11.2, 15 15.25 C15.13 20.04, 12.05 19.26, 11.25 19 C10.13 19.17, 7.17 18.53, 3.75 19 C-1.17 18.18, -0.53 19.82, 0 15.25 C-0.7 11.5, 0.26 8.12, 0 3.75 C-0.09 0.47, 2.29 1.11, 3.75 0" stroke="none" stroke-width="0" fill="var(--diagram-paper, #FBF7EE)"/><path d="M3.75 0 C5.23 -0.34, 6.56 -0.11, 11.25 0 M3.75 0 C5.74 0.02, 7.52 -0.06, 11.25 0 M11.25 0 C13.28 0, 14.82 2.16, 15 3.75 M11.25 0 C14.14 0.84, 16.1 0.72, 15 3.75 M15 3.75 C15.03 8.05, 15.06 12.8, 15 15.25 M15 3.75 C15.2 6.66, 14.83 9.45, 15 15.25 M15 15.25 C15.13 18.75, 13.38 18.66, 11.25 19 M15 15.25 C15.61 17.71, 13.71 19.03, 11.25 19 M11.25 19 C8.14 19.16, 5.17 19.01, 3.75 19 M11.25 19 C9.31 18.82, 7.03 18.96, 3.75 19 M3.75 19 C1.25 19.23, 0.85 17.32, 0 15.25 M3.75 19 C0.29 19.93, -0.52 17.67, 0 15.25 M0 15.25 C-0.3 10.91, 0.22 6.83, 0 3.75 M0 15.25 C0.14 12.2, 0.02 9.03, 0 3.75 M0 3.75 C0.44 1.28, 1.13 0.64, 3.75 0 M0 3.75 C-0.92 0.71, 1.85 0.51, 3.75 0" stroke="var(--diagram-ink, #1B1F23)" stroke-width="1.6" fill="none"/></g><g stroke-linecap="round"><g transform="translate(52 83) rotate(0 2.5 2.5)"><path d="M0 0 C1.01 1.01, 2.02 2.02, 5 5 M0 0 C1.62 1.62, 3.25 3.25, 5 5 M5 5 C3.56 5, 2.12 5, 0 5 M5 5 C3.85 5, 2.7 5, 0 5 M0 5 C0 3.65, 0 2.29, 0 0 M0 5 C0 3.7, 0 2.41, 0 0" stroke="var(--diagram-ink, #1B1F23)" stroke-width="1.3" fill="none"/></g></g><mask/><g transform="translate(69 80) rotate(0 143.5 14)"><text x="0" y="17.619999999999997" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="var(--diagram-ink, #1B1F23)" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Meadow DAL (Book entity)</text></g><g transform="translate(374 83) rotate(0 115.5 11)"><text x="0" y="14.096" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="16px" fill="var(--diagram-deemphasis, #8A7F72)" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">← meadow + inline schema</text></g><g stroke-linecap="round"><g transform="translate(20 110) rotate(0 0.08159443978504655 17.5)"><path d="M0 0 C0.44 7.42, 0.09 14.17, 0 35 M0 0 C-0.14 13.69, 0.06 27.81, 0 35" stroke="var(--diagram-deemphasis, #8A7F72)" stroke-width="1.3" fill="none"/></g></g><mask/><g stroke-linecap="round"><g transform="translate(20 128) rotate(0 8 -0.031452255759162995)"><path d="M0 0 C3.29 0.12, 6.81 -0.1, 16 0 M0 0 C4.47 -0.14, 8.46 -0.13, 16 0" stroke="var(--diagram-deemphasis, #8A7F72)" stroke-width="1.3" fill="none"/></g></g><mask/><g stroke-linecap="round" transform="translate(42 118) rotate(0 7.5 9.5)"><path d="M3.75 0 C5.03 1.05, 7.58 -0.7, 11.25 0 C14.54 -1.67, 12.94 -0.8, 15 3.75 C15.85 8.43, 15.47 10.84, 15 15.25 C13.17 16.61, 11.41 18.7, 11.25 19 C8.51 19.67, 5.11 18.71, 3.75 19 C3.39 21.08, 1.29 19.56, 0 15.25 C-0.56 12.31, -0.25 9.31, 0 3.75 C0.6 1.68, 1.65 1.09, 3.75 0" stroke="none" stroke-width="0" fill="var(--diagram-paper, #FBF7EE)"/><path d="M3.75 0 C5.01 0.03, 6.65 0.16, 11.25 0 M3.75 0 C5.68 0.07, 7.88 0.16, 11.25 0 M11.25 0 C14.12 -0.96, 15.35 1.62, 15 3.75 M11.25 0 C13.95 -0.61, 15.14 1.32, 15 3.75 M15 3.75 C14.55 7.22, 14.67 11.56, 15 15.25 M15 3.75 C14.99 7.24, 15.14 11.07, 15 15.25 M15 15.25 C15.42 18.09, 14.3 19.05, 11.25 19 M15 15.25 C15.56 18.56, 12.83 18.76, 11.25 19 M11.25 19 C9.38 19.14, 6.77 18.67, 3.75 19 M11.25 19 C8.61 19.22, 5.86 18.89, 3.75 19 M3.75 19 C0.56 18.16, -0.86 18.43, 0 15.25 M3.75 19 C1.37 19.51, 0.7 17.13, 0 15.25 M0 15.25 C0.29 11.36, -0.47 7.2, 0 3.75 M0 15.25 C-0.11 11.56, 0.03 7.37, 0 3.75 M0 3.75 C-0.65 1.42, 0.52 -0.08, 3.75 0 M0 3.75 C0.68 0.41, 2.34 -0.65, 3.75 0" stroke="var(--diagram-ink, #1B1F23)" stroke-width="1.6" fill="none"/></g><g stroke-linecap="round"><g transform="translate(52 118) rotate(0 2.5 2.5)"><path d="M0 0 C1.01 1.01, 2.02 2.02, 5 5 M0 0 C1.75 1.75, 3.49 3.49, 5 5 M5 5 C3.14 5, 1.28 5, 0 5 M5 5 C3.59 5, 2.19 5, 0 5 M0 5 C0 3.67, 0 2.35, 0 0 M0 5 C0 3.68, 0 2.36, 0 0" stroke="var(--diagram-ink, #1B1F23)" stroke-width="1.3" fill="none"/></g></g><mask/><g transform="translate(69 115) rotate(0 137.5 14)"><text x="0" y="17.619999999999997" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="var(--diagram-ink, #1B1F23)" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">meadow-endpoints (Book)</text></g><g transform="translate(374 118) rotate(0 194.5 11)"><text x="0" y="14.096" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="16px" fill="var(--diagram-deemphasis, #8A7F72)" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">← auto-generates /1.0/Book(s) REST routes</text></g><g stroke-linecap="round"><g transform="translate(20 145) rotate(0 -0.01239004878942751 17.5)"><path d="M0 0 C-0.21 6.72, -0.08 14.21, 0 35 M0 0 C-0.02 8.32, 0.21 16.82, 0 35" stroke="var(--diagram-deemphasis, #8A7F72)" stroke-width="1.3" fill="none"/></g></g><mask/><g stroke-linecap="round"><g transform="translate(20 163) rotate(0 8 0.06909254857049518)"><path d="M0 0 C2.84 0.35, 6.73 -0.06, 16 0 M0 0 C5.11 0.01, 9.77 0, 16 0" stroke="var(--diagram-deemphasis, #8A7F72)" stroke-width="1.3" fill="none"/></g></g><mask/><g stroke-linecap="round" transform="translate(40 155) rotate(0 5 4)"><path d="M2 0 C4.07 -0.38, 7.24 -0.04, 8 0 C8.22 0.27, 9.19 -0.86, 10 2 C9.96 2.87, 9.83 4.04, 10 6 C8.83 7.26, 7.26 7.38, 8 8 C6.46 8.6, 5.1 7.77, 2 8 C0.59 7.29, 2.09 8.13, 0 6 C-0.07 5.15, -0.24 3.38, 0 2 C0.37 1.12, 1.01 0.17, 2 0" stroke="none" stroke-width="0" fill="var(--diagram-paper, #FBF7EE)"/><path d="M2 0 C3.24 0.1, 4.34 0.08, 8 0 M2 0 C3.85 -0.07, 5.81 -0.04, 8 0 M8 0 C9.64 0.36, 9.57 0.32, 10 2 M8 0 C9.76 -0.43, 10.02 0.26, 10 2 M10 2 C10.05 3.07, 9.98 4, 10 6 M10 2 C9.95 3.5, 9.99 5, 10 6 M10 6 C9.97 7, 9.5 7.67, 8 8 M10 6 C9.52 7.08, 9.43 7.44, 8 8 M8 8 C6.62 7.99, 5.49 8.09, 2 8 M8 8 C6.35 8.01, 4.67 7.96, 2 8 M2 8 C0.18 8.44, 0.29 7.51, 0 6 M2 8 C0.16 7.7, 0.53 7.48, 0 6 M0 6 C-0.08 4.7, 0.09 3.29, 0 2 M0 6 C-0.02 4.61, 0 3.17, 0 2 M0 2 C-0.37 0.76, 0.74 0.09, 2 0 M0 2 C0.54 1.11, 0.52 -0.29, 2 0" stroke="var(--diagram-accent, #C9602F)" stroke-width="1.6" fill="none"/></g><g stroke-linecap="round" transform="translate(40 160) rotate(0 9.5 5.5)"><path d="M2.75 0 C4.83 0.53, 9.85 -1.08, 16.25 0 C16.48 0.78, 20.54 -0.63, 19 2.75 C19.19 5.25, 18.78 6.75, 19 8.25 C18.61 9.84, 19.41 11.3, 16.25 11 C12.43 10.97, 11.02 11.46, 2.75 11 C1.2 10.77, 0.2 10.17, 0 8.25 C0.08 5.88, 0.39 4.1, 0 2.75 C-0.45 -1.17, 2.93 1.99, 2.75 0" stroke="none" stroke-width="0" fill="var(--diagram-paper, #FBF7EE)"/><path d="M2.75 0 C5.34 0.08, 8.31 0.06, 16.25 0 M2.75 0 C8.08 -0.06, 13.39 -0.13, 16.25 0 M16.25 0 C18.57 -0.01, 19.29 0.47, 19 2.75 M16.25 0 C17.98 0.29, 19.26 0.37, 19 2.75 M19 2.75 C19.02 4.33, 18.89 5.65, 19 8.25 M19 2.75 C18.97 4.8, 18.94 6.79, 19 8.25 M19 8.25 C18.61 9.85, 17.87 10.74, 16.25 11 M19 8.25 C18.67 10.42, 17.84 11.22, 16.25 11 M16.25 11 C13.44 11.27, 10.01 10.84, 2.75 11 M16.25 11 C12.46 10.97, 8.45 11.11, 2.75 11 M2.75 11 C0.46 10.87, -0.25 9.89, 0 8.25 M2.75 11 C1.45 11.27, 0.49 9.68, 0 8.25 M0 8.25 C-0.02 6.92, 0.08 5.8, 0 2.75 M0 8.25 C0.01 6.99, -0.02 5.74, 0 2.75 M0 2.75 C0.24 1.01, 1.1 0.27, 2.75 0 M0 2.75 C-0.19 1.42, 0.45 -0.3, 2.75 0" stroke="var(--diagram-accent, #C9602F)" stroke-width="1.6" fill="none"/></g><g transform="translate(69 150) rotate(0 137.5 14)"><text x="0" y="17.619999999999997" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="var(--diagram-ink, #1B1F23)" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Demo pipeline endpoints</text></g><g transform="translate(374 153) rotate(0 64.5 11)"><text x="0" y="14.096" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="16px" fill="var(--diagram-deemphasis, #8A7F72)" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">← /1.0/Demo/*</text></g><g stroke-linecap="round"><g transform="translate(20 180) rotate(0 -0.04665529711100547 17.5)"><path d="M0 0 C-0.09 7.25, -0.31 13.74, 0 35 M0 0 C0.03 10.93, 0.13 22.47, 0 35" stroke="var(--diagram-deemphasis, #8A7F72)" stroke-width="1.3" fill="none"/></g></g><mask/><g stroke-linecap="round"><g transform="translate(50 180) rotate(0 0.006309311279384389 17.5)"><path d="M0 0 C-0.32 7.43, 0.35 13.92, 0 35 M0 0 C-0.02 9.97, 0.21 19.52, 0 35" stroke="var(--diagram-deemphasis, #8A7F72)" stroke-width="1.3" fill="none"/></g></g><mask/><g stroke-linecap="round"><g transform="translate(50 198) rotate(0 8 -0.06688298186955421)"><path d="M0 0 C3.51 0.06, 6.23 -0.34, 16 0 M0 0 C5.42 -0.19, 11.12 -0.1, 16 0" stroke="var(--diagram-deemphasis, #8A7F72)" stroke-width="1.3" fill="none"/></g></g><mask/><g stroke-linecap="round" transform="translate(72 188) rotate(0 7.5 9.5)"><path d="M3.75 0 C5.82 -0.74, 9.15 0.87, 11.25 0 C14.2 1.18, 15.3 1.95, 15 3.75 C13.86 6.83, 14.91 10.25, 15 15.25 C14.48 18.8, 12.76 21.08, 11.25 19 C8.65 19.93, 7.72 19.29, 3.75 19 C1.85 17.6, 2.59 15.85, 0 15.25 C-1.38 13.11, 1.51 9.83, 0 3.75 C-1.88 -1.22, 2.05 1.75, 3.75 0" stroke="none" stroke-width="0" fill="var(--diagram-paper, #FBF7EE)"/><path d="M3.75 0 C5.22 0.05, 6.87 0, 11.25 0 M3.75 0 C6.35 0.02, 9.16 -0.19, 11.25 0 M11.25 0 C14.26 -0.45, 14.99 1.46, 15 3.75 M11.25 0 C13.55 -0.31, 15.53 0.18, 15 3.75 M15 3.75 C15.53 6.98, 14.85 9.95, 15 15.25 M15 3.75 C14.91 6.52, 15.14 8.9, 15 15.25 M15 15.25 C15.12 17.03, 14.72 19.16, 11.25 19 M15 15.25 C14.9 17.04, 13.31 19.98, 11.25 19 M11.25 19 C8.22 19.2, 6.21 19.16, 3.75 19 M11.25 19 C9.72 18.9, 8.24 19.09, 3.75 19 M3.75 19 C1.75 19.38, -0.39 17, 0 15.25 M3.75 19 C0.62 19.11, -0.23 18.79, 0 15.25 M0 15.25 C0 10.52, 0.27 6.69, 0 3.75 M0 15.25 C0 12.31, 0.27 9.61, 0 3.75 M0 3.75 C-0.18 1.57, 1.46 0.5, 3.75 0 M0 3.75 C0.59 2.19, 1.8 0.52, 3.75 0" stroke="var(--diagram-ink, #1B1F23)" stroke-width="1.6" fill="none"/></g><g stroke-linecap="round"><g transform="translate(82 188) rotate(0 2.5 2.5)"><path d="M0 0 C1.01 1.01, 2.02 2.02, 5 5 M0 0 C1.15 1.15, 2.3 2.3, 5 5 M5 5 C3.07 5, 1.14 5, 0 5 M5 5 C3.09 5, 1.18 5, 0 5 M0 5 C0 3.32, 0 1.64, 0 0 M0 5 C0 3.07, 0 1.14, 0 0" stroke="var(--diagram-ink, #1B1F23)" stroke-width="1.3" fill="none"/></g></g><mask/><g transform="translate(99 185) rotate(0 97 14)"><text x="0" y="17.619999999999997" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="var(--diagram-ink, #1B1F23)" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">TabularTransform</text></g><g transform="translate(374 188) rotate(0 139 11)"><text x="0" y="14.096" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="16px" fill="var(--diagram-deemphasis, #8A7F72)" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">← parse + map = comprehension</text></g><g stroke-linecap="round"><g transform="translate(20 215) rotate(0 -0.08862710478580738 17.5)"><path d="M0 0 C-0.14 7.24, -0.36 14.32, 0 35 M0 0 C0.1 9, -0.26 18.14, 0 35" stroke="var(--diagram-deemphasis, #8A7F72)" stroke-width="1.3" fill="none"/></g></g><mask/><g stroke-linecap="round"><g transform="translate(50 215) rotate(0 -0.08020147874042038 9)"><path d="M0 0 C-0.47 3.93, 0.13 7.56, 0 18 M0 0 C0.09 3.82, -0.13 7.75, 0 18" stroke="var(--diagram-deemphasis, #8A7F72)" stroke-width="1.3" fill="none"/></g></g><mask/><g stroke-linecap="round"><g transform="translate(50 233) rotate(0 8 0.035100542484158836)"><path d="M0 0 C3.44 0.01, 6.19 0.02, 16 0 M0 0 C4.61 -0.04, 9.4 0.19, 16 0" stroke="var(--diagram-deemphasis, #8A7F72)" stroke-width="1.3" fill="none"/></g></g><mask/><g stroke-linecap="round" transform="translate(72 223) rotate(0 7.5 9.5)"><path d="M3.75 0 C5.83 0.53, 7.52 0.04, 11.25 0 C15.08 -1.01, 14.43 2.93, 15 3.75 C14.35 7.57, 16.58 10.64, 15 15.25 C13.13 17.79, 15.55 19.04, 11.25 19 C8.82 18.4, 8.08 19.07, 3.75 19 C0.79 19.79, 0.5 16.02, 0 15.25 C0.97 10.11, 1.22 5.24, 0 3.75 C-1.14 1.11, -1.13 2.11, 3.75 0" stroke="none" stroke-width="0" fill="var(--diagram-paper, #FBF7EE)"/><path d="M3.75 0 C5.14 0.01, 6.8 0.34, 11.25 0 M3.75 0 C6.03 0.09, 8.06 0, 11.25 0 M11.25 0 C13.06 -0.85, 15.62 1.25, 15 3.75 M11.25 0 C14.76 0.03, 15.15 0.49, 15 3.75 M15 3.75 C15.2 7.47, 15.13 12.53, 15 15.25 M15 3.75 C14.84 7.01, 15.29 10.06, 15 15.25 M15 15.25 C15.67 17.75, 14.12 18.38, 11.25 19 M15 15.25 C14.94 17.43, 13.2 19.08, 11.25 19 M11.25 19 C9.82 19.08, 7.53 19.26, 3.75 19 M11.25 19 C8.37 19.15, 5.77 19.08, 3.75 19 M3.75 19 C1.32 18.41, -0.11 18.25, 0 15.25 M3.75 19 C0.34 19.73, 0.24 17.54, 0 15.25 M0 15.25 C-0.49 12.61, -0.35 9.6, 0 3.75 M0 15.25 C-0.2 10.76, 0.26 6.39, 0 3.75 M0 3.75 C0.34 0.77, 0.82 0.92, 3.75 0 M0 3.75 C0.7 1.01, 0.9 -1.1, 3.75 0" stroke="var(--diagram-ink, #1B1F23)" stroke-width="1.6" fill="none"/></g><g stroke-linecap="round"><g transform="translate(82 223) rotate(0 2.5 2.5)"><path d="M0 0 C1.02 1.02, 2.04 2.04, 5 5 M0 0 C1.85 1.85, 3.71 3.71, 5 5 M5 5 C3.67 5, 2.34 5, 0 5 M5 5 C3.95 5, 2.9 5, 0 5 M0 5 C0 3.3, 0 1.6, 0 0 M0 5 C0 3.61, 0 2.23, 0 0" stroke="var(--diagram-ink, #1B1F23)" stroke-width="1.3" fill="none"/></g></g><mask/><g transform="translate(99 220) rotate(0 108.5 14)"><text x="0" y="17.619999999999997" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="var(--diagram-ink, #1B1F23)" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">IntegrationAdapter</text></g><g transform="translate(374 223) rotate(0 157.5 11)"><text x="0" y="14.096" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="16px" fill="var(--diagram-deemphasis, #8A7F72)" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">← comprehension → upsert via REST</text></g><g stroke-linecap="round"><g transform="translate(20 250) rotate(0 0.10549628565599356 9)"><path d="M0 0 C0.22 3.87, 0.34 7.54, 0 18 M0 0 C0.04 6.04, 0 12.18, 0 18" stroke="var(--diagram-deemphasis, #8A7F72)" stroke-width="1.3" fill="none"/></g></g><mask/><g stroke-linecap="round"><g transform="translate(20 268) rotate(0 8 0.028939482574884323)"><path d="M0 0 C3.17 0.04, 6.27 0.11, 16 0 M0 0 C3.31 -0.05, 7.02 0.17, 16 0" stroke="var(--diagram-deemphasis, #8A7F72)" stroke-width="1.3" fill="none"/></g></g><mask/><g stroke-linecap="round" transform="translate(42 258) rotate(0 7.5 9.5)"><path d="M3.75 0 C5.47 0.71, 8.12 0.41, 11.25 0 C12.1 -1.55, 13.8 1.57, 15 3.75 C14.66 6.23, 14.73 13.05, 15 15.25 C15.65 16.29, 11.22 19.09, 11.25 19 C10.07 18.11, 7.53 19.41, 3.75 19 C2.01 19.5, 0.51 15.76, 0 15.25 C-0.44 11.69, 1.03 8.15, 0 3.75 C1.59 2.61, 0.95 -2.38, 3.75 0" stroke="none" stroke-width="0" fill="var(--diagram-paper, #FBF7EE)"/><path d="M3.75 0 C4.9 -0.05, 6.9 0.35, 11.25 0 M3.75 0 C5.39 0.15, 6.98 0.06, 11.25 0 M11.25 0 C14.47 0.72, 14.27 1.22, 15 3.75 M11.25 0 C14.75 0.76, 14.42 1.37, 15 3.75 M15 3.75 C15.11 6.81, 15.22 9.83, 15 15.25 M15 3.75 C15.14 6.86, 15.08 10.3, 15 15.25 M15 15.25 C14.69 17.43, 13.63 18.83, 11.25 19 M15 15.25 C13.97 17.41, 14.32 17.94, 11.25 19 M11.25 19 C8.43 18.72, 6.46 18.72, 3.75 19 M11.25 19 C9.72 19.14, 8.24 19.01, 3.75 19 M3.75 19 C0.43 19.66, 0.55 18.17, 0 15.25 M3.75 19 C0.1 19, -1.07 17.06, 0 15.25 M0 15.25 C-0.11 12.52, 0.09 9.65, 0 3.75 M0 15.25 C0.16 11.44, 0.03 6.9, 0 3.75 M0 3.75 C0.44 1.55, 2.15 0.66, 3.75 0 M0 3.75 C-0.83 1.26, 0.99 0.35, 3.75 0" stroke="var(--diagram-ink, #1B1F23)" stroke-width="1.6" fill="none"/></g><g stroke-linecap="round"><g transform="translate(52 258) rotate(0 2.5 2.5)"><path d="M0 0 C1.01 1.01, 2.02 2.02, 5 5 M0 0 C1.47 1.47, 2.94 2.94, 5 5 M5 5 C3.96 5, 2.93 5, 0 5 M5 5 C3.57 5, 2.14 5, 0 5 M0 5 C0 3.63, 0 2.25, 0 0 M0 5 C0 3.61, 0 2.23, 0 0" stroke="var(--diagram-ink, #1B1F23)" stroke-width="1.3" fill="none"/></g></g><mask/><g transform="translate(69 255) rotate(0 79.5 14)"><text x="0" y="17.619999999999997" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="var(--diagram-ink, #1B1F23)" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Static web UI</text></g><g transform="translate(374 258) rotate(0 78.5 11)"><text x="0" y="14.096" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="16px" fill="var(--diagram-deemphasis, #8A7F72)" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">← web/index.html</text></g></svg>
@@ -5,10 +5,31 @@
5
5
  "main": "server.js",
6
6
  "scripts": {
7
7
  "start": "node server.js",
8
+ "brand": "node ../../node_modules/pict-section-theme/bin/pict-section-theme-brand.js --palette forest --display-name \"Mapping Demo\" --tagline \"Meadow-Integration mapping editor showcase\" --favicons web/favicons",
9
+ "prebuild": "npm run brand",
8
10
  "build": "node generate-build-config.js && ../../node_modules/.bin/quack build",
9
11
  "demo": "npm run build && node server.js"
10
12
  },
11
13
  "author": "steven velozo <steven@velozo.com>",
12
14
  "license": "MIT",
13
- "dependencies": {}
15
+ "retold": {
16
+ "brand": {
17
+ "Hash": "mapping-demo",
18
+ "Name": "Mapping Demo",
19
+ "Tagline": "Meadow-Integration mapping editor showcase",
20
+ "Palette": "forest",
21
+ "Icon": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 96 96\" width=\"96\" height=\"96\">\n\t\t<defs>\n\t\t\t<clipPath id=\"frame-mapping-demo-filled-light\">\n\t\t\t\t<path d=\"M 24 2\n\t\tH 72\n\t\tQ 94 2 94 24\n\t\tV 72\n\t\tQ 94 94 72 94\n\t\tH 24\n\t\tQ 2 94 2 72\n\t\tV 24\n\t\tQ 2 2 24 2 Z\"/>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<path d=\"M 24 2\n\t\tH 72\n\t\tQ 94 2 94 24\n\t\tV 72\n\t\tQ 94 94 72 94\n\t\tH 24\n\t\tQ 2 94 2 72\n\t\tV 24\n\t\tQ 2 2 24 2 Z\" fill=\"#55af3b\"/>\n\t\t<g clip-path=\"url(#frame-mapping-demo-filled-light)\"><circle cx=\"37.5\" cy=\"48\" r=\"30\" fill=\"#ddc536\" opacity=\"0.85\"/>\n\t\t\t\t\t<circle cx=\"58.5\" cy=\"48\" r=\"30\" fill=\"rgba(255,255,255,0.32)\" opacity=\"0.95\"/></g>\n\t\t<text x=\"48\" y=\"50\" text-anchor=\"middle\" dominant-baseline=\"central\"\n\t\t\tfont-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\"\n\t\t\tfont-size=\"38\" font-weight=\"600\"\n\t\t\tfill=\"#ffffff\" letter-spacing=\"-1\">MD</text>\n\t</svg>",
22
+ "IconType": "svg",
23
+ "Favicon": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 96 96\" width=\"96\" height=\"96\">\n\t\t<defs>\n\t\t\t<clipPath id=\"fav-mapping-demo-light\">\n\t\t\t\t<path d=\"M 24 2\n\t\tH 72\n\t\tQ 94 2 94 24\n\t\tV 72\n\t\tQ 94 94 72 94\n\t\tH 24\n\t\tQ 2 94 2 72\n\t\tV 24\n\t\tQ 2 2 24 2 Z\"/>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<path d=\"M 24 2\n\t\tH 72\n\t\tQ 94 2 94 24\n\t\tV 72\n\t\tQ 94 94 72 94\n\t\tH 24\n\t\tQ 2 94 2 72\n\t\tV 24\n\t\tQ 2 2 24 2 Z\" fill=\"#55af3b\"/>\n\t\t<g clip-path=\"url(#fav-mapping-demo-light)\"><circle cx=\"37.5\" cy=\"48\" r=\"34\" fill=\"#ddc536\"/>\n\t\t\t\t\t<circle cx=\"58.5\" cy=\"48\" r=\"34\" fill=\"rgba(255,255,255,0.22)\"/></g>\n\t\t<text x=\"48\" y=\"50\" text-anchor=\"middle\" dominant-baseline=\"central\"\n\t\t\tfont-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\"\n\t\t\tfont-size=\"60\" font-weight=\"800\"\n\t\t\tfill=\"#ffffff\" letter-spacing=\"-1\">M</text>\n\t</svg>",
24
+ "FaviconDark": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 96 96\" width=\"96\" height=\"96\">\n\t\t<defs>\n\t\t\t<clipPath id=\"fav-mapping-demo-dark\">\n\t\t\t\t<path d=\"M 24 2\n\t\tH 72\n\t\tQ 94 2 94 24\n\t\tV 72\n\t\tQ 94 94 72 94\n\t\tH 24\n\t\tQ 2 94 2 72\n\t\tV 24\n\t\tQ 2 2 24 2 Z\"/>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<path d=\"M 24 2\n\t\tH 72\n\t\tQ 94 2 94 24\n\t\tV 72\n\t\tQ 94 94 72 94\n\t\tH 24\n\t\tQ 2 94 2 72\n\t\tV 24\n\t\tQ 2 2 24 2 Z\" fill=\"#8dcb7b\"/>\n\t\t<g clip-path=\"url(#fav-mapping-demo-dark)\"><circle cx=\"37.5\" cy=\"48\" r=\"34\" fill=\"#e6d989\"/>\n\t\t\t\t\t<circle cx=\"58.5\" cy=\"48\" r=\"34\" fill=\"rgba(255,255,255,0.22)\"/></g>\n\t\t<text x=\"48\" y=\"50\" text-anchor=\"middle\" dominant-baseline=\"central\"\n\t\t\tfont-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\"\n\t\t\tfont-size=\"60\" font-weight=\"800\"\n\t\t\tfill=\"#101418\" letter-spacing=\"-1\">M</text>\n\t</svg>",
25
+ "Colors": {
26
+ "Primary": "#55af3b",
27
+ "Secondary": "#ddc536",
28
+ "PrimaryLight": "#55af3b",
29
+ "PrimaryDark": "#8dcb7b",
30
+ "SecondaryLight": "#ddc536",
31
+ "SecondaryDark": "#e6d989"
32
+ }
33
+ }
34
+ }
14
35
  }
@@ -317,6 +317,34 @@ function registerStaticRoutes(pOrator)
317
317
  pResponse.end(tmpContent);
318
318
  return fNext();
319
319
  });
320
+
321
+ // ── Favicons (generated by `npm run brand` into web/favicons/) ──
322
+ let tmpFaviconDir = libPath.join(WEB_DIR, 'favicons');
323
+ let fServeFavicon = (pFileName, pContentType) =>
324
+ {
325
+ return function(pRequest, pResponse, fNext)
326
+ {
327
+ let tmpFile = libPath.join(tmpFaviconDir, pFileName);
328
+ if (!libFS.existsSync(tmpFile))
329
+ {
330
+ pResponse.send(404, { Success: false, Error: 'Favicon not found: ' + pFileName });
331
+ return fNext();
332
+ }
333
+ let tmpIsBinary = !/\.svg$/i.test(pFileName);
334
+ let tmpContent = libFS.readFileSync(tmpFile, tmpIsBinary ? null : 'utf8');
335
+ pResponse.setHeader('Content-Type', pContentType);
336
+ pResponse.end(tmpContent);
337
+ return fNext();
338
+ };
339
+ };
340
+ pOrator.serviceServer.get('/favicons/favicon.svg', fServeFavicon('favicon.svg', 'image/svg+xml'));
341
+ pOrator.serviceServer.get('/favicons/favicon-light.svg', fServeFavicon('favicon-light.svg', 'image/svg+xml'));
342
+ pOrator.serviceServer.get('/favicons/favicon-dark.svg', fServeFavicon('favicon-dark.svg', 'image/svg+xml'));
343
+ pOrator.serviceServer.get('/favicons/favicon-16.png', fServeFavicon('favicon-16.png', 'image/png'));
344
+ pOrator.serviceServer.get('/favicons/favicon-32.png', fServeFavicon('favicon-32.png', 'image/png'));
345
+ pOrator.serviceServer.get('/favicons/favicon-192.png', fServeFavicon('favicon-192.png', 'image/png'));
346
+ pOrator.serviceServer.get('/favicons/favicon-512.png', fServeFavicon('favicon-512.png', 'image/png'));
347
+ pOrator.serviceServer.get('/favicons/apple-touch-icon.png', fServeFavicon('apple-touch-icon.png', 'image/png'));
320
348
  }
321
349
 
322
350
  // ── Route: GET /1.0/Demo/SourceSchema ────────────────────────────────────────
@@ -1,16 +1,25 @@
1
1
  'use strict';
2
2
 
3
3
  const libPictApplication = require('pict-application');
4
+
5
+ const libPictSectionModal = require('pict-section-modal');
6
+ const libPictSectionTheme = require('pict-section-theme');
7
+
8
+ const libMappingDemoBrand = require('./MappingDemoBrand.js');
4
9
  const libMappingDemoEditorView = require('./views/MappingDemoEditorView.js');
5
10
 
6
11
  /**
7
12
  * MappingDemoApplication
8
13
  *
9
- * Minimal pict application that hosts the MappingDemoEditorView.
14
+ * Pict application that hosts the MappingDemoEditorView and brings up
15
+ * the unified pict-section-theme stack so visitors can flip themes and
16
+ * watch the embedded MeadowMappingEditor library view reskin live.
17
+ *
10
18
  * Loaded client-side by Pict.safeLoadPictApplication(MappingDemoApplication, 2).
11
19
  *
12
- * After initialization it exposes window.openMappingEditor() so the static
13
- * HTML pipeline UI can activate the visual editor from a plain onclick handler.
20
+ * After initialization it exposes window.openMappingEditor() so the
21
+ * static HTML pipeline UI can activate the visual editor from a plain
22
+ * onclick handler.
14
23
  */
15
24
  class MappingDemoApplication extends libPictApplication
16
25
  {
@@ -18,14 +27,44 @@ class MappingDemoApplication extends libPictApplication
18
27
  {
19
28
  super(pFable, pOptions, pServiceHash);
20
29
 
30
+ // Modal system (confirm dialogs the editor may pop)
31
+ this.pict.addView('Pict-Section-Modal', libPictSectionModal.default_configuration, libPictSectionModal);
32
+
21
33
  this.pict.addView(
22
34
  'MappingDemoEditor',
23
35
  libMappingDemoEditorView.default_configuration,
24
36
  libMappingDemoEditorView);
37
+
38
+ // Unified theme stack — the demo's whole point is to prove the
39
+ // library view picks up theme tokens, so the picker is exposed
40
+ // inline in the page header (not behind a gear toggle). Just
41
+ // register the runtime here; mount the controls in onAfterInitializeAsync
42
+ // once the destination div exists in the DOM.
43
+ this.pict.addProvider('Theme-Section',
44
+ {
45
+ ApplyDefault: 'pict-default',
46
+ DefaultMode: 'system',
47
+ DefaultScale: 1.0,
48
+ Brand: libMappingDemoBrand,
49
+ Views: ['Picker', 'ModeToggle', 'ScaleSelect', 'BrandMark']
50
+ }, libPictSectionTheme);
25
51
  }
26
52
 
27
53
  onAfterInitializeAsync(fCallback)
28
54
  {
55
+ // Mount the theme controls directly into the header strip so users
56
+ // can switch themes and watch every surface (the static HTML
57
+ // pipeline UI + the embedded library editor) reskin in lockstep.
58
+ let tmpThemeProvider = this.pict.providers['Theme-Section'];
59
+ if (tmpThemeProvider && typeof tmpThemeProvider.mount === 'function')
60
+ {
61
+ tmpThemeProvider.mount(
62
+ {
63
+ Container: '#MappingDemo-Theme-Controls',
64
+ Views: ['Picker', 'ModeToggle', 'ScaleSelect']
65
+ });
66
+ }
67
+
29
68
  // Expose a global hook so the outer HTML can open the editor
30
69
  window.openMappingEditor = () =>
31
70
  {
@@ -0,0 +1,17 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Brand wrapper for the mapping-demo Pict app. Reads the retold.brand
5
+ * block populated by `npm run brand` (which invokes
6
+ * pict-section-theme/bin/pict-section-theme-brand.js with the forest
7
+ * palette) and exposes it for the Theme-Section provider's BrandMark.
8
+ */
9
+ const tmpPackage = require('../package.json');
10
+
11
+ if (!tmpPackage.retold || !tmpPackage.retold.brand)
12
+ {
13
+ throw new Error('mapping-demo: package.json is missing retold.brand — '
14
+ + 'run `npm run brand` (chained from prebuild) before building');
15
+ }
16
+
17
+ module.exports = tmpPackage.retold.brand;
@@ -0,0 +1,30 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96" width="96" height="96">
2
+ <defs>
3
+ <clipPath id="fav-mapping-demo-dark">
4
+ <path d="M 24 2
5
+ H 72
6
+ Q 94 2 94 24
7
+ V 72
8
+ Q 94 94 72 94
9
+ H 24
10
+ Q 2 94 2 72
11
+ V 24
12
+ Q 2 2 24 2 Z"/>
13
+ </clipPath>
14
+ </defs>
15
+ <path d="M 24 2
16
+ H 72
17
+ Q 94 2 94 24
18
+ V 72
19
+ Q 94 94 72 94
20
+ H 24
21
+ Q 2 94 2 72
22
+ V 24
23
+ Q 2 2 24 2 Z" fill="#8dcb7b"/>
24
+ <g clip-path="url(#fav-mapping-demo-dark)"><circle cx="37.5" cy="48" r="34" fill="#e6d989"/>
25
+ <circle cx="58.5" cy="48" r="34" fill="rgba(255,255,255,0.22)"/></g>
26
+ <text x="48" y="50" text-anchor="middle" dominant-baseline="central"
27
+ font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif"
28
+ font-size="60" font-weight="800"
29
+ fill="#101418" letter-spacing="-1">M</text>
30
+ </svg>
@@ -0,0 +1,30 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96" width="96" height="96">
2
+ <defs>
3
+ <clipPath id="fav-mapping-demo-light">
4
+ <path d="M 24 2
5
+ H 72
6
+ Q 94 2 94 24
7
+ V 72
8
+ Q 94 94 72 94
9
+ H 24
10
+ Q 2 94 2 72
11
+ V 24
12
+ Q 2 2 24 2 Z"/>
13
+ </clipPath>
14
+ </defs>
15
+ <path d="M 24 2
16
+ H 72
17
+ Q 94 2 94 24
18
+ V 72
19
+ Q 94 94 72 94
20
+ H 24
21
+ Q 2 94 2 72
22
+ V 24
23
+ Q 2 2 24 2 Z" fill="#55af3b"/>
24
+ <g clip-path="url(#fav-mapping-demo-light)"><circle cx="37.5" cy="48" r="34" fill="#ddc536"/>
25
+ <circle cx="58.5" cy="48" r="34" fill="rgba(255,255,255,0.22)"/></g>
26
+ <text x="48" y="50" text-anchor="middle" dominant-baseline="central"
27
+ font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif"
28
+ font-size="60" font-weight="800"
29
+ fill="#ffffff" letter-spacing="-1">M</text>
30
+ </svg>
@@ -0,0 +1,30 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96" width="96" height="96">
2
+ <defs>
3
+ <clipPath id="fav-mapping-demo-light">
4
+ <path d="M 24 2
5
+ H 72
6
+ Q 94 2 94 24
7
+ V 72
8
+ Q 94 94 72 94
9
+ H 24
10
+ Q 2 94 2 72
11
+ V 24
12
+ Q 2 2 24 2 Z"/>
13
+ </clipPath>
14
+ </defs>
15
+ <path d="M 24 2
16
+ H 72
17
+ Q 94 2 94 24
18
+ V 72
19
+ Q 94 94 72 94
20
+ H 24
21
+ Q 2 94 2 72
22
+ V 24
23
+ Q 2 2 24 2 Z" fill="#55af3b"/>
24
+ <g clip-path="url(#fav-mapping-demo-light)"><circle cx="37.5" cy="48" r="34" fill="#ddc536"/>
25
+ <circle cx="58.5" cy="48" r="34" fill="rgba(255,255,255,0.22)"/></g>
26
+ <text x="48" y="50" text-anchor="middle" dominant-baseline="central"
27
+ font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif"
28
+ font-size="60" font-weight="800"
29
+ fill="#ffffff" letter-spacing="-1">M</text>
30
+ </svg>
@@ -4,23 +4,35 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Meadow-Integration Pipeline Demo</title>
7
+ <!-- Favicons (generated by `npm run brand`) -->
8
+ <link rel="icon" type="image/svg+xml" href="favicons/favicon.svg">
9
+ <link rel="icon" type="image/svg+xml" href="favicons/favicon-light.svg" media="(prefers-color-scheme: light)">
10
+ <link rel="icon" type="image/svg+xml" href="favicons/favicon-dark.svg" media="(prefers-color-scheme: dark)">
7
11
  <style id="PICT-CSS"></style>
8
12
  <style>
13
+ /* :root bridge — alias the demo's local vocabulary onto the
14
+ --theme-color-* tokens driven by pict-section-theme so every
15
+ surface (this static HTML + the embedded MeadowMappingEditor
16
+ library view) reskins together when the user picks a theme.
17
+ Hex fallbacks preserve the original look when no provider is
18
+ mounted (e.g. when the bundle is served as a plain demo). */
9
19
  :root {
10
- --brand: #18a5a0;
11
- --brand-dark: #127b77;
12
- --bg: #f5efe4;
13
- --bg-surface: #fdf8f0;
14
- --bg-card: #ffffff;
15
- --text: #3a3020;
16
- --text-mid: #6b5c45;
17
- --text-dim: #a09070;
18
- --border: #d6c8ae;
19
- --border-sub: #ece3d0;
20
- --success: #2ecc71;
21
- --error: #e74c3c;
22
- --warn: #f39c12;
23
- --step-1: #18a5a0;
20
+ --brand: var(--theme-color-brand-primary, #18a5a0);
21
+ --brand-dark: var(--theme-color-brand-primary-hover, #127b77);
22
+ --bg: var(--theme-color-background-primary, #f5efe4);
23
+ --bg-surface: var(--theme-color-background-secondary, #fdf8f0);
24
+ --bg-card: var(--theme-color-background-panel, #ffffff);
25
+ --text: var(--theme-color-text-primary, #3a3020);
26
+ --text-mid: var(--theme-color-text-secondary, #6b5c45);
27
+ --text-dim: var(--theme-color-text-muted, #a09070);
28
+ --border: var(--theme-color-border-default, #d6c8ae);
29
+ --border-sub: var(--theme-color-border-light, #ece3d0);
30
+ --success: var(--theme-color-status-success, #2ecc71);
31
+ --error: var(--theme-color-status-error, #e74c3c);
32
+ --warn: var(--theme-color-status-warning, #f39c12);
33
+ /* Step colors stay distinct hex literals — they encode pipeline
34
+ stage identity, not theme palette. */
35
+ --step-1: var(--theme-color-brand-primary, #18a5a0);
24
36
  --step-2: #3498db;
25
37
  --step-3: #c0392b;
26
38
  --step-4: #9b59b6;
@@ -35,18 +47,19 @@
35
47
  .meadow-mapping-editor.active {
36
48
  display: block;
37
49
  }
38
- /* Override facto-specific CSS vars with demo theme equivalents */
39
- .meadow-mapping-editor,
40
- .meadow-flow-container,
41
- .meadow-mapping-btn,
42
- .meadow-mapping-json-editor {
43
- --facto-brand: var(--brand);
44
- --facto-border: var(--border);
45
- --facto-border-subtle: var(--border-sub);
46
- --facto-bg-surface: var(--bg-surface);
47
- --facto-bg-input: var(--bg-card);
48
- --facto-text: var(--text);
49
- --facto-text-tertiary: var(--text-dim);
50
+
51
+ /* ── Inline theme-controls strip in the header ── */
52
+ #MappingDemo-Theme-Controls {
53
+ display: flex;
54
+ align-items: center;
55
+ gap: 8px;
56
+ flex-wrap: wrap;
57
+ }
58
+ #MappingDemo-Theme-Controls .pict-theme-mount,
59
+ #MappingDemo-Theme-Controls .pict-theme-mount-row {
60
+ display: flex;
61
+ align-items: center;
62
+ gap: 8px;
50
63
  }
51
64
 
52
65
  * { box-sizing: border-box; margin: 0; padding: 0; }
@@ -323,6 +336,7 @@
323
336
  <h1>Meadow-Integration Pipeline Demo</h1>
324
337
  <span class="subtitle">meadow-integration &rsaquo; example-applications/mapping-demo</span>
325
338
  </div>
339
+ <div id="MappingDemo-Theme-Controls" title="Switch themes to see the embedded library view reskin"></div>
326
340
  <span class="demo-badge">LIVE</span>
327
341
  </header>
328
342