@ngxviewbuilder/plugin-shared 0.0.0-stage → 0.13.1

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/LICENSE.md ADDED
@@ -0,0 +1,79 @@
1
+ # NGX View Builder Designer Commercial License Agreement
2
+
3
+ Copyright © 2026 NGX View Builder (https://ngxviewbuilder.io). All rights reserved.
4
+
5
+ This is a legal agreement between you (the **"Licensee"**) and NGX View Builder (the **"Licensor"**) covering the `@ngxviewbuilder/designer` package and the official `@ngxviewbuilder/plugin-*` packages (together the **"Software"**). By installing or using the Software you agree to these terms.
6
+
7
+ **This is commercial software. It is not open source.** The Software's source form being readable in the npm distribution does not grant any open-source rights.
8
+
9
+ The `@ngxviewbuilder/runtime` package is **not** covered by this agreement. It is free to use in production, requires no License Key, and has its own terms in that package's `LICENSE.md`. What you pay for here is the visual editor your team designs views in.
10
+
11
+ ## 1. Definitions
12
+
13
+ - **"License Key"** a cryptographically signed key issued by Licensor that identifies the customer, plan, and expiry date (the **"License Term"**).
14
+ - **"Covered Version"** any version of the Software whose release date is earlier than the expiry date of Licensee's License Key.
15
+ - **"Application"** a software product that incorporates the Software, developed by Licensee for itself **or for a client of Licensee** (contract / agency work).
16
+
17
+ ## 2. License grant
18
+
19
+ Subject to the purchase of a valid License Key and compliance with this agreement, Licensor grants Licensee a non-exclusive, non-transferable, worldwide license to:
20
+
21
+ 1. use the Software to develop Applications, within the limits of the purchased plan;
22
+ 2. deploy Covered Versions in any number of Applications and environments, unless the purchased plan states otherwise;
23
+ 3. develop Applications **for third parties (Licensee's clients)** and deliver or transfer such Applications to them the client may operate, host, and use the delivered Application without a separate License Key;
24
+ 4. keep using Covered Versions **perpetually** this right survives the end of the License Term.
25
+
26
+ End users of Licensee's Applications do **not** need their own License Key: an Application ships `@ngxviewbuilder/runtime`, which is free and shows no license UI.
27
+
28
+ For clarity, development with the Software must be covered by a License Key held by **either side of a contract-work relationship**:
29
+
30
+ - If Licensee is a development company or agency, its License Key covers the development it performs for its clients (Section 2.3).
31
+ - If Licensee is the end customer of an Application, Licensee's License Key also covers **contractors and outsourced developers** working on that Application on Licensee's behalf. Such contractor use is limited to Licensee's Applications and does not extend to the contractor's own or other clients' projects.
32
+
33
+ Any party that develops with the Software outside these two cases needs its own License Key.
34
+
35
+ ## 3. Evaluation use
36
+
37
+ The Software may be used **without** a License Key for evaluation and development trial purposes only. In that mode the builder displays a watermark. Any production use requires a valid License Key.
38
+
39
+ ## 4. Updates
40
+
41
+ Versions of the Software released **after** the end of the License Term are not Covered Versions. Using them requires renewing the License Key; without renewal they run in degraded (watermarked) mode.
42
+
43
+ ## 5. Restrictions
44
+
45
+ Licensee may not:
46
+
47
+ 1. redistribute, resell, rent, lease, or sublicense the Software on its own (i.e. other than embedded in an Application);
48
+ 2. offer the Software, or a product derived from it, as a form-builder, view-builder, or low-code SDK/service that competes with the Software;
49
+ 3. remove, disable, alter, or circumvent the license-enforcement mechanisms (License Keys, watermark, signature or server validation), nor assist or permit anyone else to do so;
50
+ 4. exceed the seat, plan, or usage limits of the purchased plan;
51
+ 5. remove or alter copyright or license notices.
52
+
53
+ ## 6. Third-party software
54
+
55
+ The Software depends on third-party open-source packages installed separately from npm, each under its own license (MIT: `codemirror`, `@codemirror/*`, `jexl`, `prettier`, `lodash-es`; 0BSD: `tslib`). Those licenses govern those packages only; this agreement governs the Software.
56
+
57
+ ## 7. Ownership
58
+
59
+ The Software is licensed, not sold. Licensor retains all right, title, and interest in and to the Software.
60
+
61
+ ## 8. Warranty disclaimer
62
+
63
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
64
+
65
+ ## 9. Limitation of liability
66
+
67
+ TO THE MAXIMUM EXTENT PERMITTED BY LAW, LICENSOR SHALL NOT BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES, NOR FOR LOSS OF PROFITS, DATA, OR BUSINESS, ARISING FROM THE USE OF THE SOFTWARE. LICENSOR'S AGGREGATE LIABILITY UNDER THIS AGREEMENT SHALL NOT EXCEED THE LICENSE FEES PAID BY LICENSEE IN THE TWELVE (12) MONTHS PRECEDING THE CLAIM.
68
+
69
+ ## 10. Termination
70
+
71
+ This agreement terminates automatically if Licensee materially breaches it. Upon termination, Licensee must stop using the Software; rights to Covered Versions granted under Section 2.3 do not survive termination for breach. Sections 6–11 survive termination.
72
+
73
+ ## 11. Governing law
74
+
75
+ This agreement is governed by the laws of the Republic of Lithuania. Any disputes shall be resolved by the competent courts of the Republic of Lithuania.
76
+
77
+ ---
78
+
79
+ Questions about licensing: info@heydelabs.com · Pricing and License Keys: https://ngxviewbuilder.io/pricing
@@ -0,0 +1 @@
1
+ import{LicenseService as B,NvbIcon as C,UiTranslationService as G,elements as H}from"@ngxviewbuilder/designer";import*as v from"@angular/core";import{ChangeDetectionStrategy as U,Component as K,Injectable as Q,Pipe as Y,computed as X,inject as k,input as M}from"@angular/core";const J=["visibility","required","locked","value","reset","validation","data","action"];const V={"logic.visibleIf.when":"Visible when","logic.visibleIf.always":"Always visible","logic.visibleIf.never":"Always hidden","logic.requireIf.when":"Required when","logic.requireIf.always":"Always required","logic.requireIf.never":"Never required","logic.disableIf.when":"Disabled when","logic.disableIf.always":"Always disabled","logic.disableIf.never":"Never disabled","logic.readonlyIf.when":"Read-only when","logic.readonlyIf.always":"Always read-only","logic.readonlyIf.never":"Never read-only","logic.resetIf.when":"Cleared when","logic.resetIf.always":"Always cleared","logic.resetIf.never":"Never cleared","logic.expression.when":"Calculated as","logic.op.and":"and","logic.op.or":"or","logic.op.is":"is","logic.op.isNot":"is not","logic.op.not":"not","logic.op.isEmpty":"is empty","logic.op.isNotEmpty":"is not empty","logic.calc.when":"when","logic.calc.otherwise":"otherwise","logic.trigger.click":"On click","logic.trigger.submit":"On submit","logic.trigger.input":"While typing","logic.trigger.change":"On change","logic.trigger.blur":"On leaving the field","logic.trigger.focus":"On entering the field","logic.trigger.beforeLoad":"Before load","logic.trigger.onLoad":"On load","logic.trigger.afterLoad":"After load","logic.trigger.always":"On every event","logic.trigger.whenItRuns":"When it runs","logic.event.beforeLoad":"before the view loads","logic.event.onLoad":"when the view loads","logic.event.afterLoad":"after the view loads","logic.event.valueChanged":"when a value changes","logic.event.pageChanged":"when the page changes","logic.event.dialogClosed":"when a dialog closes","logic.event.validated":"after validation","logic.event.completed":"when the form is completed","logic.event.saveRequested":"when saving is requested","logic.validator.required":"Required","logic.validator.minlength":"At least {value} characters","logic.validator.maxlength":"At most {value} characters","logic.validator.min":"At least {value}","logic.validator.max":"At most {value}","logic.validator.pattern":"Must match {value}","logic.validator.email":"Must be an e-mail address","logic.validator.strictoptions":"Must be one of the listed options","logic.validator.validWhen":"Valid when","logic.validator.onlyWhen":"only when","logic.validator.message":'Message: "{message}"',"logic.data.optionsFrom":"Options come from","logic.data.valueFrom":"Value loaded from","logic.data.sending":"sending","logic.data.requestUses":"Request uses","logic.data.sourceType":"{type} data source","logic.dataSourceType.rest":"REST","logic.dataSourceType.route":"Route","logic.dataSourceType.local":"Local","logic.dataSourceType.websocket":"WebSocket","logic.action.sets":"sets","logic.action.changesProperty":"changes {property} of","logic.action.aProperty":"a property","logic.action.to":"to","logic.action.replacesOptions":"replaces the options of","logic.action.reloads":"reloads","logic.action.calls":"calls","logic.action.aDataSource":"a data source","logic.action.with":"with","logic.action.putsAnswerIn":"and puts the answer in","logic.action.sendsMessageOver":"sends a message over","logic.action.aWebsocket":"a websocket","logic.action.opensDialog":"opens the dialog","logic.action.closesDialog":"closes the dialog","logic.action.togglesDialog":"toggles the dialog","logic.action.goesTo":"goes to {target}","logic.action.anotherPage":"another page","logic.action.showsMessage":'shows the message "{message}"',"logic.action.checksForm":"checks the form","logic.action.submitsForm":"submits the form","logic.action.movesProcess":"moves the process to {state}","logic.action.nextState":"the next state","logic.action.runsAction":"runs an action","logic.action.onlyWhen":"only when","logic.variable.view":"View variable","logic.variable.host":"Host value","logic.variable.calculatedAs":"Calculated as","logic.variable.loadedFrom":"Loaded from","logic.variable.writesTo":"Writes its value to","logic.automation.viewRule":"View rule","logic.automation.trigger":"Trigger {event}","logic.automation.runs":"Runs {event}","logic.automation.applies":"Applies","logic.automation.when":"when","logic.automation.then":"Then","logic.automation.otherwise":"Otherwise","logic.context.column":"Column of {parent}","logic.context.item":"Each item of {parent}","logic.context.in":"In {parent}","logic.missing.field":"Not in this view (field)","logic.missing.dataSource":"Not in this view (data source)","logic.issue.selfReference":"{name} is calculated from its own value, so the calculation never settles.","logic.issue.unknownTarget":'{owner} changes "{name}", which is not in this view.',"logic.issue.unknownDataSource":'{owner} uses the data source "{name}" ({property}), which this view does not define.',"logic.issue.unknownReference":'{owner} ({property}) refers to "{name}", which is not a field, data source or variable in this view.',"logic.issue.cycle":"These values calculate each other in a loop: {names}.","proGate.checking":"Checking the license key…","proGate.missing.eyebrow":"No license key","proGate.expired.eyebrow":"License expired","proGate.invalid.eyebrow":"License key not verified","proGate.missing.text":"This part of the builder comes with an NGX View Builder license. Put your key in the builder settings as licenseKey and it turns on right away.","proGate.expired.textOn":"The license key expired on {date}.","proGate.expired.text":"The license key has expired.","proGate.expired.renew":"Renew the license and everything set up here is still in place.","proGate.invalid.text":"The license key in the builder settings could not be verified. Check that the whole key was copied, or take a fresh one from your license console.","proGate.plans":"See plans","proGate.docs":"Where the key goes"};const N={...V};function ee(e){Object.assign(N,e)}function I(e,t){if(!t)return e;return e.replace(/\{(\w+)\}/g,(s,a)=>Object.prototype.hasOwnProperty.call(t,a)?String(t[a]??""):s)}const Z=(e,t,s)=>I(N[e]??s??e,t);function z(e){return(t,s,a)=>I(e.translate(t,N[t]??a??t),s)}var O=class R{t=z(k(G));static ɵfac=v.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"22.2.1",ngImport:v,type:R,deps:[],target:v.ɵɵFactoryTarget.Injectable});static ɵprov=v.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"22.2.1",ngImport:v,type:R,providedIn:"root"})};v.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"22.2.1",ngImport:v,type:O,decorators:[{type:Q,args:[{providedIn:"root"}]}]});var T=class D{i18n=k(O);transform(t,s){return this.i18n.t(t,s??void 0)}static ɵfac=v.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"22.2.1",ngImport:v,type:D,deps:[],target:v.ɵɵFactoryTarget.Pipe});static ɵpipe=v.ɵɵngDeclarePipe({minVersion:"14.0.0",version:"22.2.1",ngImport:v,type:D,isStandalone:true,name:"nvbT",pure:false})};v.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"22.2.1",ngImport:v,type:T,decorators:[{type:Y,args:[{name:"nvbT",pure:false}]}]});const te=[{key:"visibleIf",kind:"visibility",constants:true},{key:"requireIf",kind:"required",constants:true},{key:"disableIf",kind:"locked",constants:true},{key:"readonlyIf",kind:"locked",constants:true},{key:"resetIf",kind:"reset",constants:true},{key:"expression",kind:"value",constants:false}];const se=new Set(["item","row","panel","value","index","data","parent","this","true","false","null"]);const ae=new Set(["click","submit","input","change","blur","focus","beforeLoad","onLoad","afterLoad","always"]);const ne=new Set(["beforeLoad","onLoad","afterLoad","valueChanged","pageChanged","dialogClosed","validated","completed","saveRequested"]);const ie=new Set(["required","minlength","maxlength","min","max","pattern","email","strictoptions"]);const re=new Map(H.map(e=>[String(e.type),e]));function oe(e,t={}){return new le(u(e),t).build()}function ce(e,t){const s=e.nodes.find(i=>i.id===t);if(!s)return null;const a=i=>{const o=new Map([[t,0]]);const r=[t];while(r.length>0){const n=r.shift();const l=o.get(n);e.edges.forEach(g=>{const c=i?g.from===n?g.to:null:g.to===n?g.from:null;if(c&&!o.has(c)){o.set(c,l+1);r.push(c)}})}o.delete(t);return Array.from(o,([n,l])=>({id:n,depth:l})).sort((n,l)=>n.depth-l.depth)};return{node:s,upstream:a(false),downstream:a(true)}}function W(e){return e.map(t=>"ref"in t?t.label:t.text).join("").replace(/\s+/g," ").trim()}function f(e){return`el:${e}`}var le=class{structure;options;nodes=new Map;rules=[];issues=[];pages=[];definitions=new Map;pathsByName=new Map;dataSourceNames=new Set;variableNames=new Set;order=0;ruleCounter=0;t;constructor(e,t){this.structure=e;this.options=t;this.t=t.translate??Z}build(){this.collectElements();this.collectDataSources();this.collectVariables();this.definitions.forEach((t,s)=>this.readElementRules(s,t));this.readDataSourceRules();this.readVariableRules();this.readAutomation("rules");this.readAutomation("triggers");const e=this.buildEdges();this.findCycles(e);return{nodes:Array.from(this.nodes.values()).sort((t,s)=>t.order-s.order),rules:this.rules,edges:e,issues:this.issues,pages:this.pages}}collectElements(){const e=u(this.structure["elements"]);(Array.isArray(this.structure["pages"])?this.structure["pages"]:[]).forEach(t=>{const s=u(t);const a=String(s["name"]??"").trim();const i=w(u(e[a])["label"])||a;this.pages.push({name:a,label:i});this.walkLayout(s["rows"],{pageName:a,pageLabel:i,parentPath:"",parentDefinition:null})});Object.entries(e).forEach(([t,s])=>{const a=u(s);if(String(a["type"]??"")==="page"||this.definitions.has(t))return;this.addElement(t,a,{pageName:"",pageLabel:"",parentPath:""})});Array.from(this.definitions.entries()).forEach(([t,s])=>this.addUnplacedChildren(t,s))}walkLayout(e,t){if(Array.isArray(e)){e.forEach(o=>this.walkLayout(o,t));return}if(!e||typeof e!=="object")return;const s=e;const a=String(s["elementRef"]??"").trim();let i=t;if(a){const o=u(u(t.parentDefinition?.["template"])[a]);const r=Object.keys(o).length>0;const n=r?o:u(u(this.structure["elements"])[a]);const l=r&&t.parentPath?`${t.parentPath}.${a}`:a;if(!this.definitions.has(l)&&Object.keys(n).length>0)this.addElement(l,n,t);i={...t,parentPath:l,parentDefinition:n}}Object.entries(s).forEach(([o,r])=>{if(o!=="elementRef"&&r&&typeof r==="object")this.walkLayout(r,i)})}addUnplacedChildren(e,t){const s=u(t["template"]);Object.entries(s).forEach(([a,i])=>{const o=`${e}.${a}`;if(!this.definitions.has(o)){const r=this.nodes.get(f(e));this.addElement(o,u(i),{pageName:r?.pageName??"",pageLabel:r?.pageLabel??"",parentPath:e});this.addUnplacedChildren(o,u(i))}});if(String(t["type"]??"")==="dynamicTable"&&Array.isArray(t["columns"]))t["columns"].forEach(a=>{const i=u(a);const o=String(i["name"]??"").trim();const r=`${e}.${o}`;if(o&&!this.definitions.has(r)){const n=this.nodes.get(f(e));this.addElement(r,i,{pageName:n?.pageName??"",pageLabel:n?.pageLabel??"",parentPath:e})}})}addElement(e,t,s){const a=String(t["type"]??"").trim();const i=re.get(a);const o=e.split(".").pop();this.definitions.set(e,t);this.pathsByName.set(o,[...this.pathsByName.get(o)??[],e]);this.nodes.set(f(e),{id:f(e),kind:"element",name:e,label:ge(t,o),type:a,typeLabel:this.options.typeLabels?.[a]??this.t(`element.${a}`,void 0,i?.label??S(a)),group:String(i?.groupCode??(a==="dynamicTable"?"tables":"")),pageName:s.pageName||void 0,pageLabel:s.pageLabel||void 0,parent:s.parentPath||void 0,context:this.describeContext(s.parentPath)||void 0,order:this.order++,required:t["required"]===true||void 0,hidden:t["hidden"]===true||void 0})}describeContext(e){const t=e?this.nodes.get(f(e)):void 0;if(!t)return"";switch(t.type){case"dynamicTable":return this.t("logic.context.column",{parent:t.label});case"dynamicPanel":return this.t("logic.context.item",{parent:t.label});default:return this.t("logic.context.in",{parent:t.label})}}collectDataSources(){(Array.isArray(this.structure["dataSources"])?this.structure["dataSources"]:[]).forEach(e=>{const t=u(e);const s=String(t["name"]??"").trim();if(!s)return;this.dataSourceNames.add(s);this.nodes.set(`ds:${s}`,{id:`ds:${s}`,kind:"dataSource",name:s,label:w(t["title"])||s,type:String(t["type"]??""),typeLabel:this.t("logic.data.sourceType",{type:this.t(`logic.dataSourceType.${String(t["type"]??"rest")}`,void 0,S(String(t["type"]??"rest")))}),order:1e5+this.order++})})}collectVariables(){const e=u(this.structure["settings"]);(Array.isArray(e["variables"])?e["variables"]:[]).forEach(t=>{const s=u(t);const a=String(s["name"]??"").trim();if(a)this.addVariable(a,w(s["title"])||a,this.t("logic.variable.view"))});(this.options.externalNames??[]).forEach(t=>{if(t&&!this.variableNames.has(t))this.addVariable(t,t,this.t("logic.variable.host"))})}addVariable(e,t,s){this.variableNames.add(e);this.nodes.set(`var:${e}`,{id:`var:${e}`,kind:"variable",name:e,label:t,typeLabel:s,order:2e5+this.order++})}readElementRules(e,t){const s=f(e);te.forEach(({key:a,kind:i,constants:o})=>{const r=String(t[a]??"").trim();if(!r)return;const n=r.toLowerCase();if(o&&(n==="true"||n==="false")){this.addRule({kind:i,owner:s,property:a,expression:r,segments:[{text:this.t(`logic.${a}.${n==="true"?"always":"never"}`)}],sources:[],targets:[]});return}const l=a==="expression"?this.parseCalculation(r,e):this.parseExpression(r,e);this.addRule({kind:i,owner:s,property:a,expression:r,segments:[{text:`${this.t(`logic.${a}.when`)} `},...l.segments],sources:l.refs,targets:[]})});this.readValidators(e,s,t);this.readElementDataSource(e,s,t);this.readActions(e,s,t["events"],"events")}readValidators(e,t,s){(Array.isArray(s["validators"])?s["validators"]:[]).forEach((a,i)=>{const o=u(a);const r=String(o["type"]??"").trim().toLowerCase();const n=String(o["value"]??"").trim();const l=String(o["condition"]??"").trim();const g=String(o["applyIf"]??"").trim();const c=w(o["message"]);const h=[];const p=[];if(r==="custom"&&l){const b=this.parseExpression(l,e);h.push({text:`${this.t("logic.validator.validWhen")} `},...b.segments);p.push(...b.refs)}else h.push({text:ie.has(r)?this.t(`logic.validator.${r}`,{value:n}):`${S(r||"rule")}${n?` ${n}`:""}`});if(g){const b=this.parseExpression(g,e);h.push({text:`, ${this.t("logic.validator.onlyWhen")} `},...b.segments);p.push(...b.refs)}if(c)h.push({text:`. ${this.t("logic.validator.message",{message:c})}`});this.addRule({kind:"validation",owner:t,property:`validators[${i}]`,subtype:r||void 0,expression:l||g||void 0,segments:h,sources:p,targets:[]})})}readElementDataSource(e,t,s){const a=u(s["dataSource"]);const i=String(a["name"]??s["dataSourceName"]??"").trim();if(!i)return;const o=this.resolveDataSource(i,t,"dataSource");const r=String(a["useFor"]??"option");const n=o?[o]:[];const l=[{text:`${this.t(r==="value"?"logic.data.valueFrom":"logic.data.optionsFrom")} `},o?{ref:o,label:this.labelOf(o)}:{text:i}];const g=this.readParams(a["params"],e);if(g.segments.length>0){l.push({text:`, ${this.t("logic.data.sending")} `},...g.segments);n.push(...g.refs)}(Array.isArray(a["refreshPaths"])?a["refreshPaths"]:[]).forEach(c=>{const h=this.resolveToken(String(c??""),e);if(h)n.push(h)});this.addRule({kind:"data",owner:t,property:"dataSource",segments:l,sources:n,targets:[]})}readActions(e,t,s,a,i){(Array.isArray(s)?s:[]).forEach((o,r)=>{const n=u(o);const l=String(n["type"]??"").trim();const g=String(n["trigger"]??"").trim();const c=[];const h=[];const p=[];let b="action";const E=i??(g?ae.has(g)?this.t(`logic.trigger.${g}`):S(g):this.t("logic.trigger.whenItRuns"));p.push({text:`${E}: `});const _=m=>{(Array.isArray(m)?m.map(d=>String(d??"")):String(m??"").split(",")).map(d=>d.trim()).filter(Boolean).forEach((d,x)=>{const y=this.resolveTarget(d,t,e);if(x>0)p.push({text:", "});p.push(y?{ref:y,label:this.labelOf(y)}:{text:d});if(y)h.push(y)})};switch(l){case"setValue":case"setElementProperty":{b="value";const m=String(n["setValueTargetPath"]??n["targetElement"]??n["dataPath"]??"").trim();p.push({text:`${l==="setElementProperty"?this.t("logic.action.changesProperty",{property:String(n["propertyKey"]??"")||this.t("logic.action.aProperty")}):this.t("logic.action.sets")} `});_(m);const d=String(n["setValueValue"]??n["valueExpression"]??n["value"]??"").trim();if(d){const x=this.parseExpression(d,e);p.push({text:` ${this.t("logic.action.to")} `},...x.segments);c.push(...x.refs)}break}case"setOptions":b="data";p.push({text:`${this.t("logic.action.replacesOptions")} `});_(n["setOptionsTargetElement"]);break;case"reloadElements":b="data";p.push({text:`${this.t("logic.action.reloads")} `});_(n["reloadElementNames"]);break;case"dataSource":{b="data";const m=String(n["dataSourceName"]??"").trim();const d=m?this.resolveDataSource(m,t,`${a}[${r}]`):null;p.push({text:`${this.t("logic.action.calls")} `},d?{ref:d,label:this.labelOf(d)}:{text:m||this.t("logic.action.aDataSource")});if(d)h.push(d);const x=this.readParams(n["params"],e);if(x.segments.length>0){p.push({text:` ${this.t("logic.action.with")} `},...x.segments);c.push(...x.refs)}const y=String(n["responseTargetElement"]??n["responseTargetPath"]??"").trim();if(y){p.push({text:` ${this.t("logic.action.putsAnswerIn")} `});_(y)}break}case"sendMessage":{const m=String(n["dataSourceName"]??"").trim();const d=m?this.resolveDataSource(m,t,`${a}[${r}]`):null;p.push({text:`${this.t("logic.action.sendsMessageOver")} `},d?{ref:d,label:this.labelOf(d)}:{text:m||this.t("logic.action.aWebsocket")});if(d)h.push(d);break}case"dialog":p.push({text:`${this.t(String(n["dialogOperation"]??"open")==="close"?"logic.action.closesDialog":String(n["dialogOperation"]??"")==="toggle"?"logic.action.togglesDialog":"logic.action.opensDialog")} `});_(n["dialogName"]);break;case"navigate":p.push({text:this.t("logic.action.goesTo",{target:String(n["navigateTo"]??"").trim()||this.t("logic.action.anotherPage")})});break;case"toast":p.push({text:this.t("logic.action.showsMessage",{message:w(n["toastMessage"])||w(n["toastTitle"])||"…"})});break;case"validate":p.push({text:this.t("logic.action.checksForm")});break;case"submit":p.push({text:this.t("logic.action.submitsForm")});break;case"transitionProcess":case"setProcessState":p.push({text:this.t("logic.action.movesProcess",{state:String(n["processState"]??n["processTransitionId"]??"").trim()||this.t("logic.action.nextState")})});break;default:p.push({text:l?S(l).toLowerCase():this.t("logic.action.runsAction")})}String(n["reloadDataSourceNames"]??"").split(",").map(m=>m.trim()).filter(Boolean).forEach(m=>{const d=this.resolveDataSource(m,t,`${a}[${r}]`);if(d){b=b==="action"?"data":b;p.push({text:`, ${this.t("logic.action.reloads")} `},{ref:d,label:this.labelOf(d)});h.push(d)}});const A=String(n["condition"]??"").trim();if(A){const m=this.parseExpression(A,e);p.push({text:`, ${this.t("logic.action.onlyWhen")} `},...m.segments);c.push(...m.refs)}this.addRule({kind:b,owner:t,property:`${a}[${r}]`,subtype:l||void 0,trigger:g||void 0,expression:A||void 0,segments:p,sources:c,targets:h})})}readParams(e,t){const s=Array.isArray(e)?e:[];const a=[];const i=[];s.forEach(o=>{const r=u(o);const n=String(r["name"]??"").trim();const l=String(r["value"]??"").trim();if(!n||!l)return;if(a.length>0)a.push({text:", "});a.push({text:`${n} = `});if(r["isPlainValue"]===true){a.push({text:l});return}const g=/^[A-Za-z_$][\w$]*(\.[\w$]+)*$/.test(l);const c=this.parseExpression(g?`{${l}}`:l,t);a.push(...c.segments);i.push(...c.refs)});return{segments:a,refs:i}}readDataSourceRules(){(Array.isArray(this.structure["dataSources"])?this.structure["dataSources"]:[]).forEach(e=>{const t=u(e);const s=String(t["name"]??"").trim();if(!s)return;const a=new Set;L(t["params"]).forEach(o=>{this.parseExpression(o,null,true).refs.forEach(r=>a.add(r))});if(a.size===0)return;const i=[{text:`${this.t("logic.data.requestUses")} `}];Array.from(a).forEach((o,r)=>{if(r>0)i.push({text:", "});i.push({ref:o,label:this.labelOf(o)})});this.addRule({kind:"data",owner:`ds:${s}`,property:"params",segments:i,sources:Array.from(a),targets:[]})})}readVariableRules(){const e=u(this.structure["settings"]);(Array.isArray(e["variables"])?e["variables"]:[]).forEach(t=>{const s=u(t);const a=String(s["name"]??"").trim();if(!a)return;const i=`var:${a}`;const o=String(s["sourceType"]??"").trim();const r=String(s["expression"]??"").trim();if(o==="expression"&&r){const g=this.parseCalculation(r,null);this.addRule({kind:"value",owner:i,property:"expression",expression:r,segments:[{text:`${this.t("logic.variable.calculatedAs")} `},...g.segments],sources:g.refs,targets:[]})}else if(o==="dataSource"){const g=this.resolveDataSource(String(s["source"]??""),i,"source");if(g)this.addRule({kind:"data",owner:i,property:"source",segments:[{text:`${this.t("logic.variable.loadedFrom")} `},{ref:g,label:this.labelOf(g)}],sources:[g],targets:[]})}const n=String(s["targetPath"]??"").trim();const l=n?this.resolveToken(n,null):null;if(l)this.addRule({kind:"value",owner:i,property:"targetPath",segments:[{text:`${this.t("logic.variable.writesTo")} `},{ref:l,label:this.labelOf(l)}],sources:[],targets:[l]})})}readAutomation(e){const t=u(this.structure["settings"]);(Array.isArray(t[e])?t[e]:[]).forEach((s,a)=>{const i=u(s);const o=String(i["id"]??`${e}${a+1}`).trim();const r=e==="rules"?"rule":"trigger";const n=`${r}:${o}`;const l=w(i["title"])||S(o);this.nodes.set(n,{id:n,kind:r,name:o,label:l,typeLabel:e==="rules"?this.t("logic.automation.viewRule"):this.t("logic.automation.trigger",{event:this.eventWords(String(i["event"]??""))}).trim(),order:3e5+this.order++});const g=[];const c=[];const h=String(i["condition"]??"").trim();if(e==="triggers")c.push({text:this.t("logic.automation.runs",{event:this.eventWords(String(i["event"]??""))})});else c.push({text:this.t("logic.automation.applies")});if(h){const p=this.parseExpression(h,null);c.push({text:` ${this.t("logic.automation.when")} `},...p.segments);g.push(...p.refs)}(Array.isArray(i["watchPaths"])?i["watchPaths"]:[]).forEach(p=>{const b=this.resolveToken(String(p??""),null);if(b)g.push(b)});this.addRule({kind:"action",owner:n,property:"condition",expression:h||void 0,segments:c,sources:g,targets:[]});this.readActions(null,n,i["actions"],"actions",this.t("logic.automation.then"));if(e==="rules")this.readActions(null,n,i["otherwiseActions"],"otherwiseActions",this.t("logic.automation.otherwise"))})}readOperators(e){return e.replace(/\s*&&\s*/g,` ${this.t("logic.op.and")} `).replace(/\s*\|\|\s*/g,` ${this.t("logic.op.or")} `).replace(/\s*!==?\s*/g,` ${this.t("logic.op.isNot")} `).replace(/\s*===?\s*/g,` ${this.t("logic.op.is")} `).replace(/!(?=\s*[({A-Za-z])/g,`${this.t("logic.op.not")} `).replace(/\s+/g," ")}eventWords(e){return ne.has(e)?this.t(`logic.event.${e}`):e}addRule(e){const t=$(e.sources).filter(a=>a!==e.owner||e.property!=="expression");if(e.property==="expression"&&e.sources.includes(e.owner))this.issues.push({severity:"warning",code:"selfReference",message:this.t("logic.issue.selfReference",{name:this.labelOf(e.owner)}),nodeIds:[e.owner]});const s=q(e.segments);this.rules.push({...e,id:`r${++this.ruleCounter}`,segments:s,summary:W(s),sources:t,targets:$(e.targets)})}parseExpression(e,t,s=false){const a=[];const i=[];if(!s){const l=this.t("logic.op.isNotEmpty");const g=this.t("logic.op.isEmpty");e=e.replace(/!\s*isEmpty\(\s*(\{[^{}()]+\})\s*\)/g,(c,h)=>`${h} ${l}`).replace(/\bisEmpty\(\s*(\{[^{}()]+\})\s*\)/g,(c,h)=>`${h} ${g}`)}const o=s?/\{\s*([A-Za-z_$][\w$]*(?:\.[\w$]+|\[\d+\])*)\s*\}/g:/\{\s*([A-Za-z_$][\w$]*(?:\.[\w$]+|\[\d+\])*)\s*\}|\b((?:panel|row)\.[A-Za-z_$][\w$]*)/g;let r=0;let n;while((n=o.exec(e))!==null){if(!s)a.push({text:this.readOperators(e.slice(r,n.index))});const l=(n[1]??n[2]??"").trim();const g=this.resolveToken(l,t);if(g){i.push(g);a.push({ref:g,label:this.labelOf(g)})}else a.push({text:l});r=n.index+n[0].length}if(!s)a.push({text:this.readOperators(e.slice(r))});return{segments:q(a),refs:$(i)}}parseCalculation(e,t){const s=e.replace(/'[^']*'|"[^"]*"|\([^()]*\)/g,l=>"_".repeat(l.length));const a=s.indexOf("?");const i=s.indexOf(":",a+1);if(!(a>0&&i>a&&s.indexOf("?",a+1)===-1&&s.indexOf(":",i+1)===-1))return this.parseExpression(e,t);const o=this.parseExpression(e.slice(0,a).trim(),t);const r=this.parseExpression(e.slice(a+1,i).trim(),t);const n=this.parseExpression(e.slice(i+1).trim(),t);return{segments:q([...r.segments,{text:` ${this.t("logic.calc.when")} `},...o.segments,{text:`, ${this.t("logic.calc.otherwise")} `},...n.segments]),refs:$([...o.refs,...r.refs,...n.refs])}}resolveToken(e,t){const s=e.replace(/\[\d+\]/g,"").trim();if(!s)return null;const a=s.split(".");const i=a[0];if((i==="panel"||i==="row")&&a.length>1){const r=t&&t.includes(".")?t.slice(0,t.lastIndexOf(".")):"";const n=r?`${r}.${a[1]}`:"";if(n&&this.definitions.has(n))return f(n);return null}if(i.startsWith("__")||i.startsWith("$")||se.has(i))return null;for(let r=a.length;r>0;r--){const n=a.slice(0,r).join(".");if(this.definitions.has(n))return f(n)}const o=this.pathsByName.get(i);if(o&&o.length>0)return f(o[0]);if(this.variableNames.has(i))return`var:${i}`;if(this.dataSourceNames.has(i))return`ds:${i}`;return this.missing(i)}resolveTarget(e,t,s){const a=this.resolveToken(e,s);if(a?.startsWith("missing:"))this.issues.push({severity:"error",code:"unknownTarget",message:this.t("logic.issue.unknownTarget",{owner:this.labelOf(t),name:e}),nodeIds:[t,a]});return a}resolveDataSource(e,t,s){const a=e.trim();if(!a)return null;if(this.dataSourceNames.has(a))return`ds:${a}`;const i=this.missing(a,"dataSource");this.issues.push({severity:"error",code:"unknownDataSource",message:this.t("logic.issue.unknownDataSource",{owner:this.labelOf(t),name:a,property:s}),nodeIds:[t,i]});return i}missing(e,t="field"){const s=`missing:${e}`;if(!this.nodes.has(s))this.nodes.set(s,{id:s,kind:"missing",name:e,label:e,typeLabel:this.t(`logic.missing.${t}`),order:4e5+this.order++});return s}labelOf(e){return this.nodes.get(e)?.label??e.replace(/^[a-z]+:/,"")}buildEdges(){const e=new Map;const t=(s,a,i,o)=>{if(s===a)return;const r=`${s}>${a}>${i}`;if(!e.has(r))e.set(r,{id:r,from:s,to:a,kind:i,ruleId:o})};this.rules.forEach(s=>{s.sources.forEach(a=>t(a,s.owner,s.kind,s.id));s.targets.forEach(a=>t(s.owner,a,s.kind,s.id))});this.rules.filter(s=>s.sources.some(a=>a.startsWith("missing:"))).forEach(s=>{s.sources.filter(a=>a.startsWith("missing:")).forEach(a=>{const i=s.property;this.issues.push({severity:"warning",code:"unknownReference",message:this.t("logic.issue.unknownReference",{owner:this.labelOf(s.owner),property:i,name:this.labelOf(a)}),nodeIds:[s.owner,a],ruleId:s.id})})});return Array.from(e.values())}findCycles(e){const t=new Set(this.rules.filter(c=>c.property==="expression").map(c=>c.id));const s=e.filter(c=>t.has(c.ruleId));const a=new Map;s.forEach(c=>a.set(c.from,[...a.get(c.from)??[],c.to]));let i=0;const o=new Map;const r=new Map;const n=[];const l=new Set;const g=c=>{o.set(c,i);r.set(c,i);i++;n.push(c);l.add(c);(a.get(c)??[]).forEach(h=>{if(!o.has(h)){g(h);r.set(c,Math.min(r.get(c),r.get(h)))}else if(l.has(h))r.set(c,Math.min(r.get(c),o.get(h)))});if(r.get(c)===o.get(c)){const h=[];let p;do{p=n.pop();l.delete(p);h.push(p)}while(p!==c);if(h.length>1){const b=h.map(E=>this.labelOf(E)).reverse().join(" → ");this.issues.push({severity:"error",code:"cycle",message:this.t("logic.issue.cycle",{names:b}),nodeIds:h})}}};Array.from(a.keys()).forEach(c=>{if(!o.has(c))g(c)})}};function u(e){return e&&typeof e==="object"&&!Array.isArray(e)?e:{}}function $(e){return Array.from(new Set(e.filter(Boolean)))}function w(e){return String(e??"").replace(/<[^>]*>/g," ").replace(/&nbsp;/g," ").replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/\s+/g," ").trim()}function ge(e,t){for(const s of["label","title","text","checkboxLabel","caption","alt"]){const a=w(e[s]);if(a)return a}return t}function S(e){const t=String(e??"").replace(/([a-z0-9])([A-Z])/g,"$1 $2").replace(/[_-]+/g," ").trim().toLowerCase();return t?t.charAt(0).toUpperCase()+t.slice(1):""}function q(e){const t=[];e.forEach(s=>{const a=t[t.length-1];if("text"in s&&a&&"text"in a)a.text+=s.text;else if(!("text"in s)||s.text)t.push({...s})});return t}function L(e,t=[]){if(typeof e==="string")t.push(e);else if(Array.isArray(e))e.forEach(s=>L(s,t));else if(e&&typeof e==="object")Object.values(e).forEach(s=>L(s,t));return t}const F={lock:"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\" viewBox=\"0 -960 960 960\"><path d=\"M220-80q-24.75 0-42.37-17.63Q160-115.25 160-140v-434q0-24.75 17.63-42.38Q195.25-634 220-634h70v-96q0-78.85 55.61-134.42Q401.21-920 480.11-920q78.89 0 134.39 55.58Q670-808.85 670-730v96h70q24.75 0 42.38 17.62Q800-598.75 800-574v434q0 24.75-17.62 42.37Q764.75-80 740-80H220Zm0-60h520v-434H220v434Zm314.5-162.03Q557-324.06 557-355q0-30-22.67-54.5t-54.5-24.5q-31.83 0-54.33 24.5t-22.5 55q0 30.5 22.67 52.5t54.5 22q31.83 0 54.33-22.03ZM350-634h260v-96q0-54.17-37.88-92.08-37.88-37.92-92-37.92T388-822.08q-38 37.91-38 92.08v96ZM220-140v-434 434Z\"/></svg>",account_tree:"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\" viewBox=\"0 -960 960 960\"><path d=\"M604-120v-125H450v-410h-93v130H80v-315h277v125h247v-125h276v315H604v-130h-94v350h94v-130h276v315H604ZM140-780v195-195Zm524 405v195-195Zm0-405v195-195Zm0 195h156v-195H664v195Zm0 405h156v-195H664v195ZM140-585h157v-195H140v195Z\"/></svg>",filter_list:"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\" viewBox=\"0 -960 960 960\"><path d=\"M400-240v-60h160v60H400ZM240-450v-60h480v60H240ZM120-660v-60h720v60H120Z\"/></svg>",functions:"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\" viewBox=\"0 -960 960 960\"><path d=\"M240-160v-63l275-257-275-257v-63h480v100H396l235 220-235 220h324v100H240Z\"/></svg>",cloud_done:"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\" viewBox=\"0 -960 960 960\"><path d=\"m412-279 230-230-40-40-189 189-100-100-41 41 140 140ZM251-160q-88 0-149.5-61.5T40-371q0-78 50-137t127-71q20-97 94-158.5T482-799q112 0 189 81.5T748-522v24q72-2 122 46.5T920-329q0 69-50 119t-119 50H251Zm0-60h500q45 0 77-32t32-77q0-45-32-77t-77-32h-63v-84q0-91-61-154t-149-63q-88 0-149.5 63T267-522h-19q-62 0-105 43.5T100-371q0 63 44 107t107 44Zm229-260Z\"/></svg>",cloud_off:"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\" viewBox=\"0 -960 960 960\"><path d=\"M818-56 703-171H248q-88 0-148-59T40-377q0-80 50.5-134T217-577q2-14 6.5-31.5T236-640L70-806l42-42L861-99l-43 43ZM248-231h397L285-591q-11 15-14.5 34t-3.5 37h-19q-62 0-105 39.5t-43 101q0 61.5 43 105T248-231Zm216-181Zm390 210-47-47q25-17 39-38t14-50q0-43-31-73.5T755-441h-67v-81q0-88-61-147.5T478.47-729q-28.47 0-60.97 9T358-691l-42-42q36-29 77.5-42.5T478-789q111 0 190.5 79T748-520v21q72-1 122 45t50 117q0 35-16.5 73.5T854-202ZM583-470Z\"/></svg>",arrow_forward:"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\" viewBox=\"0 -960 960 960\"><path d=\"M686-450H160v-60h526L438-758l42-42 320 320-320 320-42-42 248-248Z\"/></svg>"};const pe="https://ngxviewbuilder.io/pricing";const he="https://ngxviewbuilder.io/developers/licensing";var j=class P{license=k(B);ui=k(G);feature=M("",...ngDevMode?[{debugName:"feature"}]:[]);compact=M(false,...ngDevMode?[{debugName:"compact"}]:[]);lockIcon=F.lock;pricingUrl=pe;docsUrl=he;state=this.license.proAccess;expiresOn=X(()=>{const t=this.license.licenseExpiresAt();return t?t.toLocaleDateString(this.ui.getLanguage()||void 0,{year:"numeric",month:"short",day:"numeric"}):""},...ngDevMode?[{debugName:"expiresOn"}]:[]);static ɵfac=v.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"22.2.1",ngImport:v,type:P,deps:[],target:v.ɵɵFactoryTarget.Component});static ɵcmp=v.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"22.2.1",type:P,isStandalone:true,selector:"nvb-pro-feature-gate",inputs:{feature:{classPropertyName:"feature",publicName:"feature",isSignal:true,isRequired:false,transformFunction:null},compact:{classPropertyName:"compact",publicName:"compact",isSignal:true,isRequired:false,transformFunction:null}},ngImport:v,template:"@switch (state()) {\n @case ('ready') {\n <ng-content />\n }\n @case ('checking') {\n <div class=\"nvb-pro-gate nvb-pro-gate--checking\" [class.nvb-pro-gate--compact]=\"compact()\" role=\"status\" data-testid=\"pro-gate-checking\">\n <span class=\"nvb-pro-gate__spinner\" aria-hidden=\"true\"></span>\n <span>{{ 'proGate.checking' | nvbT }}</span>\n </div>\n }\n @default {\n <section\n class=\"nvb-pro-gate\"\n [class.nvb-pro-gate--compact]=\"compact()\"\n [attr.data-state]=\"state()\"\n data-testid=\"pro-gate-locked\"\n >\n <span class=\"nvb-pro-gate__badge\" aria-hidden=\"true\">\n <nvb-icon [svg]=\"lockIcon\" />\n </span>\n <div class=\"nvb-pro-gate__body\">\n <p class=\"nvb-pro-gate__eyebrow\">\n @switch (state()) {\n @case ('missing') {\n {{ 'proGate.missing.eyebrow' | nvbT }}\n }\n @case ('expired') {\n {{ 'proGate.expired.eyebrow' | nvbT }}\n }\n @default {\n {{ 'proGate.invalid.eyebrow' | nvbT }}\n }\n }\n </p>\n <h3 class=\"nvb-pro-gate__title\">{{ feature() }}</h3>\n <p class=\"nvb-pro-gate__text\">\n @switch (state()) {\n @case ('missing') {\n {{\n 'proGate.missing.text' | nvbT\n }}\n }\n @case ('expired') {\n @if (expiresOn()) {\n {{ 'proGate.expired.textOn' | nvbT: { date: expiresOn() } }}\n } @else {\n {{ 'proGate.expired.text' | nvbT }}\n }\n {{ 'proGate.expired.renew' | nvbT }}\n }\n @default {\n {{\n 'proGate.invalid.text' | nvbT\n }}\n }\n }\n </p>\n <div class=\"nvb-pro-gate__actions\">\n <a\n class=\"nvb-button nvb-button--primary nvb-button--sm\"\n [href]=\"pricingUrl\"\n target=\"_blank\"\n rel=\"noopener\"\n data-testid=\"pro-gate-plans\"\n >{{ 'proGate.plans' | nvbT }}</a>\n <a\n class=\"nvb-button nvb-button--neutral nvb-button--sm\"\n [href]=\"docsUrl\"\n target=\"_blank\"\n rel=\"noopener\"\n data-testid=\"pro-gate-docs\"\n >{{ 'proGate.docs' | nvbT }}</a>\n </div>\n </div>\n </section>\n }\n}\n",styles:[":host{display:contents}.nvb-pro-gate{display:flex;gap:14px;align-items:flex-start;max-width:520px;margin:72px auto 0;padding:20px 22px;border:1px solid var(--nvb-color-neutral-200);border-radius:var(--nvb-radius-lg, 10px);background:var(--nvb-color-neutral-000);color:var(--nvb-color-neutral-800);box-shadow:var(--nvb-card-shadow, none)}.nvb-pro-gate--compact{margin:0;max-width:none;padding:12px;gap:10px;box-shadow:none;background:var(--nvb-color-neutral-050)}.nvb-pro-gate__badge{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:999px;background:var(--nvb-color-primary-050);color:var(--nvb-color-primary-600);font-size:20px}.nvb-pro-gate--compact .nvb-pro-gate__badge{width:28px;height:28px;font-size:16px}.nvb-pro-gate__body{min-width:0}.nvb-pro-gate__eyebrow{margin:0 0 2px;font-size:11px;font-weight:600;line-height:16px;letter-spacing:.02em;text-transform:uppercase;color:var(--nvb-color-primary-600)}.nvb-pro-gate[data-state=expired] .nvb-pro-gate__eyebrow,.nvb-pro-gate[data-state=invalid] .nvb-pro-gate__eyebrow{color:var(--nvb-color-warning-700)}.nvb-pro-gate__title{margin:0 0 4px;font-size:14px;font-weight:600;line-height:20px;color:var(--nvb-color-neutral-900)}.nvb-pro-gate--compact .nvb-pro-gate__title{font-size:12px;line-height:16px}.nvb-pro-gate__text{margin:0;font-size:13px;line-height:19px;color:var(--nvb-color-neutral-600)}.nvb-pro-gate--compact .nvb-pro-gate__text{font-size:12px;line-height:17px}.nvb-pro-gate__actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}.nvb-pro-gate--compact .nvb-pro-gate__actions{margin-top:10px}.nvb-pro-gate__actions a{text-decoration:none}.nvb-pro-gate--checking{align-items:center;gap:10px;font-size:13px;color:var(--nvb-color-neutral-600)}.nvb-pro-gate__spinner{width:14px;height:14px;border:2px solid var(--nvb-color-neutral-200);border-top-color:var(--nvb-color-primary-500);border-radius:999px;animation:nvb-pro-gate-spin .8s linear infinite}@keyframes nvb-pro-gate-spin{to{transform:rotate(360deg)}}@media(prefers-reduced-motion:reduce){.nvb-pro-gate__spinner{animation:none}}\n"],dependencies:[{kind:"component",type:C,selector:"nvb-icon",inputs:["name","svg","ariaLabel"]},{kind:"pipe",type:T,name:"nvbT"}],changeDetection:v.ChangeDetectionStrategy.OnPush})};v.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"22.2.1",ngImport:v,type:j,decorators:[{type:K,args:[{selector:"nvb-pro-feature-gate",imports:[C,T],changeDetection:U.OnPush,template:"@switch (state()) {\n @case ('ready') {\n <ng-content />\n }\n @case ('checking') {\n <div class=\"nvb-pro-gate nvb-pro-gate--checking\" [class.nvb-pro-gate--compact]=\"compact()\" role=\"status\" data-testid=\"pro-gate-checking\">\n <span class=\"nvb-pro-gate__spinner\" aria-hidden=\"true\"></span>\n <span>{{ 'proGate.checking' | nvbT }}</span>\n </div>\n }\n @default {\n <section\n class=\"nvb-pro-gate\"\n [class.nvb-pro-gate--compact]=\"compact()\"\n [attr.data-state]=\"state()\"\n data-testid=\"pro-gate-locked\"\n >\n <span class=\"nvb-pro-gate__badge\" aria-hidden=\"true\">\n <nvb-icon [svg]=\"lockIcon\" />\n </span>\n <div class=\"nvb-pro-gate__body\">\n <p class=\"nvb-pro-gate__eyebrow\">\n @switch (state()) {\n @case ('missing') {\n {{ 'proGate.missing.eyebrow' | nvbT }}\n }\n @case ('expired') {\n {{ 'proGate.expired.eyebrow' | nvbT }}\n }\n @default {\n {{ 'proGate.invalid.eyebrow' | nvbT }}\n }\n }\n </p>\n <h3 class=\"nvb-pro-gate__title\">{{ feature() }}</h3>\n <p class=\"nvb-pro-gate__text\">\n @switch (state()) {\n @case ('missing') {\n {{\n 'proGate.missing.text' | nvbT\n }}\n }\n @case ('expired') {\n @if (expiresOn()) {\n {{ 'proGate.expired.textOn' | nvbT: { date: expiresOn() } }}\n } @else {\n {{ 'proGate.expired.text' | nvbT }}\n }\n {{ 'proGate.expired.renew' | nvbT }}\n }\n @default {\n {{\n 'proGate.invalid.text' | nvbT\n }}\n }\n }\n </p>\n <div class=\"nvb-pro-gate__actions\">\n <a\n class=\"nvb-button nvb-button--primary nvb-button--sm\"\n [href]=\"pricingUrl\"\n target=\"_blank\"\n rel=\"noopener\"\n data-testid=\"pro-gate-plans\"\n >{{ 'proGate.plans' | nvbT }}</a>\n <a\n class=\"nvb-button nvb-button--neutral nvb-button--sm\"\n [href]=\"docsUrl\"\n target=\"_blank\"\n rel=\"noopener\"\n data-testid=\"pro-gate-docs\"\n >{{ 'proGate.docs' | nvbT }}</a>\n </div>\n </div>\n </section>\n }\n}\n",styles:[":host{display:contents}.nvb-pro-gate{display:flex;gap:14px;align-items:flex-start;max-width:520px;margin:72px auto 0;padding:20px 22px;border:1px solid var(--nvb-color-neutral-200);border-radius:var(--nvb-radius-lg, 10px);background:var(--nvb-color-neutral-000);color:var(--nvb-color-neutral-800);box-shadow:var(--nvb-card-shadow, none)}.nvb-pro-gate--compact{margin:0;max-width:none;padding:12px;gap:10px;box-shadow:none;background:var(--nvb-color-neutral-050)}.nvb-pro-gate__badge{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:999px;background:var(--nvb-color-primary-050);color:var(--nvb-color-primary-600);font-size:20px}.nvb-pro-gate--compact .nvb-pro-gate__badge{width:28px;height:28px;font-size:16px}.nvb-pro-gate__body{min-width:0}.nvb-pro-gate__eyebrow{margin:0 0 2px;font-size:11px;font-weight:600;line-height:16px;letter-spacing:.02em;text-transform:uppercase;color:var(--nvb-color-primary-600)}.nvb-pro-gate[data-state=expired] .nvb-pro-gate__eyebrow,.nvb-pro-gate[data-state=invalid] .nvb-pro-gate__eyebrow{color:var(--nvb-color-warning-700)}.nvb-pro-gate__title{margin:0 0 4px;font-size:14px;font-weight:600;line-height:20px;color:var(--nvb-color-neutral-900)}.nvb-pro-gate--compact .nvb-pro-gate__title{font-size:12px;line-height:16px}.nvb-pro-gate__text{margin:0;font-size:13px;line-height:19px;color:var(--nvb-color-neutral-600)}.nvb-pro-gate--compact .nvb-pro-gate__text{font-size:12px;line-height:17px}.nvb-pro-gate__actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}.nvb-pro-gate--compact .nvb-pro-gate__actions{margin-top:10px}.nvb-pro-gate__actions a{text-decoration:none}.nvb-pro-gate--checking{align-items:center;gap:10px;font-size:13px;color:var(--nvb-color-neutral-600)}.nvb-pro-gate__spinner{width:14px;height:14px;border:2px solid var(--nvb-color-neutral-200);border-top-color:var(--nvb-color-primary-500);border-radius:999px;animation:nvb-pro-gate-spin .8s linear infinite}@keyframes nvb-pro-gate-spin{to{transform:rotate(360deg)}}@media(prefers-reduced-motion:reduce){.nvb-pro-gate__spinner{animation:none}}\n"]}]}],propDecorators:{feature:[{type:v.Input,args:[{isSignal:true,alias:"feature",required:false}]}],compact:[{type:v.Input,args:[{isSignal:true,alias:"compact",required:false}]}]}});export{V as NGX_VIEW_BUILDER_SHARED_UI_EN,F as NVB_PLUGIN_ICONS,O as NvbPluginI18n,j as NvbProFeatureGate,T as NvbTranslatePipe,J as VIEW_LOGIC_KINDS,oe as analyzeViewLogic,z as createPluginTranslate,f as elementNodeId,Z as englishTranslate,S as humanize,I as interpolate,w as plainText,ee as registerPluginEnglish,W as segmentsToText,ce as traceViewLogic};
package/package.json CHANGED
@@ -1,6 +1,36 @@
1
1
  {
2
2
  "name": "@ngxviewbuilder/plugin-shared",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.13.1",
4
+ "description": "Shared pieces of the NGX View Builder plugins (view logic analysis, license gate, icons). Installed with the plugins that need it; not meant to be added on its own.",
5
+ "license": "SEE LICENSE IN LICENSE.md",
6
+ "homepage": "https://ngxviewbuilder.io",
7
+ "author": "NGX View Builder (https://ngxviewbuilder.io)",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/ngxviewbuilder/ngx-view-builder-community.git"
11
+ },
12
+ "publishConfig": {
13
+ "access": "public"
14
+ },
15
+ "peerDependencies": {
16
+ "@angular/common": "^22.0.0",
17
+ "@angular/core": "^22.0.0",
18
+ "@ngxviewbuilder/designer": "^0.13.0"
19
+ },
20
+ "dependencies": {
21
+ "tslib": "^2.6.0"
22
+ },
23
+ "module": "fesm2022/ngxviewbuilder-plugin-shared.mjs",
24
+ "typings": "types/ngxviewbuilder-plugin-shared.d.ts",
25
+ "exports": {
26
+ "./package.json": {
27
+ "default": "./package.json"
28
+ },
29
+ ".": {
30
+ "types": "./types/ngxviewbuilder-plugin-shared.d.ts",
31
+ "default": "./fesm2022/ngxviewbuilder-plugin-shared.mjs"
32
+ }
33
+ },
34
+ "sideEffects": false,
35
+ "type": "module"
6
36
  }
@@ -0,0 +1,225 @@
1
+ import * as i0 from "@angular/core";
2
+ import { PipeTransform } from "@angular/core";
3
+ import { UiTranslationService } from "@ngxviewbuilder/designer";
4
+ /**
5
+ * The logic of one view as a graph: what each element does, what it reads and what it
6
+ * changes. Built from the view JSON alone, so the logic map, the documentation and AI
7
+ * clients all describe the very same thing.
8
+ */
9
+ export type ViewLogicNodeKind = 'element' | 'dataSource' | 'variable' | 'rule' | 'trigger' | 'missing';
10
+ /**
11
+ * What a link means, in the groups people think in. `locked` covers disabled and
12
+ * read-only, `value` covers calculated and set values, `data` covers data sources,
13
+ * options and reloads, `action` covers dialogs, navigation, messages and submit.
14
+ */
15
+ export type ViewLogicKind = 'visibility' | 'required' | 'locked' | 'value' | 'reset' | 'validation' | 'data' | 'action';
16
+ export declare const VIEW_LOGIC_KINDS: ViewLogicKind[];
17
+ export interface IViewLogicNode {
18
+ /** `el:<path>`, `ds:<name>`, `var:<name>`, `rule:<id>`, `trigger:<id>` or `missing:<token>`. */
19
+ id: string;
20
+ kind: ViewLogicNodeKind;
21
+ /** Element path (`billing.city` for a panel child), data source or variable name. */
22
+ name: string;
23
+ /** What people call it: the label, title or caption, falling back to the name. */
24
+ label: string;
25
+ /** Element type, e.g. `number`. */
26
+ type?: string;
27
+ /** Element type as people read it, e.g. "Number input". */
28
+ typeLabel?: string;
29
+ /** Element group from the library: inputs, containers, content, actions, tables. */
30
+ group?: string;
31
+ pageName?: string;
32
+ pageLabel?: string;
33
+ /** Path of the container the element sits in, when it is not on the page itself. */
34
+ parent?: string;
35
+ /**
36
+ * Where the element sits, said the way people would: "Column of Order lines" for a
37
+ * dynamic table column, "In Billing address" for a panel child. Empty on page level.
38
+ */
39
+ context?: string;
40
+ /** Position in the view, top to bottom, for ordering lists and layers. */
41
+ order: number;
42
+ required?: boolean;
43
+ hidden?: boolean;
44
+ }
45
+ /** One piece of text in a rule, either plain words or a reference to a node. */
46
+ export type ViewLogicSegment = {
47
+ text: string;
48
+ } | {
49
+ ref: string;
50
+ label: string;
51
+ };
52
+ export interface IViewLogicRule {
53
+ id: string;
54
+ kind: ViewLogicKind;
55
+ /** The node the rule is written on. */
56
+ owner: string;
57
+ /** Where on the owner it lives: `visibleIf`, `events[0]`, `validators[1]`, `dataSource`… */
58
+ property: string;
59
+ /** The rule read back as a sentence, e.g. "Visible when Income > 10". */
60
+ summary: string;
61
+ /** The same sentence with references kept apart, for rendering names as links. */
62
+ segments: ViewLogicSegment[];
63
+ /** The expression as written, when the rule has one. */
64
+ expression?: string;
65
+ /**
66
+ * What the rule is, for code that must not read the words: the validator type for a
67
+ * validator (`required`, `min`…), the action type for an action (`dataSource`, `dialog`…).
68
+ */
69
+ subtype?: string;
70
+ /** When the rule runs, for events: click, change, load… */
71
+ trigger?: string;
72
+ /** Nodes the rule reads. */
73
+ sources: string[];
74
+ /** Nodes the rule changes, for events, rules and triggers. */
75
+ targets: string[];
76
+ }
77
+ export interface IViewLogicEdge {
78
+ id: string;
79
+ from: string;
80
+ to: string;
81
+ kind: ViewLogicKind;
82
+ ruleId: string;
83
+ }
84
+ export type ViewLogicIssueCode = 'unknownReference' | 'unknownTarget' | 'unknownDataSource' | 'cycle' | 'selfReference';
85
+ export interface IViewLogicIssue {
86
+ severity: 'error' | 'warning';
87
+ code: ViewLogicIssueCode;
88
+ message: string;
89
+ nodeIds: string[];
90
+ ruleId?: string;
91
+ }
92
+ export interface IViewLogicGraph {
93
+ nodes: IViewLogicNode[];
94
+ rules: IViewLogicRule[];
95
+ edges: IViewLogicEdge[];
96
+ issues: IViewLogicIssue[];
97
+ pages: Array<{
98
+ name: string;
99
+ label: string;
100
+ }>;
101
+ }
102
+ export interface IViewLogicTrace {
103
+ node: IViewLogicNode;
104
+ /** Every node it depends on, nearest first, with the distance in links. */
105
+ upstream: Array<{
106
+ id: string;
107
+ depth: number;
108
+ }>;
109
+ /** Every node it changes, nearest first. */
110
+ downstream: Array<{
111
+ id: string;
112
+ depth: number;
113
+ }>;
114
+ }
115
+ /** Values put into a text where it has `{name}` placeholders. */
116
+ export type NvbTranslateParams = Record<string, string | number | boolean | null | undefined>;
117
+ /**
118
+ * Gives the text for a key in the language the builder is in. `{name}` placeholders take
119
+ * `params`; `fallback` is used when no dictionary knows the key (a data source type, say).
120
+ */
121
+ export type NvbTranslate = (key: string, params?: NvbTranslateParams, fallback?: string) => string;
122
+ /** A plugin hands its English dictionary over once, when it is provided. */
123
+ export declare function registerPluginEnglish(dictionary: Record<string, string>): void;
124
+ export declare function interpolate(text: string, params?: NvbTranslateParams): string;
125
+ /** English only: for code that runs without the builder, such as a test or a script. */
126
+ export declare const englishTranslate: NvbTranslate;
127
+ /**
128
+ * The host's text for the key when it has one, English otherwise. It reads the builder's
129
+ * language signal, so anything computed with it follows a language switch.
130
+ */
131
+ export declare function createPluginTranslate(ui: UiTranslationService): NvbTranslate;
132
+ /** The plugins' translator, for components and services. */
133
+ export declare class NvbPluginI18n {
134
+ readonly t: NvbTranslate;
135
+ static ɵfac: i0.ɵɵFactoryDeclaration<NvbPluginI18n, never>;
136
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
137
+ }
138
+ /**
139
+ * `{{ 'docs.counter' | nvbT: { documented: 3, total: 12 } }}`: the plugin text for the key
140
+ * in the builder's language, with its placeholders filled in.
141
+ */
142
+ export declare class NvbTranslatePipe implements PipeTransform {
143
+ private readonly i18n;
144
+ transform(key: string, params?: NvbTranslateParams | null): string;
145
+ static ɵfac: i0.ɵɵFactoryDeclaration<NvbTranslatePipe, never>;
146
+ static ɵpipe: i0.ɵɵPipeDeclaration<NvbTranslatePipe, "nvbT", true>;
147
+ }
148
+ export interface IViewLogicOptions {
149
+ /**
150
+ * Names the host provides at run time (runtime variables, context keys). References to
151
+ * them are fine, so they become variable nodes instead of "not in this view" warnings.
152
+ */
153
+ externalNames?: string[];
154
+ /** Element type labels for custom elements the library list does not know. */
155
+ typeLabels?: Record<string, string>;
156
+ /**
157
+ * Gives the words the sentences are made of, in the builder's language. Without it the
158
+ * sentences are English.
159
+ */
160
+ translate?: NvbTranslate;
161
+ }
162
+ /** Builds the logic graph of a view. Pure: the same structure always gives the same graph. */
163
+ export declare function analyzeViewLogic(structure: unknown, options?: IViewLogicOptions): IViewLogicGraph;
164
+ /** Everything a node depends on and everything it changes, through any number of links. */
165
+ export declare function traceViewLogic(graph: IViewLogicGraph, nodeId: string): IViewLogicTrace | null;
166
+ /** Turns segments back into plain text, references by their label. */
167
+ export declare function segmentsToText(segments: ViewLogicSegment[]): string;
168
+ export declare function elementNodeId(path: string): string;
169
+ /** Strips markup and collapses whitespace: labels may hold rich text. */
170
+ export declare function plainText(value: unknown): string;
171
+ /** `dynamicTable` → "Dynamic table". */
172
+ export declare function humanize(value: string): string;
173
+ /**
174
+ * Shows its content only while the license unlocks licensed plugins, and an explanation
175
+ * with the way forward otherwise. Both licensed plugins wrap their whole UI in it, so a
176
+ * locked builder says the same thing in every place.
177
+ */
178
+ export declare class NvbProFeatureGate {
179
+ private readonly license;
180
+ private readonly ui;
181
+ /** The feature's name as people see it, e.g. "Logic map". */
182
+ feature: import("@angular/core").InputSignal<string>;
183
+ /** Narrow layout for the Properties panel. */
184
+ compact: import("@angular/core").InputSignal<boolean>;
185
+ readonly lockIcon: "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\" viewBox=\"0 -960 960 960\"><path d=\"M220-80q-24.75 0-42.37-17.63Q160-115.25 160-140v-434q0-24.75 17.63-42.38Q195.25-634 220-634h70v-96q0-78.85 55.61-134.42Q401.21-920 480.11-920q78.89 0 134.39 55.58Q670-808.85 670-730v96h70q24.75 0 42.38 17.62Q800-598.75 800-574v434q0 24.75-17.62 42.37Q764.75-80 740-80H220Zm0-60h520v-434H220v434Zm314.5-162.03Q557-324.06 557-355q0-30-22.67-54.5t-54.5-24.5q-31.83 0-54.33 24.5t-22.5 55q0 30.5 22.67 52.5t54.5 22q31.83 0 54.33-22.03ZM350-634h260v-96q0-54.17-37.88-92.08-37.88-37.92-92-37.92T388-822.08q-38 37.91-38 92.08v96ZM220-140v-434 434Z\"/></svg>";
186
+ readonly pricingUrl = "https://ngxviewbuilder.io/pricing";
187
+ readonly docsUrl = "https://ngxviewbuilder.io/developers/licensing";
188
+ readonly state: import("@angular/core").Signal<import("@ngxviewbuilder/designer").AiAccessState>;
189
+ readonly expiresOn: import("@angular/core").Signal<string>;
190
+ static ɵfac: i0.ɵɵFactoryDeclaration<NvbProFeatureGate, never>;
191
+ static ɵcmp: i0.ɵɵComponentDeclaration<NvbProFeatureGate, "nvb-pro-feature-gate", never, {
192
+ "feature": {
193
+ "alias": "feature";
194
+ "required": false;
195
+ "isSignal": true;
196
+ };
197
+ "compact": {
198
+ "alias": "compact";
199
+ "required": false;
200
+ "isSignal": true;
201
+ };
202
+ }, {}, never, ["*"], true, never>;
203
+ }
204
+ /**
205
+ * Icons the plugins draw that the core icon set does not carry. Passed to `nvb-icon` as
206
+ * `[svg]` (and as a tab's `icon`), so they never land in the host's icon library and
207
+ * leave with the plugins. Material Symbols, outlined, weight 400.
208
+ */
209
+ export declare const NVB_PLUGIN_ICONS: {
210
+ readonly lock: "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\" viewBox=\"0 -960 960 960\"><path d=\"M220-80q-24.75 0-42.37-17.63Q160-115.25 160-140v-434q0-24.75 17.63-42.38Q195.25-634 220-634h70v-96q0-78.85 55.61-134.42Q401.21-920 480.11-920q78.89 0 134.39 55.58Q670-808.85 670-730v96h70q24.75 0 42.38 17.62Q800-598.75 800-574v434q0 24.75-17.62 42.37Q764.75-80 740-80H220Zm0-60h520v-434H220v434Zm314.5-162.03Q557-324.06 557-355q0-30-22.67-54.5t-54.5-24.5q-31.83 0-54.33 24.5t-22.5 55q0 30.5 22.67 52.5t54.5 22q31.83 0 54.33-22.03ZM350-634h260v-96q0-54.17-37.88-92.08-37.88-37.92-92-37.92T388-822.08q-38 37.91-38 92.08v96ZM220-140v-434 434Z\"/></svg>";
211
+ readonly account_tree: "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\" viewBox=\"0 -960 960 960\"><path d=\"M604-120v-125H450v-410h-93v130H80v-315h277v125h247v-125h276v315H604v-130h-94v350h94v-130h276v315H604ZM140-780v195-195Zm524 405v195-195Zm0-405v195-195Zm0 195h156v-195H664v195Zm0 405h156v-195H664v195ZM140-585h157v-195H140v195Z\"/></svg>";
212
+ readonly filter_list: "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\" viewBox=\"0 -960 960 960\"><path d=\"M400-240v-60h160v60H400ZM240-450v-60h480v60H240ZM120-660v-60h720v60H120Z\"/></svg>";
213
+ readonly functions: "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\" viewBox=\"0 -960 960 960\"><path d=\"M240-160v-63l275-257-275-257v-63h480v100H396l235 220-235 220h324v100H240Z\"/></svg>";
214
+ readonly cloud_done: "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\" viewBox=\"0 -960 960 960\"><path d=\"m412-279 230-230-40-40-189 189-100-100-41 41 140 140ZM251-160q-88 0-149.5-61.5T40-371q0-78 50-137t127-71q20-97 94-158.5T482-799q112 0 189 81.5T748-522v24q72-2 122 46.5T920-329q0 69-50 119t-119 50H251Zm0-60h500q45 0 77-32t32-77q0-45-32-77t-77-32h-63v-84q0-91-61-154t-149-63q-88 0-149.5 63T267-522h-19q-62 0-105 43.5T100-371q0 63 44 107t107 44Zm229-260Z\"/></svg>";
215
+ readonly cloud_off: "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\" viewBox=\"0 -960 960 960\"><path d=\"M818-56 703-171H248q-88 0-148-59T40-377q0-80 50.5-134T217-577q2-14 6.5-31.5T236-640L70-806l42-42L861-99l-43 43ZM248-231h397L285-591q-11 15-14.5 34t-3.5 37h-19q-62 0-105 39.5t-43 101q0 61.5 43 105T248-231Zm216-181Zm390 210-47-47q25-17 39-38t14-50q0-43-31-73.5T755-441h-67v-81q0-88-61-147.5T478.47-729q-28.47 0-60.97 9T358-691l-42-42q36-29 77.5-42.5T478-789q111 0 190.5 79T748-520v21q72-1 122 45t50 117q0 35-16.5 73.5T854-202ZM583-470Z\"/></svg>";
216
+ readonly arrow_forward: "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\" viewBox=\"0 -960 960 960\"><path d=\"M686-450H160v-60h526L438-758l42-42 320 320-320 320-42-42 248-248Z\"/></svg>";
217
+ };
218
+ /**
219
+ * English texts of the shared plugin pieces: the sentences the logic analysis writes
220
+ * about a view (rules, actions, issues) and the license gate. A host translates them by
221
+ * giving the same keys in its own language, e.g. with
222
+ * `provideNgxViewBuilderUiTranslations({ lt: { 'logic.visibleIf.when': 'Matomas, kai' } })`.
223
+ * Placeholders in braces, `{name}`, are filled in by the plugin and stay as they are.
224
+ */
225
+ export declare const NGX_VIEW_BUILDER_SHARED_UI_EN: Record<string, string>;
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.