retold-data-service 2.1.5 → 2.1.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/.github/workflows/publish-image.yml +2 -2
- package/BUILDING-AND-PUBLISHING.md +4 -4
- package/CONTRIBUTING.md +1 -1
- package/package.json +10 -10
- package/source/services/comprehension-loader/web/comprehension-loader.js +121 -19
- package/source/services/comprehension-loader/web/comprehension-loader.js.map +1 -1
- package/source/services/comprehension-loader/web/comprehension-loader.min.js +3 -3
- package/source/services/comprehension-loader/web/comprehension-loader.min.js.map +1 -1
- package/source/services/data-cloner/DataCloner-Command-Headless.js +100 -3
- package/source/services/data-cloner/DataCloner-Command-Schema.js +105 -8
- package/source/services/data-cloner/DataCloner-Command-Sync.js +1 -0
- package/source/services/data-cloner/web/data-cloner.js +121 -19
- package/source/services/data-cloner/web/data-cloner.js.map +1 -1
- package/source/services/data-cloner/web/data-cloner.min.js +3 -3
- package/source/services/data-cloner/web/data-cloner.min.js.map +1 -1
- package/tools/smoke-converge-endpoint.js +190 -0
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
# version tag push (e.g. `v1.2.3`). Generated by `quack docker-init`.
|
|
3
3
|
#
|
|
4
4
|
# Image lands at:
|
|
5
|
-
# ghcr.io/
|
|
6
|
-
# ghcr.io/
|
|
5
|
+
# ghcr.io/fable-retold/retold-data-service:<version>
|
|
6
|
+
# ghcr.io/fable-retold/retold-data-service:latest (only on stable tags)
|
|
7
7
|
|
|
8
8
|
name: Publish container image
|
|
9
9
|
|
|
@@ -110,7 +110,7 @@ BUILD_DOCKER=1 npm publish (or: npm run publish:docker)
|
|
|
110
110
|
→ postpublish: BUILD_DOCKER=1 → tag + push ← image trigger
|
|
111
111
|
→ .github/workflows/publish-image.yml fires
|
|
112
112
|
→ docker buildx build linux/amd64,linux/arm64
|
|
113
|
-
→ docker push ghcr.io/
|
|
113
|
+
→ docker push ghcr.io/fable-retold/retold-data-service:<version>
|
|
114
114
|
```
|
|
115
115
|
|
|
116
116
|
---
|
|
@@ -119,7 +119,7 @@ BUILD_DOCKER=1 npm publish (or: npm run publish:docker)
|
|
|
119
119
|
|
|
120
120
|
1. **npm**: `npm view retold-data-service version`
|
|
121
121
|
2. **Workflow**: `https://github.com/fable-retold/retold-data-service/actions`
|
|
122
|
-
3. **Image**: `docker pull ghcr.io/
|
|
122
|
+
3. **Image**: `docker pull ghcr.io/fable-retold/retold-data-service:latest`
|
|
123
123
|
|
|
124
124
|
If the first `docker pull` returns `denied`, the package is private by
|
|
125
125
|
default — flip visibility to public via Package Settings → Danger Zone
|
|
@@ -130,8 +130,8 @@ on the package page.
|
|
|
130
130
|
## Image consumption
|
|
131
131
|
|
|
132
132
|
```bash
|
|
133
|
-
docker pull ghcr.io/
|
|
134
|
-
docker run --rm ghcr.io/
|
|
133
|
+
docker pull ghcr.io/fable-retold/retold-data-service:latest
|
|
134
|
+
docker run --rm ghcr.io/fable-retold/retold-data-service:latest
|
|
135
135
|
```
|
|
136
136
|
|
|
137
137
|
Configuration via env vars: see this module's README for the supported
|
package/CONTRIBUTING.md
CHANGED
|
@@ -47,4 +47,4 @@ When in doubt, match what the surrounding code does.
|
|
|
47
47
|
|
|
48
48
|
## Repository Structure
|
|
49
49
|
|
|
50
|
-
Each module is its own git repository. The [retold](https://github.com/
|
|
50
|
+
Each module is its own git repository. The [retold](https://github.com/fable-retold/retold) repository tracks module organization but does not contain module source code. Direct your pull request to the specific module repository where your change belongs.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "retold-data-service",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.6",
|
|
4
4
|
"description": "Serve up a whole model!",
|
|
5
5
|
"main": "source/Retold-Data-Service.js",
|
|
6
6
|
"bin": {
|
|
@@ -78,8 +78,8 @@
|
|
|
78
78
|
"devDependencies": {
|
|
79
79
|
"chai": "^4.5.0",
|
|
80
80
|
"jsdom": "^25.0.1",
|
|
81
|
-
"meadow-connection-sqlite": "^1.0.
|
|
82
|
-
"mocha": "^11.
|
|
81
|
+
"meadow-connection-sqlite": "^1.0.21",
|
|
82
|
+
"mocha": "^11.7.6",
|
|
83
83
|
"pict-docuserve": "^1.4.19",
|
|
84
84
|
"puppeteer": "^24.40.0",
|
|
85
85
|
"quackage": "^1.3.0",
|
|
@@ -88,23 +88,23 @@
|
|
|
88
88
|
},
|
|
89
89
|
"dependencies": {
|
|
90
90
|
"bibliograph": "^1.0.0",
|
|
91
|
-
"fable": "^3.1.
|
|
91
|
+
"fable": "^3.1.80",
|
|
92
92
|
"fable-serviceproviderbase": "^3.0.19",
|
|
93
|
-
"meadow": "^2.0.
|
|
93
|
+
"meadow": "^2.0.47",
|
|
94
94
|
"meadow-connection-manager": "^1.1.5",
|
|
95
|
-
"meadow-connection-mysql": "^1.0.
|
|
95
|
+
"meadow-connection-mysql": "^1.0.20",
|
|
96
96
|
"meadow-endpoints": "^4.0.22",
|
|
97
|
-
"meadow-integration": "^1.
|
|
98
|
-
"meadow-migrationmanager": "^1.0.
|
|
97
|
+
"meadow-integration": "^1.1.3",
|
|
98
|
+
"meadow-migrationmanager": "^1.0.5",
|
|
99
99
|
"orator": "^6.1.2",
|
|
100
100
|
"orator-http-proxy": "^1.0.5",
|
|
101
101
|
"orator-serviceserver-restify": "^2.0.11",
|
|
102
102
|
"orator-static-server": "^2.1.4",
|
|
103
|
-
"pict": "^1.0.
|
|
103
|
+
"pict": "^1.0.393",
|
|
104
104
|
"pict-provider-theme": "^1.1.2",
|
|
105
105
|
"pict-section-connection-form": "^1.0.0",
|
|
106
106
|
"pict-section-histogram": "^1.0.1",
|
|
107
|
-
"pict-section-modal": "^1.
|
|
107
|
+
"pict-section-modal": "^1.3.2",
|
|
108
108
|
"pict-section-theme": "^1.1.1",
|
|
109
109
|
"pict-sessionmanager": "^1.0.2",
|
|
110
110
|
"stricture": "^4.0.6"
|
|
@@ -1277,12 +1277,18 @@ fResolve(pResult);}/**
|
|
|
1277
1277
|
* a rect-like { left, top, width, height } anchor (handy for context menus).
|
|
1278
1278
|
* @param {object} pOptions
|
|
1279
1279
|
* @param {Array} pOptions.items - [{ Hash, Label, Style?, Disabled?, Tooltip?, Icon?, Separator? }]
|
|
1280
|
-
* @param {string} [pOptions.
|
|
1280
|
+
* @param {string} [pOptions.ContentHTML] - Free-form HTML body for the popover, rendered
|
|
1281
|
+
* verbatim via innerHTML INSTEAD of building a menu from items[]. When set, the element is
|
|
1282
|
+
* a plain anchored popover (no role=menu / keyboard item nav); outside-click, Escape,
|
|
1283
|
+
* auto-flip and reposition still apply. Sanitize untrusted content. items is ignored.
|
|
1284
|
+
* @param {string} [pOptions.align] - 'left'|'right'|'center' (default 'left')
|
|
1281
1285
|
* @param {string} [pOptions.position]- 'auto'|'below'|'above' (default 'auto')
|
|
1282
1286
|
* @param {string} [pOptions.minWidth]- CSS minWidth (default: anchor width if known, else '160px')
|
|
1287
|
+
* @param {string} [pOptions.maxWidth]- CSS maxWidth (default unset; the base menu caps at 360px,
|
|
1288
|
+
* the --content variant uncaps — set this for wide rich-content popovers)
|
|
1283
1289
|
* @param {string} [pOptions.maxHeight]- CSS maxHeight (default '60vh')
|
|
1284
1290
|
* @param {string} [pOptions.className]- extra class(es) for the menu element
|
|
1285
|
-
* @param {boolean} [pOptions.closeOnSelect] - default true
|
|
1291
|
+
* @param {boolean} [pOptions.closeOnSelect] - default true (no-op in ContentHTML mode)
|
|
1286
1292
|
* @param {function} [pOptions.onSelect]- called with (Hash, Item) on selection
|
|
1287
1293
|
* @param {function} [pOptions.onClose] - called after dismiss
|
|
1288
1294
|
* @returns {Promise<{Hash: string, Item: object}|null>}
|
|
@@ -1306,7 +1312,21 @@ setTimeout(()=>{this._focusFirstEnabled(tmpMenu);},0);this._activeMenu={element:
|
|
|
1306
1312
|
// ─────────────────────────────────────────────
|
|
1307
1313
|
_resolveAnchor(pAnchor){if(!pAnchor){return null;}if(typeof pAnchor==='string'){return document.querySelector(pAnchor);}if(pAnchor.nodeType===1){return pAnchor;}// rect-like — no element to attach focus / outside-click ignore to,
|
|
1308
1314
|
// but that's fine, the caller knows what they're doing.
|
|
1309
|
-
return null;}_anchorRect(pAnchor,pAnchorEl){if(pAnchorEl&&typeof pAnchorEl.getBoundingClientRect==='function'){return pAnchorEl.getBoundingClientRect();}if(pAnchor&&typeof pAnchor==='object'&&typeof pAnchor.left==='number'&&typeof pAnchor.top==='number'){return{left:pAnchor.left,top:pAnchor.top,width:pAnchor.width||0,height:pAnchor.height||0,right:pAnchor.left+(pAnchor.width||0),bottom:pAnchor.top+(pAnchor.height||0)};}return null;}
|
|
1315
|
+
return null;}_anchorRect(pAnchor,pAnchorEl){if(pAnchorEl&&typeof pAnchorEl.getBoundingClientRect==='function'){return pAnchorEl.getBoundingClientRect();}if(pAnchor&&typeof pAnchor==='object'&&typeof pAnchor.left==='number'&&typeof pAnchor.top==='number'){return{left:pAnchor.left,top:pAnchor.top,width:pAnchor.width||0,height:pAnchor.height||0,right:pAnchor.left+(pAnchor.width||0),bottom:pAnchor.top+(pAnchor.height||0)};}return null;}/**
|
|
1316
|
+
* True when the value is usable as ContentHTML — a primitive string or a
|
|
1317
|
+
* boxed String object (some template engines hand back `new String(...)`,
|
|
1318
|
+
* which is `typeof 'object'` and would otherwise slip past the guard).
|
|
1319
|
+
*
|
|
1320
|
+
* @param {*} pValue
|
|
1321
|
+
* @returns {boolean}
|
|
1322
|
+
*/_isContentHTML(pValue){return typeof pValue==='string'||pValue instanceof String;}_buildMenu(pItems,pOptions){let tmpId=this._modal._nextId();let tmpMenu=document.createElement('div');tmpMenu.className='pict-modal-dropdown';// Free-form content popovers carry a modifier so the host can reset the
|
|
1323
|
+
// menu-item chrome (padding / max-width) and style the body itself.
|
|
1324
|
+
if(this._isContentHTML(pOptions.ContentHTML)){tmpMenu.className+=' pict-modal-dropdown--content';}if(pOptions.className){tmpMenu.className+=' '+pOptions.className;}tmpMenu.id='pict-modal-dropdown-'+tmpId;tmpMenu.style.maxHeight=pOptions.maxHeight;if(pOptions.maxWidth){tmpMenu.style.maxWidth=pOptions.maxWidth;}// ContentHTML mode: render the caller's HTML verbatim instead of building
|
|
1325
|
+
// a menu from items[]. This is a free-form anchored popover (e.g. a rich
|
|
1326
|
+
// info card, or a pre-rendered template menu) — not a role=menu list, so
|
|
1327
|
+
// we skip the menu role and the per-item keyboard semantics. Outside-click
|
|
1328
|
+
// / Escape / auto-flip / reposition all still apply from dropdown().
|
|
1329
|
+
if(this._isContentHTML(pOptions.ContentHTML)){tmpMenu.innerHTML=pOptions.ContentHTML;return tmpMenu;}tmpMenu.setAttribute('role','menu');let tmpHtml='';for(let i=0;i<pItems.length;i++){let tmpItem=pItems[i];if(tmpItem.Separator){tmpHtml+='<div class="pict-modal-dropdown-separator" role="separator"></div>';continue;}if(tmpItem.Header){tmpHtml+='<div class="pict-modal-dropdown-header">'+this._escapeHTML(tmpItem.Header)+'</div>';continue;}let tmpCls='pict-modal-dropdown-item';if(tmpItem.Style){tmpCls+=' pict-modal-dropdown-item--'+tmpItem.Style;}if(tmpItem.Disabled){tmpCls+=' pict-modal-dropdown-item--disabled';}let tmpAttrs=''+' data-pict-modal-dropdown-item'+' data-index="'+i+'"'+' data-hash="'+this._escapeHTML(tmpItem.Hash||'')+'"'+' role="menuitem"'+' tabindex="-1"';if(tmpItem.Disabled){tmpAttrs+=' aria-disabled="true" data-disabled';}if(tmpItem.Tooltip){tmpAttrs+=' title="'+this._escapeHTML(tmpItem.Tooltip)+'"';}let tmpIcon=tmpItem.Icon?'<span class="pict-modal-dropdown-item-icon">'+tmpItem.Icon+'</span>':'';let tmpHint=tmpItem.Hint?'<span class="pict-modal-dropdown-item-hint">'+this._escapeHTML(tmpItem.Hint)+'</span>':'';tmpHtml+='<div class="'+tmpCls+'"'+tmpAttrs+'>'+tmpIcon+'<span class="pict-modal-dropdown-item-label">'+this._escapeHTML(tmpItem.Label||'')+'</span>'+tmpHint+'</div>';}tmpMenu.innerHTML=tmpHtml;return tmpMenu;}_positionMenu(pMenu,pAnchorRect,pOptions){// Apply min-width before measuring so the menu's natural size accounts
|
|
1310
1330
|
// for the constraint.
|
|
1311
1331
|
let tmpMinWidth=pOptions.minWidth||(pAnchorRect.width>=80?Math.ceil(pAnchorRect.width)+'px':'160px');pMenu.style.minWidth=tmpMinWidth;// Measure after attaching.
|
|
1312
1332
|
let tmpMenuRect=pMenu.getBoundingClientRect();let tmpVw=window.innerWidth||document.documentElement.clientWidth;let tmpVh=window.innerHeight||document.documentElement.clientHeight;let tmpGap=4;// breathing room between anchor and menu
|
|
@@ -1692,9 +1712,11 @@ class PictModalShellManager{constructor(pModalSection){this._modal=pModalSection
|
|
|
1692
1712
|
* Show a toast notification.
|
|
1693
1713
|
*
|
|
1694
1714
|
* @param {string} pMessage - Toast message text
|
|
1695
|
-
* @param {object} [pOptions] - Options (type, duration, position, dismissible)
|
|
1715
|
+
* @param {object} [pOptions] - Options (type, duration, position, dismissible, allowHTML)
|
|
1716
|
+
* @param {boolean} [pOptions.allowHTML=false] - When true, render pMessage as raw HTML instead of escaping it. Only pass trusted markup.
|
|
1696
1717
|
* @returns {{ dismiss: function }} Handle with dismiss method
|
|
1697
|
-
*/toast(pMessage,pOptions){let tmpOptions=Object.assign({},this._modal.options.DefaultToastOptions,pOptions);let tmpContainer=this._getContainer(tmpOptions.position);let tmpId=this._modal._nextId();let tmpToast=document.createElement('div');tmpToast.className='pict-modal-toast pict-modal-toast--'+tmpOptions.type;tmpToast.id='pict-modal-toast-'+tmpId
|
|
1718
|
+
*/toast(pMessage,pOptions){let tmpOptions=Object.assign({},this._modal.options.DefaultToastOptions,pOptions);let tmpContainer=this._getContainer(tmpOptions.position);let tmpId=this._modal._nextId();let tmpToast=document.createElement('div');tmpToast.className='pict-modal-toast pict-modal-toast--'+tmpOptions.type;tmpToast.id='pict-modal-toast-'+tmpId;// Escape by default; render raw markup only when the caller opts in with allowHTML (trusted content).
|
|
1719
|
+
let tmpMessageMarkup=tmpOptions.allowHTML===true?pMessage:this._escapeHTML(pMessage);let tmpContent='<span class="pict-modal-toast-message">'+tmpMessageMarkup+'</span>';if(tmpOptions.dismissible){tmpContent+='<button class="pict-modal-toast-dismiss" aria-label="Dismiss">×</button>';}tmpToast.innerHTML=tmpContent;// Create handle
|
|
1698
1720
|
let tmpDismissed=false;let tmpTimeoutHandle=null;let tmpDismiss=()=>{if(tmpDismissed){return;}tmpDismissed=true;if(tmpTimeoutHandle){clearTimeout(tmpTimeoutHandle);}// Exit animation
|
|
1699
1721
|
tmpToast.classList.remove('pict-modal-visible');tmpToast.classList.add('pict-modal-toast-exit');// Remove from active list
|
|
1700
1722
|
this._modal._activeToasts=this._modal._activeToasts.filter(pEntry=>{return pEntry.element!==tmpToast;});// Remove from DOM after transition
|
|
@@ -1740,6 +1762,19 @@ if(tmpOptions.duration>0){tmpTimeoutHandle=setTimeout(tmpDismiss,tmpOptions.dura
|
|
|
1740
1762
|
* @param {object} [pOptions] - Options (position, delay, maxWidth, interactive)
|
|
1741
1763
|
* @returns {{ destroy: function }} Handle to remove the tooltip
|
|
1742
1764
|
*/richTooltip(pElement,pHTMLContent,pOptions){let tmpOptions=Object.assign({},this._modal.options.DefaultTooltipOptions,pOptions);return this._attachTooltip(pElement,pHTMLContent,true,tmpOptions);}/**
|
|
1765
|
+
* Attach a pinnable rich HTML tooltip to an element.
|
|
1766
|
+
*
|
|
1767
|
+
* Behaves like richTooltip() on hover/focus, but a click on the element
|
|
1768
|
+
* toggles a pinned state: while pinned the tooltip stays open (it does not
|
|
1769
|
+
* hide on mouseleave/focusout) and follows its anchor on scroll/resize.
|
|
1770
|
+
* This is opt-in sugar over richTooltip() with `{ pinnable: true }` — the
|
|
1771
|
+
* default tooltip()/richTooltip() behavior is unchanged.
|
|
1772
|
+
*
|
|
1773
|
+
* @param {HTMLElement} pElement - Target element
|
|
1774
|
+
* @param {string} pHTMLContent - HTML content for the tooltip
|
|
1775
|
+
* @param {object} [pOptions] - Options (position, delay, maxWidth, interactive, startPinned, onPinChange)
|
|
1776
|
+
* @returns {{ destroy: function, pin: function, unpin: function, isPinned: function }} Handle
|
|
1777
|
+
*/pinnableTooltip(pElement,pHTMLContent,pOptions){let tmpOptions=Object.assign({},this._modal.options.DefaultTooltipOptions,pOptions,{pinnable:true});return this._attachTooltip(pElement,pHTMLContent,true,tmpOptions);}/**
|
|
1743
1778
|
* Internal: attach tooltip event listeners to an element.
|
|
1744
1779
|
*
|
|
1745
1780
|
* @param {HTMLElement} pElement
|
|
@@ -1747,18 +1782,46 @@ if(tmpOptions.duration>0){tmpTimeoutHandle=setTimeout(tmpDismiss,tmpOptions.dura
|
|
|
1747
1782
|
* @param {boolean} pIsHTML
|
|
1748
1783
|
* @param {object} pOptions
|
|
1749
1784
|
* @returns {{ destroy: function }}
|
|
1750
|
-
*/_attachTooltip(pElement,pContent,pIsHTML,pOptions){let tmpTooltipElement=null;let tmpShowTimeout=null;let tmpHideTimeout=null;let tmpDestroyed=false;let tmpId=this._modal._nextId()
|
|
1785
|
+
*/_attachTooltip(pElement,pContent,pIsHTML,pOptions){let tmpTooltipElement=null;let tmpShowTimeout=null;let tmpHideTimeout=null;let tmpDestroyed=false;let tmpId=this._modal._nextId();// Pin state — only meaningful when pOptions.pinnable is set. A pinned
|
|
1786
|
+
// tooltip stays visible (transient hide is suppressed) and follows its
|
|
1787
|
+
// anchor on scroll/resize.
|
|
1788
|
+
let tmpPinned=false;let tmpShow=()=>{if(tmpDestroyed||tmpTooltipElement){return;}tmpTooltipElement=document.createElement('div');tmpTooltipElement.className='pict-modal-tooltip pict-modal-tooltip--'+pOptions.position;tmpTooltipElement.id='pict-modal-tooltip-'+tmpId;tmpTooltipElement.setAttribute('role','tooltip');tmpTooltipElement.style.maxWidth=pOptions.maxWidth;if(pOptions.interactive){tmpTooltipElement.classList.add('pict-modal-tooltip-interactive');}// Optional consumer-supplied class(es) on the tooltip element, e.g.
|
|
1789
|
+
// to theme the bubble + arrow by overriding the --pict-modal-tooltip-*
|
|
1790
|
+
// custom properties for a specific tooltip.
|
|
1791
|
+
if(pOptions.className){let tmpExtraClasses=String(pOptions.className).split(/\s+/);for(let i=0;i<tmpExtraClasses.length;i++){if(tmpExtraClasses[i]){tmpTooltipElement.classList.add(tmpExtraClasses[i]);}}}// Arrow
|
|
1751
1792
|
let tmpArrow=document.createElement('div');tmpArrow.className='pict-modal-tooltip-arrow';// Content
|
|
1752
1793
|
let tmpContentDiv=document.createElement('div');if(pIsHTML){tmpContentDiv.innerHTML=pContent;}else{tmpContentDiv.textContent=pContent;}tmpTooltipElement.appendChild(tmpArrow);tmpTooltipElement.appendChild(tmpContentDiv);document.body.appendChild(tmpTooltipElement);// Set aria-describedby on target
|
|
1753
1794
|
pElement.setAttribute('aria-describedby',tmpTooltipElement.id);// Position
|
|
1754
|
-
this._positionTooltip(tmpTooltipElement,pElement,pOptions.position);// Animate in
|
|
1755
|
-
|
|
1795
|
+
this._positionTooltip(tmpTooltipElement,pElement,pOptions.position);// Animate in — but only paint when the anchor is actually rendered.
|
|
1796
|
+
// A pinned / startPinned tooltip whose anchor lives in a hidden
|
|
1797
|
+
// container (e.g. an inactive tab panel) would otherwise show at the
|
|
1798
|
+
// clamped corner as an orphan. It is revealed later by tmpReposition
|
|
1799
|
+
// once the anchor gains a layout box (see the ResizeObserver below).
|
|
1800
|
+
void tmpTooltipElement.offsetHeight;if(this._isElementRendered(pElement)){tmpTooltipElement.classList.add('pict-modal-visible');}// Track
|
|
1756
1801
|
this._modal._activeTooltips.push({element:tmpTooltipElement,targetElement:pElement,destroy:tmpDestroy});// For interactive tooltips, allow hovering over the tooltip itself
|
|
1757
|
-
if(pOptions.interactive&&tmpTooltipElement){tmpTooltipElement.addEventListener('mouseenter',()=>{if(tmpHideTimeout){clearTimeout(tmpHideTimeout);tmpHideTimeout=null;}});tmpTooltipElement.addEventListener('mouseleave',()=>{tmpHide();});}
|
|
1802
|
+
if(pOptions.interactive&&tmpTooltipElement){tmpTooltipElement.addEventListener('mouseenter',()=>{if(tmpHideTimeout){clearTimeout(tmpHideTimeout);tmpHideTimeout=null;}});tmpTooltipElement.addEventListener('mouseleave',()=>{if(!tmpPinned){tmpHide();}});}// Reflect pinned state on a freshly-(re)created element.
|
|
1803
|
+
if(tmpPinned&&tmpTooltipElement){tmpTooltipElement.classList.add('pict-modal-tooltip-pinned');}};let tmpHide=()=>{if(!tmpTooltipElement){return;}tmpTooltipElement.classList.remove('pict-modal-visible');let tmpEl=tmpTooltipElement;tmpTooltipElement=null;// Remove aria
|
|
1758
1804
|
pElement.removeAttribute('aria-describedby');// Remove from tracking
|
|
1759
|
-
this._modal._activeTooltips=this._modal._activeTooltips.filter(pEntry=>{return pEntry.element!==tmpEl;});setTimeout(()=>{if(tmpEl.parentNode){tmpEl.parentNode.removeChild(tmpEl);}},220);};let tmpOnMouseEnter=()=>{if(tmpHideTimeout){clearTimeout(tmpHideTimeout);tmpHideTimeout=null;}tmpShowTimeout=setTimeout(tmpShow,pOptions.delay);};let tmpOnMouseLeave=()=>{if(tmpShowTimeout){clearTimeout(tmpShowTimeout);tmpShowTimeout=null;}//
|
|
1760
|
-
if(
|
|
1761
|
-
|
|
1805
|
+
this._modal._activeTooltips=this._modal._activeTooltips.filter(pEntry=>{return pEntry.element!==tmpEl;});setTimeout(()=>{if(tmpEl.parentNode){tmpEl.parentNode.removeChild(tmpEl);}},220);};let tmpOnMouseEnter=()=>{if(tmpHideTimeout){clearTimeout(tmpHideTimeout);tmpHideTimeout=null;}tmpShowTimeout=setTimeout(tmpShow,pOptions.delay);};let tmpOnMouseLeave=()=>{if(tmpShowTimeout){clearTimeout(tmpShowTimeout);tmpShowTimeout=null;}// A pinned tooltip stays open regardless of pointer.
|
|
1806
|
+
if(tmpPinned){return;}// Small delay before hiding to allow moving to interactive tooltip
|
|
1807
|
+
if(pOptions.interactive){tmpHideTimeout=setTimeout(tmpHide,100);}else{tmpHide();}};let tmpOnFocusIn=()=>{tmpShowTimeout=setTimeout(tmpShow,pOptions.delay);};let tmpOnFocusOut=()=>{if(tmpShowTimeout){clearTimeout(tmpShowTimeout);tmpShowTimeout=null;}// A pinned tooltip stays open regardless of focus.
|
|
1808
|
+
if(tmpPinned){return;}tmpHide();};// -- Pin lifecycle (opt-in via pOptions.pinnable) --
|
|
1809
|
+
// Keep a pinned tooltip glued to its anchor as the page scrolls/resizes.
|
|
1810
|
+
// The element is position:fixed and portaled to <body>, so it does not
|
|
1811
|
+
// move with the document on its own. When the anchor scrolls out of the
|
|
1812
|
+
// viewport we fade the tooltip out (without dropping the pin) and bring
|
|
1813
|
+
// it back when the anchor returns.
|
|
1814
|
+
let tmpResizeObserver=null;let tmpReposition=()=>{if(!tmpTooltipElement){return;}let tmpRect=pElement.getBoundingClientRect();// Rendered (has a layout box) AND within the viewport. A hidden anchor
|
|
1815
|
+
// (display:none, or inside a hidden tab panel) has no box, so the
|
|
1816
|
+
// tooltip is hidden rather than stranded at the clamped corner.
|
|
1817
|
+
let tmpInView=this._isElementRendered(pElement)&&tmpRect.bottom>0&&tmpRect.top<window.innerHeight&&tmpRect.right>0&&tmpRect.left<window.innerWidth;if(tmpInView){this._positionTooltip(tmpTooltipElement,pElement,pOptions.position);tmpTooltipElement.classList.add('pict-modal-visible');}else{tmpTooltipElement.classList.remove('pict-modal-visible');}};let tmpAddRepositionListeners=()=>{// `true` (capture) so scrolls inside any nested container reposition too.
|
|
1818
|
+
window.addEventListener('scroll',tmpReposition,true);window.addEventListener('resize',tmpReposition);// A ResizeObserver on the anchor catches it being shown/hidden (e.g. a
|
|
1819
|
+
// tab panel toggling display) — transitions the window scroll/resize
|
|
1820
|
+
// listeners miss — so a pinned tooltip appears the moment its anchor
|
|
1821
|
+
// gains a layout box and hides again when it loses one.
|
|
1822
|
+
if(typeof ResizeObserver!=='undefined'){tmpResizeObserver=new ResizeObserver(()=>tmpReposition());tmpResizeObserver.observe(pElement);}};let tmpRemoveRepositionListeners=()=>{window.removeEventListener('scroll',tmpReposition,true);window.removeEventListener('resize',tmpReposition);if(tmpResizeObserver){tmpResizeObserver.disconnect();tmpResizeObserver=null;}};let tmpPin=()=>{if(tmpPinned||tmpDestroyed){return;}tmpPinned=true;if(!tmpTooltipElement){tmpShow();}if(tmpTooltipElement){tmpTooltipElement.classList.add('pict-modal-tooltip-pinned');}tmpAddRepositionListeners();if(typeof pOptions.onPinChange==='function'){pOptions.onPinChange(true,pElement);}};let tmpUnpin=()=>{if(!tmpPinned){return;}tmpPinned=false;tmpRemoveRepositionListeners();if(tmpTooltipElement){tmpTooltipElement.classList.remove('pict-modal-tooltip-pinned');}tmpHide();if(typeof pOptions.onPinChange==='function'){pOptions.onPinChange(false,pElement);}};let tmpOnClick=pEvent=>{if(pEvent){pEvent.preventDefault();pEvent.stopPropagation();}if(tmpPinned){tmpUnpin();}else{tmpPin();}};// Attach listeners
|
|
1823
|
+
pElement.addEventListener('mouseenter',tmpOnMouseEnter);pElement.addEventListener('mouseleave',tmpOnMouseLeave);pElement.addEventListener('focusin',tmpOnFocusIn);pElement.addEventListener('focusout',tmpOnFocusOut);if(pOptions.pinnable){pElement.addEventListener('click',tmpOnClick);}let tmpDestroy=()=>{if(tmpDestroyed){return;}tmpDestroyed=true;if(tmpShowTimeout){clearTimeout(tmpShowTimeout);}if(tmpHideTimeout){clearTimeout(tmpHideTimeout);}tmpRemoveRepositionListeners();tmpPinned=false;tmpHide();pElement.removeEventListener('mouseenter',tmpOnMouseEnter);pElement.removeEventListener('mouseleave',tmpOnMouseLeave);pElement.removeEventListener('focusin',tmpOnFocusIn);pElement.removeEventListener('focusout',tmpOnFocusOut);if(pOptions.pinnable){pElement.removeEventListener('click',tmpOnClick);}};// Optionally render already-pinned (explicit consumer opt-in).
|
|
1824
|
+
if(pOptions.pinnable&&pOptions.startPinned){tmpPin();}return{destroy:tmpDestroy,pin:tmpPin,unpin:tmpUnpin,isPinned:()=>{return tmpPinned;}};}/**
|
|
1762
1825
|
* Position a tooltip element relative to the target element.
|
|
1763
1826
|
* Flips direction if the tooltip would overflow the viewport.
|
|
1764
1827
|
*
|
|
@@ -1769,6 +1832,14 @@ pElement.addEventListener('mouseenter',tmpOnMouseEnter);pElement.addEventListene
|
|
|
1769
1832
|
if(tmpPosition==='top'&&tmpTargetRect.top<tmpTooltipRect.height+tmpGap){tmpPosition='bottom';}else if(tmpPosition==='bottom'&&window.innerHeight-tmpTargetRect.bottom<tmpTooltipRect.height+tmpGap){tmpPosition='top';}else if(tmpPosition==='left'&&tmpTargetRect.left<tmpTooltipRect.width+tmpGap){tmpPosition='right';}else if(tmpPosition==='right'&&window.innerWidth-tmpTargetRect.right<tmpTooltipRect.width+tmpGap){tmpPosition='left';}// Update class for arrow direction
|
|
1770
1833
|
pTooltip.className=pTooltip.className.replace(/pict-modal-tooltip--\w+/,'pict-modal-tooltip--'+tmpPosition);let tmpTop=0;let tmpLeft=0;switch(tmpPosition){case'top':tmpTop=tmpTargetRect.top-tmpTooltipRect.height-tmpGap;tmpLeft=tmpTargetRect.left+tmpTargetRect.width/2-tmpTooltipRect.width/2;break;case'bottom':tmpTop=tmpTargetRect.bottom+tmpGap;tmpLeft=tmpTargetRect.left+tmpTargetRect.width/2-tmpTooltipRect.width/2;break;case'left':tmpTop=tmpTargetRect.top+tmpTargetRect.height/2-tmpTooltipRect.height/2;tmpLeft=tmpTargetRect.left-tmpTooltipRect.width-tmpGap;break;case'right':tmpTop=tmpTargetRect.top+tmpTargetRect.height/2-tmpTooltipRect.height/2;tmpLeft=tmpTargetRect.right+tmpGap;break;}// Clamp to viewport
|
|
1771
1834
|
tmpLeft=Math.max(4,Math.min(tmpLeft,window.innerWidth-tmpTooltipRect.width-4));tmpTop=Math.max(4,Math.min(tmpTop,window.innerHeight-tmpTooltipRect.height-4));pTooltip.style.top=tmpTop+'px';pTooltip.style.left=tmpLeft+'px';}/**
|
|
1835
|
+
* Whether an element is currently rendered (has a layout box). Returns false
|
|
1836
|
+
* for a display:none element or one inside a display:none ancestor (e.g. an
|
|
1837
|
+
* inactive tab panel) — in which case a pinned tooltip should stay hidden
|
|
1838
|
+
* until the anchor reappears.
|
|
1839
|
+
*
|
|
1840
|
+
* @param {HTMLElement} pElement
|
|
1841
|
+
* @returns {boolean}
|
|
1842
|
+
*/_isElementRendered(pElement){return!!(pElement&&typeof pElement.getClientRects==='function'&&pElement.getClientRects().length>0);}/**
|
|
1772
1843
|
* Dismiss all active tooltips.
|
|
1773
1844
|
*/dismissAll(){let tmpTooltips=this._modal._activeTooltips.slice();for(let i=0;i<tmpTooltips.length;i++){tmpTooltips[i].destroy();}}}module.exports=PictModalTooltip;},{}],25:[function(require,module,exports){/**
|
|
1774
1845
|
* Pict-Modal-Window
|
|
@@ -1823,7 +1894,7 @@ if(typeof pOptions.onOpen==='function'){pOptions.onOpen(pDialog);}}/**
|
|
|
1823
1894
|
*
|
|
1824
1895
|
* @param {string} pText
|
|
1825
1896
|
* @returns {string}
|
|
1826
|
-
*/_escapeHTML(pText){if(typeof pText!=='string'){return'';}return pText.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"');}}module.exports=PictModalWindow;},{}],26:[function(require,module,exports){module.exports={"AutoInitialize":true,"AutoRender":false,"AutoSolveWithApp":false,"ViewIdentifier":"Pict-Section-Modal","OverlayClickDismisses":true,"DefaultConfirmOptions":{"title":"Confirm","confirmLabel":"OK","cancelLabel":"Cancel","dangerous":false,"unbounded":false},"DefaultDoubleConfirmOptions":{"title":"Are you sure?","confirmLabel":"Confirm","cancelLabel":"Cancel","phrasePrompt":"Type \"{phrase}\" to confirm:","confirmPhrase":"","unbounded":false},"DefaultModalOptions":{"title":"","content":"","buttons":[],"closeable":true,"width":"480px","unbounded":false},"DefaultTooltipOptions":{"position":"top","delay":200,"maxWidth":"300px","interactive":false},"DefaultToastOptions":{"type":"info","duration":3000,"position":"top-right","dismissible":true},"DefaultPanelOptions":{"position":"right","width":340,"minWidth":200,"maxWidth":600,"collapsible":true,"collapsed":false,"persist":false,"persistKey":""},"Templates":[],"Renderables":[],"CSS":/*css*/`
|
|
1897
|
+
*/_escapeHTML(pText){if(typeof pText!=='string'){return'';}return pText.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"');}}module.exports=PictModalWindow;},{}],26:[function(require,module,exports){module.exports={"AutoInitialize":true,"AutoRender":false,"AutoSolveWithApp":false,"ViewIdentifier":"Pict-Section-Modal","OverlayClickDismisses":true,"DefaultConfirmOptions":{"title":"Confirm","confirmLabel":"OK","cancelLabel":"Cancel","dangerous":false,"unbounded":false},"DefaultDoubleConfirmOptions":{"title":"Are you sure?","confirmLabel":"Confirm","cancelLabel":"Cancel","phrasePrompt":"Type \"{phrase}\" to confirm:","confirmPhrase":"","unbounded":false},"DefaultModalOptions":{"title":"","content":"","buttons":[],"closeable":true,"width":"480px","unbounded":false},"DefaultTooltipOptions":{"position":"top","delay":200,"maxWidth":"300px","interactive":false,"pinnable":false,"startPinned":false},"DefaultToastOptions":{"type":"info","duration":3000,"position":"top-right","dismissible":true,"allowHTML":false},"DefaultPanelOptions":{"position":"right","width":340,"minWidth":200,"maxWidth":600,"collapsible":true,"collapsed":false,"persist":false,"persistKey":""},"Templates":[],"Renderables":[],"CSS":/*css*/`
|
|
1827
1898
|
/* pict-section-modal */
|
|
1828
1899
|
.pict-modal-root
|
|
1829
1900
|
{
|
|
@@ -1874,6 +1945,7 @@ if(typeof pOptions.onOpen==='function'){pOptions.onOpen(pDialog);}}/**
|
|
|
1874
1945
|
--pict-modal-tooltip-fg: var(--theme-color-text-primary, #ffffff);
|
|
1875
1946
|
--pict-modal-tooltip-border-radius:4px;
|
|
1876
1947
|
--pict-modal-tooltip-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
1948
|
+
--pict-modal-tooltip-pinned-ring: var(--theme-color-brand-primary, #2E7D74);
|
|
1877
1949
|
|
|
1878
1950
|
/* Dropdown */
|
|
1879
1951
|
--pict-modal-dropdown-bg: var(--theme-color-background-panel, #ffffff);
|
|
@@ -2236,6 +2308,14 @@ if(typeof pOptions.onOpen==='function'){pOptions.onOpen(pDialog);}}/**
|
|
|
2236
2308
|
opacity: 1;
|
|
2237
2309
|
}
|
|
2238
2310
|
|
|
2311
|
+
/* Pinned tooltips stay open and can be interacted with; a subtle ring
|
|
2312
|
+
distinguishes a pinned tooltip from a transient hover tooltip. */
|
|
2313
|
+
.pict-modal-tooltip.pict-modal-tooltip-pinned
|
|
2314
|
+
{
|
|
2315
|
+
pointer-events: auto;
|
|
2316
|
+
box-shadow: var(--pict-modal-tooltip-shadow), 0 0 0 1px var(--pict-modal-tooltip-pinned-ring);
|
|
2317
|
+
}
|
|
2318
|
+
|
|
2239
2319
|
.pict-modal-tooltip-arrow
|
|
2240
2320
|
{
|
|
2241
2321
|
position: absolute;
|
|
@@ -2299,6 +2379,16 @@ if(typeof pOptions.onOpen==='function'){pOptions.onOpen(pDialog);}}/**
|
|
|
2299
2379
|
transform var(--pict-modal-transition-duration) ease;
|
|
2300
2380
|
}
|
|
2301
2381
|
|
|
2382
|
+
/* Free-form content popovers keep the dropdown chrome (bg / border / shadow /
|
|
2383
|
+
flip / dismiss) but hand sizing + inner padding to the injected content, so a
|
|
2384
|
+
pre-rendered template menu or a wide rich card isn't boxed by the menu
|
|
2385
|
+
defaults. Cap width per-call via the maxWidth option. */
|
|
2386
|
+
.pict-modal-dropdown.pict-modal-dropdown--content
|
|
2387
|
+
{
|
|
2388
|
+
max-width: none;
|
|
2389
|
+
padding: 0;
|
|
2390
|
+
}
|
|
2391
|
+
|
|
2302
2392
|
.pict-modal-dropdown.pict-modal-dropdown--above { transform: translateY(4px); }
|
|
2303
2393
|
|
|
2304
2394
|
.pict-modal-dropdown.pict-modal-visible
|
|
@@ -3229,7 +3319,16 @@ if(typeof document!=='undefined'&&document.body){if(!document.body.classList.con
|
|
|
3229
3319
|
* @param {string} pHTMLContent - HTML content
|
|
3230
3320
|
* @param {object} [pOptions] - Options { position, delay, maxWidth, interactive }
|
|
3231
3321
|
* @returns {{ destroy: function }}
|
|
3232
|
-
*/richTooltip(pElement,pHTMLContent,pOptions){return this._tooltip.richTooltip(pElement,pHTMLContent,pOptions);}
|
|
3322
|
+
*/richTooltip(pElement,pHTMLContent,pOptions){return this._tooltip.richTooltip(pElement,pHTMLContent,pOptions);}/**
|
|
3323
|
+
* Attach a pinnable rich HTML tooltip to an element. Hover/focus behaves
|
|
3324
|
+
* like richTooltip(); a click on the element toggles a pinned state that
|
|
3325
|
+
* keeps the tooltip open and follows the anchor on scroll/resize.
|
|
3326
|
+
*
|
|
3327
|
+
* @param {HTMLElement} pElement - Target element
|
|
3328
|
+
* @param {string} pHTMLContent - HTML content
|
|
3329
|
+
* @param {object} [pOptions] - Options { position, delay, maxWidth, interactive, startPinned, onPinChange }
|
|
3330
|
+
* @returns {{ destroy: function, pin: function, unpin: function, isPinned: function }}
|
|
3331
|
+
*/pinnableTooltip(pElement,pHTMLContent,pOptions){return this._tooltip.pinnableTooltip(pElement,pHTMLContent,pOptions);}// -- Toast API --
|
|
3233
3332
|
/**
|
|
3234
3333
|
* Show a toast notification.
|
|
3235
3334
|
*
|
|
@@ -3239,13 +3338,16 @@ if(typeof document!=='undefined'&&document.body){if(!document.body.classList.con
|
|
|
3239
3338
|
*/toast(pMessage,pOptions){return this._toast.toast(pMessage,pOptions);}// -- Dropdown API --
|
|
3240
3339
|
/**
|
|
3241
3340
|
* Open an anchor-positioned dropdown menu (no backdrop, click-outside
|
|
3242
|
-
* dismisses). Useful for nav menus and split-button addenda.
|
|
3341
|
+
* dismisses). Useful for nav menus and split-button addenda. Pass
|
|
3342
|
+
* `ContentHTML` instead of `items` to render a free-form anchored popover
|
|
3343
|
+
* (rich card, pre-rendered template menu) with the same dismiss/flip behavior.
|
|
3243
3344
|
*
|
|
3244
3345
|
* @param {HTMLElement|string|object} pAnchor - Element, CSS selector, or
|
|
3245
3346
|
* { left, top, width, height } rect for context-menu style anchoring.
|
|
3246
|
-
* @param {object} pOptions - { items, align, position, minWidth,
|
|
3247
|
-
* className, closeOnSelect, onSelect, onClose }
|
|
3248
|
-
* @returns {Promise<{Hash, Item}|null>} Selection or null on dismiss
|
|
3347
|
+
* @param {object} pOptions - { items | ContentHTML, align, position, minWidth,
|
|
3348
|
+
* maxWidth, maxHeight, className, closeOnSelect, onSelect, onClose }
|
|
3349
|
+
* @returns {Promise<{Hash, Item}|null>} Selection or null on dismiss
|
|
3350
|
+
* (always resolves null in ContentHTML mode).
|
|
3249
3351
|
*/dropdown(pAnchor,pOptions){return this._dropdown.dropdown(pAnchor,pOptions);}/**
|
|
3250
3352
|
* Dismiss any open dropdown.
|
|
3251
3353
|
*/dismissDropdowns(){this._dropdown.dismissAll();}// -- Panel API --
|
|
@@ -5280,7 +5382,7 @@ return cachedClearTimeout.call(null,marker);}catch(e){// same as above but when
|
|
|
5280
5382
|
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
|
|
5281
5383
|
return cachedClearTimeout.call(this,marker);}}}var queue=[];var draining=false;var currentQueue;var queueIndex=-1;function cleanUpNextTick(){if(!draining||!currentQueue){return;}draining=false;if(currentQueue.length){queue=currentQueue.concat(queue);}else{queueIndex=-1;}if(queue.length){drainQueue();}}function drainQueue(){if(draining){return;}var timeout=runTimeout(cleanUpNextTick);draining=true;var len=queue.length;while(len){currentQueue=queue;queue=[];while(++queueIndex<len){if(currentQueue){currentQueue[queueIndex].run();}}queueIndex=-1;len=queue.length;}currentQueue=null;draining=false;runClearTimeout(timeout);}process.nextTick=function(fun){var args=new Array(arguments.length-1);if(arguments.length>1){for(var i=1;i<arguments.length;i++){args[i-1]=arguments[i];}}queue.push(new Item(fun,args));if(queue.length===1&&!draining){runTimeout(drainQueue);}};// v8 likes predictible objects
|
|
5282
5384
|
function Item(fun,array){this.fun=fun;this.array=array;}Item.prototype.run=function(){this.fun.apply(null,this.array);};process.title='browser';process.browser=true;process.env={};process.argv=[];process.version='';// empty string to avoid regexp issues
|
|
5283
|
-
process.versions={};function noop(){}process.on=noop;process.addListener=noop;process.once=noop;process.off=noop;process.removeListener=noop;process.removeAllListeners=noop;process.emit=noop;process.prependListener=noop;process.prependOnceListener=noop;process.listeners=function(name){return[];};process.binding=function(name){throw new Error('process.binding is not supported');};process.cwd=function(){return'/';};process.chdir=function(dir){throw new Error('process.chdir is not supported');};process.umask=function(){return 0;};},{}],91:[function(require,module,exports){module.exports={"name":"retold-data-service","version":"2.1.
|
|
5385
|
+
process.versions={};function noop(){}process.on=noop;process.addListener=noop;process.once=noop;process.off=noop;process.removeListener=noop;process.removeAllListeners=noop;process.emit=noop;process.prependListener=noop;process.prependOnceListener=noop;process.listeners=function(name){return[];};process.binding=function(name){throw new Error('process.binding is not supported');};process.cwd=function(){return'/';};process.chdir=function(dir){throw new Error('process.chdir is not supported');};process.umask=function(){return 0;};},{}],91:[function(require,module,exports){module.exports={"name":"retold-data-service","version":"2.1.6","description":"Serve up a whole model!","main":"source/Retold-Data-Service.js","bin":{"retold-data-service-clone":"bin/retold-data-service-clone.js"},"scripts":{"start":"node bin/retold-data-service-clone.js","coverage":"npx quack coverage","test":"npx quack test","brand":"node node_modules/pict-section-theme/bin/pict-section-theme-brand.js --manifest ../../../Retold-Modules-Manifest.json --module retold-data-service --favicons source/services/comprehension-loader/web/favicons && cp -r source/services/comprehension-loader/web/favicons source/services/data-cloner/web/favicons","build":"node build-all.js","build:cloner":"npx quack build","build:loader":"node -e \"require('fs').writeFileSync('.quackage.json', require('fs').readFileSync('.quackage-comprehension-loader.json', 'utf8'))\" && npx quack build","prepublishOnly":"npm run build","build-test-model":"cd test && npx stricture -i model/ddl/BookStore.ddl","docker-dev-build":"docker build ./ -f Dockerfile_LUXURYCode -t retold-data-service-image:local","docker-dev-run":"docker run -it -d --name retold-data-service-dev -p 44444:8080 -p 43306:3306 -p 48086:8086 -v \"$PWD/.config:/home/coder/.config\" -v \"$PWD:/home/coder/retold-data-service\" -u \"$(id -u):$(id -g)\" -e \"DOCKER_USER=$USER\" retold-data-service-image:local","docker-dev-shell":"docker exec -it retold-data-service-dev /bin/bash","docker-service-build":"docker build ./ -f Dockerfile_Service -t retold-data-service-server-image:local","docker-service-run-test":"docker run -it --init -d --name retold-data-service -p 8086:8086 -p 43306:3306 -v \"$(pwd):/retold-data-service:z\" -u \"$(id -u):$(id -g)\" retold-data-service-server-image:local","docker-service-run":"docker run -it --init -d --name retold-data-service -p 8086:8086 -p 43306:3306 -v \"$(pwd):/retold-data-service:z\" retold-data-service-server-image:local","docker-service-shell":"docker exec -it retold-data-service /bin/bash","test:integration":"node test/run-integration-tests.js","test:integration:no-browser":"node test/run-integration-tests.js --skip-puppeteer","test:all":"npx quack test && node test/run-integration-tests.js --skip-puppeteer","postversion":"npx quack release postversion","postpublish":"npx quack release postpublish","publish:docker":"npx quack release publish --image","release:patch":"npx quack release patch","release:minor":"npx quack release minor","release:major":"npx quack release major","release:patch:image":"npx quack release patch --image","release:minor:image":"npx quack release minor --image","release:major:image":"npx quack release major --image"},"mocha":{"spec":["test/RetoldDataService_tests.js","test/Bundles_smoke_tests.js","test/ComprehensionLoader_smoke_tests.js","test/DataCloner_smoke_tests.js"],"diff":true,"extension":["js"],"package":"./package.json","reporter":"spec","slow":"75","timeout":"5000","ui":"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]},"repository":{"type":"git","url":"https://github.com/fable-retold/retold-data-service.git"},"keywords":["entity","behavior","api"],"author":"Steven Velozo <steven@velozo.com> (http://velozo.com/)","license":"MIT","bugs":{"url":"https://github.com/fable-retold/retold-data-service/issues"},"homepage":"https://github.com/fable-retold/retold-data-service","devDependencies":{"chai":"^4.5.0","jsdom":"^25.0.1","meadow-connection-sqlite":"^1.0.21","mocha":"^11.7.6","pict-docuserve":"^1.4.19","puppeteer":"^24.40.0","quackage":"^1.3.0","stricture":"^4.0.6","supertest":"^7.2.2"},"dependencies":{"bibliograph":"^1.0.0","fable":"^3.1.80","fable-serviceproviderbase":"^3.0.19","meadow":"^2.0.47","meadow-connection-manager":"^1.1.5","meadow-connection-mysql":"^1.0.20","meadow-endpoints":"^4.0.22","meadow-integration":"^1.1.3","meadow-migrationmanager":"^1.0.5","orator":"^6.1.2","orator-http-proxy":"^1.0.5","orator-serviceserver-restify":"^2.0.11","orator-static-server":"^2.1.4","pict":"^1.0.393","pict-provider-theme":"^1.1.2","pict-section-connection-form":"^1.0.0","pict-section-histogram":"^1.0.1","pict-section-modal":"^1.3.2","pict-section-theme":"^1.1.1","pict-sessionmanager":"^1.0.2","stricture":"^4.0.6"},"retold":{"brand":{"Hash":"retold-data-service","Name":"Retold Data Service","Tagline":"Schema-driven data movement and comprehension","Palette":"ocean","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-retold-data-service-filled-light\">\n\t\t\t\t<path d=\"M 48.00 2.00 L 87.84 25.00 L 87.84 71.00 L 48.00 94.00 L 8.16 71.00 L 8.16 25.00 Z\"/>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<path d=\"M 48.00 2.00 L 87.84 25.00 L 87.84 71.00 L 48.00 94.00 L 8.16 71.00 L 8.16 25.00 Z\" fill=\"#23a6c7\"/>\n\t\t<g clip-path=\"url(#frame-retold-data-service-filled-light)\"><rect x=\"20\" y=\"20\" width=\"56\" height=\"56\" rx=\"8\" fill=\"rgba(255,255,255,0.18)\"/>\n\t\t\t\t\t<path d=\"M 48 30 L 70 48 L 48 66 L 26 48 Z\" fill=\"#e36b59\"/></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=\"28\" font-weight=\"600\"\n\t\t\tfill=\"#ffffff\" letter-spacing=\"-1\">RDS</text>\n\t</svg>","IconType":"svg","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-retold-data-service-light\">\n\t\t\t\t<path d=\"M 48.00 2.00 L 87.84 25.00 L 87.84 71.00 L 48.00 94.00 L 8.16 71.00 L 8.16 25.00 Z\"/>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<path d=\"M 48.00 2.00 L 87.84 25.00 L 87.84 71.00 L 48.00 94.00 L 8.16 71.00 L 8.16 25.00 Z\" fill=\"#23a6c7\"/>\n\t\t<g clip-path=\"url(#fav-retold-data-service-light)\"><rect x=\"16\" y=\"16\" width=\"64\" height=\"64\" rx=\"10\" 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\">R</text>\n\t</svg>","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-retold-data-service-dark\">\n\t\t\t\t<path d=\"M 48.00 2.00 L 87.84 25.00 L 87.84 71.00 L 48.00 94.00 L 8.16 71.00 L 8.16 25.00 Z\"/>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<path d=\"M 48.00 2.00 L 87.84 25.00 L 87.84 71.00 L 48.00 94.00 L 8.16 71.00 L 8.16 25.00 Z\" fill=\"#67c6de\"/>\n\t\t<g clip-path=\"url(#fav-retold-data-service-dark)\"><rect x=\"16\" y=\"16\" width=\"64\" height=\"64\" rx=\"10\" 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\">R</text>\n\t</svg>","Colors":{"Primary":"#23a6c7","Secondary":"#e36b59","PrimaryLight":"#23a6c7","PrimaryDark":"#67c6de","SecondaryLight":"#e36b59","SecondaryDark":"#edb3aa"}}}};},{}],92:[function(require,module,exports){'use strict';// Located at source/services/. Apps live one level deeper at
|
|
5284
5386
|
// source/services/<app>/pict-app/. The package.json is two levels up.
|
|
5285
5387
|
const tmpPackage=require('../../package.json');if(!tmpPackage.retold||!tmpPackage.retold.brand){throw new Error('retold-data-service: package.json is missing retold.brand — '+'run `npm run brand` (which calls pict-section-theme-brand) before building');}module.exports=tmpPackage.retold.brand;},{"../../package.json":91}],93:[function(require,module,exports){module.exports={"Name":"Retold Comprehension Loader","Hash":"ComprehensionLoader","MainViewportViewIdentifier":"ComprehensionLoader-Layout","MainViewportDestinationAddress":"#ComprehensionLoader-Application-Container","MainViewportDefaultDataAddress":"AppData.ComprehensionLoader","pict_configuration":{"Product":"ComprehensionLoader"},"AutoRenderMainViewportViewAfterInitialize":false};},{}],94:[function(require,module,exports){const libPictApplication=require('pict-application');const libProvider=require('./providers/Pict-Provider-ComprehensionLoader.js');const libViewLayout=require('./views/PictView-ComprehensionLoader-Layout.js');const libViewSession=require('./views/PictView-ComprehensionLoader-Session.js');const libViewSchema=require('./views/PictView-ComprehensionLoader-Schema.js');const libViewSource=require('./views/PictView-ComprehensionLoader-Source.js');const libViewLoad=require('./views/PictView-ComprehensionLoader-Load.js');const libViewHistogram=require('pict-section-histogram');const libPictSectionModal=require('pict-section-modal');const libPictSectionTheme=require('pict-section-theme');const libBrand=require('../../RetoldDataService-Brand.js');const libViewShell=require('./views/PictView-ComprehensionLoader-Shell.js');const libViewTopBarNav=require('./views/PictView-ComprehensionLoader-TopBar-Nav.js');const libViewTopBarUser=require('./views/PictView-ComprehensionLoader-TopBar-User.js');const libViewStatusBar=require('./views/PictView-ComprehensionLoader-StatusBar.js');const libViewStatusDetail=require('./views/PictView-ComprehensionLoader-StatusDetail.js');const libViewSettings=require('./views/PictView-ComprehensionLoader-SettingsPanel.js');class ComprehensionLoaderApplication extends libPictApplication{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);// 1. Modal section (provides shell + panels + modal API).
|
|
5286
5388
|
this.pict.addView('Pict-Section-Modal',libPictSectionModal.default_configuration,libPictSectionModal);// 2. Provider + existing section views.
|