@supersoniks/concorde 4.9.3 → 4.9.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -28,7 +28,7 @@ yarn ai-init
28
28
  node node_modules/@supersoniks/concorde/scripts/ai-init.mjs
29
29
  ```
30
30
 
31
- Installe `.cursor/skills`, `.cursor/rules`, `.aiassistant/rules` et `AGENTS.md`. Voir [ai/README.md](ai/README.md).
31
+ Installe `.cursor/skills`, `.cursor/rules`, `.aiassistant/rules`. `AGENTS.md` n’est créé que s’il est absent ; un fichier projet existant (sans marker Concorde) est laissé intact. Voir [ai/README.md](ai/README.md).
32
32
 
33
33
  ## 📁 Structure du projet
34
34
 
package/ai/README.md CHANGED
@@ -10,12 +10,36 @@ node node_modules/@supersoniks/concorde/scripts/ai-init.mjs
10
10
 
11
11
  Options :
12
12
 
13
- - `--overlay <dir>` — couche additionnelle (ex. kit starter)
14
- - `--merge-agents` — fusionne avec un `AGENTS.md` existant
13
+ - `--overlay <dir>` — couche additionnelle (ex. kit starter) ; lit aussi `AGENTS.starter.md`
14
+ - `--skip-agents` — n’écrit jamais `AGENTS.md` (skills / rules seulement)
15
+ - `--merge-agents` — opt-in : conserve le préambule projet et ajoute / rafraîchit le bloc Concorde
16
+ - `--force-agents` — opt-in : **remplace** tout `AGENTS.md` (destructif)
15
17
  - `--cursor-only` / `--jetbrains-only`
16
18
 
17
19
  Depuis le dépôt Concorde (dev) : `yarn ai-init`
18
20
 
21
+ ## Politique `AGENTS.md` (non invasive)
22
+
23
+ | Situation | Comportement par défaut |
24
+ |-----------|-------------------------|
25
+ | Pas de `AGENTS.md` | Création du guide Concorde |
26
+ | Fichier avec `<!-- concorde-ai -->` | Rafraîchit la zone gérée seulement |
27
+ | Fichier **sans** marker (notes projet) | **Laissé intact** — skills / rules suffisent |
28
+ | `--merge-agents` | Préambule projet + bloc Concorde après le marker |
29
+ | `--force-agents` | Remplacement complet |
30
+ | `--skip-agents` | Jamais d’écriture `AGENTS.md` |
31
+
32
+ ```text
33
+ [optional project preamble — short, project-only]
34
+ <!-- concorde-ai -->
35
+ <package ai/AGENTS.md>
36
+ [--- + overlay AGENTS.starter.md]
37
+ ```
38
+
39
+ - Tout **après** `<!-- concorde-ai -->` est **régénéré** à chaque run (pas d’empilement).
40
+ - Ne pas recopier le guide Concorde dans le préambule : notes projet → `overlay/AGENTS.starter.md`.
41
+ - Si le préambule duplique `ai/AGENTS.md`, `ai-init` le **allège / drop** et affiche un warning.
42
+
19
43
  ## Contenu
20
44
 
21
45
  | Dossier | Cible |
@@ -23,8 +47,14 @@ Depuis le dépôt Concorde (dev) : `yarn ai-init`
23
47
  | `skills/` | `.cursor/skills/` (concorde, imports, scope, theme, menu) |
24
48
  | `cursor/rules/` | `.cursor/rules/` |
25
49
  | `jetbrains/rules/` | `.aiassistant/rules/` |
26
- | `AGENTS.md` | racine du projet |
50
+ | `AGENTS.md` | racine du projet **seulement** si absent, déjà marqué, ou via `--merge-agents` / `--force-agents` |
27
51
 
28
52
  ## Template starter
29
53
 
30
54
  Le package `create-concorde-ts-starter` ajoute un overlay via `yarn ai:sync`.
55
+
56
+ ## Tests
57
+
58
+ ```bash
59
+ node --test scripts/ai-init.test.mjs
60
+ ```
package/build-infos.json CHANGED
@@ -1 +1 @@
1
- {"date":1783597327}
1
+ {"date":1785400304}
@@ -1,4 +1,4 @@
1
- (function(Z){typeof define=="function"&&define.amd?define(Z):Z()})((function(){"use strict";var M,tt;let Z=class Ft{static getLanguage(){const t=document.documentElement.lang;return localStorage.getItem("SonicSelectedLanguage")||t}static getCookies(){return document.cookie.split(";").reduce((t,i)=>{const r=i.indexOf("=");return t[i.substring(0,r).trim()]=i.substring(r+1),t},{})}static everyAncestors(t,i){for(;t;){if(!i(t))return;t=t.parentNode||t.host}}static getScrollableAncestor(t){for(;t;){const i=t;if(i.nodeType===1){const r=window.getComputedStyle(i);if(r?.overflowY==="auto"||r?.overflowY==="scroll"||r?.overflowY==="hidden"||r?.overflowX==="auto"||r?.overflowX==="scroll"||r?.overflowX==="hidden")return t}t=t.parentNode||t.host}return null}static scopeAttributeNames(t){const i=t.toLowerCase();return i===t?[t]:[t,i]}static readScopeAttributeOnElement(t,i){for(const r of Ft.scopeAttributeNames(i))if(t.hasAttribute(r))return t.getAttribute(r)??"";return null}static getAncestorAttributeValue(t,i){if(!t)return null;let r=t;for(;r;){if(r instanceof HTMLElement){const o=Ft.readScopeAttributeOnElement(r,i);if(o!=null)return o}const e=r.parentNode||r.host;if(!e)break;r=e}return null}static getApiConfiguration(t){const i=Ft.getAncestorAttributeValue(t,"token"),r=Ft.getAncestorAttributeValue(t,"addHTTPResponse")!=null,e=Ft.getAncestorAttributeValue(t,"serviceURL");let o=null,n=null;const l=Ft.getAncestorAttributeValue(t,"tokenProvider"),c=Ft.getAncestorAttributeValue(t,"eventsApiToken");i||(o=Ft.getAncestorAttributeValue(t,"userName"),n=Ft.getAncestorAttributeValue(t,"password"));const h=Ft.getAncestorAttributeValue(t,"credentials")||void 0,u=t.getAttribute("cache"),d=t.hasAttribute("blockUntilDone"),p=t.hasAttribute("keepAlive");return{serviceURL:e,token:i,userName:o,password:n,authToken:c,tokenProvider:l,addHTTPResponse:r,credentials:h,cache:u,blockUntilDone:d,keepAlive:p}}static getClosestElement(t,i){for(;!(t.nodeName&&t.nodeName.toLowerCase()===i)&&(t.parentNode||t.host);)t=t.parentNode||t.host;return t.nodeName?t:null}static getClosestForm(t){return Ft.getClosestElement(t,"form")}static getAncestorsByTagNames(t,i){const r=new Set(i.map(n=>n.toLowerCase())),e=[];let o=t.parentNode||t.host;for(;o;)o instanceof Element&&r.has(o.tagName.toLowerCase())&&e.push(o),o=o.parentNode||o.host;return e}static getAncestorsBySelectors(t,i){const r=[];let e=t.parentNode||t.host;for(;e;){if(e instanceof Element)for(const o of i)try{if(e.matches(o)){r.push(e);break}}catch{}e=e.parentNode||e.host}return r}static async loadJS(t){return new Promise(async r=>{const e=document.createElement("script");e.src=t,e.onload=()=>r(!0),e.onerror=()=>r(!0),document.head.appendChild(e)})}static async loadCSS(t){return new Promise(async r=>{const e=document.createElement("link");e.type="text/css",e.rel="stylesheet",e.href=t,e.onload=()=>r(!0),e.onerror=()=>r(!0),document.head.appendChild(e)})}};const bi=s=>{const t=document.documentElement,i=new MutationObserver(e=>{for(let o of e)o.type==="attributes"&&o.attributeName==="lang"&&s()}),r={attributes:!0,attributeFilter:["lang"]};i.observe(t,r)};let Os=class{static ucFirst(t){return typeof t!="string"?t:t.charAt(0).toUpperCase()+t.substring(1)}static minutesDuration(t,i="",r="long"){i||(i=Z.getLanguage());const e=(h,u)=>[Math.floor(h/u),h%u];function o(h,u,d){return new Intl.NumberFormat(h,{style:"unit",unit:u,unitDisplay:d}).format}const[n,l]=e(t,60),c=[];return n&&c.push(o(i,"hour",r)(n)),l&&c.push(o(i,"minute",r)(l)),new Intl.ListFormat(i,{style:"long",type:"conjunction"}).format(c)}static js(t){try{return Function("return "+t)()}catch{return""}}};class _r{constructor(t){this.path=t}toString(){return this.path}}function wr(s){return new Proxy(s,{get(t,i){if(i==="path")return t.path;if(i==="toString")return t.toString.bind(t);if(i===Symbol.toStringTag)return"DataProviderKey";if(typeof i=="symbol")return t[i];const r=t.path?`${t.path}.${String(i)}`:String(i);return wr(new _r(r))}})}const Jo=/\$\{|\{\$/;function tn(s){return Jo.test(s)}function mi(s){const t=typeof s=="string"?s:s.path;if(tn(t))throw new Error("Static publisher path required for get/set/dp. Use @subscribe, @publish, or @handle for dynamic DataProviderKey paths.");return t}const es=function(s){return this instanceof es?wr(new _r(s)):new es(s)};let nt=class oe{static shallowEqual(t,i,r=!0){const e=Object.keys(t),o=Object.keys(i);if(e.length!==o.length&&r)return!1;for(const n of e){const l=t[n],c=i[n];if(r?l!==c:l!=c)return!1}return!0}static deepEqual(t,i,r=!0){const e=Object.keys(t),o=Object.keys(i);if(e.length!==o.length&&r)return!1;for(const n of e){const l=t[n],c=i[n],h=oe.isObject(l)&&oe.isObject(c),u=r?l!==c:l!=c;if(h&&!oe.deepEqual(l,c)||!h&&u)return!1}return!0}static isObject(t){return t!=null&&typeof t=="object"}static isUndefindOrNull(t){return t==null}static isEmpty(t){return oe.isUndefindOrNull(t)?!0:Object.keys(t).length===0}static traverse(t,i,r=!1){for(const e of i){const o=t[e];if(o===void 0)return;r&&oe.isObject(o)?t=Object.assign(Array.isArray(o)?[]:{},t,o):t=t[e]}return t}static traverseDotNotation(t,i,r=!1){return oe.traverse(t,i.split("."),r)}static getURLSearchArray(t,i=""){let r=[];for(let e in t){const o=t[e];i&&(e=i+"["+e+"]"),oe.isObject(o)?r=[...r,...this.getURLSearchArray(o,e)]:r.push(`${e}=${o}`)}return r}static getURLSearchString(t){return oe.getURLSearchArray(t,"").join("&")}};const yt=nt.traverseDotNotation;let en=class{static async queueTaskPromise(){return new Promise(t=>{window.queueMicrotask(()=>t(null))})}static async delayPromise(t){return new Promise(i=>{setTimeout(i,t)})}},xr="sonic";typeof __SONIC_PREFIX__<"u"&&(xr=__SONIC_PREFIX__);let Pr=xr.replace(/-([a-z])/g,s=>s[1].toUpperCase());const Es=Pr.charAt(0).toUpperCase()+Pr.slice(1),sn=new Set(["localStorageMode","expirationDelayMs","invalidateOnPageShow"]);function Cr(s){return s==null||typeof s!="object"||Array.isArray(s)?!1:Object.keys(s).some(t=>sn.has(t))}function Ls(s){return Object.prototype.hasOwnProperty.call(s,"__value")}function ne(s){return typeof s=="object"&&s!==null}let ze="sonic";typeof __SONIC_PREFIX__>"u"&&(ze="sonic");const gi=ze=="sonic"?"publisher-proxies-data":ze+"-publisher-proxies-data",xe=class xe{constructor(t,i,r){for(this._proxies_=new Map,this._is_savable_=!1,this._expiration_delay_=1e3*60*60*12,this._invalidate_on_page_show_=!1,this._invalidateListeners_=new Set,this._formInvalidateListeners_=new Set,this._assignListeners_=new Set,this._mutationListeners_=new Set,this._fillListeners_=new Set,this._templateFillListeners_=new Set,this._lockInternalMutationPublishing_=!1,this._instanceCounter_=0,this._assignmentId_=0,this._value_=t,this.parent=i||null,this._parentKey_=r,this.root=this,this._instanceCounter_=0;this.root.parent;)this.root=this.root.parent}delete(){for(const t in this._proxies_.keys())t!="_parent_"&&this._proxies_.get(t)?.delete();this._invalidateListeners_.clear(),this._formInvalidateListeners_.clear(),this._assignListeners_.clear(),this._mutationListeners_.clear(),this._fillListeners_.clear(),this._templateFillListeners_.clear(),this._proxies_.clear(),xe.instances.delete(this._instanceCounter_)}hasListener(){return this._templateFillListeners_.size>0||this._assignListeners_.size>0||this._invalidateListeners_.size>0||this._formInvalidateListeners_.size>0||this._mutationListeners_.size>0||this._fillListeners_.size>0}_publishInternalMutation_(t=!1){if(this._mutationListeners_.forEach(i=>i()),this._is_savable_&&!E.changed){E.changed=!0,E.saveId++;const i=E.saveId;setTimeout(()=>E.getInstance().saveToLocalStorage(i),1e3)}t||this.parent&&this.parent._publishInternalMutation_()}async _publishAssignement_(t=!1){if(this._assignmentId_++,this._assignmentId_!==this._assignmentId_)return;const r=this.get();this._assignListeners_.forEach(e=>{e(r)}),this._publishInternalMutation_(t)}_publishInvalidation_(){this._invalidateListeners_.forEach(t=>t())}_publishFormInvalidation_(){this._formInvalidateListeners_.forEach(t=>t())}_publishDynamicFilling_(t,i){this._fillListeners_.forEach(r=>{r[t]!==i&&(r[t]=i)}),this._publishTemplateFilling_(t,i)}_publishTemplateFilling_(t,i){this._templateFillListeners_.forEach(r=>{const e=Object.getOwnPropertyDescriptor(r,t);e&&!e.set&&!e.writable||(r.propertyMap&&r.propertyMap[t]&&(t=r.propertyMap[t]),typeof r[t]<"u"&&r[t]!==i&&(r[t]=i))})}onAssign(t,i=!0){typeof t=="function"&&(this._assignListeners_.has(t)||(this._assignListeners_.add(t),i&&t(this.get())))}offAssign(t){this._assignListeners_.delete(t)}onInvalidate(t){typeof t=="function"&&this._invalidateListeners_.add(t)}offInvalidate(t){typeof t=="function"&&this._invalidateListeners_.delete(t)}invalidate(){this._publishInvalidation_()}onFormInvalidate(t){typeof t=="function"&&this._formInvalidateListeners_.add(t)}offFormInvalidate(t){typeof t=="function"&&this._formInvalidateListeners_.delete(t)}invalidateForm(){this._publishFormInvalidation_()}onInternalMutation(t){typeof t=="function"&&(this._mutationListeners_.add(t),t())}offInternalMutation(t){typeof t=="function"&&this._mutationListeners_.delete(t)}startTemplateFilling(t){if(this._templateFillListeners_.add(t),typeof this._value_=="object")for(const i in this._value_){let r=i;const e=this._value_[i];t.propertyMap&&t.propertyMap[i]&&(r=t.propertyMap[i]),typeof t[i]<"u"&&t[i]!==e&&(t[r]=e)}}stopTemplateFilling(t){this._templateFillListeners_.delete(t)}startDynamicFilling(t){this._fillListeners_.add(t);for(const i in this._value_){const r=this._value_[i];t[i]!==r&&(t[i]=r)}}stopDynamicFilling(t){this._fillListeners_.delete(t)}set(t,i=!1){if(this._value_===t||ne(this._value_)&&ne(t)&&t&&Ls(this._value_)&&Ls(t)&&this._value_.__value===t.__value||!ne(t)&&t===this._value_.__value)return!0;this._value_=ne(t)?t:{__value:t},this._cachedGet_=void 0;const r=Ls(this._value_);if(this._parentKey_&&this.parent){const e=Ls(this._value_)?this._value_.__value:this._value_;if(this.parent?.get()==null&&this.parent?.get()==null)if(isNaN(Number(this._parentKey_)))this.parent.set({[this._parentKey_]:e});else{const o=[];o[Number(this._parentKey_)]=e,this.parent.set(o)}else this.parent._value_[this._parentKey_]=e}if(r)return this._proxies_.forEach((e,o)=>{o!="_parent_"&&(e.set(null),this._publishDynamicFilling_(o,null))}),this._publishAssignement_(i),this.parent&&this._parentKey_&&this.parent._publishDynamicFilling_(this._parentKey_,this._value_.__value),!0;for(const e in this._value_)this._value_[e]===void 0&&delete this._value_[e];if(this._proxies_.forEach((e,o)=>{const n=this._value_[o];o!="_parent_"&&n===void 0&&n!==null&&isNaN(Number(o))&&(e.set(null),this._publishDynamicFilling_(o,null))}),this._publishAssignement_(),this.parent&&this._parentKey_&&this.parent._publishDynamicFilling_(this._parentKey_,this._value_),ne(this._value_))for(const e in this._value_){const o=t[e],l=ne(o)?o:{__value:o};if(!this._proxies_.has(e)){this._publishDynamicFilling_(e,o);continue}this._proxies_.get(e)?.set(l,!0),this._publishDynamicFilling_(e,o)}return!0}get(){if(rn(this),this._cachedGet_!==void 0)return this._cachedGet_;if(Object.prototype.hasOwnProperty.call(this._value_,"__value")){const t=this._value_.__value;return this._cachedGet_=t??null}return this._cachedGet_=this._value_!=null?this._value_:null}get $tag(){return this._instanceCounter_||(xe.instancesCounter++,this._instanceCounter_=xe.instancesCounter),xe.instances.set(this._instanceCounter_,this),"<"+ze+'-publisher-proxy publisher="'+this._instanceCounter_+'"></'+ze+"-publisher-proxy>"}};xe.instances=new Map,xe.instancesCounter=0;let ss=xe;const Ts=[];function rn(s){Ts.length>0&&Ts[0].add(s)}function Sr(){Ts.unshift(new Set)}function $r(){return Ts.shift()}const F=class F{constructor(){if(this.enabledLocaStorageProxies=[],this.publishers=new Map,this.localStorageData={},this.isLocalStrorageReady=null,this.initialisedData=[],F.instance!=null)throw"Singleton / use getInstance";F.instance=this,this.isLocalStrorageReady=this.cleanStorageData(),F.initPageShowHandler()}static initPageShowHandler(){F.pageShowHandlerInitialized||(F.pageShowHandlerInitialized=!0,window.addEventListener("pageshow",t=>{t.persisted&&F.getInstance().invalidateAll()}))}invalidateAll(){this.publishers.forEach(t=>{t._invalidate_on_page_show_&&t.invalidate()})}async cleanStorageData(){return new Promise(t=>{(async()=>{try{let r=localStorage.getItem(gi),e=null;if(r&&(e=await this.decompress(r,"gzip")),e)try{this.localStorageData=JSON.parse(e)}catch{this.localStorageData={}}else r=await this.compress("{}","gzip"),localStorage.setItem(gi,r),this.localStorageData={};const o=1e3*60*60*12;for(const n in this.localStorageData){const l=this.localStorageData[n],c=new Date().getTime()-(l.expirationDelayMs||o);l.lastModifiationMS<c&&delete this.localStorageData[n]}t(!0)}catch{window.requestAnimationFrame(()=>{t(!1)}),console.warn("no publisher cache in this browser")}})()})}static getInstance(t){if(t){const i=F.instances.get(t);return i||(console.warn("No PublisherManager instance registered with id:",t,"creating new one"),new F)}return F.instance==null?new F:F.instance}static get(t,i){return F.getInstance().get(t,i)}async setLocalData(t,i){await this.isLocalStrorageReady,t.set(this.localStorageData[i+"¤lang_"+Z.getLanguage()]?.data||t.get())}get(t,i){const r=i?.localStorageMode==="enabled",e=i?.invalidateOnPageShow===!0;if(!this.publishers.has(t)){const l=vi({});this.set(t,l)}const o=this.publishers.get(t);return r&&this.initialisedData.indexOf(t)===-1&&(i?.expirationDelayMs&&(o._expiration_delay_=i.expirationDelayMs),o._is_savable_=!0,this.initialisedData.push(t),this.setLocalData(o,t)),e&&(o._invalidate_on_page_show_=e),this.publishers.get(t)}set(t,i){this.publishers.set(t,i)}delete(t){return this.publishers.has(t)?(this.publishers.delete(t),!0):!1}async saveToLocalStorage(t=0){if(!(t!==F.saveId&&t%10!=0))try{if(!F.changed||F.saving)return;F.saving=!0,F.changed=!1;const i=Array.from(this.publishers.keys());let r=!1;for(const e of i){const o=this.publishers.get(e);if(!o?._is_savable_)continue;const n=o?.get();n&&(this.localStorageData[e+"¤lang_"+Z.getLanguage()]={lastModifiationMS:new Date().getTime(),expirationDelayMs:o._expiration_delay_,data:n},r=!0)}if(r){const e=await this.compress(JSON.stringify(this.localStorageData),"gzip");localStorage.setItem(gi,e)}if(F.saving=!1,F.changed){F.saveId++;const e=F.saveId;setTimeout(()=>this.saveToLocalStorage(e),1e3)}}catch{F.saving=!1}}async compress(t,i){const r=new TextEncoder().encode(t),e=window,o=new e.CompressionStream(i),n=o.writable.getWriter();n.write(r),n.close();const l=await new Response(o.readable).arrayBuffer(),c=new Uint8Array(l);let h="";for(let u=0;u<c.length;u++)h+=String.fromCharCode(c[u]);return btoa(h)}async decompress(t,i){const r=atob(t),o=Uint8Array.from(r,u=>u.charCodeAt(0)).buffer,n=window,l=new n.DecompressionStream(i),c=l.writable.getWriter();c.write(o),c.close();const h=await new Response(l.readable).arrayBuffer();return new TextDecoder().decode(h)}};F.buildDate="Thu Jul 09 2026 13:42:07 GMT+0200 (Central European Summer Time)",F.changed=!1,F.saving=!1,F.saveId=0,F.instance=null,F.instances=new Map,F.pageShowHandlerInitialized=!1;let E=F;if(typeof window<"u"){const s=window;s[Es+"PublisherManager"]=s[Es+"PublisherManager"]||E}const on=new Set(["invalidate","onInvalidate","offInvalidate","invalidateForm","onFormInvalidate","offFormInvalidate","onAssign","offAssign","startDynamicFilling","stopDynamicFilling","startTemplateFilling","stopTemplateFilling","onInternalMutation","offInternalMutation","set","get","$tag","_cachedGet_","_templateFillListeners_","_fillListeners_","_assignListeners_","_invalidateListeners_","_formInvalidateListeners_","_publishInternalMutation_","hasListener","delete","_mutationListeners_","_publishDynamicFilling_","_publishInvalidation_","_publishFormInvalidation_","_publishTemplateFilling_","_publishAssignement_","_proxies_","parent","_parentKey_","_value_","_is_savable_","_expiration_delay_","_lockInternalMutationPublishing_","_instanceCounter_","_assignmentId_","_invalidate_on_page_show_"]);function nn(s,t){return{get:function(i,r){if(typeof r=="string"&&on.has(r))return s[r];if(r==Symbol.toPrimitive)return()=>t().get();if(!s._proxies_.has(r)){const e=s._value_[r],o=vi(ne(e)?e:{__value:e},s,r);o._proxies_.set("_parent_",t()),s._proxies_.set(r,o)}return s._proxies_.get(r)},set:function(i,r,e){if(r=="_value_")return s._value_=e,!0;if(r=="_cachedGet_")return s._cachedGet_=e,!0;if(r=="_assignmentId_")return s._assignmentId_=e,!0;if(r=="_is_savable_")return s._is_savable_=e,!0;if(r=="_expiration_delay_")return s._expiration_delay_=e,!0;if(r=="_invalidate_on_page_show_")return s._invalidate_on_page_show_=e,!0;if(r=="_instanceCounter_")return s._instanceCounter_=e,!0;if(!s._proxies_.has(r)){const n=vi({},s,r);n._proxies_.set("_parent_",t()),s._proxies_.set(r,n)}return s._value_[r]!==e&&(s._value_[r]=e,s._publishDynamicFilling_(r,e),s._proxies_.get(r)?.set(ne(e)?e:{__value:e})),!0},deleteProperty:function(i,r){return s._publishDynamicFilling_(r,null),s._proxies_.get(r)?.set(null),delete s._value_[r]},has:function(i,r){return r in s._value_&&r!="_lockInternalMutationPublishing_"},defineProperty:function(i,r,e){return e&&"value"in e&&(s._value_[r]=e.value),!0},getOwnPropertyDescriptor:function(i,r){return{enumerable:!0,configurable:!0}},ownKeys:function(i){return s._value_.__value?Object.keys(s._value_.__value):Object.keys(s._value_)}}}function vi(s,t=null,i){const r=new ss(s,t,i);let e=null;const o=nn(r,()=>e);return e=new Proxy(r,o),e}class an extends HTMLElement{constructor(){super(),this.publisherId="",this.onAssign=t=>{this.innerHTML=t.toString()}}connectedCallback(){this.publisherId=this.getAttribute("publisher")||"",this.publisher=ss.instances.get(parseInt(this.publisherId)),this.publisher?.onAssign(this.onAssign)}disconnectedCallback(){this.publisher?.offAssign(this.onAssign)}}try{customElements.define(ze+"-publisher-proxy",an)}catch{}const Is=(s,t)=>{if(typeof s=="function"){const i=s;return Sr(),i(),$r()}if(typeof s=="string"){const i=s.split("."),r=i.shift()||"";let e=E.get(r,t);e=nt.traverse(e,i);const o=new Set;return o.add(e),o}return new Set([s])};function ln(s){const t=mi(s);return Is(t).values().next().value?.get()}function Ms(s,t,i){const r=mi(s);return Is(r,i).values().next().value}function cn(s,t){return Cr(t)?Ms(s,void 0,t):Ms(s)}function Ns(s,t){return Cr(t)?Ms(s,void 0,t):Ms(s)}function hn(s,t){const i=mi(s);Is(i).values().next().value?.set(t)}let Fs=(M=class{static disable(){this.enabled&&(this.enabled=!1,Array.from(M.observedElements.keys()).forEach(t=>M.unObserve(t)))}static observe(t){if(!t||!M.enabled||M.observedElements.has(t))return;const i=new MutationObserver(M.onMutation),r={};r.childList=!0,r.subtree=!0,r.attributes=!0,r.attributeFilter=["data-bind"],i.observe(t,r),t.querySelectorAll("[data-bind]").forEach(e=>M.addPublisherListeners(e)),M.observedElements.set(t,i)}static unObserve(t){if(!t)return;const i=this.observedElements.get(t);i&&(i.disconnect(),t.querySelectorAll("[data-bind]").forEach(r=>M.removePublisherListeners(r)))}static onAdded(t){t.hasAttribute&&t.hasAttribute("data-bind")&&M.addPublisherListeners(t),t.querySelectorAll?t.querySelectorAll("[data-bind]").forEach(i=>M.addPublisherListeners(i)):t.childNodes.forEach(i=>M.onAdded(i))}static onRemoved(t){t.hasAttribute&&t.hasAttribute("data-bind")&&M.removePublisherListeners(t),t.querySelectorAll?t.querySelectorAll("[data-bind]").forEach(i=>M.removePublisherListeners(i)):t.childNodes.forEach(i=>M.onRemoved(i))}static onMutation(t){for(const i of t)switch(i.type){case"attributes":M.addPublisherListeners(i.target);break;case"childList":i.addedNodes.forEach(r=>{M.onAdded(r)}),i.removedNodes.forEach(r=>{M.onRemoved(r)});break}}static removePublisherListeners(t){const i=M.publisherListeners.get(t);i&&(M.publisherListeners.delete(t),i.forEach(r=>{r.publisher?.offAssign(r.onAssign)}))}static getVariablesDescriptor(t){let i=t.match(/(\$(?:\w+\\?\.?)+)/g);return i?i=i.map(r=>r.replace("$","")):i=[t],i=i.filter(r=>r.length>0),{expression:t.replace("\\",""),variables:i.map(r=>r.split(/\b\.\b/).map(e=>e.replace("\\","")))}}static getDataBindItems(t){return"attributes"in t?Array.from(t.attributes).filter(i=>i.name.indexOf("::")==0).map(i=>({propertyToUpdate:i.name.substring(2).replace(/-((html)|\w)/g,e=>e.substring(1).toUpperCase()),bindedVariablesDescriptor:M.getVariablesDescriptor(i.value)})):[]}static getSubPublisher(t,i){if(!i)return t;for(const r of i)if(r!="_self_"){if(!t)return null;t=t[r]}return t}static addPublisherListeners(t){M.removePublisherListeners(t);const i=Z.getAncestorAttributeValue(t.parentNode||t.host||t,"dataProvider");if(!i)return;const r=E.getInstance().get(i),e=M.getDataBindItems(t),o=[];e.forEach(n=>{const l=n.bindedVariablesDescriptor,c=n.propertyToUpdate;for(const h of l.variables){const u=h;let d=r;d=M.getSubPublisher(r,u);const p=t,w={publisher:d,onAssign:()=>{const v=l.variables.map(D=>M.getSubPublisher(r,D)?.get());let m=l.expression,y=!1;if(v.length==1&&l.variables[0].join(".")==m.substring(1)){let D=v[0];D===null&&(D=""),p[c]=D;return}for(let D=0;D<v.length;D++){let f=v[D];const b=l.variables[D];f===null&&(y=!0,f=void 0),m=m.replace("$"+b.join("."),f)}if(m.indexOf("|")!=-1){const D=m.indexOf("|");if(D==0)m=Os.js(m.substring(1));else{const f=m.substring(0,D),b=m.substring(D+1),x=Os[f];m=y?"":x?x(b):m}}else m=y?"":m;p[c]=m}};d?.onAssign(w.onAssign),o.push(w)}}),M.publisherListeners.set(t,o)}},M.observedElements=new Map,M.enabled=!0,M.publisherListeners=new Map,M);Fs.observe(document.documentElement),window.SonicDataBindObserver||(window.SonicDataBindObserver=Fs);/**
1
+ (function(Z){typeof define=="function"&&define.amd?define(Z):Z()})((function(){"use strict";var M,tt;let Z=class Ft{static getLanguage(){const t=document.documentElement.lang;return localStorage.getItem("SonicSelectedLanguage")||t}static getCookies(){return document.cookie.split(";").reduce((t,i)=>{const r=i.indexOf("=");return t[i.substring(0,r).trim()]=i.substring(r+1),t},{})}static everyAncestors(t,i){for(;t;){if(!i(t))return;t=t.parentNode||t.host}}static getScrollableAncestor(t){for(;t;){const i=t;if(i.nodeType===1){const r=window.getComputedStyle(i);if(r?.overflowY==="auto"||r?.overflowY==="scroll"||r?.overflowY==="hidden"||r?.overflowX==="auto"||r?.overflowX==="scroll"||r?.overflowX==="hidden")return t}t=t.parentNode||t.host}return null}static scopeAttributeNames(t){const i=t.toLowerCase();return i===t?[t]:[t,i]}static readScopeAttributeOnElement(t,i){for(const r of Ft.scopeAttributeNames(i))if(t.hasAttribute(r))return t.getAttribute(r)??"";return null}static getAncestorAttributeValue(t,i){if(!t)return null;let r=t;for(;r;){if(r instanceof HTMLElement){const o=Ft.readScopeAttributeOnElement(r,i);if(o!=null)return o}const e=r.parentNode||r.host;if(!e)break;r=e}return null}static getApiConfiguration(t){const i=Ft.getAncestorAttributeValue(t,"token"),r=Ft.getAncestorAttributeValue(t,"addHTTPResponse")!=null,e=Ft.getAncestorAttributeValue(t,"serviceURL");let o=null,n=null;const l=Ft.getAncestorAttributeValue(t,"tokenProvider"),c=Ft.getAncestorAttributeValue(t,"eventsApiToken");i||(o=Ft.getAncestorAttributeValue(t,"userName"),n=Ft.getAncestorAttributeValue(t,"password"));const h=Ft.getAncestorAttributeValue(t,"credentials")||void 0,u=t.getAttribute("cache"),d=t.hasAttribute("blockUntilDone"),p=t.hasAttribute("keepAlive");return{serviceURL:e,token:i,userName:o,password:n,authToken:c,tokenProvider:l,addHTTPResponse:r,credentials:h,cache:u,blockUntilDone:d,keepAlive:p}}static getClosestElement(t,i){for(;!(t.nodeName&&t.nodeName.toLowerCase()===i)&&(t.parentNode||t.host);)t=t.parentNode||t.host;return t.nodeName?t:null}static getClosestForm(t){return Ft.getClosestElement(t,"form")}static getAncestorsByTagNames(t,i){const r=new Set(i.map(n=>n.toLowerCase())),e=[];let o=t.parentNode||t.host;for(;o;)o instanceof Element&&r.has(o.tagName.toLowerCase())&&e.push(o),o=o.parentNode||o.host;return e}static getAncestorsBySelectors(t,i){const r=[];let e=t.parentNode||t.host;for(;e;){if(e instanceof Element)for(const o of i)try{if(e.matches(o)){r.push(e);break}}catch{}e=e.parentNode||e.host}return r}static async loadJS(t){return new Promise(async r=>{const e=document.createElement("script");e.src=t,e.onload=()=>r(!0),e.onerror=()=>r(!0),document.head.appendChild(e)})}static async loadCSS(t){return new Promise(async r=>{const e=document.createElement("link");e.type="text/css",e.rel="stylesheet",e.href=t,e.onload=()=>r(!0),e.onerror=()=>r(!0),document.head.appendChild(e)})}};const bi=s=>{const t=document.documentElement,i=new MutationObserver(e=>{for(let o of e)o.type==="attributes"&&o.attributeName==="lang"&&s()}),r={attributes:!0,attributeFilter:["lang"]};i.observe(t,r)};let Os=class{static ucFirst(t){return typeof t!="string"?t:t.charAt(0).toUpperCase()+t.substring(1)}static minutesDuration(t,i="",r="long"){i||(i=Z.getLanguage());const e=(h,u)=>[Math.floor(h/u),h%u];function o(h,u,d){return new Intl.NumberFormat(h,{style:"unit",unit:u,unitDisplay:d}).format}const[n,l]=e(t,60),c=[];return n&&c.push(o(i,"hour",r)(n)),l&&c.push(o(i,"minute",r)(l)),new Intl.ListFormat(i,{style:"long",type:"conjunction"}).format(c)}static js(t){try{return Function("return "+t)()}catch{return""}}};class _r{constructor(t){this.path=t}toString(){return this.path}}function wr(s){return new Proxy(s,{get(t,i){if(i==="path")return t.path;if(i==="toString")return t.toString.bind(t);if(i===Symbol.toStringTag)return"DataProviderKey";if(typeof i=="symbol")return t[i];const r=t.path?`${t.path}.${String(i)}`:String(i);return wr(new _r(r))}})}const Jo=/\$\{|\{\$/;function tn(s){return Jo.test(s)}function mi(s){const t=typeof s=="string"?s:s.path;if(tn(t))throw new Error("Static publisher path required for get/set/dp. Use @subscribe, @publish, or @handle for dynamic DataProviderKey paths.");return t}const es=function(s){return this instanceof es?wr(new _r(s)):new es(s)};let nt=class oe{static shallowEqual(t,i,r=!0){const e=Object.keys(t),o=Object.keys(i);if(e.length!==o.length&&r)return!1;for(const n of e){const l=t[n],c=i[n];if(r?l!==c:l!=c)return!1}return!0}static deepEqual(t,i,r=!0){const e=Object.keys(t),o=Object.keys(i);if(e.length!==o.length&&r)return!1;for(const n of e){const l=t[n],c=i[n],h=oe.isObject(l)&&oe.isObject(c),u=r?l!==c:l!=c;if(h&&!oe.deepEqual(l,c)||!h&&u)return!1}return!0}static isObject(t){return t!=null&&typeof t=="object"}static isUndefindOrNull(t){return t==null}static isEmpty(t){return oe.isUndefindOrNull(t)?!0:Object.keys(t).length===0}static traverse(t,i,r=!1){for(const e of i){const o=t[e];if(o===void 0)return;r&&oe.isObject(o)?t=Object.assign(Array.isArray(o)?[]:{},t,o):t=t[e]}return t}static traverseDotNotation(t,i,r=!1){return oe.traverse(t,i.split("."),r)}static getURLSearchArray(t,i=""){let r=[];for(let e in t){const o=t[e];i&&(e=i+"["+e+"]"),oe.isObject(o)?r=[...r,...this.getURLSearchArray(o,e)]:r.push(`${e}=${o}`)}return r}static getURLSearchString(t){return oe.getURLSearchArray(t,"").join("&")}};const yt=nt.traverseDotNotation;let en=class{static async queueTaskPromise(){return new Promise(t=>{window.queueMicrotask(()=>t(null))})}static async delayPromise(t){return new Promise(i=>{setTimeout(i,t)})}},xr="sonic";typeof __SONIC_PREFIX__<"u"&&(xr=__SONIC_PREFIX__);let Pr=xr.replace(/-([a-z])/g,s=>s[1].toUpperCase());const Es=Pr.charAt(0).toUpperCase()+Pr.slice(1),sn=new Set(["localStorageMode","expirationDelayMs","invalidateOnPageShow"]);function Cr(s){return s==null||typeof s!="object"||Array.isArray(s)?!1:Object.keys(s).some(t=>sn.has(t))}function Ls(s){return Object.prototype.hasOwnProperty.call(s,"__value")}function ne(s){return typeof s=="object"&&s!==null}let ze="sonic";typeof __SONIC_PREFIX__>"u"&&(ze="sonic");const gi=ze=="sonic"?"publisher-proxies-data":ze+"-publisher-proxies-data",xe=class xe{constructor(t,i,r){for(this._proxies_=new Map,this._is_savable_=!1,this._expiration_delay_=1e3*60*60*12,this._invalidate_on_page_show_=!1,this._invalidateListeners_=new Set,this._formInvalidateListeners_=new Set,this._assignListeners_=new Set,this._mutationListeners_=new Set,this._fillListeners_=new Set,this._templateFillListeners_=new Set,this._lockInternalMutationPublishing_=!1,this._instanceCounter_=0,this._assignmentId_=0,this._value_=t,this.parent=i||null,this._parentKey_=r,this.root=this,this._instanceCounter_=0;this.root.parent;)this.root=this.root.parent}delete(){for(const t in this._proxies_.keys())t!="_parent_"&&this._proxies_.get(t)?.delete();this._invalidateListeners_.clear(),this._formInvalidateListeners_.clear(),this._assignListeners_.clear(),this._mutationListeners_.clear(),this._fillListeners_.clear(),this._templateFillListeners_.clear(),this._proxies_.clear(),xe.instances.delete(this._instanceCounter_)}hasListener(){return this._templateFillListeners_.size>0||this._assignListeners_.size>0||this._invalidateListeners_.size>0||this._formInvalidateListeners_.size>0||this._mutationListeners_.size>0||this._fillListeners_.size>0}_publishInternalMutation_(t=!1){if(this._mutationListeners_.forEach(i=>i()),this._is_savable_&&!E.changed){E.changed=!0,E.saveId++;const i=E.saveId;setTimeout(()=>E.getInstance().saveToLocalStorage(i),1e3)}t||this.parent&&this.parent._publishInternalMutation_()}async _publishAssignement_(t=!1){if(this._assignmentId_++,this._assignmentId_!==this._assignmentId_)return;const r=this.get();this._assignListeners_.forEach(e=>{e(r)}),this._publishInternalMutation_(t)}_publishInvalidation_(){this._invalidateListeners_.forEach(t=>t())}_publishFormInvalidation_(){this._formInvalidateListeners_.forEach(t=>t())}_publishDynamicFilling_(t,i){this._fillListeners_.forEach(r=>{r[t]!==i&&(r[t]=i)}),this._publishTemplateFilling_(t,i)}_publishTemplateFilling_(t,i){this._templateFillListeners_.forEach(r=>{const e=Object.getOwnPropertyDescriptor(r,t);e&&!e.set&&!e.writable||(r.propertyMap&&r.propertyMap[t]&&(t=r.propertyMap[t]),typeof r[t]<"u"&&r[t]!==i&&(r[t]=i))})}onAssign(t,i=!0){typeof t=="function"&&(this._assignListeners_.has(t)||(this._assignListeners_.add(t),i&&t(this.get())))}offAssign(t){this._assignListeners_.delete(t)}onInvalidate(t){typeof t=="function"&&this._invalidateListeners_.add(t)}offInvalidate(t){typeof t=="function"&&this._invalidateListeners_.delete(t)}invalidate(){this._publishInvalidation_()}onFormInvalidate(t){typeof t=="function"&&this._formInvalidateListeners_.add(t)}offFormInvalidate(t){typeof t=="function"&&this._formInvalidateListeners_.delete(t)}invalidateForm(){this._publishFormInvalidation_()}onInternalMutation(t){typeof t=="function"&&(this._mutationListeners_.add(t),t())}offInternalMutation(t){typeof t=="function"&&this._mutationListeners_.delete(t)}startTemplateFilling(t){if(this._templateFillListeners_.add(t),typeof this._value_=="object")for(const i in this._value_){let r=i;const e=this._value_[i];t.propertyMap&&t.propertyMap[i]&&(r=t.propertyMap[i]),typeof t[i]<"u"&&t[i]!==e&&(t[r]=e)}}stopTemplateFilling(t){this._templateFillListeners_.delete(t)}startDynamicFilling(t){this._fillListeners_.add(t);for(const i in this._value_){const r=this._value_[i];t[i]!==r&&(t[i]=r)}}stopDynamicFilling(t){this._fillListeners_.delete(t)}set(t,i=!1){if(this._value_===t||ne(this._value_)&&ne(t)&&t&&Ls(this._value_)&&Ls(t)&&this._value_.__value===t.__value||!ne(t)&&t===this._value_.__value)return!0;this._value_=ne(t)?t:{__value:t},this._cachedGet_=void 0;const r=Ls(this._value_);if(this._parentKey_&&this.parent){const e=Ls(this._value_)?this._value_.__value:this._value_;if(this.parent?.get()==null&&this.parent?.get()==null)if(isNaN(Number(this._parentKey_)))this.parent.set({[this._parentKey_]:e});else{const o=[];o[Number(this._parentKey_)]=e,this.parent.set(o)}else this.parent._value_[this._parentKey_]=e}if(r)return this._proxies_.forEach((e,o)=>{o!="_parent_"&&(e.set(null),this._publishDynamicFilling_(o,null))}),this._publishAssignement_(i),this.parent&&this._parentKey_&&this.parent._publishDynamicFilling_(this._parentKey_,this._value_.__value),!0;for(const e in this._value_)this._value_[e]===void 0&&delete this._value_[e];if(this._proxies_.forEach((e,o)=>{const n=this._value_[o];o!="_parent_"&&n===void 0&&n!==null&&isNaN(Number(o))&&(e.set(null),this._publishDynamicFilling_(o,null))}),this._publishAssignement_(),this.parent&&this._parentKey_&&this.parent._publishDynamicFilling_(this._parentKey_,this._value_),ne(this._value_))for(const e in this._value_){const o=t[e],l=ne(o)?o:{__value:o};if(!this._proxies_.has(e)){this._publishDynamicFilling_(e,o);continue}this._proxies_.get(e)?.set(l,!0),this._publishDynamicFilling_(e,o)}return!0}get(){if(rn(this),this._cachedGet_!==void 0)return this._cachedGet_;if(Object.prototype.hasOwnProperty.call(this._value_,"__value")){const t=this._value_.__value;return this._cachedGet_=t??null}return this._cachedGet_=this._value_!=null?this._value_:null}get $tag(){return this._instanceCounter_||(xe.instancesCounter++,this._instanceCounter_=xe.instancesCounter),xe.instances.set(this._instanceCounter_,this),"<"+ze+'-publisher-proxy publisher="'+this._instanceCounter_+'"></'+ze+"-publisher-proxy>"}};xe.instances=new Map,xe.instancesCounter=0;let ss=xe;const Ts=[];function rn(s){Ts.length>0&&Ts[0].add(s)}function Sr(){Ts.unshift(new Set)}function $r(){return Ts.shift()}const F=class F{constructor(){if(this.enabledLocaStorageProxies=[],this.publishers=new Map,this.localStorageData={},this.isLocalStrorageReady=null,this.initialisedData=[],F.instance!=null)throw"Singleton / use getInstance";F.instance=this,this.isLocalStrorageReady=this.cleanStorageData(),F.initPageShowHandler()}static initPageShowHandler(){F.pageShowHandlerInitialized||(F.pageShowHandlerInitialized=!0,window.addEventListener("pageshow",t=>{t.persisted&&F.getInstance().invalidateAll()}))}invalidateAll(){this.publishers.forEach(t=>{t._invalidate_on_page_show_&&t.invalidate()})}async cleanStorageData(){return new Promise(t=>{(async()=>{try{let r=localStorage.getItem(gi),e=null;if(r&&(e=await this.decompress(r,"gzip")),e)try{this.localStorageData=JSON.parse(e)}catch{this.localStorageData={}}else r=await this.compress("{}","gzip"),localStorage.setItem(gi,r),this.localStorageData={};const o=1e3*60*60*12;for(const n in this.localStorageData){const l=this.localStorageData[n],c=new Date().getTime()-(l.expirationDelayMs||o);l.lastModifiationMS<c&&delete this.localStorageData[n]}t(!0)}catch{window.requestAnimationFrame(()=>{t(!1)}),console.warn("no publisher cache in this browser")}})()})}static getInstance(t){if(t){const i=F.instances.get(t);return i||(console.warn("No PublisherManager instance registered with id:",t,"creating new one"),new F)}return F.instance==null?new F:F.instance}static get(t,i){return F.getInstance().get(t,i)}async setLocalData(t,i){await this.isLocalStrorageReady,t.set(this.localStorageData[i+"¤lang_"+Z.getLanguage()]?.data||t.get())}get(t,i){const r=i?.localStorageMode==="enabled",e=i?.invalidateOnPageShow===!0;if(!this.publishers.has(t)){const l=vi({});this.set(t,l)}const o=this.publishers.get(t);return r&&this.initialisedData.indexOf(t)===-1&&(i?.expirationDelayMs&&(o._expiration_delay_=i.expirationDelayMs),o._is_savable_=!0,this.initialisedData.push(t),this.setLocalData(o,t)),e&&(o._invalidate_on_page_show_=e),this.publishers.get(t)}set(t,i){this.publishers.set(t,i)}delete(t){return this.publishers.has(t)?(this.publishers.delete(t),!0):!1}async saveToLocalStorage(t=0){if(!(t!==F.saveId&&t%10!=0))try{if(!F.changed||F.saving)return;F.saving=!0,F.changed=!1;const i=Array.from(this.publishers.keys());let r=!1;for(const e of i){const o=this.publishers.get(e);if(!o?._is_savable_)continue;const n=o?.get();n&&(this.localStorageData[e+"¤lang_"+Z.getLanguage()]={lastModifiationMS:new Date().getTime(),expirationDelayMs:o._expiration_delay_,data:n},r=!0)}if(r){const e=await this.compress(JSON.stringify(this.localStorageData),"gzip");localStorage.setItem(gi,e)}if(F.saving=!1,F.changed){F.saveId++;const e=F.saveId;setTimeout(()=>this.saveToLocalStorage(e),1e3)}}catch{F.saving=!1}}async compress(t,i){const r=new TextEncoder().encode(t),e=window,o=new e.CompressionStream(i),n=o.writable.getWriter();n.write(r),n.close();const l=await new Response(o.readable).arrayBuffer(),c=new Uint8Array(l);let h="";for(let u=0;u<c.length;u++)h+=String.fromCharCode(c[u]);return btoa(h)}async decompress(t,i){const r=atob(t),o=Uint8Array.from(r,u=>u.charCodeAt(0)).buffer,n=window,l=new n.DecompressionStream(i),c=l.writable.getWriter();c.write(o),c.close();const h=await new Response(l.readable).arrayBuffer();return new TextDecoder().decode(h)}};F.buildDate="Thu Jul 30 2026 10:31:44 GMT+0200 (Central European Summer Time)",F.changed=!1,F.saving=!1,F.saveId=0,F.instance=null,F.instances=new Map,F.pageShowHandlerInitialized=!1;let E=F;if(typeof window<"u"){const s=window;s[Es+"PublisherManager"]=s[Es+"PublisherManager"]||E}const on=new Set(["invalidate","onInvalidate","offInvalidate","invalidateForm","onFormInvalidate","offFormInvalidate","onAssign","offAssign","startDynamicFilling","stopDynamicFilling","startTemplateFilling","stopTemplateFilling","onInternalMutation","offInternalMutation","set","get","$tag","_cachedGet_","_templateFillListeners_","_fillListeners_","_assignListeners_","_invalidateListeners_","_formInvalidateListeners_","_publishInternalMutation_","hasListener","delete","_mutationListeners_","_publishDynamicFilling_","_publishInvalidation_","_publishFormInvalidation_","_publishTemplateFilling_","_publishAssignement_","_proxies_","parent","_parentKey_","_value_","_is_savable_","_expiration_delay_","_lockInternalMutationPublishing_","_instanceCounter_","_assignmentId_","_invalidate_on_page_show_"]);function nn(s,t){return{get:function(i,r){if(typeof r=="string"&&on.has(r))return s[r];if(r==Symbol.toPrimitive)return()=>t().get();if(!s._proxies_.has(r)){const e=s._value_[r],o=vi(ne(e)?e:{__value:e},s,r);o._proxies_.set("_parent_",t()),s._proxies_.set(r,o)}return s._proxies_.get(r)},set:function(i,r,e){if(r=="_value_")return s._value_=e,!0;if(r=="_cachedGet_")return s._cachedGet_=e,!0;if(r=="_assignmentId_")return s._assignmentId_=e,!0;if(r=="_is_savable_")return s._is_savable_=e,!0;if(r=="_expiration_delay_")return s._expiration_delay_=e,!0;if(r=="_invalidate_on_page_show_")return s._invalidate_on_page_show_=e,!0;if(r=="_instanceCounter_")return s._instanceCounter_=e,!0;if(!s._proxies_.has(r)){const n=vi({},s,r);n._proxies_.set("_parent_",t()),s._proxies_.set(r,n)}return s._value_[r]!==e&&(s._value_[r]=e,s._publishDynamicFilling_(r,e),s._proxies_.get(r)?.set(ne(e)?e:{__value:e})),!0},deleteProperty:function(i,r){return s._publishDynamicFilling_(r,null),s._proxies_.get(r)?.set(null),delete s._value_[r]},has:function(i,r){return r in s._value_&&r!="_lockInternalMutationPublishing_"},defineProperty:function(i,r,e){return e&&"value"in e&&(s._value_[r]=e.value),!0},getOwnPropertyDescriptor:function(i,r){return{enumerable:!0,configurable:!0}},ownKeys:function(i){return s._value_.__value?Object.keys(s._value_.__value):Object.keys(s._value_)}}}function vi(s,t=null,i){const r=new ss(s,t,i);let e=null;const o=nn(r,()=>e);return e=new Proxy(r,o),e}class an extends HTMLElement{constructor(){super(),this.publisherId="",this.onAssign=t=>{this.innerHTML=t.toString()}}connectedCallback(){this.publisherId=this.getAttribute("publisher")||"",this.publisher=ss.instances.get(parseInt(this.publisherId)),this.publisher?.onAssign(this.onAssign)}disconnectedCallback(){this.publisher?.offAssign(this.onAssign)}}try{customElements.define(ze+"-publisher-proxy",an)}catch{}const Is=(s,t)=>{if(typeof s=="function"){const i=s;return Sr(),i(),$r()}if(typeof s=="string"){const i=s.split("."),r=i.shift()||"";let e=E.get(r,t);e=nt.traverse(e,i);const o=new Set;return o.add(e),o}return new Set([s])};function ln(s){const t=mi(s);return Is(t).values().next().value?.get()}function Ms(s,t,i){const r=mi(s);return Is(r,i).values().next().value}function cn(s,t){return Cr(t)?Ms(s,void 0,t):Ms(s)}function Ns(s,t){return Cr(t)?Ms(s,void 0,t):Ms(s)}function hn(s,t){const i=mi(s);Is(i).values().next().value?.set(t)}let Fs=(M=class{static disable(){this.enabled&&(this.enabled=!1,Array.from(M.observedElements.keys()).forEach(t=>M.unObserve(t)))}static observe(t){if(!t||!M.enabled||M.observedElements.has(t))return;const i=new MutationObserver(M.onMutation),r={};r.childList=!0,r.subtree=!0,r.attributes=!0,r.attributeFilter=["data-bind"],i.observe(t,r),t.querySelectorAll("[data-bind]").forEach(e=>M.addPublisherListeners(e)),M.observedElements.set(t,i)}static unObserve(t){if(!t)return;const i=this.observedElements.get(t);i&&(i.disconnect(),t.querySelectorAll("[data-bind]").forEach(r=>M.removePublisherListeners(r)))}static onAdded(t){t.hasAttribute&&t.hasAttribute("data-bind")&&M.addPublisherListeners(t),t.querySelectorAll?t.querySelectorAll("[data-bind]").forEach(i=>M.addPublisherListeners(i)):t.childNodes.forEach(i=>M.onAdded(i))}static onRemoved(t){t.hasAttribute&&t.hasAttribute("data-bind")&&M.removePublisherListeners(t),t.querySelectorAll?t.querySelectorAll("[data-bind]").forEach(i=>M.removePublisherListeners(i)):t.childNodes.forEach(i=>M.onRemoved(i))}static onMutation(t){for(const i of t)switch(i.type){case"attributes":M.addPublisherListeners(i.target);break;case"childList":i.addedNodes.forEach(r=>{M.onAdded(r)}),i.removedNodes.forEach(r=>{M.onRemoved(r)});break}}static removePublisherListeners(t){const i=M.publisherListeners.get(t);i&&(M.publisherListeners.delete(t),i.forEach(r=>{r.publisher?.offAssign(r.onAssign)}))}static getVariablesDescriptor(t){let i=t.match(/(\$(?:\w+\\?\.?)+)/g);return i?i=i.map(r=>r.replace("$","")):i=[t],i=i.filter(r=>r.length>0),{expression:t.replace("\\",""),variables:i.map(r=>r.split(/\b\.\b/).map(e=>e.replace("\\","")))}}static getDataBindItems(t){return"attributes"in t?Array.from(t.attributes).filter(i=>i.name.indexOf("::")==0).map(i=>({propertyToUpdate:i.name.substring(2).replace(/-((html)|\w)/g,e=>e.substring(1).toUpperCase()),bindedVariablesDescriptor:M.getVariablesDescriptor(i.value)})):[]}static getSubPublisher(t,i){if(!i)return t;for(const r of i)if(r!="_self_"){if(!t)return null;t=t[r]}return t}static addPublisherListeners(t){M.removePublisherListeners(t);const i=Z.getAncestorAttributeValue(t.parentNode||t.host||t,"dataProvider");if(!i)return;const r=E.getInstance().get(i),e=M.getDataBindItems(t),o=[];e.forEach(n=>{const l=n.bindedVariablesDescriptor,c=n.propertyToUpdate;for(const h of l.variables){const u=h;let d=r;d=M.getSubPublisher(r,u);const p=t,w={publisher:d,onAssign:()=>{const v=l.variables.map(D=>M.getSubPublisher(r,D)?.get());let m=l.expression,y=!1;if(v.length==1&&l.variables[0].join(".")==m.substring(1)){let D=v[0];D===null&&(D=""),p[c]=D;return}for(let D=0;D<v.length;D++){let f=v[D];const b=l.variables[D];f===null&&(y=!0,f=void 0),m=m.replace("$"+b.join("."),f)}if(m.indexOf("|")!=-1){const D=m.indexOf("|");if(D==0)m=Os.js(m.substring(1));else{const f=m.substring(0,D),b=m.substring(D+1),x=Os[f];m=y?"":x?x(b):m}}else m=y?"":m;p[c]=m}};d?.onAssign(w.onAssign),o.push(w)}}),M.publisherListeners.set(t,o)}},M.observedElements=new Map,M.enabled=!0,M.publisherListeners=new Map,M);Fs.observe(document.documentElement),window.SonicDataBindObserver||(window.SonicDataBindObserver=Fs);/**
2
2
  * @license
3
3
  * Copyright 2017 Google LLC
4
4
  * SPDX-License-Identifier: BSD-3-Clause
@@ -742,7 +742,7 @@ const j = class j {
742
742
  return new TextDecoder().decode(h);
743
743
  }
744
744
  };
745
- j.buildDate = "Thu Jul 09 2026 13:42:07 GMT+0200 (Central European Summer Time)", j.changed = !1, j.saving = !1, j.saveId = 0, j.instance = null, j.instances = /* @__PURE__ */ new Map(), j.pageShowHandlerInitialized = !1;
745
+ j.buildDate = "Thu Jul 30 2026 10:31:44 GMT+0200 (Central European Summer Time)", j.changed = !1, j.saving = !1, j.saveId = 0, j.instance = null, j.instances = /* @__PURE__ */ new Map(), j.pageShowHandlerInitialized = !1;
746
746
  let E = j;
747
747
  if (typeof window < "u") {
748
748
  const s = window;
@@ -1,4 +1,4 @@
1
- (function(Z){typeof define=="function"&&define.amd?define(Z):Z()})((function(){"use strict";var M,tt;let Z=class Ft{static getLanguage(){const t=document.documentElement.lang;return localStorage.getItem("SonicSelectedLanguage")||t}static getCookies(){return document.cookie.split(";").reduce((t,i)=>{const r=i.indexOf("=");return t[i.substring(0,r).trim()]=i.substring(r+1),t},{})}static everyAncestors(t,i){for(;t;){if(!i(t))return;t=t.parentNode||t.host}}static getScrollableAncestor(t){for(;t;){const i=t;if(i.nodeType===1){const r=window.getComputedStyle(i);if(r?.overflowY==="auto"||r?.overflowY==="scroll"||r?.overflowY==="hidden"||r?.overflowX==="auto"||r?.overflowX==="scroll"||r?.overflowX==="hidden")return t}t=t.parentNode||t.host}return null}static scopeAttributeNames(t){const i=t.toLowerCase();return i===t?[t]:[t,i]}static readScopeAttributeOnElement(t,i){for(const r of Ft.scopeAttributeNames(i))if(t.hasAttribute(r))return t.getAttribute(r)??"";return null}static getAncestorAttributeValue(t,i){if(!t)return null;let r=t;for(;r;){if(r instanceof HTMLElement){const o=Ft.readScopeAttributeOnElement(r,i);if(o!=null)return o}const e=r.parentNode||r.host;if(!e)break;r=e}return null}static getApiConfiguration(t){const i=Ft.getAncestorAttributeValue(t,"token"),r=Ft.getAncestorAttributeValue(t,"addHTTPResponse")!=null,e=Ft.getAncestorAttributeValue(t,"serviceURL");let o=null,n=null;const l=Ft.getAncestorAttributeValue(t,"tokenProvider"),c=Ft.getAncestorAttributeValue(t,"eventsApiToken");i||(o=Ft.getAncestorAttributeValue(t,"userName"),n=Ft.getAncestorAttributeValue(t,"password"));const h=Ft.getAncestorAttributeValue(t,"credentials")||void 0,u=t.getAttribute("cache"),d=t.hasAttribute("blockUntilDone"),p=t.hasAttribute("keepAlive");return{serviceURL:e,token:i,userName:o,password:n,authToken:c,tokenProvider:l,addHTTPResponse:r,credentials:h,cache:u,blockUntilDone:d,keepAlive:p}}static getClosestElement(t,i){for(;!(t.nodeName&&t.nodeName.toLowerCase()===i)&&(t.parentNode||t.host);)t=t.parentNode||t.host;return t.nodeName?t:null}static getClosestForm(t){return Ft.getClosestElement(t,"form")}static getAncestorsByTagNames(t,i){const r=new Set(i.map(n=>n.toLowerCase())),e=[];let o=t.parentNode||t.host;for(;o;)o instanceof Element&&r.has(o.tagName.toLowerCase())&&e.push(o),o=o.parentNode||o.host;return e}static getAncestorsBySelectors(t,i){const r=[];let e=t.parentNode||t.host;for(;e;){if(e instanceof Element)for(const o of i)try{if(e.matches(o)){r.push(e);break}}catch{}e=e.parentNode||e.host}return r}static async loadJS(t){return new Promise(async r=>{const e=document.createElement("script");e.src=t,e.onload=()=>r(!0),e.onerror=()=>r(!0),document.head.appendChild(e)})}static async loadCSS(t){return new Promise(async r=>{const e=document.createElement("link");e.type="text/css",e.rel="stylesheet",e.href=t,e.onload=()=>r(!0),e.onerror=()=>r(!0),document.head.appendChild(e)})}};const bi=s=>{const t=document.documentElement,i=new MutationObserver(e=>{for(let o of e)o.type==="attributes"&&o.attributeName==="lang"&&s()}),r={attributes:!0,attributeFilter:["lang"]};i.observe(t,r)};let Os=class{static ucFirst(t){return typeof t!="string"?t:t.charAt(0).toUpperCase()+t.substring(1)}static minutesDuration(t,i="",r="long"){i||(i=Z.getLanguage());const e=(h,u)=>[Math.floor(h/u),h%u];function o(h,u,d){return new Intl.NumberFormat(h,{style:"unit",unit:u,unitDisplay:d}).format}const[n,l]=e(t,60),c=[];return n&&c.push(o(i,"hour",r)(n)),l&&c.push(o(i,"minute",r)(l)),new Intl.ListFormat(i,{style:"long",type:"conjunction"}).format(c)}static js(t){try{return Function("return "+t)()}catch{return""}}};class _r{constructor(t){this.path=t}toString(){return this.path}}function wr(s){return new Proxy(s,{get(t,i){if(i==="path")return t.path;if(i==="toString")return t.toString.bind(t);if(i===Symbol.toStringTag)return"DataProviderKey";if(typeof i=="symbol")return t[i];const r=t.path?`${t.path}.${String(i)}`:String(i);return wr(new _r(r))}})}const Jo=/\$\{|\{\$/;function tn(s){return Jo.test(s)}function mi(s){const t=typeof s=="string"?s:s.path;if(tn(t))throw new Error("Static publisher path required for get/set/dp. Use @subscribe, @publish, or @handle for dynamic DataProviderKey paths.");return t}const es=function(s){return this instanceof es?wr(new _r(s)):new es(s)};let nt=class oe{static shallowEqual(t,i,r=!0){const e=Object.keys(t),o=Object.keys(i);if(e.length!==o.length&&r)return!1;for(const n of e){const l=t[n],c=i[n];if(r?l!==c:l!=c)return!1}return!0}static deepEqual(t,i,r=!0){const e=Object.keys(t),o=Object.keys(i);if(e.length!==o.length&&r)return!1;for(const n of e){const l=t[n],c=i[n],h=oe.isObject(l)&&oe.isObject(c),u=r?l!==c:l!=c;if(h&&!oe.deepEqual(l,c)||!h&&u)return!1}return!0}static isObject(t){return t!=null&&typeof t=="object"}static isUndefindOrNull(t){return t==null}static isEmpty(t){return oe.isUndefindOrNull(t)?!0:Object.keys(t).length===0}static traverse(t,i,r=!1){for(const e of i){const o=t[e];if(o===void 0)return;r&&oe.isObject(o)?t=Object.assign(Array.isArray(o)?[]:{},t,o):t=t[e]}return t}static traverseDotNotation(t,i,r=!1){return oe.traverse(t,i.split("."),r)}static getURLSearchArray(t,i=""){let r=[];for(let e in t){const o=t[e];i&&(e=i+"["+e+"]"),oe.isObject(o)?r=[...r,...this.getURLSearchArray(o,e)]:r.push(`${e}=${o}`)}return r}static getURLSearchString(t){return oe.getURLSearchArray(t,"").join("&")}};const yt=nt.traverseDotNotation;let en=class{static async queueTaskPromise(){return new Promise(t=>{window.queueMicrotask(()=>t(null))})}static async delayPromise(t){return new Promise(i=>{setTimeout(i,t)})}},xr="sonic";typeof __SONIC_PREFIX__<"u"&&(xr=__SONIC_PREFIX__);let Pr=xr.replace(/-([a-z])/g,s=>s[1].toUpperCase());const Es=Pr.charAt(0).toUpperCase()+Pr.slice(1),sn=new Set(["localStorageMode","expirationDelayMs","invalidateOnPageShow"]);function Cr(s){return s==null||typeof s!="object"||Array.isArray(s)?!1:Object.keys(s).some(t=>sn.has(t))}function Ls(s){return Object.prototype.hasOwnProperty.call(s,"__value")}function ne(s){return typeof s=="object"&&s!==null}let ze="sonic";typeof __SONIC_PREFIX__>"u"&&(ze="sonic");const gi=ze=="sonic"?"publisher-proxies-data":ze+"-publisher-proxies-data",xe=class xe{constructor(t,i,r){for(this._proxies_=new Map,this._is_savable_=!1,this._expiration_delay_=1e3*60*60*12,this._invalidate_on_page_show_=!1,this._invalidateListeners_=new Set,this._formInvalidateListeners_=new Set,this._assignListeners_=new Set,this._mutationListeners_=new Set,this._fillListeners_=new Set,this._templateFillListeners_=new Set,this._lockInternalMutationPublishing_=!1,this._instanceCounter_=0,this._assignmentId_=0,this._value_=t,this.parent=i||null,this._parentKey_=r,this.root=this,this._instanceCounter_=0;this.root.parent;)this.root=this.root.parent}delete(){for(const t in this._proxies_.keys())t!="_parent_"&&this._proxies_.get(t)?.delete();this._invalidateListeners_.clear(),this._formInvalidateListeners_.clear(),this._assignListeners_.clear(),this._mutationListeners_.clear(),this._fillListeners_.clear(),this._templateFillListeners_.clear(),this._proxies_.clear(),xe.instances.delete(this._instanceCounter_)}hasListener(){return this._templateFillListeners_.size>0||this._assignListeners_.size>0||this._invalidateListeners_.size>0||this._formInvalidateListeners_.size>0||this._mutationListeners_.size>0||this._fillListeners_.size>0}_publishInternalMutation_(t=!1){if(this._mutationListeners_.forEach(i=>i()),this._is_savable_&&!E.changed){E.changed=!0,E.saveId++;const i=E.saveId;setTimeout(()=>E.getInstance().saveToLocalStorage(i),1e3)}t||this.parent&&this.parent._publishInternalMutation_()}async _publishAssignement_(t=!1){if(this._assignmentId_++,this._assignmentId_!==this._assignmentId_)return;const r=this.get();this._assignListeners_.forEach(e=>{e(r)}),this._publishInternalMutation_(t)}_publishInvalidation_(){this._invalidateListeners_.forEach(t=>t())}_publishFormInvalidation_(){this._formInvalidateListeners_.forEach(t=>t())}_publishDynamicFilling_(t,i){this._fillListeners_.forEach(r=>{r[t]!==i&&(r[t]=i)}),this._publishTemplateFilling_(t,i)}_publishTemplateFilling_(t,i){this._templateFillListeners_.forEach(r=>{const e=Object.getOwnPropertyDescriptor(r,t);e&&!e.set&&!e.writable||(r.propertyMap&&r.propertyMap[t]&&(t=r.propertyMap[t]),typeof r[t]<"u"&&r[t]!==i&&(r[t]=i))})}onAssign(t,i=!0){typeof t=="function"&&(this._assignListeners_.has(t)||(this._assignListeners_.add(t),i&&t(this.get())))}offAssign(t){this._assignListeners_.delete(t)}onInvalidate(t){typeof t=="function"&&this._invalidateListeners_.add(t)}offInvalidate(t){typeof t=="function"&&this._invalidateListeners_.delete(t)}invalidate(){this._publishInvalidation_()}onFormInvalidate(t){typeof t=="function"&&this._formInvalidateListeners_.add(t)}offFormInvalidate(t){typeof t=="function"&&this._formInvalidateListeners_.delete(t)}invalidateForm(){this._publishFormInvalidation_()}onInternalMutation(t){typeof t=="function"&&(this._mutationListeners_.add(t),t())}offInternalMutation(t){typeof t=="function"&&this._mutationListeners_.delete(t)}startTemplateFilling(t){if(this._templateFillListeners_.add(t),typeof this._value_=="object")for(const i in this._value_){let r=i;const e=this._value_[i];t.propertyMap&&t.propertyMap[i]&&(r=t.propertyMap[i]),typeof t[i]<"u"&&t[i]!==e&&(t[r]=e)}}stopTemplateFilling(t){this._templateFillListeners_.delete(t)}startDynamicFilling(t){this._fillListeners_.add(t);for(const i in this._value_){const r=this._value_[i];t[i]!==r&&(t[i]=r)}}stopDynamicFilling(t){this._fillListeners_.delete(t)}set(t,i=!1){if(this._value_===t||ne(this._value_)&&ne(t)&&t&&Ls(this._value_)&&Ls(t)&&this._value_.__value===t.__value||!ne(t)&&t===this._value_.__value)return!0;this._value_=ne(t)?t:{__value:t},this._cachedGet_=void 0;const r=Ls(this._value_);if(this._parentKey_&&this.parent){const e=Ls(this._value_)?this._value_.__value:this._value_;if(this.parent?.get()==null&&this.parent?.get()==null)if(isNaN(Number(this._parentKey_)))this.parent.set({[this._parentKey_]:e});else{const o=[];o[Number(this._parentKey_)]=e,this.parent.set(o)}else this.parent._value_[this._parentKey_]=e}if(r)return this._proxies_.forEach((e,o)=>{o!="_parent_"&&(e.set(null),this._publishDynamicFilling_(o,null))}),this._publishAssignement_(i),this.parent&&this._parentKey_&&this.parent._publishDynamicFilling_(this._parentKey_,this._value_.__value),!0;for(const e in this._value_)this._value_[e]===void 0&&delete this._value_[e];if(this._proxies_.forEach((e,o)=>{const n=this._value_[o];o!="_parent_"&&n===void 0&&n!==null&&isNaN(Number(o))&&(e.set(null),this._publishDynamicFilling_(o,null))}),this._publishAssignement_(),this.parent&&this._parentKey_&&this.parent._publishDynamicFilling_(this._parentKey_,this._value_),ne(this._value_))for(const e in this._value_){const o=t[e],l=ne(o)?o:{__value:o};if(!this._proxies_.has(e)){this._publishDynamicFilling_(e,o);continue}this._proxies_.get(e)?.set(l,!0),this._publishDynamicFilling_(e,o)}return!0}get(){if(rn(this),this._cachedGet_!==void 0)return this._cachedGet_;if(Object.prototype.hasOwnProperty.call(this._value_,"__value")){const t=this._value_.__value;return this._cachedGet_=t??null}return this._cachedGet_=this._value_!=null?this._value_:null}get $tag(){return this._instanceCounter_||(xe.instancesCounter++,this._instanceCounter_=xe.instancesCounter),xe.instances.set(this._instanceCounter_,this),"<"+ze+'-publisher-proxy publisher="'+this._instanceCounter_+'"></'+ze+"-publisher-proxy>"}};xe.instances=new Map,xe.instancesCounter=0;let ss=xe;const Ts=[];function rn(s){Ts.length>0&&Ts[0].add(s)}function Sr(){Ts.unshift(new Set)}function $r(){return Ts.shift()}const F=class F{constructor(){if(this.enabledLocaStorageProxies=[],this.publishers=new Map,this.localStorageData={},this.isLocalStrorageReady=null,this.initialisedData=[],F.instance!=null)throw"Singleton / use getInstance";F.instance=this,this.isLocalStrorageReady=this.cleanStorageData(),F.initPageShowHandler()}static initPageShowHandler(){F.pageShowHandlerInitialized||(F.pageShowHandlerInitialized=!0,window.addEventListener("pageshow",t=>{t.persisted&&F.getInstance().invalidateAll()}))}invalidateAll(){this.publishers.forEach(t=>{t._invalidate_on_page_show_&&t.invalidate()})}async cleanStorageData(){return new Promise(t=>{(async()=>{try{let r=localStorage.getItem(gi),e=null;if(r&&(e=await this.decompress(r,"gzip")),e)try{this.localStorageData=JSON.parse(e)}catch{this.localStorageData={}}else r=await this.compress("{}","gzip"),localStorage.setItem(gi,r),this.localStorageData={};const o=1e3*60*60*12;for(const n in this.localStorageData){const l=this.localStorageData[n],c=new Date().getTime()-(l.expirationDelayMs||o);l.lastModifiationMS<c&&delete this.localStorageData[n]}t(!0)}catch{window.requestAnimationFrame(()=>{t(!1)}),console.warn("no publisher cache in this browser")}})()})}static getInstance(t){if(t){const i=F.instances.get(t);return i||(console.warn("No PublisherManager instance registered with id:",t,"creating new one"),new F)}return F.instance==null?new F:F.instance}static get(t,i){return F.getInstance().get(t,i)}async setLocalData(t,i){await this.isLocalStrorageReady,t.set(this.localStorageData[i+"¤lang_"+Z.getLanguage()]?.data||t.get())}get(t,i){const r=i?.localStorageMode==="enabled",e=i?.invalidateOnPageShow===!0;if(!this.publishers.has(t)){const l=vi({});this.set(t,l)}const o=this.publishers.get(t);return r&&this.initialisedData.indexOf(t)===-1&&(i?.expirationDelayMs&&(o._expiration_delay_=i.expirationDelayMs),o._is_savable_=!0,this.initialisedData.push(t),this.setLocalData(o,t)),e&&(o._invalidate_on_page_show_=e),this.publishers.get(t)}set(t,i){this.publishers.set(t,i)}delete(t){return this.publishers.has(t)?(this.publishers.delete(t),!0):!1}async saveToLocalStorage(t=0){if(!(t!==F.saveId&&t%10!=0))try{if(!F.changed||F.saving)return;F.saving=!0,F.changed=!1;const i=Array.from(this.publishers.keys());let r=!1;for(const e of i){const o=this.publishers.get(e);if(!o?._is_savable_)continue;const n=o?.get();n&&(this.localStorageData[e+"¤lang_"+Z.getLanguage()]={lastModifiationMS:new Date().getTime(),expirationDelayMs:o._expiration_delay_,data:n},r=!0)}if(r){const e=await this.compress(JSON.stringify(this.localStorageData),"gzip");localStorage.setItem(gi,e)}if(F.saving=!1,F.changed){F.saveId++;const e=F.saveId;setTimeout(()=>this.saveToLocalStorage(e),1e3)}}catch{F.saving=!1}}async compress(t,i){const r=new TextEncoder().encode(t),e=window,o=new e.CompressionStream(i),n=o.writable.getWriter();n.write(r),n.close();const l=await new Response(o.readable).arrayBuffer(),c=new Uint8Array(l);let h="";for(let u=0;u<c.length;u++)h+=String.fromCharCode(c[u]);return btoa(h)}async decompress(t,i){const r=atob(t),o=Uint8Array.from(r,u=>u.charCodeAt(0)).buffer,n=window,l=new n.DecompressionStream(i),c=l.writable.getWriter();c.write(o),c.close();const h=await new Response(l.readable).arrayBuffer();return new TextDecoder().decode(h)}};F.buildDate="Thu Jul 09 2026 13:42:07 GMT+0200 (Central European Summer Time)",F.changed=!1,F.saving=!1,F.saveId=0,F.instance=null,F.instances=new Map,F.pageShowHandlerInitialized=!1;let E=F;if(typeof window<"u"){const s=window;s[Es+"PublisherManager"]=s[Es+"PublisherManager"]||E}const on=new Set(["invalidate","onInvalidate","offInvalidate","invalidateForm","onFormInvalidate","offFormInvalidate","onAssign","offAssign","startDynamicFilling","stopDynamicFilling","startTemplateFilling","stopTemplateFilling","onInternalMutation","offInternalMutation","set","get","$tag","_cachedGet_","_templateFillListeners_","_fillListeners_","_assignListeners_","_invalidateListeners_","_formInvalidateListeners_","_publishInternalMutation_","hasListener","delete","_mutationListeners_","_publishDynamicFilling_","_publishInvalidation_","_publishFormInvalidation_","_publishTemplateFilling_","_publishAssignement_","_proxies_","parent","_parentKey_","_value_","_is_savable_","_expiration_delay_","_lockInternalMutationPublishing_","_instanceCounter_","_assignmentId_","_invalidate_on_page_show_"]);function nn(s,t){return{get:function(i,r){if(typeof r=="string"&&on.has(r))return s[r];if(r==Symbol.toPrimitive)return()=>t().get();if(!s._proxies_.has(r)){const e=s._value_[r],o=vi(ne(e)?e:{__value:e},s,r);o._proxies_.set("_parent_",t()),s._proxies_.set(r,o)}return s._proxies_.get(r)},set:function(i,r,e){if(r=="_value_")return s._value_=e,!0;if(r=="_cachedGet_")return s._cachedGet_=e,!0;if(r=="_assignmentId_")return s._assignmentId_=e,!0;if(r=="_is_savable_")return s._is_savable_=e,!0;if(r=="_expiration_delay_")return s._expiration_delay_=e,!0;if(r=="_invalidate_on_page_show_")return s._invalidate_on_page_show_=e,!0;if(r=="_instanceCounter_")return s._instanceCounter_=e,!0;if(!s._proxies_.has(r)){const n=vi({},s,r);n._proxies_.set("_parent_",t()),s._proxies_.set(r,n)}return s._value_[r]!==e&&(s._value_[r]=e,s._publishDynamicFilling_(r,e),s._proxies_.get(r)?.set(ne(e)?e:{__value:e})),!0},deleteProperty:function(i,r){return s._publishDynamicFilling_(r,null),s._proxies_.get(r)?.set(null),delete s._value_[r]},has:function(i,r){return r in s._value_&&r!="_lockInternalMutationPublishing_"},defineProperty:function(i,r,e){return e&&"value"in e&&(s._value_[r]=e.value),!0},getOwnPropertyDescriptor:function(i,r){return{enumerable:!0,configurable:!0}},ownKeys:function(i){return s._value_.__value?Object.keys(s._value_.__value):Object.keys(s._value_)}}}function vi(s,t=null,i){const r=new ss(s,t,i);let e=null;const o=nn(r,()=>e);return e=new Proxy(r,o),e}class an extends HTMLElement{constructor(){super(),this.publisherId="",this.onAssign=t=>{this.innerHTML=t.toString()}}connectedCallback(){this.publisherId=this.getAttribute("publisher")||"",this.publisher=ss.instances.get(parseInt(this.publisherId)),this.publisher?.onAssign(this.onAssign)}disconnectedCallback(){this.publisher?.offAssign(this.onAssign)}}try{customElements.define(ze+"-publisher-proxy",an)}catch{}const Is=(s,t)=>{if(typeof s=="function"){const i=s;return Sr(),i(),$r()}if(typeof s=="string"){const i=s.split("."),r=i.shift()||"";let e=E.get(r,t);e=nt.traverse(e,i);const o=new Set;return o.add(e),o}return new Set([s])};function ln(s){const t=mi(s);return Is(t).values().next().value?.get()}function Ms(s,t,i){const r=mi(s);return Is(r,i).values().next().value}function cn(s,t){return Cr(t)?Ms(s,void 0,t):Ms(s)}function Ns(s,t){return Cr(t)?Ms(s,void 0,t):Ms(s)}function hn(s,t){const i=mi(s);Is(i).values().next().value?.set(t)}let Fs=(M=class{static disable(){this.enabled&&(this.enabled=!1,Array.from(M.observedElements.keys()).forEach(t=>M.unObserve(t)))}static observe(t){if(!t||!M.enabled||M.observedElements.has(t))return;const i=new MutationObserver(M.onMutation),r={};r.childList=!0,r.subtree=!0,r.attributes=!0,r.attributeFilter=["data-bind"],i.observe(t,r),t.querySelectorAll("[data-bind]").forEach(e=>M.addPublisherListeners(e)),M.observedElements.set(t,i)}static unObserve(t){if(!t)return;const i=this.observedElements.get(t);i&&(i.disconnect(),t.querySelectorAll("[data-bind]").forEach(r=>M.removePublisherListeners(r)))}static onAdded(t){t.hasAttribute&&t.hasAttribute("data-bind")&&M.addPublisherListeners(t),t.querySelectorAll?t.querySelectorAll("[data-bind]").forEach(i=>M.addPublisherListeners(i)):t.childNodes.forEach(i=>M.onAdded(i))}static onRemoved(t){t.hasAttribute&&t.hasAttribute("data-bind")&&M.removePublisherListeners(t),t.querySelectorAll?t.querySelectorAll("[data-bind]").forEach(i=>M.removePublisherListeners(i)):t.childNodes.forEach(i=>M.onRemoved(i))}static onMutation(t){for(const i of t)switch(i.type){case"attributes":M.addPublisherListeners(i.target);break;case"childList":i.addedNodes.forEach(r=>{M.onAdded(r)}),i.removedNodes.forEach(r=>{M.onRemoved(r)});break}}static removePublisherListeners(t){const i=M.publisherListeners.get(t);i&&(M.publisherListeners.delete(t),i.forEach(r=>{r.publisher?.offAssign(r.onAssign)}))}static getVariablesDescriptor(t){let i=t.match(/(\$(?:\w+\\?\.?)+)/g);return i?i=i.map(r=>r.replace("$","")):i=[t],i=i.filter(r=>r.length>0),{expression:t.replace("\\",""),variables:i.map(r=>r.split(/\b\.\b/).map(e=>e.replace("\\","")))}}static getDataBindItems(t){return"attributes"in t?Array.from(t.attributes).filter(i=>i.name.indexOf("::")==0).map(i=>({propertyToUpdate:i.name.substring(2).replace(/-((html)|\w)/g,e=>e.substring(1).toUpperCase()),bindedVariablesDescriptor:M.getVariablesDescriptor(i.value)})):[]}static getSubPublisher(t,i){if(!i)return t;for(const r of i)if(r!="_self_"){if(!t)return null;t=t[r]}return t}static addPublisherListeners(t){M.removePublisherListeners(t);const i=Z.getAncestorAttributeValue(t.parentNode||t.host||t,"dataProvider");if(!i)return;const r=E.getInstance().get(i),e=M.getDataBindItems(t),o=[];e.forEach(n=>{const l=n.bindedVariablesDescriptor,c=n.propertyToUpdate;for(const h of l.variables){const u=h;let d=r;d=M.getSubPublisher(r,u);const p=t,w={publisher:d,onAssign:()=>{const v=l.variables.map(D=>M.getSubPublisher(r,D)?.get());let m=l.expression,y=!1;if(v.length==1&&l.variables[0].join(".")==m.substring(1)){let D=v[0];D===null&&(D=""),p[c]=D;return}for(let D=0;D<v.length;D++){let f=v[D];const b=l.variables[D];f===null&&(y=!0,f=void 0),m=m.replace("$"+b.join("."),f)}if(m.indexOf("|")!=-1){const D=m.indexOf("|");if(D==0)m=Os.js(m.substring(1));else{const f=m.substring(0,D),b=m.substring(D+1),x=Os[f];m=y?"":x?x(b):m}}else m=y?"":m;p[c]=m}};d?.onAssign(w.onAssign),o.push(w)}}),M.publisherListeners.set(t,o)}},M.observedElements=new Map,M.enabled=!0,M.publisherListeners=new Map,M);Fs.observe(document.documentElement),window.SonicDataBindObserver||(window.SonicDataBindObserver=Fs);/**
1
+ (function(Z){typeof define=="function"&&define.amd?define(Z):Z()})((function(){"use strict";var M,tt;let Z=class Ft{static getLanguage(){const t=document.documentElement.lang;return localStorage.getItem("SonicSelectedLanguage")||t}static getCookies(){return document.cookie.split(";").reduce((t,i)=>{const r=i.indexOf("=");return t[i.substring(0,r).trim()]=i.substring(r+1),t},{})}static everyAncestors(t,i){for(;t;){if(!i(t))return;t=t.parentNode||t.host}}static getScrollableAncestor(t){for(;t;){const i=t;if(i.nodeType===1){const r=window.getComputedStyle(i);if(r?.overflowY==="auto"||r?.overflowY==="scroll"||r?.overflowY==="hidden"||r?.overflowX==="auto"||r?.overflowX==="scroll"||r?.overflowX==="hidden")return t}t=t.parentNode||t.host}return null}static scopeAttributeNames(t){const i=t.toLowerCase();return i===t?[t]:[t,i]}static readScopeAttributeOnElement(t,i){for(const r of Ft.scopeAttributeNames(i))if(t.hasAttribute(r))return t.getAttribute(r)??"";return null}static getAncestorAttributeValue(t,i){if(!t)return null;let r=t;for(;r;){if(r instanceof HTMLElement){const o=Ft.readScopeAttributeOnElement(r,i);if(o!=null)return o}const e=r.parentNode||r.host;if(!e)break;r=e}return null}static getApiConfiguration(t){const i=Ft.getAncestorAttributeValue(t,"token"),r=Ft.getAncestorAttributeValue(t,"addHTTPResponse")!=null,e=Ft.getAncestorAttributeValue(t,"serviceURL");let o=null,n=null;const l=Ft.getAncestorAttributeValue(t,"tokenProvider"),c=Ft.getAncestorAttributeValue(t,"eventsApiToken");i||(o=Ft.getAncestorAttributeValue(t,"userName"),n=Ft.getAncestorAttributeValue(t,"password"));const h=Ft.getAncestorAttributeValue(t,"credentials")||void 0,u=t.getAttribute("cache"),d=t.hasAttribute("blockUntilDone"),p=t.hasAttribute("keepAlive");return{serviceURL:e,token:i,userName:o,password:n,authToken:c,tokenProvider:l,addHTTPResponse:r,credentials:h,cache:u,blockUntilDone:d,keepAlive:p}}static getClosestElement(t,i){for(;!(t.nodeName&&t.nodeName.toLowerCase()===i)&&(t.parentNode||t.host);)t=t.parentNode||t.host;return t.nodeName?t:null}static getClosestForm(t){return Ft.getClosestElement(t,"form")}static getAncestorsByTagNames(t,i){const r=new Set(i.map(n=>n.toLowerCase())),e=[];let o=t.parentNode||t.host;for(;o;)o instanceof Element&&r.has(o.tagName.toLowerCase())&&e.push(o),o=o.parentNode||o.host;return e}static getAncestorsBySelectors(t,i){const r=[];let e=t.parentNode||t.host;for(;e;){if(e instanceof Element)for(const o of i)try{if(e.matches(o)){r.push(e);break}}catch{}e=e.parentNode||e.host}return r}static async loadJS(t){return new Promise(async r=>{const e=document.createElement("script");e.src=t,e.onload=()=>r(!0),e.onerror=()=>r(!0),document.head.appendChild(e)})}static async loadCSS(t){return new Promise(async r=>{const e=document.createElement("link");e.type="text/css",e.rel="stylesheet",e.href=t,e.onload=()=>r(!0),e.onerror=()=>r(!0),document.head.appendChild(e)})}};const bi=s=>{const t=document.documentElement,i=new MutationObserver(e=>{for(let o of e)o.type==="attributes"&&o.attributeName==="lang"&&s()}),r={attributes:!0,attributeFilter:["lang"]};i.observe(t,r)};let Os=class{static ucFirst(t){return typeof t!="string"?t:t.charAt(0).toUpperCase()+t.substring(1)}static minutesDuration(t,i="",r="long"){i||(i=Z.getLanguage());const e=(h,u)=>[Math.floor(h/u),h%u];function o(h,u,d){return new Intl.NumberFormat(h,{style:"unit",unit:u,unitDisplay:d}).format}const[n,l]=e(t,60),c=[];return n&&c.push(o(i,"hour",r)(n)),l&&c.push(o(i,"minute",r)(l)),new Intl.ListFormat(i,{style:"long",type:"conjunction"}).format(c)}static js(t){try{return Function("return "+t)()}catch{return""}}};class _r{constructor(t){this.path=t}toString(){return this.path}}function wr(s){return new Proxy(s,{get(t,i){if(i==="path")return t.path;if(i==="toString")return t.toString.bind(t);if(i===Symbol.toStringTag)return"DataProviderKey";if(typeof i=="symbol")return t[i];const r=t.path?`${t.path}.${String(i)}`:String(i);return wr(new _r(r))}})}const Jo=/\$\{|\{\$/;function tn(s){return Jo.test(s)}function mi(s){const t=typeof s=="string"?s:s.path;if(tn(t))throw new Error("Static publisher path required for get/set/dp. Use @subscribe, @publish, or @handle for dynamic DataProviderKey paths.");return t}const es=function(s){return this instanceof es?wr(new _r(s)):new es(s)};let nt=class oe{static shallowEqual(t,i,r=!0){const e=Object.keys(t),o=Object.keys(i);if(e.length!==o.length&&r)return!1;for(const n of e){const l=t[n],c=i[n];if(r?l!==c:l!=c)return!1}return!0}static deepEqual(t,i,r=!0){const e=Object.keys(t),o=Object.keys(i);if(e.length!==o.length&&r)return!1;for(const n of e){const l=t[n],c=i[n],h=oe.isObject(l)&&oe.isObject(c),u=r?l!==c:l!=c;if(h&&!oe.deepEqual(l,c)||!h&&u)return!1}return!0}static isObject(t){return t!=null&&typeof t=="object"}static isUndefindOrNull(t){return t==null}static isEmpty(t){return oe.isUndefindOrNull(t)?!0:Object.keys(t).length===0}static traverse(t,i,r=!1){for(const e of i){const o=t[e];if(o===void 0)return;r&&oe.isObject(o)?t=Object.assign(Array.isArray(o)?[]:{},t,o):t=t[e]}return t}static traverseDotNotation(t,i,r=!1){return oe.traverse(t,i.split("."),r)}static getURLSearchArray(t,i=""){let r=[];for(let e in t){const o=t[e];i&&(e=i+"["+e+"]"),oe.isObject(o)?r=[...r,...this.getURLSearchArray(o,e)]:r.push(`${e}=${o}`)}return r}static getURLSearchString(t){return oe.getURLSearchArray(t,"").join("&")}};const yt=nt.traverseDotNotation;let en=class{static async queueTaskPromise(){return new Promise(t=>{window.queueMicrotask(()=>t(null))})}static async delayPromise(t){return new Promise(i=>{setTimeout(i,t)})}},xr="sonic";typeof __SONIC_PREFIX__<"u"&&(xr=__SONIC_PREFIX__);let Pr=xr.replace(/-([a-z])/g,s=>s[1].toUpperCase());const Es=Pr.charAt(0).toUpperCase()+Pr.slice(1),sn=new Set(["localStorageMode","expirationDelayMs","invalidateOnPageShow"]);function Cr(s){return s==null||typeof s!="object"||Array.isArray(s)?!1:Object.keys(s).some(t=>sn.has(t))}function Ls(s){return Object.prototype.hasOwnProperty.call(s,"__value")}function ne(s){return typeof s=="object"&&s!==null}let ze="sonic";typeof __SONIC_PREFIX__>"u"&&(ze="sonic");const gi=ze=="sonic"?"publisher-proxies-data":ze+"-publisher-proxies-data",xe=class xe{constructor(t,i,r){for(this._proxies_=new Map,this._is_savable_=!1,this._expiration_delay_=1e3*60*60*12,this._invalidate_on_page_show_=!1,this._invalidateListeners_=new Set,this._formInvalidateListeners_=new Set,this._assignListeners_=new Set,this._mutationListeners_=new Set,this._fillListeners_=new Set,this._templateFillListeners_=new Set,this._lockInternalMutationPublishing_=!1,this._instanceCounter_=0,this._assignmentId_=0,this._value_=t,this.parent=i||null,this._parentKey_=r,this.root=this,this._instanceCounter_=0;this.root.parent;)this.root=this.root.parent}delete(){for(const t in this._proxies_.keys())t!="_parent_"&&this._proxies_.get(t)?.delete();this._invalidateListeners_.clear(),this._formInvalidateListeners_.clear(),this._assignListeners_.clear(),this._mutationListeners_.clear(),this._fillListeners_.clear(),this._templateFillListeners_.clear(),this._proxies_.clear(),xe.instances.delete(this._instanceCounter_)}hasListener(){return this._templateFillListeners_.size>0||this._assignListeners_.size>0||this._invalidateListeners_.size>0||this._formInvalidateListeners_.size>0||this._mutationListeners_.size>0||this._fillListeners_.size>0}_publishInternalMutation_(t=!1){if(this._mutationListeners_.forEach(i=>i()),this._is_savable_&&!E.changed){E.changed=!0,E.saveId++;const i=E.saveId;setTimeout(()=>E.getInstance().saveToLocalStorage(i),1e3)}t||this.parent&&this.parent._publishInternalMutation_()}async _publishAssignement_(t=!1){if(this._assignmentId_++,this._assignmentId_!==this._assignmentId_)return;const r=this.get();this._assignListeners_.forEach(e=>{e(r)}),this._publishInternalMutation_(t)}_publishInvalidation_(){this._invalidateListeners_.forEach(t=>t())}_publishFormInvalidation_(){this._formInvalidateListeners_.forEach(t=>t())}_publishDynamicFilling_(t,i){this._fillListeners_.forEach(r=>{r[t]!==i&&(r[t]=i)}),this._publishTemplateFilling_(t,i)}_publishTemplateFilling_(t,i){this._templateFillListeners_.forEach(r=>{const e=Object.getOwnPropertyDescriptor(r,t);e&&!e.set&&!e.writable||(r.propertyMap&&r.propertyMap[t]&&(t=r.propertyMap[t]),typeof r[t]<"u"&&r[t]!==i&&(r[t]=i))})}onAssign(t,i=!0){typeof t=="function"&&(this._assignListeners_.has(t)||(this._assignListeners_.add(t),i&&t(this.get())))}offAssign(t){this._assignListeners_.delete(t)}onInvalidate(t){typeof t=="function"&&this._invalidateListeners_.add(t)}offInvalidate(t){typeof t=="function"&&this._invalidateListeners_.delete(t)}invalidate(){this._publishInvalidation_()}onFormInvalidate(t){typeof t=="function"&&this._formInvalidateListeners_.add(t)}offFormInvalidate(t){typeof t=="function"&&this._formInvalidateListeners_.delete(t)}invalidateForm(){this._publishFormInvalidation_()}onInternalMutation(t){typeof t=="function"&&(this._mutationListeners_.add(t),t())}offInternalMutation(t){typeof t=="function"&&this._mutationListeners_.delete(t)}startTemplateFilling(t){if(this._templateFillListeners_.add(t),typeof this._value_=="object")for(const i in this._value_){let r=i;const e=this._value_[i];t.propertyMap&&t.propertyMap[i]&&(r=t.propertyMap[i]),typeof t[i]<"u"&&t[i]!==e&&(t[r]=e)}}stopTemplateFilling(t){this._templateFillListeners_.delete(t)}startDynamicFilling(t){this._fillListeners_.add(t);for(const i in this._value_){const r=this._value_[i];t[i]!==r&&(t[i]=r)}}stopDynamicFilling(t){this._fillListeners_.delete(t)}set(t,i=!1){if(this._value_===t||ne(this._value_)&&ne(t)&&t&&Ls(this._value_)&&Ls(t)&&this._value_.__value===t.__value||!ne(t)&&t===this._value_.__value)return!0;this._value_=ne(t)?t:{__value:t},this._cachedGet_=void 0;const r=Ls(this._value_);if(this._parentKey_&&this.parent){const e=Ls(this._value_)?this._value_.__value:this._value_;if(this.parent?.get()==null&&this.parent?.get()==null)if(isNaN(Number(this._parentKey_)))this.parent.set({[this._parentKey_]:e});else{const o=[];o[Number(this._parentKey_)]=e,this.parent.set(o)}else this.parent._value_[this._parentKey_]=e}if(r)return this._proxies_.forEach((e,o)=>{o!="_parent_"&&(e.set(null),this._publishDynamicFilling_(o,null))}),this._publishAssignement_(i),this.parent&&this._parentKey_&&this.parent._publishDynamicFilling_(this._parentKey_,this._value_.__value),!0;for(const e in this._value_)this._value_[e]===void 0&&delete this._value_[e];if(this._proxies_.forEach((e,o)=>{const n=this._value_[o];o!="_parent_"&&n===void 0&&n!==null&&isNaN(Number(o))&&(e.set(null),this._publishDynamicFilling_(o,null))}),this._publishAssignement_(),this.parent&&this._parentKey_&&this.parent._publishDynamicFilling_(this._parentKey_,this._value_),ne(this._value_))for(const e in this._value_){const o=t[e],l=ne(o)?o:{__value:o};if(!this._proxies_.has(e)){this._publishDynamicFilling_(e,o);continue}this._proxies_.get(e)?.set(l,!0),this._publishDynamicFilling_(e,o)}return!0}get(){if(rn(this),this._cachedGet_!==void 0)return this._cachedGet_;if(Object.prototype.hasOwnProperty.call(this._value_,"__value")){const t=this._value_.__value;return this._cachedGet_=t??null}return this._cachedGet_=this._value_!=null?this._value_:null}get $tag(){return this._instanceCounter_||(xe.instancesCounter++,this._instanceCounter_=xe.instancesCounter),xe.instances.set(this._instanceCounter_,this),"<"+ze+'-publisher-proxy publisher="'+this._instanceCounter_+'"></'+ze+"-publisher-proxy>"}};xe.instances=new Map,xe.instancesCounter=0;let ss=xe;const Ts=[];function rn(s){Ts.length>0&&Ts[0].add(s)}function Sr(){Ts.unshift(new Set)}function $r(){return Ts.shift()}const F=class F{constructor(){if(this.enabledLocaStorageProxies=[],this.publishers=new Map,this.localStorageData={},this.isLocalStrorageReady=null,this.initialisedData=[],F.instance!=null)throw"Singleton / use getInstance";F.instance=this,this.isLocalStrorageReady=this.cleanStorageData(),F.initPageShowHandler()}static initPageShowHandler(){F.pageShowHandlerInitialized||(F.pageShowHandlerInitialized=!0,window.addEventListener("pageshow",t=>{t.persisted&&F.getInstance().invalidateAll()}))}invalidateAll(){this.publishers.forEach(t=>{t._invalidate_on_page_show_&&t.invalidate()})}async cleanStorageData(){return new Promise(t=>{(async()=>{try{let r=localStorage.getItem(gi),e=null;if(r&&(e=await this.decompress(r,"gzip")),e)try{this.localStorageData=JSON.parse(e)}catch{this.localStorageData={}}else r=await this.compress("{}","gzip"),localStorage.setItem(gi,r),this.localStorageData={};const o=1e3*60*60*12;for(const n in this.localStorageData){const l=this.localStorageData[n],c=new Date().getTime()-(l.expirationDelayMs||o);l.lastModifiationMS<c&&delete this.localStorageData[n]}t(!0)}catch{window.requestAnimationFrame(()=>{t(!1)}),console.warn("no publisher cache in this browser")}})()})}static getInstance(t){if(t){const i=F.instances.get(t);return i||(console.warn("No PublisherManager instance registered with id:",t,"creating new one"),new F)}return F.instance==null?new F:F.instance}static get(t,i){return F.getInstance().get(t,i)}async setLocalData(t,i){await this.isLocalStrorageReady,t.set(this.localStorageData[i+"¤lang_"+Z.getLanguage()]?.data||t.get())}get(t,i){const r=i?.localStorageMode==="enabled",e=i?.invalidateOnPageShow===!0;if(!this.publishers.has(t)){const l=vi({});this.set(t,l)}const o=this.publishers.get(t);return r&&this.initialisedData.indexOf(t)===-1&&(i?.expirationDelayMs&&(o._expiration_delay_=i.expirationDelayMs),o._is_savable_=!0,this.initialisedData.push(t),this.setLocalData(o,t)),e&&(o._invalidate_on_page_show_=e),this.publishers.get(t)}set(t,i){this.publishers.set(t,i)}delete(t){return this.publishers.has(t)?(this.publishers.delete(t),!0):!1}async saveToLocalStorage(t=0){if(!(t!==F.saveId&&t%10!=0))try{if(!F.changed||F.saving)return;F.saving=!0,F.changed=!1;const i=Array.from(this.publishers.keys());let r=!1;for(const e of i){const o=this.publishers.get(e);if(!o?._is_savable_)continue;const n=o?.get();n&&(this.localStorageData[e+"¤lang_"+Z.getLanguage()]={lastModifiationMS:new Date().getTime(),expirationDelayMs:o._expiration_delay_,data:n},r=!0)}if(r){const e=await this.compress(JSON.stringify(this.localStorageData),"gzip");localStorage.setItem(gi,e)}if(F.saving=!1,F.changed){F.saveId++;const e=F.saveId;setTimeout(()=>this.saveToLocalStorage(e),1e3)}}catch{F.saving=!1}}async compress(t,i){const r=new TextEncoder().encode(t),e=window,o=new e.CompressionStream(i),n=o.writable.getWriter();n.write(r),n.close();const l=await new Response(o.readable).arrayBuffer(),c=new Uint8Array(l);let h="";for(let u=0;u<c.length;u++)h+=String.fromCharCode(c[u]);return btoa(h)}async decompress(t,i){const r=atob(t),o=Uint8Array.from(r,u=>u.charCodeAt(0)).buffer,n=window,l=new n.DecompressionStream(i),c=l.writable.getWriter();c.write(o),c.close();const h=await new Response(l.readable).arrayBuffer();return new TextDecoder().decode(h)}};F.buildDate="Thu Jul 30 2026 10:31:44 GMT+0200 (Central European Summer Time)",F.changed=!1,F.saving=!1,F.saveId=0,F.instance=null,F.instances=new Map,F.pageShowHandlerInitialized=!1;let E=F;if(typeof window<"u"){const s=window;s[Es+"PublisherManager"]=s[Es+"PublisherManager"]||E}const on=new Set(["invalidate","onInvalidate","offInvalidate","invalidateForm","onFormInvalidate","offFormInvalidate","onAssign","offAssign","startDynamicFilling","stopDynamicFilling","startTemplateFilling","stopTemplateFilling","onInternalMutation","offInternalMutation","set","get","$tag","_cachedGet_","_templateFillListeners_","_fillListeners_","_assignListeners_","_invalidateListeners_","_formInvalidateListeners_","_publishInternalMutation_","hasListener","delete","_mutationListeners_","_publishDynamicFilling_","_publishInvalidation_","_publishFormInvalidation_","_publishTemplateFilling_","_publishAssignement_","_proxies_","parent","_parentKey_","_value_","_is_savable_","_expiration_delay_","_lockInternalMutationPublishing_","_instanceCounter_","_assignmentId_","_invalidate_on_page_show_"]);function nn(s,t){return{get:function(i,r){if(typeof r=="string"&&on.has(r))return s[r];if(r==Symbol.toPrimitive)return()=>t().get();if(!s._proxies_.has(r)){const e=s._value_[r],o=vi(ne(e)?e:{__value:e},s,r);o._proxies_.set("_parent_",t()),s._proxies_.set(r,o)}return s._proxies_.get(r)},set:function(i,r,e){if(r=="_value_")return s._value_=e,!0;if(r=="_cachedGet_")return s._cachedGet_=e,!0;if(r=="_assignmentId_")return s._assignmentId_=e,!0;if(r=="_is_savable_")return s._is_savable_=e,!0;if(r=="_expiration_delay_")return s._expiration_delay_=e,!0;if(r=="_invalidate_on_page_show_")return s._invalidate_on_page_show_=e,!0;if(r=="_instanceCounter_")return s._instanceCounter_=e,!0;if(!s._proxies_.has(r)){const n=vi({},s,r);n._proxies_.set("_parent_",t()),s._proxies_.set(r,n)}return s._value_[r]!==e&&(s._value_[r]=e,s._publishDynamicFilling_(r,e),s._proxies_.get(r)?.set(ne(e)?e:{__value:e})),!0},deleteProperty:function(i,r){return s._publishDynamicFilling_(r,null),s._proxies_.get(r)?.set(null),delete s._value_[r]},has:function(i,r){return r in s._value_&&r!="_lockInternalMutationPublishing_"},defineProperty:function(i,r,e){return e&&"value"in e&&(s._value_[r]=e.value),!0},getOwnPropertyDescriptor:function(i,r){return{enumerable:!0,configurable:!0}},ownKeys:function(i){return s._value_.__value?Object.keys(s._value_.__value):Object.keys(s._value_)}}}function vi(s,t=null,i){const r=new ss(s,t,i);let e=null;const o=nn(r,()=>e);return e=new Proxy(r,o),e}class an extends HTMLElement{constructor(){super(),this.publisherId="",this.onAssign=t=>{this.innerHTML=t.toString()}}connectedCallback(){this.publisherId=this.getAttribute("publisher")||"",this.publisher=ss.instances.get(parseInt(this.publisherId)),this.publisher?.onAssign(this.onAssign)}disconnectedCallback(){this.publisher?.offAssign(this.onAssign)}}try{customElements.define(ze+"-publisher-proxy",an)}catch{}const Is=(s,t)=>{if(typeof s=="function"){const i=s;return Sr(),i(),$r()}if(typeof s=="string"){const i=s.split("."),r=i.shift()||"";let e=E.get(r,t);e=nt.traverse(e,i);const o=new Set;return o.add(e),o}return new Set([s])};function ln(s){const t=mi(s);return Is(t).values().next().value?.get()}function Ms(s,t,i){const r=mi(s);return Is(r,i).values().next().value}function cn(s,t){return Cr(t)?Ms(s,void 0,t):Ms(s)}function Ns(s,t){return Cr(t)?Ms(s,void 0,t):Ms(s)}function hn(s,t){const i=mi(s);Is(i).values().next().value?.set(t)}let Fs=(M=class{static disable(){this.enabled&&(this.enabled=!1,Array.from(M.observedElements.keys()).forEach(t=>M.unObserve(t)))}static observe(t){if(!t||!M.enabled||M.observedElements.has(t))return;const i=new MutationObserver(M.onMutation),r={};r.childList=!0,r.subtree=!0,r.attributes=!0,r.attributeFilter=["data-bind"],i.observe(t,r),t.querySelectorAll("[data-bind]").forEach(e=>M.addPublisherListeners(e)),M.observedElements.set(t,i)}static unObserve(t){if(!t)return;const i=this.observedElements.get(t);i&&(i.disconnect(),t.querySelectorAll("[data-bind]").forEach(r=>M.removePublisherListeners(r)))}static onAdded(t){t.hasAttribute&&t.hasAttribute("data-bind")&&M.addPublisherListeners(t),t.querySelectorAll?t.querySelectorAll("[data-bind]").forEach(i=>M.addPublisherListeners(i)):t.childNodes.forEach(i=>M.onAdded(i))}static onRemoved(t){t.hasAttribute&&t.hasAttribute("data-bind")&&M.removePublisherListeners(t),t.querySelectorAll?t.querySelectorAll("[data-bind]").forEach(i=>M.removePublisherListeners(i)):t.childNodes.forEach(i=>M.onRemoved(i))}static onMutation(t){for(const i of t)switch(i.type){case"attributes":M.addPublisherListeners(i.target);break;case"childList":i.addedNodes.forEach(r=>{M.onAdded(r)}),i.removedNodes.forEach(r=>{M.onRemoved(r)});break}}static removePublisherListeners(t){const i=M.publisherListeners.get(t);i&&(M.publisherListeners.delete(t),i.forEach(r=>{r.publisher?.offAssign(r.onAssign)}))}static getVariablesDescriptor(t){let i=t.match(/(\$(?:\w+\\?\.?)+)/g);return i?i=i.map(r=>r.replace("$","")):i=[t],i=i.filter(r=>r.length>0),{expression:t.replace("\\",""),variables:i.map(r=>r.split(/\b\.\b/).map(e=>e.replace("\\","")))}}static getDataBindItems(t){return"attributes"in t?Array.from(t.attributes).filter(i=>i.name.indexOf("::")==0).map(i=>({propertyToUpdate:i.name.substring(2).replace(/-((html)|\w)/g,e=>e.substring(1).toUpperCase()),bindedVariablesDescriptor:M.getVariablesDescriptor(i.value)})):[]}static getSubPublisher(t,i){if(!i)return t;for(const r of i)if(r!="_self_"){if(!t)return null;t=t[r]}return t}static addPublisherListeners(t){M.removePublisherListeners(t);const i=Z.getAncestorAttributeValue(t.parentNode||t.host||t,"dataProvider");if(!i)return;const r=E.getInstance().get(i),e=M.getDataBindItems(t),o=[];e.forEach(n=>{const l=n.bindedVariablesDescriptor,c=n.propertyToUpdate;for(const h of l.variables){const u=h;let d=r;d=M.getSubPublisher(r,u);const p=t,w={publisher:d,onAssign:()=>{const v=l.variables.map(D=>M.getSubPublisher(r,D)?.get());let m=l.expression,y=!1;if(v.length==1&&l.variables[0].join(".")==m.substring(1)){let D=v[0];D===null&&(D=""),p[c]=D;return}for(let D=0;D<v.length;D++){let f=v[D];const b=l.variables[D];f===null&&(y=!0,f=void 0),m=m.replace("$"+b.join("."),f)}if(m.indexOf("|")!=-1){const D=m.indexOf("|");if(D==0)m=Os.js(m.substring(1));else{const f=m.substring(0,D),b=m.substring(D+1),x=Os[f];m=y?"":x?x(b):m}}else m=y?"":m;p[c]=m}};d?.onAssign(w.onAssign),o.push(w)}}),M.publisherListeners.set(t,o)}},M.observedElements=new Map,M.enabled=!0,M.publisherListeners=new Map,M);Fs.observe(document.documentElement),window.SonicDataBindObserver||(window.SonicDataBindObserver=Fs);/**
2
2
  * @license
3
3
  * Copyright 2017 Google LLC
4
4
  * SPDX-License-Identifier: BSD-3-Clause
@@ -742,7 +742,7 @@ const j = class j {
742
742
  return new TextDecoder().decode(h);
743
743
  }
744
744
  };
745
- j.buildDate = "Thu Jul 09 2026 13:42:07 GMT+0200 (Central European Summer Time)", j.changed = !1, j.saving = !1, j.saveId = 0, j.instance = null, j.instances = /* @__PURE__ */ new Map(), j.pageShowHandlerInitialized = !1;
745
+ j.buildDate = "Thu Jul 30 2026 10:31:44 GMT+0200 (Central European Summer Time)", j.changed = !1, j.saving = !1, j.saveId = 0, j.instance = null, j.instances = /* @__PURE__ */ new Map(), j.pageShowHandlerInitialized = !1;
746
746
  let E = j;
747
747
  if (typeof window < "u") {
748
748
  const s = window;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supersoniks/concorde",
3
- "version": "4.9.3",
3
+ "version": "4.9.4",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "",
@@ -1,26 +1,47 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Installe les fichiers agent IA Concorde dans un projet.
3
+ * Install Concorde AI agent files into a project.
4
4
  *
5
5
  * Usage:
6
6
  * node node_modules/@supersoniks/concorde/scripts/ai-init.mjs [options]
7
- * yarn concorde ai-init
7
+ * yarn ai-init
8
8
  *
9
9
  * Options:
10
- * --project-root <dir> Racine du projet (défaut: cwd)
11
- * --concorde-ai <dir> Dossier ai/ Concorde (défaut: auto-detect)
12
- * --overlay <dir> Couche additionnelle (ex. starter kit)
13
- * --cursor-only N'installe que Cursor (.cursor/)
14
- * --jetbrains-only N'installe que JetBrains (.aiassistant/rules/)
15
- * --merge-agents Fusionne AGENTS.md au lieu d'écraser si existant
10
+ * --project-root <dir> Project root (default: cwd)
11
+ * --concorde-ai <dir> Concorde ai/ folder (default: auto-detect)
12
+ * --overlay <dir> Extra layer (e.g. starter kit) — uses AGENTS.starter.md
13
+ * --cursor-only Install only Cursor (.cursor/)
14
+ * --jetbrains-only Install only JetBrains (.aiassistant/rules/)
15
+ * --skip-agents Never write AGENTS.md (skills/rules only)
16
+ * --merge-agents Opt-in: keep project preamble, append/refresh Concorde block
17
+ * --force-agents Opt-in: replace AGENTS.md entirely (destructive)
18
+ *
19
+ * AGENTS.md policy (non-invasive by default):
20
+ * - Missing file → create Concorde guide
21
+ * - Existing with <!-- concorde-ai --> → refresh managed zone only
22
+ * - Existing without marker → leave untouched (project-owned, e.g. billetterie)
23
+ * unless --merge-agents or --force-agents
24
+ *
25
+ * Layout when writing:
26
+ *
27
+ * [optional project preamble — short, project-only]
28
+ * <!-- concorde-ai -->
29
+ * <package ai/AGENTS.md>
30
+ * [--- + overlay AGENTS.starter.md]
31
+ *
32
+ * Everything AFTER the marker is owned by Concorde and replaced on every run.
33
+ * Do not copy the full Concorde guide into the preamble — use overlay/AGENTS.starter.md
34
+ * for project-specific agent notes (endpoints, dpKeys, …).
16
35
  */
17
36
 
18
37
  import fs from "node:fs";
19
38
  import path from "node:path";
20
- import {fileURLToPath} from "node:url";
39
+ import {fileURLToPath, pathToFileURL} from "node:url";
21
40
 
22
41
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
23
42
 
43
+ const AGENTS_MARKER = "<!-- concorde-ai -->";
44
+
24
45
  const args = process.argv.slice(2);
25
46
 
26
47
  function readArg(name) {
@@ -38,10 +59,34 @@ const overlayDir = readArg("--overlay")
38
59
 
39
60
  const cursorOnly = flags.has("--cursor-only");
40
61
  const jetbrainsOnly = flags.has("--jetbrains-only");
62
+ const skipAgents = flags.has("--skip-agents");
41
63
  const mergeAgents = flags.has("--merge-agents");
64
+ const forceAgents = flags.has("--force-agents");
42
65
  const installCursor = !jetbrainsOnly;
43
66
  const installJetbrains = !cursorOnly;
44
67
 
68
+ /**
69
+ * Decide whether / how to write AGENTS.md.
70
+ * @returns {"skip" | "create" | "refresh" | "merge" | "force"}
71
+ */
72
+ export function decideAgentsAction({
73
+ existingText = "",
74
+ skipAgents: skip = false,
75
+ mergeAgents: merge = false,
76
+ forceAgents: force = false,
77
+ } = {}) {
78
+ if (skip) return "skip";
79
+ const text = existingText.replace(/\r\n/g, "\n");
80
+ const exists = text.trim().length > 0;
81
+ const hasMarker = text.includes(AGENTS_MARKER);
82
+
83
+ if (!exists) return "create";
84
+ if (hasMarker) return "refresh";
85
+ if (force) return "force";
86
+ if (merge) return "merge";
87
+ return "skip";
88
+ }
89
+
45
90
  function detectConcordeAi() {
46
91
  const explicit = readArg("--concorde-ai");
47
92
  if (explicit) return path.resolve(explicit);
@@ -72,96 +117,337 @@ function copyDir(src, dest) {
72
117
  }
73
118
  }
74
119
 
75
- function mergeAgentsFile(targetPath, baseContent, overlayContent) {
76
- const marker = "<!-- concorde-ai -->";
77
- let existing = "";
78
- if (fs.existsSync(targetPath)) {
79
- existing = fs.readFileSync(targetPath, "utf8");
120
+ function normalizeHeading(title) {
121
+ return title
122
+ .normalize("NFKD")
123
+ .replace(/\p{M}/gu, "")
124
+ .toLowerCase()
125
+ .replace(/[^a-z0-9]+/g, " ")
126
+ .trim();
127
+ }
128
+
129
+ function isStockConcordeH1(title) {
130
+ // "# Agents — Concorde" with optional project suffix in parentheses
131
+ return /^agents\s+concorde(\s|$)/i.test(normalizeHeading(title));
132
+ }
133
+
134
+ /**
135
+ * Split markdown into a leading H1 block + ## sections (## title → body).
136
+ * @returns {{ h1: string | null, sections: Array<{ title: string, body: string }> }}
137
+ */
138
+ function splitAgentsSections(markdown) {
139
+ const text = markdown.replace(/\r\n/g, "\n").trim();
140
+ if (!text) return {h1: null, sections: []};
141
+
142
+ const parts = text.split(/\n(?=##\s+)/);
143
+ let h1 = null;
144
+ const sections = [];
145
+
146
+ for (const part of parts) {
147
+ const trimmed = part.trim();
148
+ if (!trimmed) continue;
149
+ if (trimmed.startsWith("## ")) {
150
+ const nl = trimmed.indexOf("\n");
151
+ const titleLine = nl === -1 ? trimmed : trimmed.slice(0, nl);
152
+ const title = titleLine.replace(/^##\s+/, "").trim();
153
+ const body = nl === -1 ? "" : trimmed.slice(nl + 1).trim();
154
+ sections.push({title, body});
155
+ } else if (h1 === null) {
156
+ h1 = trimmed;
157
+ } else {
158
+ // Orphan content without ## — keep as synthetic section
159
+ sections.push({title: "", body: trimmed});
160
+ }
161
+ }
162
+
163
+ return {h1, sections};
164
+ }
165
+
166
+ function baseHeadingSet(baseContent) {
167
+ const {sections} = splitAgentsSections(baseContent);
168
+ return new Set(sections.map((s) => normalizeHeading(s.title)).filter(Boolean));
169
+ }
170
+
171
+ /** Match "## Skills / rules" with "## Skills / rules (après installation)". */
172
+ function isSameAgentsHeading(a, b) {
173
+ if (!a || !b) return false;
174
+ if (a === b) return true;
175
+ const stripParen = (s) => s.replace(/\s*\(.*\)$/, "").trim();
176
+ const aa = stripParen(a);
177
+ const bb = stripParen(b);
178
+ if (aa === bb) return true;
179
+ return aa.startsWith(bb) || bb.startsWith(aa);
180
+ }
181
+
182
+ function isPackageHeading(titleKey, baseHeads) {
183
+ for (const bh of baseHeads) {
184
+ if (isSameAgentsHeading(titleKey, bh)) return true;
185
+ }
186
+ return false;
187
+ }
188
+
189
+ /**
190
+ * True when preamble looks like a full (or near-full) copy of package AGENTS.md.
191
+ */
192
+ export function preambleDuplicatesBase(preamble, baseContent) {
193
+ const p = preamble.trim();
194
+ const b = baseContent.trim();
195
+ if (!p || !b) return false;
196
+
197
+ const fingerprints = [
198
+ "sonic-fetch",
199
+ "publishermanager",
200
+ "formdataprovider",
201
+ "dataprovide",
202
+ "concorde-get-set-dp",
203
+ ];
204
+ const pNorm = p.toLowerCase();
205
+ const hits = fingerprints.filter((fp) => pNorm.includes(fp)).length;
206
+ const longEnough = p.length >= b.length * 0.45;
207
+ const stockTitle = /^#\s*agents\s*[—–-]\s*concorde\b/im.test(p);
208
+
209
+ return stockTitle && longEnough && hits >= 3;
210
+ }
211
+
212
+ /**
213
+ * Keep only project-specific preamble bits (unique ## vs package, short custom H1).
214
+ * Drops sections that duplicate Concorde ai/AGENTS.md so re-runs heal stacked copies.
215
+ */
216
+ export function slimPreamble(preamble, baseContent) {
217
+ const raw = preamble.trim();
218
+ if (!raw) return "";
219
+
220
+ const {h1, sections} = splitAgentsSections(raw);
221
+ const h1Title = h1?.split("\n")[0]?.replace(/^#\s+/, "").trim() ?? "";
222
+ // Full forks OR any preamble titled like Concorde AGENTS → strip package ## sections
223
+ const shouldDedup =
224
+ preambleDuplicatesBase(raw, baseContent) || isStockConcordeH1(h1Title);
225
+
226
+ if (!shouldDedup) {
227
+ return raw;
228
+ }
229
+
230
+ const baseHeads = baseHeadingSet(baseContent);
231
+ const kept = [];
232
+
233
+ for (const section of sections) {
234
+ const key = normalizeHeading(section.title);
235
+ if (!key) {
236
+ if (!preambleDuplicatesBase(section.body, baseContent)) {
237
+ kept.push(section.body);
238
+ }
239
+ continue;
240
+ }
241
+ if (!isPackageHeading(key, baseHeads)) {
242
+ kept.push(`## ${section.title}\n\n${section.body}`.trim());
243
+ }
244
+ }
245
+
246
+ let intro = "";
247
+ if (h1) {
248
+ const firstLine = h1.split("\n")[0].trim();
249
+ const title = firstLine.replace(/^#\s+/, "");
250
+ if (isStockConcordeH1(title) && /[()]/.test(title)) {
251
+ intro = firstLine;
252
+ } else if (!isStockConcordeH1(title)) {
253
+ intro = firstLine;
254
+ }
80
255
  }
81
256
 
257
+ return [intro, ...kept].filter(Boolean).join("\n\n").trim();
258
+ }
259
+
260
+ export function buildManagedAgents(baseContent, overlayContent) {
82
261
  const parts = [baseContent.trim()];
83
262
  if (overlayContent?.trim()) {
84
263
  parts.push(overlayContent.trim());
85
264
  }
265
+ return parts.join("\n\n---\n\n");
266
+ }
86
267
 
87
- const combined = parts.join("\n\n---\n\n");
268
+ /**
269
+ * Build final AGENTS.md. Never stacks managed (post-marker) content.
270
+ * @returns {{ markdown: string, warnings: string[] }}
271
+ */
272
+ export function buildAgentsFile({
273
+ existing = "",
274
+ baseContent,
275
+ overlayContent = "",
276
+ mergeAgents: merge = false,
277
+ forceAgents: force = false,
278
+ }) {
279
+ const warnings = [];
280
+ const combined = buildManagedAgents(baseContent, overlayContent);
88
281
 
89
- if (!existing) {
90
- fs.mkdirSync(path.dirname(targetPath), {recursive: true});
91
- fs.writeFileSync(targetPath, combined + "\n");
92
- return;
282
+ // Destructive replace: ignore any existing project content
283
+ if (force && !existing.replace(/\r\n/g, "\n").includes(AGENTS_MARKER)) {
284
+ return {markdown: `${combined}\n`, warnings};
93
285
  }
94
286
 
95
- if (existing.includes(marker)) {
96
- const before = existing.split(marker)[0].trimEnd();
97
- fs.writeFileSync(targetPath, `${before}\n\n${marker}\n\n${combined}\n`);
98
- return;
287
+ let preamble = "";
288
+ const existingText = existing.replace(/\r\n/g, "\n");
289
+
290
+ if (existingText.includes(AGENTS_MARKER)) {
291
+ preamble = existingText.split(AGENTS_MARKER)[0].trimEnd();
292
+ } else if (merge && existingText.trim()) {
293
+ preamble = existingText.trimEnd();
99
294
  }
100
295
 
101
- if (mergeAgents) {
102
- fs.writeFileSync(
103
- targetPath,
104
- `${existing.trimEnd()}\n\n---\n\n${marker}\n\n${combined}\n`,
105
- );
106
- return;
296
+ const hadMarker = existingText.includes(AGENTS_MARKER);
297
+
298
+ if (preamble) {
299
+ const before = preamble;
300
+ preamble = slimPreamble(preamble, baseContent);
301
+ if (before.trim() && !preamble) {
302
+ warnings.push(
303
+ "AGENTS.md preamble duplicated Concorde ai/AGENTS.md — dropped. Put project-only notes in overlay AGENTS.starter.md (or a short preamble before <!-- concorde-ai -->).",
304
+ );
305
+ } else if (before.trim() && preamble !== before.trim()) {
306
+ warnings.push(
307
+ "AGENTS.md preamble slimmed: removed sections that duplicate package AGENTS.md.",
308
+ );
309
+ }
107
310
  }
108
311
 
109
- fs.writeFileSync(targetPath, combined + "\n");
312
+ // Always emit the marker when refreshing a marked file or merging a preamble,
313
+ // so re-runs stay idempotent even if the preamble was fully dropped.
314
+ const emitMarker = hadMarker || Boolean(preamble) || merge;
315
+ const markdown = emitMarker
316
+ ? preamble
317
+ ? `${preamble.trimEnd()}\n\n${AGENTS_MARKER}\n\n${combined}\n`
318
+ : `${AGENTS_MARKER}\n\n${combined}\n`
319
+ : `${combined}\n`;
320
+
321
+ return {markdown, warnings};
110
322
  }
111
323
 
112
- const concordeAi = detectConcordeAi();
324
+ export function mergeAgentsFile(targetPath, baseContent, overlayContent, options = {}) {
325
+ const merge = options.mergeAgents ?? false;
326
+ const force = options.forceAgents ?? false;
327
+ let existing = "";
328
+ if (fs.existsSync(targetPath)) {
329
+ existing = fs.readFileSync(targetPath, "utf8");
330
+ }
113
331
 
114
- console.log(`Concorde ai-init → ${projectRoot}`);
115
- console.log(` source: ${concordeAi}`);
116
- if (overlayDir) console.log(` overlay: ${overlayDir}`);
332
+ const {markdown, warnings} = buildAgentsFile({
333
+ existing,
334
+ baseContent,
335
+ overlayContent,
336
+ mergeAgents: merge,
337
+ forceAgents: force,
338
+ });
117
339
 
118
- if (installCursor) {
119
- copyDir(
120
- path.join(concordeAi, "cursor", "rules"),
121
- path.join(projectRoot, ".cursor", "rules"),
122
- );
123
- copyDir(
124
- path.join(concordeAi, "skills"),
125
- path.join(projectRoot, ".cursor", "skills"),
126
- );
340
+ fs.mkdirSync(path.dirname(targetPath), {recursive: true});
341
+ fs.writeFileSync(targetPath, markdown);
342
+ return warnings;
343
+ }
344
+
345
+ function main() {
346
+ const concordeAi = detectConcordeAi();
347
+
348
+ console.log(`Concorde ai-init → ${projectRoot}`);
349
+ console.log(` source: ${concordeAi}`);
350
+ if (overlayDir) console.log(` overlay: ${overlayDir}`);
127
351
 
128
- if (overlayDir) {
352
+ if (installCursor) {
129
353
  copyDir(
130
- path.join(overlayDir, "cursor", "rules"),
354
+ path.join(concordeAi, "cursor", "rules"),
131
355
  path.join(projectRoot, ".cursor", "rules"),
132
356
  );
133
357
  copyDir(
134
- path.join(overlayDir, "skills"),
358
+ path.join(concordeAi, "skills"),
135
359
  path.join(projectRoot, ".cursor", "skills"),
136
360
  );
137
- }
138
- }
139
361
 
140
- if (installJetbrains) {
141
- copyDir(
142
- path.join(concordeAi, "jetbrains", "rules"),
143
- path.join(projectRoot, ".aiassistant", "rules"),
144
- );
362
+ if (overlayDir) {
363
+ copyDir(
364
+ path.join(overlayDir, "cursor", "rules"),
365
+ path.join(projectRoot, ".cursor", "rules"),
366
+ );
367
+ copyDir(
368
+ path.join(overlayDir, "skills"),
369
+ path.join(projectRoot, ".cursor", "skills"),
370
+ );
371
+ }
372
+ }
145
373
 
146
- if (overlayDir) {
374
+ if (installJetbrains) {
147
375
  copyDir(
148
- path.join(overlayDir, "jetbrains", "rules"),
376
+ path.join(concordeAi, "jetbrains", "rules"),
149
377
  path.join(projectRoot, ".aiassistant", "rules"),
150
378
  );
379
+
380
+ if (overlayDir) {
381
+ copyDir(
382
+ path.join(overlayDir, "jetbrains", "rules"),
383
+ path.join(projectRoot, ".aiassistant", "rules"),
384
+ );
385
+ }
151
386
  }
152
- }
153
387
 
154
- const baseAgents = fs.readFileSync(path.join(concordeAi, "AGENTS.md"), "utf8");
155
- let overlayAgents = "";
156
- if (overlayDir) {
157
- const overlayPath = path.join(overlayDir, "AGENTS.starter.md");
158
- if (fs.existsSync(overlayPath)) {
159
- overlayAgents = fs.readFileSync(overlayPath, "utf8");
388
+ const agentsPath = path.join(projectRoot, "AGENTS.md");
389
+ let existingAgents = "";
390
+ if (fs.existsSync(agentsPath)) {
391
+ existingAgents = fs.readFileSync(agentsPath, "utf8");
160
392
  }
393
+
394
+ const action = decideAgentsAction({
395
+ existingText: existingAgents,
396
+ skipAgents,
397
+ mergeAgents,
398
+ forceAgents,
399
+ });
400
+
401
+ if (action === "skip") {
402
+ if (skipAgents) {
403
+ console.log(" ⊘ AGENTS.md skipped (--skip-agents)");
404
+ } else if (existingAgents.trim()) {
405
+ console.log(
406
+ " ⊘ AGENTS.md left untouched (project-owned, no <!-- concorde-ai --> marker).",
407
+ );
408
+ console.log(
409
+ " Use --merge-agents to append a Concorde block, or --force-agents to replace.",
410
+ );
411
+ } else {
412
+ console.log(" ⊘ AGENTS.md skipped");
413
+ }
414
+ } else {
415
+ const baseAgents = fs.readFileSync(path.join(concordeAi, "AGENTS.md"), "utf8");
416
+ let overlayAgents = "";
417
+ if (overlayDir) {
418
+ const overlayPath = path.join(overlayDir, "AGENTS.starter.md");
419
+ if (fs.existsSync(overlayPath)) {
420
+ overlayAgents = fs.readFileSync(overlayPath, "utf8");
421
+ }
422
+ }
423
+
424
+ const warnings = mergeAgentsFile(agentsPath, baseAgents, overlayAgents, {
425
+ mergeAgents: action === "merge" || action === "refresh",
426
+ forceAgents: action === "force",
427
+ });
428
+ for (const w of warnings) {
429
+ console.warn(` ⚠ ${w}`);
430
+ }
431
+ const label =
432
+ action === "create"
433
+ ? "created"
434
+ : action === "merge"
435
+ ? "merged"
436
+ : action === "force"
437
+ ? "replaced (--force-agents)"
438
+ : "refreshed";
439
+ console.log(` ✓ AGENTS.md (${label})`);
440
+ }
441
+
442
+ if (installCursor) console.log(" ✓ .cursor/skills + .cursor/rules");
443
+ if (installJetbrains) console.log(" ✓ .aiassistant/rules");
444
+ console.log("Done.");
161
445
  }
162
- mergeAgentsFile(path.join(projectRoot, "AGENTS.md"), baseAgents, overlayAgents);
163
446
 
164
- console.log(" ✓ AGENTS.md");
165
- if (installCursor) console.log(" ✓ .cursor/skills + .cursor/rules");
166
- if (installJetbrains) console.log(" ✓ .aiassistant/rules");
167
- console.log("Done.");
447
+ const isDirectRun =
448
+ process.argv[1] &&
449
+ import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href;
450
+
451
+ if (isDirectRun) {
452
+ main();
453
+ }
@@ -0,0 +1,206 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+ import {
4
+ buildAgentsFile,
5
+ decideAgentsAction,
6
+ preambleDuplicatesBase,
7
+ slimPreamble,
8
+ } from "./ai-init.mjs";
9
+
10
+ const base = `# Agents — Concorde
11
+
12
+ Guide for Concorde.
13
+
14
+ ## Skills / rules
15
+
16
+ | File | Role |
17
+ |------|------|
18
+ | \`.cursor/skills/concorde/SKILL.md\` | Patterns |
19
+
20
+ ## Conventions impératives
21
+
22
+ - Always **DataProvider**
23
+ - No **sonic-fetch**, no **PublisherManager**
24
+ - Forms: **formDataProvider**
25
+ - Skill **concorde-get-set-dp**
26
+ `;
27
+
28
+ const overlay = `## Conventions (project)
29
+
30
+ - HTTP routes: \`endpoints.*\`
31
+ `;
32
+
33
+ test("decideAgentsAction: missing file → create", () => {
34
+ assert.equal(decideAgentsAction({existingText: ""}), "create");
35
+ });
36
+
37
+ test("decideAgentsAction: project-owned AGENTS.md → skip by default", () => {
38
+ assert.equal(
39
+ decideAgentsAction({existingText: "# Billetterie\n\nProject notes.\n"}),
40
+ "skip",
41
+ );
42
+ });
43
+
44
+ test("decideAgentsAction: --skip-agents always skips", () => {
45
+ assert.equal(
46
+ decideAgentsAction({existingText: "", skipAgents: true}),
47
+ "skip",
48
+ );
49
+ });
50
+
51
+ test("decideAgentsAction: --merge-agents on project-owned → merge", () => {
52
+ assert.equal(
53
+ decideAgentsAction({
54
+ existingText: "# Billetterie\n\nNotes.\n",
55
+ mergeAgents: true,
56
+ }),
57
+ "merge",
58
+ );
59
+ });
60
+
61
+ test("decideAgentsAction: --force-agents on project-owned → force", () => {
62
+ assert.equal(
63
+ decideAgentsAction({
64
+ existingText: "# Billetterie\n\nNotes.\n",
65
+ forceAgents: true,
66
+ }),
67
+ "force",
68
+ );
69
+ });
70
+
71
+ test("decideAgentsAction: marked file → refresh", () => {
72
+ assert.equal(
73
+ decideAgentsAction({
74
+ existingText: "# App\n\n<!-- concorde-ai -->\n\nold\n",
75
+ }),
76
+ "refresh",
77
+ );
78
+ });
79
+
80
+ test("forceAgents replaces project-owned content", () => {
81
+ const {markdown} = buildAgentsFile({
82
+ existing: "# Old project notes\n\nkeep me",
83
+ baseContent: base,
84
+ overlayContent: "",
85
+ forceAgents: true,
86
+ });
87
+ assert.equal(markdown.includes("keep me"), false);
88
+ assert.equal(markdown.includes("<!-- concorde-ai -->"), false);
89
+ assert.match(markdown, /^# Agents — Concorde/m);
90
+ });
91
+
92
+ test("without force/merge, buildAgentsFile still builds content (caller decides skip)", () => {
93
+ const {markdown} = buildAgentsFile({
94
+ existing: "",
95
+ baseContent: base,
96
+ overlayContent: "",
97
+ });
98
+ assert.match(markdown, /^# Agents — Concorde/m);
99
+ });
100
+
101
+ test("merge without marker keeps short unique preamble", () => {
102
+ const {markdown, warnings} = buildAgentsFile({
103
+ existing: "# My app\n\nOnly project notes here.\n",
104
+ baseContent: base,
105
+ overlayContent: "",
106
+ mergeAgents: true,
107
+ });
108
+ assert.match(markdown, /# My app/);
109
+ assert.match(markdown, /<!-- concorde-ai -->/);
110
+ assert.match(markdown, /# Agents — Concorde/);
111
+ assert.equal(warnings.length, 0);
112
+ });
113
+
114
+ test("re-run with marker replaces managed zone only (idempotent)", () => {
115
+ const first = buildAgentsFile({
116
+ existing: "# My app\n\nNote.\n",
117
+ baseContent: base,
118
+ overlayContent: "v1 overlay",
119
+ mergeAgents: true,
120
+ }).markdown;
121
+
122
+ const second = buildAgentsFile({
123
+ existing: first.replace("v1 overlay", "STALE"),
124
+ baseContent: base,
125
+ overlayContent: "v2 overlay",
126
+ mergeAgents: true,
127
+ }).markdown;
128
+
129
+ assert.equal(second.includes("STALE"), false);
130
+ assert.match(second, /v2 overlay/);
131
+ assert.equal(second.split("<!-- concorde-ai -->").length, 2);
132
+ });
133
+
134
+ test("duplicate Concorde preamble is dropped", () => {
135
+ const fork = `${base}\n\nExtra copy of the same guide.\n`;
136
+ assert.equal(preambleDuplicatesBase(fork, base), true);
137
+
138
+ const {markdown, warnings} = buildAgentsFile({
139
+ existing: `${fork}\n\n<!-- concorde-ai -->\n\nold managed\n`,
140
+ baseContent: base,
141
+ overlayContent: overlay,
142
+ mergeAgents: true,
143
+ });
144
+
145
+ assert.equal(markdown.split("<!-- concorde-ai -->").length, 2);
146
+ assert.equal(
147
+ markdown.indexOf("# Agents — Concorde"),
148
+ markdown.lastIndexOf("# Agents — Concorde"),
149
+ );
150
+ assert.match(markdown, /Conventions \(project\)/);
151
+ assert.ok(warnings.some((w) => /duplicated|slimmed/i.test(w)));
152
+ });
153
+
154
+ test("slimPreamble keeps unique ## sections", () => {
155
+ const preamble = `# Agents — Concorde (my-app)
156
+
157
+ Guide.
158
+
159
+ ## Skills / rules
160
+
161
+ dup
162
+
163
+ ## Project only
164
+
165
+ - use endpoints.ts
166
+ `;
167
+ const slim = slimPreamble(preamble, base);
168
+ assert.match(slim, /Project only/);
169
+ assert.equal(slim.includes("## Skills / rules"), false);
170
+ assert.match(slim, /Concorde \(my-app\)/);
171
+ });
172
+
173
+ test("slimPreamble drops Skills even when package title has suffix", () => {
174
+ const packageBase = `# Agents — Concorde
175
+
176
+ ## Skills / rules (après installation)
177
+
178
+ table
179
+
180
+ ## Conventions impératives
181
+
182
+ - sonic-fetch
183
+ - PublisherManager
184
+ - formDataProvider
185
+ - concorde-get-set-dp
186
+ `;
187
+ const preamble = `# Agents — Concorde (app)
188
+
189
+ ## Skills / rules
190
+
191
+ dup table
192
+
193
+ ## Installation / réinstallation
194
+
195
+ custom install cmd
196
+
197
+ ## Project endpoints
198
+
199
+ - endpoints.ts
200
+ `;
201
+ const slim = slimPreamble(preamble, packageBase);
202
+ assert.equal(slim.includes("## Skills / rules"), false);
203
+ assert.match(slim, /Project endpoints/);
204
+ // Installation may stay if not in package — package has no Installation ##
205
+ assert.match(slim, /Installation \/ réinstallation|Project endpoints/);
206
+ });
@@ -26,16 +26,36 @@ node node_modules/@supersoniks/concorde/scripts/ai-init.mjs
26
26
 
27
27
  | Flag | Effect |
28
28
  |------|--------|
29
- | `--merge-agents` | Append to an existing `AGENTS.md` instead of replacing it |
30
- | `--overlay <dir>` | Copy extra rules/skills from another layer (e.g. starter kit) |
29
+ | `--skip-agents` | Never write `AGENTS.md` (skills / rules only) |
30
+ | `--merge-agents` | Opt-in: keep the project preamble and append / refresh the Concorde block |
31
+ | `--force-agents` | Opt-in: **replace** the whole `AGENTS.md` (destructive) |
32
+ | `--overlay <dir>` | Extra rules/skills + optional `AGENTS.starter.md` for project-only agent notes |
31
33
  | `--cursor-only` | Install only `.cursor/skills` and `.cursor/rules` |
32
34
  | `--jetbrains-only` | Install only `.aiassistant/rules/` |
33
35
 
36
+ ## `AGENTS.md` policy (non-invasive)
37
+
38
+ | Situation | Default |
39
+ |-----------|---------|
40
+ | No `AGENTS.md` | Create the Concorde guide |
41
+ | File with `<!-- concorde-ai -->` | Refresh the managed zone only |
42
+ | File **without** marker (project notes) | **Left untouched** — skills / rules are enough |
43
+ | `--merge-agents` / `--force-agents` / `--skip-agents` | See flags above |
44
+
45
+ ```text
46
+ [optional project preamble — short, project-only]
47
+ <!-- concorde-ai -->
48
+ <package ai/AGENTS.md>
49
+ [--- + overlay AGENTS.starter.md]
50
+ ```
51
+
52
+ Everything **after** `<!-- concorde-ai -->` is replaced on each `ai-init` run (idempotent). Do not paste a full copy of the Concorde guide above the marker — put project-specific notes in `AGENTS.starter.md` (overlay). If the preamble duplicates package `AGENTS.md`, `ai-init` slims or drops it and prints a warning.
53
+
34
54
  ## What gets installed
35
55
 
36
56
  | Path | Role |
37
57
  |------|------|
38
- | `AGENTS.md` | Project-level guide for agents (Concorde conventions) |
58
+ | `AGENTS.md` | Created only if missing; existing project-owned files are left alone unless `--merge-agents` / `--force-agents` |
39
59
  | `.cursor/skills/concorde/` | Core Lit + DataProvider patterns |
40
60
  | `.cursor/skills/concorde-imports/` | Short `@supersoniks/concorde/…` import paths |
41
61
  | `.cursor/skills/concorde-scope/` | `serviceURL`, `formDataProvider`, API configuration |
@@ -49,7 +69,7 @@ node node_modules/@supersoniks/concorde/scripts/ai-init.mjs
49
69
 
50
70
  1. **Starter project:** [Installation](#docs/_getting-started/concorde-outside.md/concorde-outside) — `yarn ai:sync` is wired in the kit.
51
71
  2. **Existing / manual Vite project:** [Manual installation](#docs/_getting-started/concorde-manual-install.md/concorde-manual-install), then **`ai-init`** after `yarn add @supersoniks/concorde`.
52
- 3. Commit `AGENTS.md`, `.cursor/`, and `.aiassistant/` if your team shares agent settings.
72
+ 3. Commit `.cursor/` and `.aiassistant/` (and `AGENTS.md` only if you opted in / it was created) if your team shares agent settings.
53
73
  4. Re-run the same command when you bump `@supersoniks/concorde` to refresh skills from `node_modules/@supersoniks/concorde/ai/`.
54
74
  5. In Cursor, skills under `.cursor/skills/` are picked up automatically; mention a skill in chat for focused tasks (e.g. migration → `concorde-get-set-dp`).
55
75