@the-portland-company/shell 0.41.1 → 0.42.0
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/dist/app-chrome.cjs.map +1 -1
- package/dist/app-chrome.js +1 -1
- package/dist/chrome.css +9 -4
- package/dist/{chunk-IX664IMD.js → chunk-BE5OQB3X.js} +4 -4
- package/dist/{chunk-IX664IMD.js.map → chunk-BE5OQB3X.js.map} +1 -1
- package/dist/native.cjs +2 -2
- package/dist/native.cjs.map +1 -1
- package/dist/native.js +1 -1
- package/package.json +1 -1
package/dist/app-chrome.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/topbarIconSlot.ts","../src/lib/brandGlyphs.tsx","../src/theme-preference.ts","../src/native/chromeActions.tsx","../src/native/standardNav.ts","../src/native/index.tsx","../src/active-org.ts","../src/nav-preference.ts","../src/lib/breadcrumbs.ts","../src/lib/identity.ts","../src/logout-signal.ts","../src/app-chrome/frame.tsx","../src/app-chrome/index.tsx"],"names":["useState","useEffect","FiBatteryCharging","FiBattery","FiZap","FiGrid","FiBell","FiAlertTriangle","FiAlertCircle","FiLifeBuoy","FiHelpCircle","FiMoon","FiSun","FiInfo","FiMail","FiMessageSquare","FiSettings","FiUser","useSyncExternalStore","jsxs","jsx","createContext","useContext","useRef","Fragment","useCallback","createPortal","base","useMemo","VALID","trail","FiHome","FiUsers","FiLayout","FiActivity","FiList","FiUpload","FiEdit3","FiFileText","FiSend","FiClock","FiBarChart2","FiBriefcase","FiCreditCard","FiDollarSign","FiShare2","FiPhone","FiMap","FiMapPin","FiTarget","FiFlag","createDevNotesClient","DevNotesProvider","DevNotesTaskListModal","DevNotesOverlay","DevNotesMenu"],"mappings":";;;;;;;;AA6BO,SAAS,uBAAuB,IAAA,EAAqC;AAC1E,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIA,eAAwB,IAAI,CAAA;AAEpD,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AAEnC,IAAA,MAAM,OAAO,MAAM;AACjB,MAAA,MAAM,GAAA,GAAM,MAAA,CACT,gBAAA,CAAiB,QAAA,CAAS,eAAe,CAAA,CACzC,gBAAA,CAAiB,CAAA,cAAA,EAAiB,IAAI,EAAE,CAAA,CACxC,IAAA,EAAK,CAEL,OAAA,CAAQ,gBAAgB,EAAE,CAAA;AAC7B,MAAA,OAAA,CAAQ,GAAA,CAAI,MAAA,GAAS,CAAA,GAAI,GAAA,GAAM,IAAI,CAAA;AAAA,IACrC,CAAA;AAEA,IAAA,IAAA,EAAK;AAEL,IAAA,MAAM,QAAA,GAAW,IAAI,gBAAA,CAAiB,IAAI,CAAA;AAC1C,IAAA,QAAA,CAAS,OAAA,CAAQ,SAAS,IAAA,EAAM,EAAE,WAAW,IAAA,EAAM,OAAA,EAAS,MAAM,CAAA;AAClE,IAAA,OAAO,MAAM,SAAS,UAAA,EAAW;AAAA,EACnC,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAA,OAAO,IAAA;AACT;ACnBA,IAAM,MAAA,GAAyC;AAAA;AAAA;AAAA,EAG7C,kBAAA,EAAoBC,oBAAA;AAAA,EACpB,OAAA,EAASC,YAAA;AAAA,EACT,IAAA,EAAMD,oBAAA;AAAA,EACN,IAAA,EAAME,QAAA;AAAA,EACN,GAAA,EAAKA,QAAA;AAAA,EACL,IAAA,EAAMC,SAAA;AAAA,EACN,IAAA,EAAMA,SAAA;AAAA,EACN,IAAA,EAAMC,SAAA;AAAA,EACN,YAAA,EAAcA,SAAA;AAAA,EACd,gBAAA,EAAkBC,kBAAA;AAAA,EAClB,KAAA,EAAOA,kBAAA;AAAA,EACP,cAAA,EAAgBC,gBAAA;AAAA,EAChB,WAAA,EAAaC,aAAA;AAAA,EACb,WAAA,EAAaA,aAAA;AAAA,EACb,OAAA,EAASA,aAAA;AAAA,EACT,aAAA,EAAeC,eAAA;AAAA,EACf,IAAA,EAAMC,SAAA;AAAA,EACN,GAAA,EAAKC,QAAA;AAAA,EACL,IAAA,EAAMC,SAAA;AAAA,EACN,IAAA,EAAMC,SAAA;AAAA,EACN,gBAAA,EAAkBC,kBAAA;AAAA,EAClB,QAAA,EAAUC,aAAA;AAAA,EACV,IAAA,EAAMC;AACR,CAAA;AAOO,SAAS,kBAAkB,IAAA,EAAwD;AACxF,EAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,EAAA,OAAO,OAAO,IAAA,CAAK,IAAA,EAAK,CAAE,WAAA,EAAa,CAAA,IAAK,IAAA;AAC9C;;;ACjDO,IAAM,iBAAA,GAAoB,gBAAA;AAC1B,IAAM,YAAA,GAAe,gBAAA;AAWrB,IAAM,oBAAA,GAAuB,wBAAA;AAEpC,IAAM,KAAA,GAAoC,CAAC,OAAA,EAAS,MAAA,EAAQ,QAAQ,CAAA;AAE7D,SAAS,kBAAkB,CAAA,EAAkC;AAClE,EAAA,OAAO,OAAO,CAAA,KAAM,QAAA,IAAa,KAAA,CAA4B,SAAS,CAAC,CAAA;AACzE;AAGO,SAAS,eAAA,GAA0C;AACxD,EAAA,IAAI,OAAO,QAAA,KAAa,WAAA,EAAa,OAAO,IAAA;AAC5C,EAAA,IAAI;AACF,IAAA,MAAM,CAAA,GAAI,SAAS,MAAA,CAAO,KAAA;AAAA,MACxB,IAAI,MAAA,CAAO,CAAA,WAAA,EAAc,YAAY,CAAA,QAAA,CAAU;AAAA,KACjD;AACA,IAAA,MAAM,IAAI,CAAA,GAAI,kBAAA,CAAmB,CAAA,CAAE,CAAC,CAAC,CAAA,GAAI,IAAA;AACzC,IAAA,OAAO,iBAAA,CAAkB,CAAC,CAAA,GAAI,CAAA,GAAI,IAAA;AAAA,EACpC,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAOO,SAAS,iBAAiB,IAAA,EAA6B;AAC5D,EAAA,IAAI,OAAO,QAAA,KAAa,WAAA,IAAe,OAAO,WAAW,WAAA,EAAa;AACtE,EAAA,MAAM,IAAA,GAAO,OAAO,QAAA,CAAS,QAAA;AAC7B,EAAA,MAAM,cAAA,GAAiB,0BAAA,CAA2B,IAAA,CAAK,IAAI,CAAA;AAC3D,EAAA,MAAM,UAAA,GAAa,iBAAiB,2BAAA,GAA8B,EAAA;AAClE,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,QAAA,CAAS,QAAA,KAAa,WAAW,UAAA,GAAa,EAAA;AACpE,EAAA,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG,YAAY,CAAA,CAAA,EAAI,kBAAA;AAAA,IACnC;AAAA,GACD,CAAA,wCAAA,EAA2C,UAAU,CAAA,EAAG,MAAM,CAAA,CAAA;AACjE;AAIA,SAAS,iBAAA,CAAkB,IAAA,EAAc,KAAA,EAAe,aAAA,EAA6B;AACnF,EAAA,IAAI,OAAO,QAAA,KAAa,WAAA,IAAe,OAAO,WAAW,WAAA,EAAa;AACtE,EAAA,MAAM,IAAA,GAAO,OAAO,QAAA,CAAS,QAAA;AAC7B,EAAA,MAAM,UAAA,GAAa,0BAAA,CAA2B,IAAA,CAAK,IAAI,IAAI,2BAAA,GAA8B,EAAA;AACzF,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,QAAA,CAAS,QAAA,KAAa,WAAW,UAAA,GAAa,EAAA;AACpE,EAAA,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,kBAAA;AAAA,IAC3B;AAAA,GACD,CAAA,kBAAA,EAAqB,aAAa,CAAA,cAAA,EAAiB,UAAU,GAAG,MAAM,CAAA,CAAA;AACzE;AAOO,SAAS,uBAAuB,IAAA,EAA6B;AAClE,EAAA,iBAAA,CAAkB,oBAAA,EAAsB,MAAM,OAAQ,CAAA;AACxD;AAGO,SAAS,sBAAA,GAAiD;AAC/D,EAAA,IAAI,OAAO,QAAA,KAAa,WAAA,EAAa,OAAO,IAAA;AAC5C,EAAA,IAAI;AACF,IAAA,MAAM,CAAA,GAAI,SAAS,MAAA,CAAO,KAAA;AAAA,MACxB,IAAI,MAAA,CAAO,CAAA,WAAA,EAAc,oBAAoB,CAAA,QAAA,CAAU;AAAA,KACzD;AACA,IAAA,MAAM,IAAI,CAAA,GAAI,kBAAA,CAAmB,CAAA,CAAE,CAAC,CAAC,CAAA,GAAI,IAAA;AACzC,IAAA,OAAO,iBAAA,CAAkB,CAAC,CAAA,GAAI,CAAA,GAAI,IAAA;AAAA,EACpC,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAGO,SAAS,uBAAA,GAAgC;AAC9C,EAAA,iBAAA,CAAkB,oBAAA,EAAsB,IAAI,CAAC,CAAA;AAC/C;AAGO,SAAS,aAAa,IAAA,EAAyC;AACpE,EAAA,IAAI,SAAS,QAAA,EAAU;AACrB,IAAA,IAAI;AACF,MAAA,OAAO,MAAA,CAAO,UAAA,CAAW,8BAA8B,CAAA,CAAE,UACrD,MAAA,GACA,OAAA;AAAA,IACN,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,OAAA;AAAA,IACT;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;AAgCO,SAAS,qBAAqB,IAAA,EAA6B;AAChE,EAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACrC,EAAA,MAAM,QAAA,GAAW,aAAa,IAAI,CAAA;AAClC,EAAA,MAAM,IAAI,QAAA,CAAS,eAAA;AACnB,EAAA,CAAA,CAAE,SAAA,CAAU,MAAA,CAAO,MAAA,EAAQ,QAAA,KAAa,MAAM,CAAA;AAC9C,EAAA,IAAI;AACF,IAAA,CAAA,CAAE,MAAM,WAAA,GAAc,QAAA;AAAA,EACxB,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAQqC,CAAA;AAAA,QAAA,EAC3B,IAAA,CAAK,SAAA,CAAU,iBAAiB,CAAC,CAAA;AAAA;AAAA,kEAAA,EAEyB,YAAY,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAAA;ACtHzE,IAAM,eAAA,GAAkB,6BAAA;AAExB,IAAM,iBAAA,GAAoB,wDAAA;AACjC,IAAM,gBAAA,GAAmB,CAAA,EAAG,eAAe,CAAA,EAAG,iBAAiB,CAAA,CAAA;AAC/D,IAAM,wBAAA,GAA2B,GAAG,eAAe,CAAA,kCAAA,CAAA;AAQnD,SAAS,YAAA,CAAa,KAAa,KAAA,EAA0C;AAC3E,EAAA,IAAI,CAAC,OAAO,OAAO,GAAA;AACnB,EAAA,OAAO,CAAA,EAAG,GAAG,CAAA,EAAG,GAAA,CAAI,QAAA,CAAS,GAAG,CAAA,GAAI,GAAA,GAAM,GAAG,CAAA,IAAA,EAAO,KAAK,CAAA,CAAA;AAC3D;AAGA,SAAS,cAAA,CAAe,KAAa,KAAA,EAA0C;AAC7E,EAAA,IAAI,CAAC,OAAO,OAAO,GAAA;AACnB,EAAA,OAAO,CAAA,EAAG,GAAG,CAAA,EAAG,GAAA,CAAI,QAAA,CAAS,GAAG,CAAA,GAAI,GAAA,GAAM,GAAG,CAAA,MAAA,EAAS,kBAAA,CAAmB,KAAK,CAAC,CAAA,CAAA;AACjF;AAeO,SAAS,kBAAkB,GAAA,EAAoD;AACpF,EAAA,MAAM,GAAA,GAAM,KAAK,IAAA,EAAK;AACtB,EAAA,IAAI,CAAC,KAAK,OAAO,MAAA;AACjB,EAAA,IAAI,+BAAA,CAAgC,IAAA,CAAK,GAAG,CAAA,EAAG,OAAO,GAAA;AACtD,EAAA,OAAO,CAAA,EAAG,eAAe,CAAA,EAAG,GAAA,CAAI,UAAA,CAAW,GAAG,CAAA,GAAI,EAAA,GAAK,GAAG,CAAA,EAAG,GAAG,CAAA,CAAA;AAClE;AAQO,SAAS,qBAAA,CAAsB,OAAyC,SAAA,EAAmB;AAChG,EAAA,MAAM,SAAA,GACJ,IAAA,KAAS,QAAA,IAAY,IAAA,KAAS,YAC1B,6EAAA,GACA,iLAAA;AACN,EAAA,OAAO;AAAA;AAAA,IAEL,iHAAA;AAAA,IACA,iFAAA;AAAA,IACA;AAAA,GACF,CAAE,KAAK,GAAG,CAAA;AACZ;AAgBA,IAAI,cAAA,GAAiB,CAAA;AACrB,IAAM,cAAA,uBAAqB,GAAA,EAAgB;AAC3C,IAAM,kBAAkB,MAAM,cAAA,CAAe,QAAQ,CAAC,CAAA,KAAM,GAAG,CAAA;AAE/D,SAAS,mBAAmB,IAAA,EAAe;AACzC,EAAA,cAAA,GAAiB,KAAK,GAAA,CAAI,CAAA,EAAG,cAAA,IAAkB,IAAA,GAAO,IAAI,EAAA,CAAG,CAAA;AAC7D,EAAA,eAAA,EAAgB;AAClB;AAGO,SAAS,qBAAA,GAAwB;AACtC,EAAA,OAAOC,0BAAA;AAAA,IACL,CAAC,EAAA,KAAO;AACN,MAAA,cAAA,CAAe,IAAI,EAAE,CAAA;AACrB,MAAA,OAAO,MAAM,cAAA,CAAe,MAAA,CAAO,EAAE,CAAA;AAAA,IACvC,CAAA;AAAA,IACA,MAAM,cAAA,GAAiB,CAAA;AAAA,IACvB,MAAM;AAAA,GACR;AACF;AAEO,SAAS,gBAAA,CAAiB,EAAE,KAAA,EAAM,EAAsB;AAC7D,EAAA,IAAI,EAAE,KAAA,GAAQ,CAAA,CAAA,EAAI,OAAO,IAAA;AACzB,EAAA,sCACG,MAAA,EAAA,EAAK,SAAA,EAAU,4KACb,QAAA,EAAA,KAAA,GAAQ,EAAA,GAAK,QAAQ,KAAA,EACxB,CAAA;AAEJ;AAQO,SAAS,aAAA,CAAc;AAAA,EAC5B,KAAA;AAAA,EACA;AACF,CAAA,EAGG;AACD,EAAA,uBACEC,eAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,SAAA;AAAA,MACL,SAAA,EAAU,+PAAA;AAAA,MAGV,QAAA,EAAA;AAAA,wBAAAC,cAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,aAAA,EAAW,IAAA;AAAA,YACX,SAAA,EAAU;AAAA;AAAA,SACZ;AAAA,wBACAA,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,sDAAA,EAAwD,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,QAC7E,8BACCA,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,2DAAA,EACb,uBACH,CAAA,GACE;AAAA;AAAA;AAAA,GACN;AAEJ;AAQO,SAAS,gBAAA,GAAmB;AACjC,EAAA,uBACEA,cAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,aAAA,EAAW,IAAA;AAAA,MACX,SAAA,EAAU;AAAA;AAAA,GACZ;AAEJ;AAOO,SAAS,gBAAA,CAAiB;AAAA,EAC/B,KAAA;AAAA,EACA,WAAA;AAAA,EACA;AACF,CAAA,EAIG;AACD,EAAA,uBACED,eAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qDAAA,EACb,QAAA,EAAA;AAAA,IAAA,QAAA;AAAA,oBACDC,cAAA,CAAC,aAAA,EAAA,EAAc,KAAA,EAAc,WAAA,EAA0B;AAAA,GAAA,EACzD,CAAA;AAEJ;AASA,IAAM,aAAA,GAA6D;AAAA,EACjE,EAAE,KAAA,EAAO,OAAA,EAAS,KAAA,EAAO,OAAA,EAAQ;AAAA,EACjC,EAAE,KAAA,EAAO,QAAA,EAAU,KAAA,EAAO,QAAA,EAAS;AAAA,EACnC,EAAE,KAAA,EAAO,MAAA,EAAQ,KAAA,EAAO,MAAA;AAC1B,CAAA;AAEO,SAAS,eAAA,CAAgB;AAAA,EAC9B,KAAA;AAAA,EACA;AACF,CAAA,EAGG;AACD,EAAA,uBACED,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,WAAA,EACb,QAAA,EAAA;AAAA,oBAAAC,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,sFAAA,EAAuF,QAAA,EAAA,YAAA,EAEpG,CAAA;AAAA,oBACAA,cAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,YAAA;AAAA,QACL,YAAA,EAAW,YAAA;AAAA,QACX,SAAA,EAAU,qEAAA;AAAA,QAET,QAAA,EAAA,aAAA,CAAc,GAAA,CAAI,CAAC,GAAA,qBAClBA,cAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YAEC,IAAA,EAAK,QAAA;AAAA,YACL,IAAA,EAAK,OAAA;AAAA,YACL,cAAA,EAAc,UAAU,GAAA,CAAI,KAAA;AAAA,YAC5B,OAAA,EAAS,MAAM,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA;AAAA,YACjC,SAAA,EAAW;AAAA,cACT,qDAAA;AAAA,cACA,KAAA,KAAU,GAAA,CAAI,KAAA,GACV,6CAAA,GACA;AAAA,aACN,CAAE,KAAK,GAAG,CAAA;AAAA,YAET,QAAA,EAAA,GAAA,CAAI;AAAA,WAAA;AAAA,UAZA,GAAA,CAAI;AAAA,SAcZ;AAAA;AAAA;AACH,GAAA,EACF,CAAA;AAEJ;AAmCA,IAAM,gBAAA,GAAmBC,oBAA4C,IAAI,CAAA;AAElE,SAAS,iBAAA,CAAkB;AAAA,EAChC,SAAA;AAAA,EACA;AACF,CAAA,EAGG;AAGD,EAAA,MAAM,CAAC,EAAA,EAAI,KAAK,CAAA,GAAIrB,eAA0B,IAAI,CAAA;AAClD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIA,eAAS,KAAK,CAAA;AAC9C,EAAAC,gBAAU,MAAM;AACd,IAAA,IAAI,SAAA,GAAY,KAAA;AAChB,IAAA,SAAA,CAAU,IAAI,CAAA,CACX,IAAA,CAAK,CAAC,IAAA,KAAS;AACd,MAAA,IAAI,CAAC,SAAA,EAAW,KAAA,CAAM,IAAgB,CAAA;AAAA,IACxC,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AAAA,IAEb,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM;AACb,MAAA,IAAI,CAAC,SAAA,EAAW,WAAA,CAAY,IAAI,CAAA;AAAA,IAClC,CAAC,CAAA;AACH,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AAAA,IACd,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAEd,EAAA,uBACEmB,cAAA,CAAC,gBAAA,CAAiB,QAAA,EAAjB,EAA0B,KAAA,EAAO,EAAE,SAAA,EAAW,EAAA,EAAI,QAAA,EAAS,EACzD,QAAA,EACH,CAAA;AAEJ;AAGO,SAAS,WAAA,GAAwD;AACtE,EAAA,MAAM,GAAA,GAAME,iBAAW,gBAAgB,CAAA;AACvC,EAAA,OAAO,EAAE,IAAI,GAAA,EAAK,EAAA,IAAM,MAAM,MAAA,EAAQ,GAAA,EAAK,YAAY,KAAA,EAAM;AAC/D;AAGO,SAAS,mBAAA,GAA+C;AAC7D,EAAA,OAAOA,gBAAA,CAAW,gBAAgB,CAAA,EAAG,SAAA,IAAa,IAAA;AACpD;AAEA,SAAS,aAAa,SAAA,EAA0C;AAC9D,EAAA,MAAM,GAAA,GAAMA,iBAAW,gBAAgB,CAAA;AACvC,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,GAAG,SAAS,CAAA,mFAAA;AAAA,KACd;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;AAwFO,SAAS,aAAA,GAId;AACA,EAAA,MAAM,EAAE,SAAA,EAAU,GAAI,YAAA,CAAa,eAAe,CAAA;AAClD,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAItB,eAAoC,IAAI,CAAA;AAChE,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIA,eAAS,IAAI,CAAA;AAC3C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,eAAS,KAAK,CAAA;AAExC,EAAAC,gBAAU,MAAM;AACd,IAAA,IAAI,SAAA,GAAY,KAAA;AAChB,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,QAAA,CAAS,KAAK,CAAA;AACd,IAAA,SAAA,CAAU,MAAM,CAAA,CACb,IAAA,CAAK,CAAC,IAAA,KAAS;AACd,MAAA,IAAI,SAAA,EAAW;AACf,MAAA,MAAM,IAAA,GAAQ,IAAA,EAAwC,IAAA,IAAQ,EAAC;AAC/D,MAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,IACd,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AACX,MAAA,IAAI,CAAC,SAAA,EAAW,QAAA,CAAS,IAAI,CAAA;AAAA,IAC/B,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM;AACb,MAAA,IAAI,CAAC,SAAA,EAAW,UAAA,CAAW,KAAK,CAAA;AAAA,IAClC,CAAC,CAAA;AACH,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AAAA,IACd,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAEd,EAAA,OAAO,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAM;AAChC;AAOA,SAAS,aAAA,CAAc,EAAE,SAAA,EAAU,EAA2B;AAC5D,EAAA,uBACEmB,cAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,aAAA,EAAW,IAAA;AAAA,MACX,SAAA,EAAW;AAAA,QACT,qEAAA;AAAA,QACA,SAAA,IAAa;AAAA,OACf,CAAE,KAAK,GAAG;AAAA;AAAA,GACZ;AAEJ;AAGA,SAAS,SAAA,CAAU;AAAA,EACjB,IAAA;AAAA,EACA,QAAA,EAAU,QAAA;AAAA,EACV,IAAA,GAAO;AACT,CAAA,EAIG;AACD,EAAA,MAAM,SAAA,GAAY,sBAAA,CAAuB,IAAA,IAAQ,MAAM,CAAA;AACvD,EAAA,MAAM,UAAA,GAAa,IAAA,GAAO,iBAAA,CAAkB,SAAS,CAAA,GAAI,IAAA;AACzD,EAAA,MAAM,QAAQ,UAAA,IAAc,QAAA;AAC5B,EAAA,uBAAOA,cAAA,CAAC,KAAA,EAAA,EAAM,IAAA,EAAY,SAAA,EAAU,cAAA,EAAe,CAAA;AACrD;AAcO,SAAS,aAAA,CAAc;AAAA,EAC5B,KAAA;AAAA,EACA,WAAA;AAAA,EACA,IAAA;AAAA,EACA,YAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAwBG;AACD,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIpB,eAAS,KAAK,CAAA;AACtC,EAAA,MAAM,eAAA,GAAkBuB,aAAO,YAAY,CAAA;AAC3C,EAAA,eAAA,CAAgB,OAAA,GAAU,YAAA;AAC1B,EAAAtB,gBAAU,MAAM;AACd,IAAA,eAAA,CAAgB,UAAU,IAAI,CAAA;AAC9B,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,kBAAA,CAAmB,IAAI,CAAA;AACvB,IAAA,OAAO,MAAM,mBAAmB,KAAK,CAAA;AAAA,EACvC,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AACT,EAAA,MAAM,OAAA,GAAUsB,aAA8B,IAAI,CAAA;AAClD,EAAA,MAAM,gBAAA,GAAmBA,aAAO,SAAS,CAAA;AAGzC,EAAAtB,gBAAU,MAAM;AACd,IAAA,IAAI,cAAc,MAAA,EAAW;AAC7B,IAAA,IAAI,SAAA,KAAc,iBAAiB,OAAA,EAAS;AAC5C,IAAA,gBAAA,CAAiB,OAAA,GAAU,SAAA;AAC3B,IAAA,OAAA,CAAQ,CAAC,CAAA,KAAM;AACb,MAAA,IAAI,CAAC,GAAG,MAAA,IAAS;AACjB,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH,CAAA,EAAG,CAAC,SAAA,EAAW,MAAM,CAAC,CAAA;AAEtB,EAAAA,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,MAAM,UAAA,GAAa,CAAC,CAAA,KAAkB;AACpC,MAAA,IAAI,OAAA,CAAQ,OAAA,IAAW,CAAC,OAAA,CAAQ,OAAA,CAAQ,SAAS,CAAA,CAAE,MAAc,CAAA,EAAG,OAAA,CAAQ,KAAK,CAAA;AAAA,IACnF,CAAA;AACA,IAAA,MAAM,KAAA,GAAQ,CAAC,CAAA,KAAqB;AAClC,MAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,QAAA,EAAU,OAAA,CAAQ,KAAK,CAAA;AAAA,IACvC,CAAA;AACA,IAAA,QAAA,CAAS,gBAAA,CAAiB,aAAa,UAAU,CAAA;AACjD,IAAA,QAAA,CAAS,gBAAA,CAAiB,WAAW,KAAK,CAAA;AAC1C,IAAA,OAAO,MAAM;AACX,MAAA,QAAA,CAAS,mBAAA,CAAoB,aAAa,UAAU,CAAA;AACpD,MAAA,QAAA,CAAS,mBAAA,CAAoB,WAAW,KAAK,CAAA;AAAA,IAC/C,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAA,uBACEkB,eAAA,CAAC,KAAA,EAAA,EAAI,GAAA,EAAK,OAAA,EAAS,WAAU,UAAA,EAC3B,QAAA,EAAA;AAAA,oBAAAA,eAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,YAAA,EAAY,KAAA;AAAA,QACZ,eAAA,EAAe,IAAA;AAAA,QACf,SAAA,EAAW,sBAAsB,IAAI,CAAA;AAAA,QACrC,SAAS,MAAM;AACb,UAAA,OAAA,CAAQ,CAAC,CAAA,KAAM;AACb,YAAA,MAAM,OAAO,CAAC,CAAA;AACd,YAAA,IAAI,MAAM,MAAA,IAAS;AACnB,YAAA,OAAO,IAAA;AAAA,UACT,CAAC,CAAA;AAAA,QACH,CAAA;AAAA,QAEA,QAAA,EAAA;AAAA,0BAAAC,cAAA,CAAC,SAAA,EAAA,EAAU,IAAA,EAAY,QAAA,EAAU,YAAA,EAAc,CAAA;AAAA,UAC9C,OAAO,KAAA,KAAU,QAAA,kCAAY,gBAAA,EAAA,EAAiB,KAAA,EAAO,OAAO,CAAA,GAAK,IAAA;AAAA,UACjE,CAAC,IAAA,mBAAOA,cAAA,CAAC,iBAAc,KAAA,EAAO,KAAA,EAAO,aAA0B,CAAA,GAAK;AAAA;AAAA;AAAA,KACvE;AAAA,IACC,IAAA,mBACCD,eAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW;AAAA,UACT,sIAAA;AAAA,UACA,cAAA,IAAkB;AAAA,SACpB,CAAE,KAAK,GAAG,CAAA;AAAA,QAEV,QAAA,EAAA;AAAA,0BAAAC,cAAA,CAAC,gBAAA,EAAA,EAAiB,CAAA;AAAA,0BAClBA,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,4BAAA,EAA8B,QAAA,EAAS;AAAA;AAAA;AAAA,KACxD,GACE;AAAA,GAAA,EACN,CAAA;AAEJ;AAGA,SAAS,YAAA,CAAa,EAAE,IAAA,GAAO,EAAA,EAAI,WAAU,EAA0C;AACrF,EAAA,uBACED,eAAA,CAAC,SAAI,KAAA,EAAO,IAAA,EAAM,QAAQ,IAAA,EAAM,OAAA,EAAQ,aAAY,IAAA,EAAK,MAAA,EAAO,QAAO,cAAA,EAAe,WAAA,EAAa,GAAG,aAAA,EAAc,OAAA,EAAQ,gBAAe,OAAA,EAAQ,SAAA,EAAsB,eAAW,IAAA,EAClL,QAAA,EAAA;AAAA,oBAAAC,cAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,GAAA,EAAI,CAAA,EAAE,GAAA,EAAI,KAAA,EAAM,IAAA,EAAK,MAAA,EAAO,IAAA,EAAK,EAAA,EAAG,GAAA,EAAI,EAAA,EAAG,GAAA,EAAI,CAAA;AAAA,oBACvDA,cAAA,CAAC,UAAK,EAAA,EAAG,IAAA,EAAK,IAAG,IAAA,EAAK,EAAA,EAAG,IAAA,EAAK,EAAA,EAAG,IAAA,EAAK,CAAA;AAAA,oBACtCA,cAAA,CAAC,UAAK,EAAA,EAAG,GAAA,EAAI,IAAG,IAAA,EAAK,EAAA,EAAG,GAAA,EAAI,EAAA,EAAG,IAAA,EAAK,CAAA;AAAA,oBACpCA,cAAA,CAAC,UAAK,EAAA,EAAG,GAAA,EAAI,IAAG,IAAA,EAAK,EAAA,EAAG,GAAA,EAAI,EAAA,EAAG,IAAA,EAAK;AAAA,GAAA,EACtC,CAAA;AAEJ;AAEA,SAAS,SAAA,CAAU,EAAE,IAAA,GAAO,EAAA,EAAI,WAAU,EAA0C;AAClF,EAAA,uBACED,eAAA,CAAC,SAAI,KAAA,EAAO,IAAA,EAAM,QAAQ,IAAA,EAAM,OAAA,EAAQ,aAAY,IAAA,EAAK,MAAA,EAAO,QAAO,cAAA,EAAe,WAAA,EAAa,GAAG,aAAA,EAAc,OAAA,EAAQ,gBAAe,OAAA,EAAQ,SAAA,EAAsB,eAAW,IAAA,EAClL,QAAA,EAAA;AAAA,oBAAAC,cAAA,CAAC,MAAA,EAAA,EAAK,GAAE,6CAAA,EAA8C,CAAA;AAAA,oBACtDA,cAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,4BAAA,EAA6B;AAAA,GAAA,EACvC,CAAA;AAEJ;AAEA,SAAS,aAAA,CAAc,EAAE,IAAA,GAAO,EAAA,EAAI,WAAU,EAA0C;AACtF,EAAA,uBACED,eAAA,CAAC,SAAI,KAAA,EAAO,IAAA,EAAM,QAAQ,IAAA,EAAM,OAAA,EAAQ,aAAY,IAAA,EAAK,MAAA,EAAO,QAAO,cAAA,EAAe,WAAA,EAAa,GAAG,aAAA,EAAc,OAAA,EAAQ,gBAAe,OAAA,EAAQ,SAAA,EAAsB,eAAW,IAAA,EAClL,QAAA,EAAA;AAAA,oBAAAC,cAAA,CAAC,YAAO,EAAA,EAAG,IAAA,EAAK,EAAA,EAAG,IAAA,EAAK,GAAE,IAAA,EAAK,CAAA;AAAA,mCAC9B,QAAA,EAAA,EAAO,EAAA,EAAG,MAAK,EAAA,EAAG,IAAA,EAAK,GAAE,GAAA,EAAI,CAAA;AAAA,oBAC9BA,cAAA,CAAC,UAAK,EAAA,EAAG,MAAA,EAAO,IAAG,MAAA,EAAO,EAAA,EAAG,MAAA,EAAO,EAAA,EAAG,MAAA,EAAO,CAAA;AAAA,oBAC9CA,cAAA,CAAC,UAAK,EAAA,EAAG,OAAA,EAAQ,IAAG,OAAA,EAAQ,EAAA,EAAG,OAAA,EAAQ,EAAA,EAAG,OAAA,EAAQ,CAAA;AAAA,oBAClDA,cAAA,CAAC,UAAK,EAAA,EAAG,OAAA,EAAQ,IAAG,MAAA,EAAO,EAAA,EAAG,OAAA,EAAQ,EAAA,EAAG,MAAA,EAAO,CAAA;AAAA,oBAChDA,cAAA,CAAC,UAAK,EAAA,EAAG,MAAA,EAAO,IAAG,OAAA,EAAQ,EAAA,EAAG,MAAA,EAAO,EAAA,EAAG,OAAA,EAAQ;AAAA,GAAA,EAClD,CAAA;AAEJ;AAEA,SAAS,WAAA,CAAY,EAAE,IAAA,GAAO,EAAA,EAAI,WAAU,EAA0C;AACpF,EAAA,uBACED,eAAA,CAAC,SAAI,KAAA,EAAO,IAAA,EAAM,QAAQ,IAAA,EAAM,OAAA,EAAQ,aAAY,IAAA,EAAK,MAAA,EAAO,QAAO,cAAA,EAAe,WAAA,EAAa,GAAG,aAAA,EAAc,OAAA,EAAQ,gBAAe,OAAA,EAAQ,SAAA,EAAsB,eAAW,IAAA,EAClL,QAAA,EAAA;AAAA,oBAAAC,cAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,GAAA,EAAI,CAAA,EAAE,GAAA,EAAI,KAAA,EAAM,IAAA,EAAK,MAAA,EAAO,IAAA,EAAK,EAAA,EAAG,GAAA,EAAI,EAAA,EAAG,GAAA,EAAI,CAAA;AAAA,oBACvDA,cAAA,CAAC,UAAK,EAAA,EAAG,GAAA,EAAI,IAAG,GAAA,EAAI,EAAA,EAAG,IAAA,EAAK,EAAA,EAAG,GAAA,EAAI,CAAA;AAAA,oBACnCA,cAAA,CAAC,UAAK,EAAA,EAAG,GAAA,EAAI,IAAG,IAAA,EAAK,EAAA,EAAG,GAAA,EAAI,EAAA,EAAG,GAAA,EAAI;AAAA,GAAA,EACrC,CAAA;AAEJ;AAEA,SAAS,SAAA,CAAU,EAAE,IAAA,GAAO,EAAA,EAAI,WAAU,EAA0C;AAClF,EAAA,uBACED,eAAA,CAAC,SAAI,KAAA,EAAO,IAAA,EAAM,QAAQ,IAAA,EAAM,OAAA,EAAQ,aAAY,IAAA,EAAK,MAAA,EAAO,QAAO,cAAA,EAAe,WAAA,EAAa,KAAK,aAAA,EAAc,OAAA,EAAQ,gBAAe,OAAA,EAAQ,SAAA,EAAsB,eAAW,IAAA,EACpL,QAAA,EAAA;AAAA,oBAAAC,cAAA,CAAC,MAAA,EAAA,EAAK,IAAG,IAAA,EAAK,EAAA,EAAG,KAAI,EAAA,EAAG,IAAA,EAAK,IAAG,IAAA,EAAK,CAAA;AAAA,oBACrCA,cAAA,CAAC,UAAK,EAAA,EAAG,GAAA,EAAI,IAAG,IAAA,EAAK,EAAA,EAAG,IAAA,EAAK,EAAA,EAAG,IAAA,EAAK;AAAA,GAAA,EACvC,CAAA;AAEJ;AAEA,SAAS,MAAA,CAAO,EAAE,IAAA,GAAO,EAAA,EAAI,WAAU,EAA0C;AAC/E,EAAA,uBACED,eAAA,CAAC,SAAI,KAAA,EAAO,IAAA,EAAM,QAAQ,IAAA,EAAM,OAAA,EAAQ,aAAY,IAAA,EAAK,MAAA,EAAO,QAAO,cAAA,EAAe,WAAA,EAAa,KAAK,aAAA,EAAc,OAAA,EAAQ,gBAAe,OAAA,EAAQ,SAAA,EAAsB,eAAW,IAAA,EACpL,QAAA,EAAA;AAAA,oBAAAC,cAAA,CAAC,MAAA,EAAA,EAAK,IAAG,IAAA,EAAK,EAAA,EAAG,KAAI,EAAA,EAAG,GAAA,EAAI,IAAG,IAAA,EAAK,CAAA;AAAA,oBACpCA,cAAA,CAAC,UAAK,EAAA,EAAG,GAAA,EAAI,IAAG,GAAA,EAAI,EAAA,EAAG,IAAA,EAAK,EAAA,EAAG,IAAA,EAAK;AAAA,GAAA,EACtC,CAAA;AAEJ;AAEA,SAAS,UAAA,CAAW,EAAE,IAAA,GAAO,EAAA,EAAI,WAAU,EAA0C;AACnF,EAAA,uBACEA,cAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO,IAAA,EAAM,MAAA,EAAQ,MAAM,OAAA,EAAQ,WAAA,EAAY,IAAA,EAAK,MAAA,EAAO,MAAA,EAAO,cAAA,EAAe,aAAa,GAAA,EAAK,aAAA,EAAc,OAAA,EAAQ,cAAA,EAAe,OAAA,EAAQ,SAAA,EAAsB,aAAA,EAAW,IAAA,EACpL,QAAA,kBAAAA,cAAA,CAAC,UAAA,EAAA,EAAS,MAAA,EAAO,gBAAA,EAAiB,CAAA,EACpC,CAAA;AAEJ;AAMA,IAAM,2BAAA,GAA8B,kCAAA;AAEpC,SAAS,OAAA,CAAQ;AAAA,EACf,KAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA,EAOG;AACD,EAAA,MAAM,SAAA,GAAY,SAAS,cAAA,IAAkB,CAAA;AAC7C,EAAA,MAAM,KAAA,GAAQ,UAAU,IAAA,CAAK,GAAA,CAAI,QAAQ,eAAA,EAAiB,OAAA,CAAQ,cAAc,CAAA,GAAI,CAAA;AACpF,EAAA,MAAM,KAAA,GAAQ,KAAA,GAAQ,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,GAAA,EAAK,IAAA,CAAK,GAAA,CAAI,CAAA,EAAI,SAAA,GAAY,KAAA,GAAS,GAAG,CAAC,CAAA,GAAI,CAAA;AAClF,EAAA,MAAM,GAAA,GAAM,SAAS,OAAA,IAAW,KAAA;AAEhC,EAAA,uBACED,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,QAAA,EACb,QAAA,EAAA;AAAA,oBAAAA,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,8CAAA,EACb,QAAA,EAAA;AAAA,sBAAAC,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,sDAAA,EAAwD,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,sBAC9ED,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBAAA,EACZ,QAAA,EAAA;AAAA,QAAA,OAAA,mBACCC,cAAA,CAAC,aAAA,EAAA,EAAc,SAAA,EAAU,YAAA,EAAa,CAAA,mBAEtCD,eAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAW;AAAA,cACT,oCAAA;AAAA,cACA,MAAM,oCAAA,GAAuC;AAAA,aAC/C,CAAE,KAAK,GAAG,CAAA;AAAA,YAET,QAAA,EAAA;AAAA,cAAA,SAAA,CAAU,cAAA,EAAe;AAAA,cAAE;AAAA;AAAA;AAAA,SAC9B;AAAA,QAED,OAAA,mBACCC,cAAA;AAAA,UAAC,GAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAM,OAAA;AAAA,YACN,YAAA,EAAY,QAAA;AAAA,YACZ,SAAA,EAAU,0MAAA;AAAA,YAEV,yCAAC,SAAA,EAAA,EAAU;AAAA;AAAA,SACb,GACE;AAAA,OAAA,EACN;AAAA,KAAA,EACF,CAAA;AAAA,oBACAA,cAAA,CAAC,SAAI,SAAA,EAAU,mEAAA,EACZ,oCACCA,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oDAAA,EAAqD,CAAA,mBAEpEA,cAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW;AAAA,UACT,wCAAA;AAAA,UACA,MAAM,kCAAA,GAAqC;AAAA,SAC7C,CAAE,KAAK,GAAG,CAAA;AAAA,QACV,KAAA,EAAO,EAAE,KAAA,EAAO,CAAA,EAAG,KAAK,CAAA,CAAA,CAAA;AAAI;AAAA,KAC9B,EAEJ;AAAA,GAAA,EACF,CAAA;AAEJ;AAQA,SAAS,WAAA,CAAY,EAAE,OAAA,EAAS,KAAA,EAAM,EAA+C;AACnF,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIpB,eAAkB,MAAM;AACxD,IAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,KAAA;AAC1C,IAAA,IAAI;AACF,MAAA,OAAO,MAAA,CAAO,cAAA,CAAe,OAAA,CAAQ,2BAA2B,CAAA,KAAM,GAAA;AAAA,IACxE,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF,CAAC,CAAA;AAED,EAAAC,gBAAU,MAAM;AACd,IAAA,IAAI,OAAA,EAAS;AACb,IAAA,IAAI;AACF,MAAA,MAAA,CAAO,cAAA,CAAe,WAAW,2BAA2B,CAAA;AAAA,IAC9D,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAKZ,EAAA,MAAM,YAAY,qBAAA,EAAsB;AAExC,EAAA,IAAI,CAAC,OAAA,IAAW,SAAA,IAAa,SAAA,EAAW,OAAO,IAAA;AAE/C,EAAA,MAAM,UAAU,MAAM;AACpB,IAAA,IAAI;AACF,MAAA,MAAA,CAAO,cAAA,CAAe,OAAA,CAAQ,2BAAA,EAA6B,GAAG,CAAA;AAAA,IAChE,CAAA,CAAA,MAAQ;AAAA,IAER;AACA,IAAA,YAAA,CAAa,IAAI,CAAA;AAAA,EACnB,CAAA;AAEA,EAAA,uBACEkB,eAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,QAAA;AAAA,MACL,SAAA,EAAU,2LAAA;AAAA,MACV,OAAA,EAAS,CAAC,CAAA,KAAM,CAAA,CAAE,eAAA,EAAgB;AAAA,MAGlC,QAAA,EAAA;AAAA,wBAAAC,cAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,aAAA,EAAW,IAAA;AAAA,YACX,SAAA,EAAU;AAAA;AAAA,SACZ;AAAA,wBACAD,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wBAAA,EACb,QAAA,EAAA;AAAA,0BAAAA,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,QAAA,EACb,QAAA,EAAA;AAAA,4BAAAC,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,uBAAA,EAAwB,QAAA,EAAA,yBAAA,EAAwB,CAAA;AAAA,4BAC7DA,cAAA;AAAA,cAAC,GAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAM,YAAA,CAAa,gBAAA,EAAkB,KAAK,CAAA;AAAA,gBAC1C,SAAA,EAAU,gEAAA;AAAA,gBACX,QAAA,EAAA;AAAA;AAAA;AAED,WAAA,EACF,CAAA;AAAA,0BACAA,cAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,QAAA;AAAA,cACL,YAAA,EAAW,yBAAA;AAAA,cACX,OAAA,EAAS,OAAA;AAAA,cACT,SAAA,EAAU,2GAAA;AAAA,cAEV,yCAAC,MAAA,EAAA,EAAO;AAAA;AAAA;AACV,SAAA,EACF;AAAA;AAAA;AAAA,GACF;AAEJ;AAEO,SAAS,UAAA,CAAW,EAAE,KAAA,EAAM,EAA6B;AAC9D,EAAA,MAAM,EAAE,SAAA,EAAU,GAAI,YAAA,CAAa,YAAY,CAAA;AAC/C,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIpB,eAA0C,IAAI,CAAA;AACtE,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIA,eAAS,IAAI,CAAA;AAC3C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,eAAS,KAAK,CAAA;AAExC,EAAAC,gBAAU,MAAM;AACd,IAAA,IAAI,SAAA,GAAY,KAAA;AAChB,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,QAAA,CAAS,KAAK,CAAA;AACd,IAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,IAAA,SAAA,CAAU,4BAAA,EAA8B;AAAA,MACtC,OAAA,EAAS,KAAA,GAAQ,EAAE,gBAAA,EAAkB,OAAM,GAAI;AAAA,KAChD,CAAA,CACE,IAAA,CAAK,CAAC,IAAA,KAAS;AACd,MAAA,IAAI,SAAA,EAAW;AACf,MAAA,OAAA,CAAS,IAAA,EAAqD,QAAQ,IAAI,CAAA;AAAA,IAC5E,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AACX,MAAA,IAAI,CAAC,SAAA,EAAW,QAAA,CAAS,IAAI,CAAA;AAAA,IAC/B,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM;AACb,MAAA,IAAI,CAAC,SAAA,EAAW,UAAA,CAAW,KAAK,CAAA;AAAA,IAClC,CAAC,CAAA;AACH,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AAAA,IACd,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,SAAA,EAAW,KAAK,CAAC,CAAA;AAErB,EAAA,MAAM,GAAA,GAAM,CAAC,CAAC,IAAA,KAAS,KAAK,MAAA,CAAO,OAAA,IAAW,KAAK,SAAA,CAAU,OAAA,CAAA;AAE7D,EAAA;AAAA;AAAA;AAAA,oBAGEkB,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sBAAA,EACb,QAAA,EAAA;AAAA,sBAAAC,cAAA;AAAA,QAAC,aAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAM,qBAAA;AAAA,UACN,WAAA,EAAY,sEAAA;AAAA,UACZ,IAAA,EAAK,YAAA;AAAA,UACL,YAAA,EAAc,YAAA;AAAA,UACd,IAAA,EAAM,MAAM,SAAA,GAAY,SAAA;AAAA,UAExB,QAAA,kBAAAD,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,WAAA,EACb,QAAA,EAAA;AAAA,4BAAAC,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,sFAAA,EAAuF,QAAA,EAAA,qBAAA,EAEpG,CAAA;AAAA,YACC,KAAA,IAAU,CAAC,OAAA,IAAW,CAAC,uBACtBA,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,mCAAA,EAAoC,QAAA,EAAA,wCAAA,EAEjD,CAAA,mBAEAD,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,qBAAA,EACb,QAAA,EAAA;AAAA,8BAAAC,cAAA;AAAA,gBAAC,OAAA;AAAA,gBAAA;AAAA,kBACC,KAAA,EAAM,YAAA;AAAA,kBACN,OAAA,EAAS,MAAM,MAAA,IAAU,IAAA;AAAA,kBACzB,OAAA;AAAA,kBACA,OAAA,EAAS,YAAA,CAAa,gBAAA,EAAkB,KAAK,CAAA;AAAA,kBAC7C,QAAA,EAAS;AAAA;AAAA,eACX;AAAA,8BACAA,cAAA;AAAA,gBAAC,OAAA;AAAA,gBAAA;AAAA,kBACC,KAAA,EAAM,iBAAA;AAAA,kBACN,OAAA,EAAS,MAAM,SAAA,IAAa,IAAA;AAAA,kBAC5B,OAAA;AAAA,kBACA,OAAA,EAAS,YAAA,CAAa,gBAAA,EAAkB,KAAK,CAAA;AAAA,kBAC7C,QAAA,EAAS;AAAA;AAAA;AACX,aAAA,EACF;AAAA,WAAA,EAEJ;AAAA;AAAA,OACF;AAAA,sBACAA,cAAA,CAAC,WAAA,EAAA,EAAY,OAAA,EAAS,GAAA,EAAK,KAAA,EAAc;AAAA,KAAA,EAC3C;AAAA;AAEJ;AAcA,SAAS,cAAc,KAAA,EAA8B;AACnD,EAAA,OAAO,CAAA,4BAAA,EAA+B,SAAS,MAAM,CAAA,CAAA;AACvD;AAEA,SAAS,eAAe,KAAA,EAAkC;AACxD,EAAA,MAAM,KAAA,GAAoB,EAAE,YAAA,EAAc,IAAI,UAAA,EAAY,IAAA,EAAM,eAAA,EAAiB,EAAC,EAAE;AACpF,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,KAAA;AAC1C,EAAA,IAAI;AACF,IAAA,MAAM,MAAM,MAAA,CAAO,YAAA,CAAa,OAAA,CAAQ,aAAA,CAAc,KAAK,CAAC,CAAA;AAC5D,IAAA,IAAI,CAAC,KAAK,OAAO,KAAA;AACjB,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC7B,IAAA,OAAO;AAAA,MACL,YAAA,EAAc,KAAA,CAAM,OAAA,CAAQ,MAAA,EAAQ,YAAY,CAAA,GAC5C,MAAA,CAAO,YAAA,CAAa,MAAA,CAAO,CAAC,EAAA,KAAqB,OAAO,EAAA,KAAO,QAAQ,IACvE,EAAC;AAAA,MACL,YAAY,OAAO,MAAA,EAAQ,UAAA,KAAe,QAAA,GAAW,OAAO,UAAA,GAAa,IAAA;AAAA,MACzE,eAAA,EAAiB,KAAA,CAAM,OAAA,CAAQ,MAAA,EAAQ,eAAe,CAAA,GAClD,MAAA,CAAO,eAAA,CAAgB,MAAA,CAAO,CAAC,EAAA,KAAqB,OAAO,EAAA,KAAO,QAAQ,IAC1E;AAAC,KACP;AAAA,EACF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAEA,SAAS,eAAA,CAAgB,OAAsB,KAAA,EAAyB;AACtE,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACnC,EAAA,IAAI;AACF,IAAA,MAAA,CAAO,YAAA,CAAa,QAAQ,aAAA,CAAc,KAAK,GAAG,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC,CAAA;AAAA,EACzE,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAEA,IAAM,sBAAA,GAAyB,2BAAA;AAG/B,SAAS,YAAY,GAAA,EAAqB;AACxC,EAAA,MAAM,MAAA,GAAS,GAAA,CAAI,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AACpC,EAAA,MAAM,GAAA,GAAM,MAAA,CAAO,MAAA,KAAW,EAAA,IAAM,MAAA,CAAO,UAAA,CAAW,GAAG,CAAA,GAAI,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA,GAAI,MAAA;AAC/E,EAAA,IAAI,GAAA,CAAI,WAAW,EAAA,EAAI,OAAO,IAAI,GAAA,CAAI,KAAA,CAAM,GAAG,CAAC,CAAC,KAAK,GAAA,CAAI,KAAA,CAAM,GAAG,CAAC,CAAC,IAAI,GAAA,CAAI,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AACrF,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,SAAA,CAAU,EAAE,GAAA,EAAI,EAAsC;AAC7D,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,OAAA,IAAW,IAAA,GAAO,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,GAAA,EAAK,GAAA,CAAI,OAAO,CAAC,CAAA;AAC/E,EAAA,uBACED,eAAA,CAAAK,mBAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAAL,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,yCAAA,EACb,QAAA,EAAA;AAAA,sBAAAC,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iDAAA,EAAmD,QAAA,EAAA,GAAA,CAAI,KAAA,EAAM,CAAA;AAAA,MAC5E,GAAA,IAAO,IAAA,mBACND,eAAA,CAAC,MAAA,EAAA,EAAK,WAAU,yDAAA,EACb,QAAA,EAAA;AAAA,QAAA,IAAA,CAAK,MAAM,GAAG,CAAA;AAAA,QAAE;AAAA,OAAA,EACnB,CAAA,GACE;AAAA,KAAA,EACN,CAAA;AAAA,IACC,GAAA,IAAO,IAAA,mBACNC,cAAA,CAAC,KAAA,EAAA,EAAI,WAAU,sEAAA,EACb,QAAA,kBAAAA,cAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAU,yEAAA;AAAA,QACV,KAAA,EAAO,EAAE,KAAA,EAAO,CAAA,EAAG,GAAG,CAAA,CAAA,CAAA;AAAI;AAAA,OAE9B,CAAA,GACE;AAAA,GAAA,EACN,CAAA;AAEJ;AAQA,SAAS,aAAA,CAAc;AAAA,EACrB,KAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA,GAAQ;AACV,CAAA,EAKG;AACD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIpB,eAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,UAAA,GAAauB,aAAO,OAAO,CAAA;AACjC,EAAA,UAAA,CAAW,OAAA,GAAU,OAAA;AAErB,EAAAtB,gBAAU,MAAM;AACd,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,QAAQ,GAAG,CAAA;AACtC,IAAA,MAAM,KAAK,MAAA,CAAO,UAAA,CAAW,MAAM,UAAA,CAAW,KAAK,GAAG,MAAM,CAAA;AAC5D,IAAA,MAAM,KAAK,MAAA,CAAO,UAAA,CAAW,MAAM,UAAA,CAAW,OAAA,IAAW,KAAK,CAAA;AAC9D,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,aAAa,EAAE,CAAA;AACtB,MAAA,MAAA,CAAO,aAAa,EAAE,CAAA;AAAA,IACxB,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEV,EAAA,MAAM,WAAW,MAAM;AACrB,IAAA,UAAA,CAAW,KAAK,CAAA;AAChB,IAAA,UAAA,EAAW;AAAA,EACb,CAAA;AAEA,EAAA,uBACEkB,eAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,QAAA;AAAA,MACL,QAAA,EAAU,CAAA;AAAA,MACV,YAAA,EAAW,gBAAA;AAAA,MACX,OAAA,EAAS,QAAA;AAAA,MACT,SAAA,EAAW,CAAC,CAAA,KAAM;AAChB,QAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,OAAA,IAAW,CAAA,CAAE,QAAQ,GAAA,EAAK;AACtC,UAAA,CAAA,CAAE,cAAA,EAAe;AACjB,UAAA,QAAA,EAAS;AAAA,QACX;AAAA,MACF,CAAA;AAAA,MACA,SAAA,EAAU,sKAAA;AAAA,MACV,KAAA,EAAO;AAAA,QACL,OAAA,EAAS,UAAU,CAAA,GAAI,CAAA;AAAA,QACvB,SAAA,EAAW,UAAU,iBAAA,GAAoB,kBAAA;AAAA,QACzC,UAAA,EAAY;AAAA,OACd;AAAA,MAGA,QAAA,EAAA;AAAA,wBAAAC,cAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,aAAA,EAAW,IAAA;AAAA,YACX,SAAA,EAAU;AAAA;AAAA,SACZ;AAAA,wBACAA,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,gCAAA,EAAkC,gBAAM,IAAA,EAAK,CAAA;AAAA,wBAC1DA,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,kCAAA,EAAoC,gBAAM,OAAA,EAAQ;AAAA;AAAA;AAAA,GACjE;AAEJ;AAEO,SAAS,mBAAA,CAAoB,EAAE,KAAA,EAAM,EAA6B;AACvE,EAAA,MAAM,EAAE,SAAA,EAAU,GAAI,YAAA,CAAa,qBAAqB,CAAA;AACxD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIpB,eAA4C,IAAI,CAAA;AAC9E,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIA,eAAS,IAAI,CAAA;AAC3C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,eAAS,KAAK,CAAA;AACxC,EAAA,MAAM,CAAC,OAAO,QAAQ,CAAA,GAAIA,eAAqB,MAAM,cAAA,CAAe,KAAK,CAAC,CAAA;AAC1E,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAIA,eAAyC,IAAI,CAAA;AACjF,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIA,eAAS,CAAC,CAAA;AAC5C,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIA,eAAS,KAAK,CAAA;AAGhD,EAAA,MAAM,eAAe,qBAAA,EAAsB;AAG3C,EAAAC,gBAAU,MAAM;AACd,IAAA,QAAA,CAAS,cAAA,CAAe,KAAK,CAAC,CAAA;AAC9B,IAAA,aAAA,CAAc,IAAI,CAAA;AAAA,EACpB,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEV,EAAAA,gBAAU,MAAM;AACd,IAAA,IAAI,SAAA,GAAY,KAAA;AAChB,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,QAAA,CAAS,KAAK,CAAA;AACd,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,SAAA,CAAU,eAAA,EAAiB;AAAA,MACzB,OAAA,EAAS,KAAA,GAAQ,EAAE,gBAAA,EAAkB,OAAM,GAAI;AAAA,KAChD,CAAA,CACE,IAAA,CAAK,CAAC,IAAA,KAAS;AACd,MAAA,IAAI,CAAC,SAAA,EAAW,UAAA,CAAW,IAAkC,CAAA;AAAA,IAC/D,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AACX,MAAA,IAAI,CAAC,SAAA,EAAW,QAAA,CAAS,IAAI,CAAA;AAAA,IAC/B,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM;AACb,MAAA,IAAI,CAAC,SAAA,EAAW,UAAA,CAAW,KAAK,CAAA;AAAA,IAClC,CAAC,CAAA;AACH,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AAAA,IACd,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,SAAA,EAAW,KAAK,CAAC,CAAA;AAKrB,EAAAA,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,IAAW,OAAO,MAAA,KAAW,WAAA,EAAa;AAC/C,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,MAAA,CAAO,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,IAAA,KAAS,oBAAA,IAAwB,CAAA,CAAE,IAAI,CAAA;AAClF,IAAA,IAAI,CAAC,OAAO,IAAA,EAAM;AAClB,IAAA,IAAI;AACF,MAAA,IAAI,MAAA,CAAO,cAAA,CAAe,OAAA,CAAQ,sBAAsB,MAAM,GAAA,EAAK;AAAA,IACrE,CAAA,CAAA,MAAQ;AACN,MAAA;AAAA,IACF;AACA,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAA,GAAS,IAAI,GAAA,CAAI,KAAA,CAAM,IAAA,EAAM,MAAA,CAAO,SAAS,IAAI,CAAA;AAAA,IACnD,CAAA,CAAA,MAAQ;AACN,MAAA;AAAA,IACF;AACA,IAAA,IAAI,MAAA,CAAO,MAAA,KAAW,MAAA,CAAO,QAAA,CAAS,MAAA,EAAQ;AAC9C,IAAA,IAAI;AACF,MAAA,MAAA,CAAO,cAAA,CAAe,OAAA,CAAQ,sBAAA,EAAwB,GAAG,CAAA;AAAA,IAC3D,CAAA,CAAA,MAAQ;AAAA,IAER;AACA,IAAA,MAAA,CAAO,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA;AAAA,EACnC,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAEZ,EAAA,MAAM,QAAA,GAAWwB,iBAAA;AAAA,IACf,CAAC,EAAA,KAAe;AACd,MAAA,QAAA,CAAS,CAAC,IAAA,KAAS;AACjB,QAAA,IAAI,IAAA,CAAK,YAAA,CAAa,QAAA,CAAS,EAAE,GAAG,OAAO,IAAA;AAC3C,QAAA,MAAM,IAAA,GAAO,EAAE,GAAG,IAAA,EAAM,YAAA,EAAc,CAAC,GAAG,IAAA,CAAK,YAAA,EAAc,EAAE,CAAA,EAAE;AACjE,QAAA,eAAA,CAAgB,OAAO,IAAI,CAAA;AAC3B,QAAA,OAAO,IAAA;AAAA,MACT,CAAC,CAAA;AAAA,IACH,CAAA;AAAA,IACA,CAAC,KAAK;AAAA,GACR;AAEA,EAAA,MAAM,UAAA,GAAaA,iBAAA;AAAA,IACjB,CAAC,EAAA,KAAe;AACd,MAAA,QAAA,CAAS,CAAC,IAAA,KAAS;AACjB,QAAA,IAAI,CAAC,IAAA,CAAK,YAAA,CAAa,QAAA,CAAS,EAAE,GAAG,OAAO,IAAA;AAC5C,QAAA,MAAM,IAAA,GAAO,EAAE,GAAG,IAAA,EAAM,YAAA,EAAc,IAAA,CAAK,YAAA,CAAa,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,KAAM,EAAE,CAAA,EAAE;AAChF,QAAA,eAAA,CAAgB,OAAO,IAAI,CAAA;AAC3B,QAAA,OAAO,IAAA;AAAA,MACT,CAAC,CAAA;AAAA,IACH,CAAA;AAAA,IACA,CAAC,KAAK;AAAA,GACR;AAGA,EAAA,MAAM,MAAA,GAASA,kBAAY,MAAM;AAG/B,IAAA,aAAA,CAAc,IAAI,CAAA;AAClB,IAAA,QAAA,CAAS,CAAC,IAAA,KAAS;AACjB,MAAA,MAAM,IAAA,GAAO,EAAE,GAAG,IAAA,EAAM,6BAAY,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY,EAAE;AAC7D,MAAA,eAAA,CAAgB,OAAO,IAAI,CAAA;AAC3B,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEV,EAAA,MAAM,MAAA,GAAS,OAAA,EAAS,MAAA,IAAU,EAAC;AACnC,EAAA,MAAM,OAAA,GAAU,OAAA,EAAS,OAAA,IAAW,EAAC;AACrC,EAAA,MAAM,OAAA,GAAU,OAAA,EAAS,OAAA,IAAW,EAAC;AACrC,EAAA,MAAM,WAAA,GAAc,OAAA,EAAS,WAAA,IAAe,EAAC;AAK7C,EAAAxB,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,IAAW,UAAA,IAAc,SAAA,EAAW;AACzC,IAAA,MAAM,SAAA,GAAY,OAAA,CACf,MAAA,CAAO,CAAC,CAAA,KAAM;AACb,MAAA,IAAI,CAAC,CAAA,CAAE,SAAA,EAAW,OAAO,KAAA;AACzB,MAAA,IAAI,MAAM,UAAA,IAAc,CAAA,CAAE,SAAA,IAAa,KAAA,CAAM,YAAY,OAAO,KAAA;AAChE,MAAA,OAAO,CAAC,KAAA,CAAM,eAAA,CAAgB,QAAA,CAAS,EAAE,EAAE,CAAA;AAAA,IAC7C,CAAC,CAAA,CACA,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAO,CAAA,CAAE,SAAA,GAAa,CAAA,CAAE,SAAA,GAAa,CAAA,GAAI,EAAG,EAAE,CAAC,CAAA;AAC3D,IAAA,IAAI,CAAC,SAAA,EAAW;AAChB,IAAA,aAAA,CAAc,SAAS,CAAA;AACvB,IAAA,QAAA,CAAS,CAAC,IAAA,KAAS;AACjB,MAAA,MAAM,IAAA,GAAO;AAAA,QACX,GAAG,IAAA;AAAA,QACH,eAAA,EAAiB,CAAC,SAAA,CAAU,EAAA,EAAI,GAAG,KAAK,eAAe,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,EAAE;AAAA,OACtE;AACA,MAAA,eAAA,CAAgB,OAAO,IAAI,CAAA;AAC3B,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH,CAAA,EAAG,CAAC,OAAA,EAAS,OAAA,EAAS,UAAA,EAAY,SAAA,EAAW,KAAA,CAAM,UAAA,EAAY,KAAA,CAAM,eAAA,EAAiB,KAAK,CAAC,CAAA;AAI5F,EAAA,MAAM,eAAA,GAAkBwB,kBAAY,MAAM;AACxC,IAAA,MAAM,OAAO,UAAA,EAAY,IAAA;AACzB,IAAA,aAAA,CAAc,IAAI,CAAA;AAClB,IAAA,IAAI,IAAA,IAAQ,OAAO,MAAA,KAAW,WAAA,EAAa;AACzC,MAAA,MAAA,CAAO,QAAA,CAAS,OAAO,IAAI,CAAA;AAC3B,MAAA;AAAA,IACF;AACA,IAAA,YAAA,CAAa,CAAC,CAAA,KAAM,CAAA,GAAI,CAAC,CAAA;AAAA,EAC3B,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AAIf,EAAA,MAAM,gBAAA,GAAmB,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,KAAA,CAAM,YAAA,CAAa,QAAA,CAAS,CAAA,CAAE,EAAE,CAAC,CAAA,CAAE,MAAA;AAClF,EAAA,MAAM,gBAAA,GAAmB,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM;AAC7C,IAAA,IAAI,CAAC,KAAA,CAAM,UAAA,EAAY,OAAO,IAAA;AAC9B,IAAA,IAAI,CAAC,CAAA,CAAE,SAAA,EAAW,OAAO,KAAA;AACzB,IAAA,OAAO,CAAA,CAAE,YAAY,KAAA,CAAM,UAAA;AAAA,EAC7B,CAAC,CAAA,CAAE,MAAA;AACH,EAAA,MAAM,aAAa,gBAAA,GAAmB,gBAAA;AAEtC,EAAA,MAAM,OAAA,GACJ,MAAA,CAAO,MAAA,KAAW,CAAA,IAAK,OAAA,CAAQ,MAAA,KAAW,CAAA,IAAK,OAAA,CAAQ,MAAA,KAAW,CAAA,IAAK,WAAA,CAAY,MAAA,KAAW,CAAA;AAEhG,EAAA;AAAA;AAAA;AAAA,oBAGEN,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sBAAA,EACf,QAAA,EAAA;AAAA,sBAAAC,cAAA;AAAA,QAAC,aAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAM,wBAAA;AAAA,UACN,WAAA,EAAY,gEAAA;AAAA,UACZ,IAAA,EAAK,eAAA;AAAA,UACL,YAAA,EAAc,SAAA;AAAA,UACd,KAAA,EAAO,UAAU,CAAA,GAAI,UAAA;AAAA,UACrB,MAAA;AAAA,UACA,SAAA;AAAA,UACA,YAAA,EAAc,YAAA;AAAA,UAEd,QAAA,kBAAAD,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,WAAA,EACb,QAAA,EAAA;AAAA,4BAAAC,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,sFAAA,EAAuF,QAAA,EAAA,eAAA,EAEpG,CAAA;AAAA,YACC,OAAA,mBACCD,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,0BAAA,EACb,QAAA,EAAA;AAAA,8BAAAC,cAAA,CAAC,aAAA,EAAA,EAAc,WAAU,YAAA,EAAa,CAAA;AAAA,8BACtCA,cAAA,CAAC,aAAA,EAAA,EAAc,SAAA,EAAU,WAAA,EAAY;AAAA,aAAA,EACvC,IACE,KAAA,mBACFA,cAAA,CAAC,OAAE,SAAA,EAAU,mCAAA,EAAoC,sDAEjD,CAAA,GACE,OAAA,mBACFA,cAAA,CAAC,GAAA,EAAA,EAAE,WAAU,wCAAA,EAAyC,QAAA,EAAA,4BAAA,EAA2B,oBAEjFD,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,8CAAA,EAEZ,QAAA,EAAA;AAAA,cAAA,MAAA,CAAO,MAAA,GAAS,KAAK,OAAA,CAAQ,MAAA,GAAS,oBACrCA,eAAA,CAAC,IAAA,EAAA,EAAG,WAAU,qBAAA,EACX,QAAA,EAAA;AAAA,gBAAA,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM;AACjB,kBAAA,MAAM,MAAA,GAAS,KAAA,CAAM,YAAA,CAAa,QAAA,CAAS,EAAE,EAAE,CAAA;AAC/C,kBAAA,uBACEC,cAAA,CAAC,QAAc,SAAA,EAAW,MAAA,GAAS,eAAe,MAAA,EAChD,QAAA,kBAAAD,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2EAAA,EACb,QAAA,EAAA;AAAA,oCAAAA,eAAA;AAAA,sBAAC,GAAA;AAAA,sBAAA;AAAA,wBACC,IAAA,EAAM,EAAE,IAAA,IAAQ,GAAA;AAAA,wBAChB,OAAA,EAAS,MAAM,QAAA,CAAS,CAAA,CAAE,EAAE,CAAA;AAAA,wBAC5B,SAAA,EAAU,sBAAA;AAAA,wBAEV,QAAA,EAAA;AAAA,0CAAAC,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,sDAAA,EACV,QAAA,EAAA,CAAA,CAAE,KAAA,EACL,CAAA;AAAA,0CACAA,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,mCAAA,EAAqC,YAAE,WAAA,EAAY;AAAA;AAAA;AAAA,qBAClE;AAAA,oCACAA,cAAA;AAAA,sBAAC,QAAA;AAAA,sBAAA;AAAA,wBACC,IAAA,EAAK,QAAA;AAAA,wBACL,YAAA,EAAY,SAAS,gBAAA,GAAmB,cAAA;AAAA,wBACxC,OAAA,EAAS,MAAO,MAAA,GAAS,UAAA,CAAW,EAAE,EAAE,CAAA,GAAI,QAAA,CAAS,CAAA,CAAE,EAAE,CAAA;AAAA,wBACzD,SAAA,EAAU,wLAAA;AAAA,wBAEV,yCAAC,UAAA,EAAA,EAAW;AAAA;AAAA;AACd,mBAAA,EACF,CAAA,EAAA,EApBO,EAAE,EAqBX,CAAA;AAAA,gBAEJ,CAAC,CAAA;AAAA,gBACA,QAAQ,GAAA,CAAI,CAAC,sBACZD,eAAA,CAAC,IAAA,EAAA,EAAc,WAAU,oDAAA,EACvB,QAAA,EAAA;AAAA,kCAAAC,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,sDAAA,EAAwD,QAAA,EAAA,CAAA,CAAE,IAAA,EAAK,CAAA;AAAA,kCAC5EA,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,4CAAA,EAA8C,YAAE,OAAA,EAAQ;AAAA,iBAAA,EAAA,EAF9D,CAAA,CAAE,EAGX,CACD;AAAA,eAAA,EACH,CAAA,GACE,IAAA;AAAA,cAGH,OAAA,CAAQ,MAAA,GAAS,CAAA,mBAChBD,eAAA,CAAC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,gCAAAC,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,2FAAA,EAA4F,QAAA,EAAA,SAAA,EAEzG,CAAA;AAAA,gCACAA,cAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,qBAAA,EACX,kBAAQ,GAAA,CAAI,CAAC,GAAA,qBACZA,cAAA,CAAC,IAAA,EAAA,EAAgB,SAAA,EAAU,oDAAA,EACxB,QAAA,EAAA,GAAA,CAAI,uBACHA,cAAA,CAAC,GAAA,EAAA,EAAE,IAAA,EAAM,GAAA,CAAI,IAAA,EAAM,SAAA,EAAU,OAAA,EAC3B,QAAA,kBAAAA,cAAA,CAAC,aAAU,GAAA,EAAU,CAAA,EACvB,CAAA,mBAEAA,cAAA,CAAC,aAAU,GAAA,EAAU,CAAA,EAAA,EANhB,GAAA,CAAI,EAQb,CACD,CAAA,EACH;AAAA,eAAA,EACF,CAAA,GACE,IAAA;AAAA,cAGH,WAAA,CAAY,MAAA,GAAS,CAAA,mBACpBD,eAAA,CAAC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,gCAAAA,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,6CAAA,EACb,QAAA,EAAA;AAAA,kCAAAC,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,iFAAA,EAAkF,QAAA,EAAA,sBAAA,EAE/F,CAAA;AAAA,kCACAA,cAAA;AAAA,oBAAC,GAAA;AAAA,oBAAA;AAAA,sBACC,IAAA,EAAM,YAAA,CAAa,wBAAA,EAA0B,KAAK,CAAA;AAAA,sBAClD,SAAA,EAAU,8EAAA;AAAA,sBACX,QAAA,EAAA;AAAA;AAAA;AAED,iBAAA,EACF,CAAA;AAAA,gCACAA,cAAA,CAAC,QAAG,SAAA,EAAU,qBAAA,EASX,sBAAY,GAAA,CAAI,CAAC,CAAA,qBAChBA,cAAA,CAAC,IAAA,EAAA,EACC,QAAA,kBAAAD,eAAA;AAAA,kBAAC,GAAA;AAAA,kBAAA;AAAA,oBACC,MAAM,cAAA,CAAe,YAAA,CAAa,0BAA0B,KAAK,CAAA,EAAG,EAAE,KAAK,CAAA;AAAA,oBAC3E,YAAA,EAAY,CAAA,OAAA,EAAU,CAAA,CAAE,KAAK,uBAAuB,CAAA,CAAE,KAAA,KAAU,CAAA,GAAI,EAAA,GAAK,GAAG,CAAA,MAAA,EAAS,WAAA,CAAY,CAAA,CAAE,KAAK,CAAC,CAAA,CAAA;AAAA,oBACzG,SAAA,EAAU,8MAAA;AAAA,oBAEV,QAAA,EAAA;AAAA,sCAAAA,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,yCAAA,EACb,QAAA,EAAA;AAAA,wCAAAC,cAAA,CAAC,UAAK,SAAA,EAAU,sDAAA,EACb,QAAA,EAAA,WAAA,CAAY,CAAA,CAAE,KAAK,CAAA,EACtB,CAAA;AAAA,wCAKAA,cAAA,CAAC,UAAK,SAAA,EAAU,oKAAA,EACb,YAAE,KAAA,GAAQ,EAAA,GAAK,KAAA,GAAQ,CAAA,CAAE,KAAA,EAC5B;AAAA,uBAAA,EACF,CAAA;AAAA,sBACC,CAAA,CAAE,QAAA,mBACDA,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,mCAAA,EACV,QAAA,EAAA,IAAI,IAAA,CAAK,CAAA,CAAE,QAAQ,CAAA,CAAE,cAAA,IACxB,CAAA,GACE;AAAA;AAAA;AAAA,iBACN,EAAA,EAvBO,CAAA,CAAE,KAwBX,CACD,CAAA,EACH;AAAA,eAAA,EACF,CAAA,GACE;AAAA,aAAA,EACN;AAAA,WAAA,EAEJ;AAAA;AAAA,OACF;AAAA,MAIC,UAAA,IAAc,CAAC,SAAA,IAAa,CAAC,YAAA,mBAC5BA,cAAA;AAAA,QAAC,aAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAO,UAAA;AAAA,UACP,UAAA,EAAY,eAAA;AAAA,UACZ,OAAA,EAAS,MAAM,aAAA,CAAc,IAAI;AAAA;AAAA,OACnC,GACE;AAAA,KAAA,EACJ;AAAA;AAEJ;AAaA,SAAS,sBAAsB,KAAA,EAOpB;AACT,EAAA,MAAM,GAAA,GAAM,CAAC,CAAA,MAAA,EAAS,KAAA,CAAM,SAAA,IAAa,SAAS,CAAA,CAAA,EAAI,CAAA,KAAA,EAAQ,KAAA,CAAM,GAAG,CAAA,CAAE,CAAA;AACzE,EAAA,IAAI,MAAM,OAAA,EAAS,GAAA,CAAI,KAAK,CAAA,KAAA,EAAQ,KAAA,CAAM,OAAO,CAAA,CAAE,CAAA;AACnD,EAAA,MAAM,KAAA,GAAQ,CAAC,KAAA,CAAM,UAAA,EAAY,MAAK,EAAG,KAAA,CAAM,UAAA,EAAY,IAAA,EAAM,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,KAAK,KAAK,CAAA;AAC7F,EAAA,IAAI,KAAA,EAAO,GAAA,CAAI,IAAA,CAAK,CAAA,UAAA,EAAa,KAAK,CAAA,CAAE,CAAA;AACxC,EAAA,OAAO,CAAA,EAAG,KAAA,CAAM,IAAA,CAAK,IAAA,EAAM;;AAAA;AAAA,EAAY,GAAA,CAAI,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA;AACvD;AAEO,SAAS,aAAA,CAAc,EAAE,KAAA,EAAM,GAA+B,EAAC,EAAG;AACvE,EAAA,MAAM,EAAE,SAAA,EAAU,GAAI,YAAA,CAAa,eAAe,CAAA;AAClD,EAAA,MAAM,EAAE,EAAA,EAAI,MAAA,EAAO,GAAI,WAAA,EAAY;AACnC,EAAA,MAAM,EAAE,IAAA,EAAK,GAAI,aAAA,EAAc;AAC/B,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIpB,eAAS,KAAK,CAAA;AACtC,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIA,eAAS,EAAE,CAAA;AACzC,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,eAAS,EAAE,CAAA;AACrC,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,eAAS,EAAE,CAAA;AACrC,EAAA,MAAM,CAAC,cAAA,EAAgB,iBAAiB,CAAA,GAAIA,eAAS,KAAK,CAAA;AAC1D,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,eAAgD,MAAM,CAAA;AAIhF,EAAA,MAAM,OAAA,GAAU,IAAI,KAAA,IAAS,IAAA;AAC7B,EAAA,MAAM,OAAA,GAAU,IAAI,KAAA,IAAS,IAAA;AAC7B,EAAA,MAAM,YAAA,GAAe,UAAU,CAAC,OAAA;AAChC,EAAA,MAAM,YAAA,GAAe,UAAU,CAAC,OAAA;AAEhC,EAAA,MAAM,aACH,KAAA,GAAQ,IAAA,EAAM,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,EAAA,KAAO,KAAK,CAAA,GAAI,UAC5C,IAAA,IAAQ,IAAA,CAAK,WAAW,CAAA,GAAI,IAAA,CAAK,CAAC,CAAA,GAAI,IAAA,CAAA;AACzC,EAAA,MAAM,OAAA,GAAU,WAAW,IAAA,IAAQ,IAAA;AAEnC,EAAA,MAAM,KAAA,GAAQyB,kBAAY,MAAM;AAC9B,IAAA,OAAA,CAAQ,KAAK,CAAA;AACb,IAAA,QAAA,CAAS,MAAM,CAAA;AACf,IAAA,UAAA,CAAW,EAAE,CAAA;AACb,IAAA,iBAAA,CAAkB,KAAK,CAAA;AAAA,EACzB,CAAA,EAAG,EAAE,CAAA;AAGL,EAAAxB,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,QAAA,CAAS,WAAW,EAAE,CAAA;AACtB,IAAA,QAAA,CAAS,WAAW,EAAE,CAAA;AACtB,IAAA,iBAAA,CAAkB,KAAK,CAAA;AAAA,EACzB,CAAA,EAAG,CAAC,IAAA,EAAM,OAAA,EAAS,OAAO,CAAC,CAAA;AAE3B,EAAAA,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,MAAM,KAAA,GAAQ,CAAC,CAAA,KAAqB;AAClC,MAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,QAAA,EAAU,KAAA,EAAM;AAAA,IAChC,CAAA;AACA,IAAA,QAAA,CAAS,gBAAA,CAAiB,WAAW,KAAK,CAAA;AAC1C,IAAA,OAAO,MAAM,QAAA,CAAS,mBAAA,CAAoB,SAAA,EAAW,KAAK,CAAA;AAAA,EAC5D,CAAA,EAAG,CAAC,IAAA,EAAM,KAAK,CAAC,CAAA;AAEhB,EAAA,MAAM,SAAS,YAAY;AACzB,IAAA,IAAI,CAAC,OAAA,CAAQ,IAAA,EAAK,IAAK,UAAU,SAAA,EAAW;AAE5C,IAAA,MAAM,aAAA,GAAA,CAAiB,YAAA,GAAe,KAAA,GAAQ,OAAA,IAAW,IAAI,IAAA,EAAK;AAClE,IAAA,MAAM,aAAA,GAAA,CAAiB,YAAA,GAAe,KAAA,GAAQ,OAAA,IAAW,IAAI,IAAA,EAAK;AAElE,IAAA,IAAI,YAAA,IAAgB,CAAC,aAAA,EAAe;AAClC,MAAA,iBAAA,CAAkB,IAAI,CAAA;AACtB,MAAA;AAAA,IACF;AACA,IAAA,iBAAA,CAAkB,KAAK,CAAA;AAEvB,IAAA,MAAM,mBAAmB,YAAA,IAAgB,YAAA;AACzC,IAAA,MAAM,cAAc,qBAAA,CAAsB;AAAA,MACxC,IAAA,EAAM,OAAA;AAAA,MACN,SAAA,EAAW,OAAO,QAAA,KAAa,WAAA,GAAc,SAAS,KAAA,GAAQ,EAAA;AAAA,MAC9D,KAAK,OAAO,MAAA,KAAW,WAAA,GAAc,MAAA,CAAO,SAAS,IAAA,GAAO,EAAA;AAAA,MAC5D,OAAA;AAAA,MACA,UAAA,EAAY,mBAAmB,aAAA,GAAgB,MAAA;AAAA,MAC/C,UAAA,EAAY,mBAAmB,aAAA,GAAgB;AAAA,KAChD,CAAA;AAED,IAAA,QAAA,CAAS,SAAS,CAAA;AAClB,IAAA,IAAI;AACF,MAAA,MAAM,UAAU,SAAA,EAAW;AAAA,QACzB,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,QAC9C,MAAM,IAAA,CAAK,SAAA,CAAU,EAAE,OAAA,EAAS,aAAa;AAAA,OAC9C,CAAA;AACD,MAAA,QAAA,CAAS,MAAM,CAAA;AAAA,IACjB,CAAA,CAAA,MAAQ;AACN,MAAA,QAAA,CAAS,OAAO,CAAA;AAAA,IAClB;AAAA,EACF,CAAA;AAEA,EAAA,uBACEkB,eAAA,CAAAK,mBAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAAL,eAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,YAAA,EAAW,SAAA;AAAA,QACX,WAAW,qBAAA,EAAsB;AAAA,QACjC,OAAA,EAAS,MAAM,OAAA,CAAQ,IAAI,CAAA;AAAA,QAE3B,QAAA,EAAA;AAAA,0BAAAC,cAAA,CAAC,SAAA,EAAA,EAAU,IAAA,EAAK,SAAA,EAAU,QAAA,EAAU,aAAA,EAAe,CAAA;AAAA,0BACnDA,cAAA;AAAA,YAAC,aAAA;AAAA,YAAA;AAAA,cACC,KAAA,EAAM,SAAA;AAAA,cACN,WAAA,EAAY;AAAA;AAAA;AACd;AAAA;AAAA,KACF;AAAA,IACC,IAAA,IAAQ,OAAO,QAAA,KAAa,WAAA,GACzBM,qBAAA;AAAA,sBACFN,cAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UAIC,SAAA,EAAU,qEAAA;AAAA,UACV,IAAA,EAAK,QAAA;AAAA,UACL,YAAA,EAAW,MAAA;AAAA,UACX,YAAA,EAAW,iBAAA;AAAA,UACX,WAAA,EAAa,CAAC,CAAA,KAAM;AAClB,YAAA,IAAI,CAAA,CAAE,MAAA,KAAW,CAAA,CAAE,aAAA,EAAe,KAAA,EAAM;AAAA,UAC1C,CAAA;AAAA,UAEA,QAAA,kBAAAD,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gIAAA,EACb,QAAA,EAAA;AAAA,4BAAAC,cAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,qEAAA,EAAsE,QAAA,EAAA,iBAAA,EAEpF,CAAA;AAAA,YACC,KAAA,KAAU,yBACTD,eAAA,CAAAK,mBAAA,EAAA,EACE,QAAA,EAAA;AAAA,8BAAAJ,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,wCAAA,EAAyC,QAAA,EAAA,sDAAA,EAEtD,CAAA;AAAA,8BACAA,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uBAAA,EACb,QAAA,kBAAAA,cAAA;AAAA,gBAAC,QAAA;AAAA,gBAAA;AAAA,kBACC,IAAA,EAAK,QAAA;AAAA,kBACL,OAAA,EAAS,KAAA;AAAA,kBACT,SAAA,EAAU,2GAAA;AAAA,kBACX,QAAA,EAAA;AAAA;AAAA,eAED,EACF;AAAA,aAAA,EACF,oBAEAD,eAAA,CAAAK,mBAAA,EAAA,EACE,QAAA,EAAA;AAAA,8BAAAJ,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,wCAAA,EAAyC,QAAA,EAAA,kFAAA,EAGtD,CAAA;AAAA,cACC,YAAA,mBACCD,eAAA,CAAC,OAAA,EAAA,EAAM,SAAA,EAAU,YAAA,EACf,QAAA,EAAA;AAAA,gCAAAC,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iEAAA,EAAkE,QAAA,EAAA,YAAA,EAElF,CAAA;AAAA,gCACAA,cAAA;AAAA,kBAAC,OAAA;AAAA,kBAAA;AAAA,oBACC,IAAA,EAAK,OAAA;AAAA,oBACL,KAAA,EAAO,KAAA;AAAA,oBACP,UAAU,CAAC,CAAA,KAAM,QAAA,CAAS,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,oBACxC,WAAA,EAAY,iBAAA;AAAA,oBACZ,SAAA,EAAU;AAAA;AAAA,iBACZ;AAAA,gBACC,iCACCA,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,uDAAA,EAAwD,kDAExE,CAAA,GACE;AAAA,eAAA,EACN,CAAA,GACE,IAAA;AAAA,cACH,YAAA,mBACCD,eAAA,CAAC,OAAA,EAAA,EAAM,SAAA,EAAU,YAAA,EACf,QAAA,EAAA;AAAA,gCAAAC,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iEAAA,EAAkE,QAAA,EAAA,4BAAA,EAElF,CAAA;AAAA,gCACAA,cAAA;AAAA,kBAAC,OAAA;AAAA,kBAAA;AAAA,oBACC,IAAA,EAAK,KAAA;AAAA,oBACL,KAAA,EAAO,KAAA;AAAA,oBACP,UAAU,CAAC,CAAA,KAAM,QAAA,CAAS,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,oBACxC,WAAA,EAAY,gBAAA;AAAA,oBACZ,SAAA,EAAU;AAAA;AAAA;AACZ,eAAA,EACF,CAAA,GACE,IAAA;AAAA,8BACJA,cAAA;AAAA,gBAAC,UAAA;AAAA,gBAAA;AAAA,kBACC,KAAA,EAAO,OAAA;AAAA,kBACP,UAAU,CAAC,CAAA,KAAM,UAAA,CAAW,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,kBAC1C,IAAA,EAAM,CAAA;AAAA,kBACN,WAAA,EAAY,kBAAA;AAAA,kBACZ,SAAA,EAAU;AAAA;AAAA,eACZ;AAAA,cACC,UAAU,OAAA,mBACTA,cAAA,CAAC,OAAE,SAAA,EAAU,iDAAA,EAAkD,8CAE/D,CAAA,GACE,IAAA;AAAA,8BACJD,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,6BAAA,EACb,QAAA,EAAA;AAAA,gCAAAC,cAAA;AAAA,kBAAC,QAAA;AAAA,kBAAA;AAAA,oBACC,IAAA,EAAK,QAAA;AAAA,oBACL,OAAA,EAAS,KAAA;AAAA,oBACT,SAAA,EAAU,6IAAA;AAAA,oBACX,QAAA,EAAA;AAAA;AAAA,iBAED;AAAA,gCACAA,cAAA;AAAA,kBAAC,QAAA;AAAA,kBAAA;AAAA,oBACC,IAAA,EAAK,QAAA;AAAA,oBACL,OAAA,EAAS,MAAA;AAAA,oBACT,QAAA,EAAU,CAAC,OAAA,CAAQ,IAAA,MAAU,KAAA,KAAU,SAAA;AAAA,oBACvC,SAAA,EAAU,sKAAA;AAAA,oBAET,QAAA,EAAA,KAAA,KAAU,YAAY,eAAA,GAAa;AAAA;AAAA;AACtC,eAAA,EACF;AAAA,aAAA,EACF;AAAA,WAAA,EAEJ;AAAA;AAAA,OACF;AAAA,MACA,QAAA,CAAS;AAAA,KACX,GACI;AAAA,GAAA,EACN,CAAA;AAEJ;AAUA,IAAM,mBAAA,GAAkE;AAAA,EACtE,EAAE,KAAA,EAAO,MAAA,EAAQ,KAAA,EAAO,UAAA,EAAW;AAAA,EACnC,EAAE,KAAA,EAAO,MAAA,EAAQ,KAAA,EAAO,WAAA,EAAY;AAAA,EACpC,EAAE,KAAA,EAAO,MAAA,EAAQ,KAAA,EAAO,MAAA;AAC1B,CAAA;AAEO,SAAS,gBAAA,CAAiB;AAAA,EAC/B,KAAA;AAAA,EACA;AACF,CAAA,EAGG;AACD,EAAA,uBACEA,cAAA;AAAA,IAAC,aAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAM,oBAAA;AAAA,MACN,WAAA,EAAY,+CAAA;AAAA,MACZ,YAAA,EAAc,WAAA;AAAA,MACd,cAAA,EAAe,MAAA;AAAA,MAEf,QAAA,kBAAAA,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,MAAA,EAAO,IAAA,EAAK,YAAA,EAAa,YAAA,EAAW,oBAAA,EAChD,QAAA,EAAA,mBAAA,CAAoB,GAAA,CAAI,CAAC,GAAA,qBACxBD,eAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UAEC,IAAA,EAAK,QAAA;AAAA,UACL,IAAA,EAAK,OAAA;AAAA,UACL,cAAA,EAAc,UAAU,GAAA,CAAI,KAAA;AAAA,UAC5B,OAAA,EAAS,MAAM,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA;AAAA,UACjC,SAAA,EAAW;AAAA,YACT,kFAAA;AAAA,YACA,KAAA,KAAU,GAAA,CAAI,KAAA,GACV,oCAAA,GACA;AAAA,WACN,CAAE,KAAK,GAAG,CAAA;AAAA,UAET,QAAA,EAAA;AAAA,YAAA,GAAA,CAAI,KAAA;AAAA,YACJ,KAAA,KAAU,IAAI,KAAA,mBAAQC,cAAA,CAAC,UAAK,aAAA,EAAW,IAAA,EAAC,oBAAC,CAAA,GAAU;AAAA;AAAA,SAAA;AAAA,QAb/C,GAAA,CAAI;AAAA,OAeZ,CAAA,EACH;AAAA;AAAA,GACF;AAEJ;AAiBO,SAAS,kBAAA,GAGd;AACA,EAAA,MAAM,GAAA,GAAME,iBAAW,gBAAgB,CAAA;AACvC,EAAA,MAAM,SAAA,GAAY,KAAK,SAAA,IAAa,IAAA;AACpC,EAAA,MAAM,CAAC,KAAA,EAAO,aAAa,CAAA,GAAItB,eAA0B,QAAQ,CAAA;AACjE,EAAA,MAAM,UAAA,GAAauB,aAAO,KAAK,CAAA;AAG/B,EAAAtB,gBAAU,MAAM;AACd,IAAA,MAAM,SAAS,eAAA,EAAgB;AAC/B,IAAA,IAAI,EAAA,GAAoB,IAAA;AACxB,IAAA,IAAI;AACF,MAAA,EAAA,GAAK,YAAA,CAAa,QAAQ,iBAAiB,CAAA;AAAA,IAC7C,CAAA,CAAA,MAAQ;AAAA,IAER;AACA,IAAA,MAAM,OAAO,MAAA,KAAW,iBAAA,CAAkB,EAAE,CAAA,GAAI,KAAK,IAAA,CAAA,IAAS,QAAA;AAC9D,IAAA,aAAA,CAAc,IAAI,CAAA;AAClB,IAAA,oBAAA,CAAqB,IAAI,CAAA;AAAA,EAC3B,CAAA,EAAG,EAAE,CAAA;AAIL,EAAA,MAAM,KAAA,GAAQqB,iBAAW,gBAAgB,CAAA;AACzC,EAAArB,gBAAU,MAAM;AACd,IAAA,IAAI,WAAW,OAAA,EAAS;AAMxB,IAAA,MAAM,UAAU,sBAAA,EAAuB;AACvC,IAAA,IAAI,OAAA,EAAS;AAGX,MAAA,IAAI,KAAA,EAAO,EAAA,EAAI,UAAA,CAAW,OAAA,GAAU,IAAA;AACpC,MAAA,aAAA,CAAc,OAAO,CAAA;AACrB,MAAA,oBAAA,CAAqB,OAAO,CAAA;AAC5B,MAAA,gBAAA,CAAiB,OAAO,CAAA;AACxB,MAAA,IAAI;AACF,QAAA,YAAA,CAAa,OAAA,CAAQ,mBAAmB,OAAO,CAAA;AAAA,MACjD,CAAA,CAAA,MAAQ;AAAA,MAER;AACA,MAAA,IAAI,CAAC,OAAO,EAAA,EAAI;AAChB,MAAA,SAAA,GAAY,gBAAA,EAAkB;AAAA,QAC5B,MAAA,EAAQ,OAAA;AAAA,QACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,QAC9C,MAAM,IAAA,CAAK,SAAA,CAAU,EAAE,eAAA,EAAiB,SAAS;AAAA,OAClD,EACE,IAAA,CAAK,MAAM,yBAAyB,CAAA,CACpC,MAAM,MAAM;AAAA,MAAC,CAAC,CAAA;AACjB,MAAA;AAAA,IACF;AACA,IAAA,MAAM,IAAA,GAAO,OAAO,EAAA,EAAI,eAAA;AACxB,IAAA,IAAI,iBAAA,CAAkB,IAAI,CAAA,EAAG;AAC3B,MAAA,UAAA,CAAW,OAAA,GAAU,IAAA;AACrB,MAAA,aAAA,CAAc,IAAI,CAAA;AAClB,MAAA,oBAAA,CAAqB,IAAI,CAAA;AACzB,MAAA,gBAAA,CAAiB,IAAI,CAAA;AACrB,MAAA,IAAI;AACF,QAAA,YAAA,CAAa,OAAA,CAAQ,mBAAmB,IAAI,CAAA;AAAA,MAC9C,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,CAAA,EAAG,CAAC,KAAA,EAAO,EAAE,CAAC,CAAA;AAId,EAAAA,gBAAU,MAAM;AACd,IAAA,MAAM,SAAA,GAAY,CAAC,CAAA,KAAoB;AACrC,MAAA,IAAI,EAAE,GAAA,KAAQ,iBAAA,IAAqB,iBAAA,CAAkB,CAAA,CAAE,QAAQ,CAAA,EAAG;AAChE,QAAA,aAAA,CAAc,EAAE,QAAQ,CAAA;AACxB,QAAA,oBAAA,CAAqB,EAAE,QAAQ,CAAA;AAAA,MACjC;AAAA,IACF,CAAA;AACA,IAAA,MAAM,SAAS,MAAM;AACnB,MAAA,MAAM,SAAS,eAAA,EAAgB;AAC/B,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,aAAA,CAAc,CAAC,IAAA,KAAS;AACtB,UAAA,IAAI,MAAA,KAAW,IAAA,EAAM,oBAAA,CAAqB,MAAM,CAAA;AAChD,UAAA,OAAO,MAAA;AAAA,QACT,CAAC,CAAA;AAAA,MACH;AAAA,IACF,CAAA;AACA,IAAA,MAAA,CAAO,gBAAA,CAAiB,WAAW,SAAS,CAAA;AAC5C,IAAA,MAAA,CAAO,gBAAA,CAAiB,SAAS,MAAM,CAAA;AACvC,IAAA,QAAA,CAAS,gBAAA,CAAiB,oBAAoB,MAAM,CAAA;AACpD,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,mBAAA,CAAoB,WAAW,SAAS,CAAA;AAC/C,MAAA,MAAA,CAAO,mBAAA,CAAoB,SAAS,MAAM,CAAA;AAC1C,MAAA,QAAA,CAAS,mBAAA,CAAoB,oBAAoB,MAAM,CAAA;AAAA,IACzD,CAAA;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAGL,EAAAA,gBAAU,MAAM;AACd,IAAA,IAAI,UAAU,QAAA,EAAU;AACxB,IAAA,IAAI,EAAA;AACJ,IAAA,IAAI;AACF,MAAA,EAAA,GAAK,MAAA,CAAO,WAAW,8BAA8B,CAAA;AAAA,IACvD,CAAA,CAAA,MAAQ;AACN,MAAA;AAAA,IACF;AACA,IAAA,MAAM,QAAA,GAAW,MAAM,oBAAA,CAAqB,QAAQ,CAAA;AACpD,IAAA,EAAA,CAAG,gBAAA,CAAiB,UAAU,QAAQ,CAAA;AACtC,IAAA,OAAO,MAAM,EAAA,CAAG,mBAAA,CAAoB,QAAA,EAAU,QAAQ,CAAA;AAAA,EACxD,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEV,EAAA,MAAM,QAAA,GAAWwB,iBAAA;AAAA,IACf,CAAC,IAAA,KAA0B;AACzB,MAAA,aAAA,CAAc,IAAI,CAAA;AAClB,MAAA,oBAAA,CAAqB,IAAI,CAAA;AACzB,MAAA,gBAAA,CAAiB,IAAI,CAAA;AACrB,MAAA,IAAI;AACF,QAAA,YAAA,CAAa,OAAA,CAAQ,mBAAmB,IAAI,CAAA;AAAA,MAC9C,CAAA,CAAA,MAAQ;AAAA,MAER;AAIA,MAAA,sBAAA,CAAuB,IAAI,CAAA;AAC3B,MAAA,SAAA,GAAY,gBAAA,EAAkB;AAAA,QAC5B,MAAA,EAAQ,OAAA;AAAA,QACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,QAC9C,MAAM,IAAA,CAAK,SAAA,CAAU,EAAE,eAAA,EAAiB,MAAM;AAAA,OAC/C,EACE,IAAA,CAAK,MAAM,yBAAyB,CAAA,CACpC,MAAM,MAAM;AAAA,MAAC,CAAC,CAAA;AAAA,IACnB,CAAA;AAAA,IACA,CAAC,SAAS;AAAA,GACZ;AAEA,EAAA,OAAO,EAAE,OAAO,QAAA,EAAS;AAC3B;;;ACtuDO,IAAM,6BAAA,GAA6D;AAAA,EACxE,GAAA,EAAK,IAAA;AAAA,EACL,SAAA,EAAW,IAAA;AAAA,EACX,OAAA,EAAS,IAAA;AAAA,EACT,KAAA,EAAO,IAAA;AAAA,EACP,MAAA,EAAQ,IAAA;AAAA,EACR,OAAA,EAAS;AACX,CAAA;AAGA,IAAM,UAAA,GAAa,8BAAA;AACnB,IAAM,gBAAA,GAAmB,oCAAA;AACzB,IAAM,cAAA,GAAiB,kCAAA;AACvB,IAAM,YAAA,GAAe,gCAAA;AACrB,IAAM,YAAA,GAAe,gCAAA;AAGrB,IAAM,eAAA,GAAkB,yCAAA;AAGxB,IAAM,oBAAA,GAAuB,wCAAA;AAkD7B,IAAM,yBAAA,GAAwC;AAAA,EAC5C,EAAE,KAAA,EAAO,WAAA,EAAa,IAAA,EAAM,MAAA,EAAQ,MAAM,kCAAA,EAAmC;AAAA,EAC7E,EAAE,KAAA,EAAO,cAAA,EAAgB,IAAA,EAAM,MAAA,EAAQ,MAAM,4BAAA,EAA6B;AAAA,EAC1E,EAAE,KAAA,EAAO,QAAA,EAAU,IAAA,EAAM,OAAA,EAAS,MAAM,+BAAA,EAAgC;AAAA,EACxE,EAAE,KAAA,EAAO,QAAA,EAAU,IAAA,EAAM,QAAA,EAAU,MAAM,+BAAA,EAAgC;AAAA,EACzE,EAAE,KAAA,EAAO,gBAAA,EAAkB,IAAA,EAAM,UAAA,EAAY,MAAM,uCAAA,EAAwC;AAAA,EAC3F,EAAE,KAAA,EAAO,aAAA,EAAe,IAAA,EAAM,QAAA,EAAU,MAAM,oCAAA;AAChD,CAAA;AAEA,IAAM,cAAA,GAA6B;AAAA,EACjC,EAAE,KAAA,EAAO,WAAA,EAAa,IAAA,EAAM,MAAA,EAAQ,MAAM,+BAAA,EAAgC;AAAA,EAC1E,EAAE,KAAA,EAAO,eAAA,EAAiB,IAAA,EAAM,MAAA,EAAQ,MAAM,qCAAA,EAAsC;AAAA,EACpF,EAAE,KAAA,EAAO,oBAAA,EAAsB,IAAA,EAAM,MAAA,EAAQ,MAAM,2BAAA,EAA4B;AAAA,EAC/E,EAAE,KAAA,EAAO,YAAA,EAAc,IAAA,EAAM,MAAA,EAAQ,MAAM,6BAAA,EAA8B;AAAA,EACzE,EAAE,KAAA,EAAO,iBAAA,EAAmB,IAAA,EAAM,OAAA,EAAS,MAAM,uCAAA,EAAwC;AAAA,EACzF,EAAE,KAAA,EAAO,YAAA,EAAc,IAAA,EAAM,UAAA,EAAY,MAAM,gCAAA;AACjD,CAAA;AAEA,IAAM,YAAA,GAA2B;AAAA,EAC/B,EAAE,KAAA,EAAO,WAAA,EAAa,IAAA,EAAM,MAAA,EAAQ,MAAM,uCAAA,EAAwC;AAAA,EAClF,EAAE,KAAA,EAAO,gBAAA,EAAkB,IAAA,EAAM,MAAA,EAAQ,MAAM,8CAAA,EAA+C;AAAA,EAC9F,EAAE,KAAA,EAAO,eAAA,EAAiB,IAAA,EAAM,eAAA,EAAiB,MAAM,2CAAA;AACzD,CAAA;AAEA,IAAM,YAAA,GAA2B;AAAA,EAC/B,EAAE,KAAA,EAAO,WAAA,EAAa,IAAA,EAAM,MAAA,EAAQ,MAAM,sCAAA,EAAuC;AAAA,EACjF,EAAE,KAAA,EAAO,eAAA,EAAiB,IAAA,EAAM,MAAA,EAAQ,MAAM,2CAAA,EAA4C;AAAA,EAC1F,EAAE,KAAA,EAAO,aAAA,EAAe,IAAA,EAAM,UAAA,EAAY,MAAM,2CAAA;AAClD,CAAA;AASA,IAAM,qBAAA,GAAsC;AAAA,EAC1C,EAAE,KAAA,EAAO,SAAA,EAAW,IAAA,EAAM,UAAA,EAAY,MAAM,wBAAA,EAAyB;AAAA,EACrE;AAAA,IACE,KAAA,EAAO,wBAAA;AAAA,IACP,IAAA,EAAM,YAAA;AAAA,IACN,IAAA,EAAM,6CAAA;AAAA,IACN,QAAA,EAAU;AAAA,MACR,EAAE,KAAA,EAAO,cAAA,EAAgB,IAAA,EAAM,UAAA,EAAY,MAAM,0DAAA,EAA2D;AAAA,MAC5G,EAAE,KAAA,EAAO,wBAAA,EAA0B,IAAA,EAAM,UAAA,EAAY,MAAM,wDAAA,EAAyD;AAAA,MACpH,EAAE,KAAA,EAAO,QAAA,EAAU,IAAA,EAAM,YAAA,EAAc,MAAM,oDAAA,EAAqD;AAAA,MAClG,EAAE,KAAA,EAAO,OAAA,EAAS,IAAA,EAAM,eAAA,EAAiB,MAAM,mDAAA,EAAoD;AAAA,MACnG,EAAE,KAAA,EAAO,iBAAA,EAAmB,IAAA,EAAM,OAAA,EAAS,MAAM,6DAAA;AAA8D;AACjH,GACF;AAAA,EACA,EAAE,KAAA,EAAO,OAAA,EAAS,IAAA,EAAM,MAAA,EAAQ,MAAM,uCAAA,EAAwC;AAAA,EAC9E,EAAE,KAAA,EAAO,OAAA,EAAS,IAAA,EAAM,OAAA,EAAS,MAAM,8BAAA,EAA+B;AAAA,EACtE,EAAE,KAAA,EAAO,cAAA,EAAgB,IAAA,EAAM,OAAA,EAAS,MAAM,qCAAA;AAChD,CAAA;AAMA,IAAM,kBAAA,GAAqB;AAAA,EACzB,EAAE,KAAA,EAAO,OAAA,EAAS,IAAA,EAAM,MAAA,EAAiB,MAAM,0CAAA,EAA2C;AAAA,EAC1F,EAAE,KAAA,EAAO,QAAA,EAAU,IAAA,EAAM,MAAA,EAAiB,MAAM,2CAAA,EAA4C;AAAA,EAC5F,EAAE,KAAA,EAAO,aAAA,EAAe,IAAA,EAAM,UAAA,EAAqB,MAAM,gDAAA;AAC3D,CAAA;AAMA,IAAM,oBAAA,GAAuB;AAAA,EAC3B,EAAE,KAAA,EAAO,SAAA,EAAW,IAAA,EAAM,MAAA,EAAiB,MAAM,yCAAA,EAA0C;AAAA,EAC3F,EAAE,KAAA,EAAO,QAAA,EAAU,IAAA,EAAM,MAAA,EAAiB,MAAM,qDAAA,EAAsD;AAAA,EACtG,EAAE,KAAA,EAAO,SAAA,EAAW,IAAA,EAAM,UAAA,EAAqB,MAAM,sDAAA;AACvD,CAAA;AACA,IAAM,kBAAA,GAAqB;AAAA,EACzB,EAAE,KAAA,EAAO,gBAAA,EAAkB,IAAA,EAAM,MAAA,EAAiB,MAAM,gCAAA,EAAiC;AAAA,EACzF,EAAE,KAAA,EAAO,UAAA,EAAY,IAAA,EAAM,MAAA,EAAiB,MAAM,yCAAA;AACpD,CAAA;AAmBA,IAAM,gBAAA,GAAmC;AAAA,EACvC,EAAE,KAAA,EAAO,WAAA,EAAa,IAAA,EAAM,MAAA,EAAQ,MAAM,WAAA,EAAY;AAAA,EACtD,EAAE,KAAA,EAAO,SAAA,EAAW,IAAA,EAAM,MAAA,EAAQ,MAAM,SAAA,EAAU;AAAA,EAClD,EAAE,KAAA,EAAO,YAAA,EAAc,IAAA,EAAM,MAAA,EAAQ,MAAM,YAAA,EAAa;AAAA,EACxD,EAAE,KAAA,EAAO,YAAA,EAAc,IAAA,EAAM,UAAA,EAAY,MAAM,YAAA,EAAa;AAAA,EAC5D,EAAE,KAAA,EAAO,QAAA,EAAU,IAAA,EAAM,OAAA,EAAS,MAAM,QAAA,EAAS;AAAA,EACjD,EAAE,KAAA,EAAO,eAAA,EAAiB,IAAA,EAAM,eAAA,EAAiB,MAAM,eAAA;AACzD,CAAA;AAGA,IAAM,sBAAA,GAAyC;AAAA,EAC7C,EAAE,KAAA,EAAO,WAAA,EAAa,IAAA,EAAM,MAAA,EAAQ,MAAM,EAAA,EAAG;AAAA,EAC7C,EAAE,KAAA,EAAO,WAAA,EAAa,IAAA,EAAM,OAAA,EAAS,MAAM,WAAA,EAAY;AAAA,EACvD,EAAE,KAAA,EAAO,SAAA,EAAW,IAAA,EAAM,eAAA,EAAiB,MAAM,SAAA,EAAU;AAAA,EAC3D,EAAE,KAAA,EAAO,SAAA,EAAW,IAAA,EAAM,UAAA,EAAY,MAAM,SAAA;AAC9C,CAAA;AAGA,IAAM,oBAAA,GAAuC;AAAA,EAC3C,EAAE,KAAA,EAAO,WAAA,EAAa,IAAA,EAAM,MAAA,EAAQ,MAAM,EAAA,EAAG;AAAA,EAC7C,EAAE,KAAA,EAAO,WAAA,EAAa,IAAA,EAAM,QAAA,EAAU,MAAM,WAAA,EAAY;AAAA,EACxD,EAAE,KAAA,EAAO,YAAA,EAAc,IAAA,EAAM,OAAA,EAAS,MAAM,YAAA;AAC9C,CAAA;AAUA,IAAM,kBAAA,GAAqC;AAAA,EACzC,EAAE,KAAA,EAAO,KAAA,EAAO,IAAA,EAAM,KAAA,EAAO,MAAM,EAAA,EAAG;AAAA,EACtC,EAAE,KAAA,EAAO,YAAA,EAAc,IAAA,EAAM,MAAA,EAAQ,MAAM,YAAA,EAAa;AAAA,EACxD,EAAE,KAAA,EAAO,cAAA,EAAgB,IAAA,EAAM,UAAA,EAAY,MAAM,QAAA,EAAS;AAAA,EAC1D,EAAE,KAAA,EAAO,UAAA,EAAY,IAAA,EAAM,MAAA,EAAQ,MAAM,UAAA,EAAW;AAAA,EACpD,EAAE,KAAA,EAAO,SAAA,EAAW,IAAA,EAAM,UAAA,EAAY,MAAM,SAAA;AAC9C,CAAA;AAQO,SAAS,oBAAoB,IAAA,EAAqC;AACvE,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,WAAA,CAAY,OAAA,CAAQ,QAAQ,EAAE,CAAA;AAChD,EAAA,MAAM,GAAA,GAAM,CAAC,IAAA,KAAyB,CAAA,EAAG,IAAI,CAAA,EAAG,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,GAAI,IAAA,GAAO,CAAA,CAAA,EAAI,IAAI,CAAA,CAAE,CAAA,CAAA;AACxF,EAAA,MAAM,IAAA,GAAO,CAAC,GAAA,KAAiD,IAAA,CAAK,QAAQ,GAAG,CAAA;AAY/E,EAAA,MAAM,WAAW,IAAA,CAAK,WAAA,GAAc,CAAA,IAAA,EAAO,IAAA,CAAK,WAAW,CAAA,CAAA,GAAK,EAAA;AAChE,EAAA,MAAM,OAAA,GAAU,CAAC,GAAA,KACf,QAAA,GAAW,GAAG,GAAG,CAAA,EAAG,GAAA,CAAI,QAAA,CAAS,GAAG,CAAA,GAAI,GAAA,GAAM,GAAG,CAAA,EAAG,QAAQ,CAAA,CAAA,GAAK,GAAA;AAEnE,EAAA,MAAM,MAAA,GAAS,CAAC,QAAA,KACd,QAAA,CAAS,IAAI,CAAC,CAAA,MAAO,EAAE,KAAA,EAAO,CAAA,CAAE,KAAA,EAAO,MAAM,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG,IAAA,EAAM,OAAA,CAAQ,IAAI,CAAA,CAAE,IAAI,CAAC,CAAA,EAAE,CAAE,CAAA;AAC1F,EAAA,MAAM,WAAW,CAAC,QAAA,KAChB,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,IACnB,OAAO,CAAA,CAAE,KAAA;AAAA,IACT,IAAA,EAAM,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AAAA,IACjB,IAAA,EAAM,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,IAAI,CAAC,CAAA;AAAA,IACzB,UAAU,CAAA,CAAE,QAAA,GAAW,MAAA,CAAO,CAAA,CAAE,QAAQ,CAAA,GAAI;AAAA,GAC9C,CAAE,CAAA;AAEJ,EAAA,MAAM,oBAAoB,MAAiB;AACzC,IAAA,MAAM,QAAA,GAAoB,KAAK,YAAA,GAC3B;AAAA,MACE,KAAA,EAAO,UAAA;AAAA,MACP,IAAA,EAAM,KAAK,OAAO,CAAA;AAAA,MAClB,IAAA,EAAM,KAAK,YAAA,CAAa,IAAA;AAAA,MACxB,QAAA,EAAU,KAAK,YAAA,CAAa;AAAA,KAC9B,GACA;AAAA,MACE,KAAA,EAAO,UAAA;AAAA,MACP,IAAA,EAAM,KAAK,OAAO,CAAA;AAAA,MAClB,IAAA,EAAM,OAAA,CAAQ,GAAA,CAAI,kCAAkC,CAAC,CAAA;AAAA,MACrD,QAAA,EAAU,OAAO,yBAAyB;AAAA,KAC5C;AAEJ,IAAA,OAAO;AAAA,MACL,EAAE,KAAA,EAAO,WAAA,EAAa,IAAA,EAAM,IAAA,CAAK,MAAM,CAAA,EAAG,IAAA,EAAM,OAAA,CAAQ,GAAA,CAAI,yBAAyB,CAAC,CAAA,EAAE;AAAA,MACxF,QAAA;AAAA,MACA;AAAA,QACE,KAAA,EAAO,iBAAA;AAAA,QACP,IAAA,EAAM,KAAK,MAAM,CAAA;AAAA,QACjB,IAAA,EAAM,OAAA,CAAQ,GAAA,CAAI,+BAA+B,CAAC,CAAA;AAAA,QAClD,QAAA,EAAU,OAAO,cAAc;AAAA,OACjC;AAAA,MACA;AAAA,QACE,KAAA,EAAO,eAAA;AAAA,QACP,IAAA,EAAM,KAAK,eAAe,CAAA;AAAA,QAC1B,IAAA,EAAM,OAAA,CAAQ,GAAA,CAAI,uCAAuC,CAAC,CAAA;AAAA,QAC1D,QAAA,EAAU,OAAO,YAAY;AAAA,OAC/B;AAAA;AAAA,MAEA,EAAE,KAAA,EAAO,iBAAA,EAAmB,IAAA,EAAM,IAAA,CAAK,QAAQ,CAAA,EAAG,QAAA,EAAU,MAAA,CAAO,YAAY,CAAA,EAAE;AAAA,MACjF;AAAA,QACE,KAAA,EAAO,OAAA;AAAA,QACP,IAAA,EAAM,KAAK,UAAU,CAAA;AAAA,QACrB,IAAA,EAAM,QAAQ,gCAAgC,CAAA;AAAA,QAC9C,UAAU,kBAAA,CAAmB,GAAA,CAAI,CAAC,CAAA,MAAO,EAAE,OAAO,CAAA,CAAE,KAAA,EAAO,MAAM,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG,IAAA,EAAM,QAAQ,CAAA,CAAE,IAAI,GAAE,CAAE;AAAA,OACzG;AAAA,MACA;AAAA,QACE,KAAA,EAAO,SAAA;AAAA,QACP,IAAA,EAAM,KAAK,UAAU,CAAA;AAAA,QACrB,IAAA,EAAM,QAAQ,yCAAyC,CAAA;AAAA,QACvD,UAAU,oBAAA,CAAqB,GAAA,CAAI,CAAC,CAAA,MAAO,EAAE,OAAO,CAAA,CAAE,KAAA,EAAO,MAAM,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG,IAAA,EAAM,QAAQ,CAAA,CAAE,IAAI,GAAE,CAAE;AAAA,OAC3G;AAAA,MACA;AAAA,QACE,KAAA,EAAO,OAAA;AAAA,QACP,IAAA,EAAM,KAAK,UAAU,CAAA;AAAA,QACrB,IAAA,EAAM,QAAQ,gCAAgC,CAAA;AAAA,QAC9C,UAAU,kBAAA,CAAmB,GAAA,CAAI,CAAC,CAAA,MAAO,EAAE,OAAO,CAAA,CAAE,KAAA,EAAO,MAAM,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG,IAAA,EAAM,QAAQ,CAAA,CAAE,IAAI,GAAE,CAAE;AAAA,OACzG;AAAA,MACA;AAAA,QACE,KAAA,EAAO,uBAAA;AAAA,QACP,IAAA,EAAM,KAAK,WAAW,CAAA;AAAA,QACtB,IAAA,EAAM,OAAA,CAAQ,GAAA,CAAI,wBAAwB,CAAC,CAAA;AAAA,QAC3C,QAAA,EAAU,SAAS,qBAAqB;AAAA;AAC1C,KACF;AAAA,EACF,CAAA;AAKA,EAAA,MAAM,gBAAgB,MAAiB;AACrC,IAAA,MAAM,KAAA,GAAqC;AAAA,MACzC,GAAG,6BAAA;AAAA,MACH,GAAG,IAAA,CAAK;AAAA,KACV;AAIA,IAAA,MAAM,SAAA,GAAY,CAAC,MAAA,EAAgB,QAAA,KAAwC;AACzE,MAAA,MAAME,KAAAA,GAAO,MAAA,CAAO,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AACtC,MAAA,OAAO,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,QAC1B,OAAO,CAAA,CAAE,KAAA;AAAA,QACT,IAAA,EAAM,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AAAA,QACjB,IAAA,EAAM,OAAA,CAAQ,CAAA,CAAE,IAAA,GAAO,CAAA,EAAGA,KAAI,CAAA,CAAA,EAAI,CAAA,CAAE,IAAI,CAAA,CAAA,GAAK,CAAA,EAAGA,KAAI,CAAA,CAAA,CAAG;AAAA,OACzD,CAAE,CAAA;AAAA,IACJ,CAAA;AAEA,IAAA,MAAM,IAAA,GAAgB;AAAA,MACpB,EAAE,KAAA,EAAO,WAAA,EAAa,IAAA,EAAM,IAAA,CAAK,MAAM,CAAA,EAAG,IAAA,EAAM,OAAA,CAAQ,GAAA,CAAI,qBAAqB,CAAC,CAAA,EAAE;AAAA,MACpF,EAAE,KAAA,EAAO,eAAA,EAAiB,IAAA,EAAM,IAAA,CAAK,QAAQ,CAAA,EAAG,IAAA,EAAM,OAAA,CAAQ,GAAA,CAAI,qBAAqB,CAAC,CAAA,EAAE;AAAA,MAC1F;AAAA,QACE,KAAA,EAAO,KAAA;AAAA,QACP,IAAA,EAAM,KAAK,eAAe,CAAA;AAAA,QAC1B,IAAA,EAAM,QAAQ,UAAU,CAAA;AAAA,QACxB,QAAA,EAAU,SAAA,CAAU,UAAA,EAAY,gBAAgB,CAAA;AAAA,QAChD,IAAA,EAAM;AAAA,OACR;AAAA,MACA;AAAA,QACE,KAAA,EAAO,eAAA;AAAA,QACP,IAAA,EAAM,KAAK,OAAO,CAAA;AAAA,QAClB,IAAA,EAAM,QAAQ,gBAAgB,CAAA;AAAA,QAC9B,QAAA,EAAU,SAAA,CAAU,gBAAA,EAAkB,sBAAsB,CAAA;AAAA,QAC5D,IAAA,EAAM;AAAA,OACR;AAAA,MACA;AAAA,QACE,KAAA,EAAO,kBAAA;AAAA,QACP,IAAA,EAAM,KAAK,KAAK,CAAA;AAAA,QAChB,IAAA,EAAM,QAAQ,cAAc,CAAA;AAAA,QAC5B,QAAA,EAAU,SAAA,CAAU,cAAA,EAAgB,oBAAoB,CAAA;AAAA,QACxD,IAAA,EAAM;AAAA,OACR;AAAA,MACA;AAAA,QACE,KAAA,EAAO,cAAA;AAAA,QACP,IAAA,EAAM,KAAK,QAAQ,CAAA;AAAA,QACnB,IAAA,EAAM,QAAQ,YAAY,CAAA;AAAA,QAC1B,QAAA,EAAU,SAAA,CAAU,YAAA,EAAc,kBAAkB,CAAA;AAAA,QACpD,IAAA,EAAM;AAAA,OACR;AAAA,MACA,EAAE,KAAA,EAAO,QAAA,EAAU,IAAA,EAAM,IAAA,CAAK,OAAO,CAAA,EAAG,IAAA,EAAM,OAAA,CAAQ,eAAe,CAAA,EAAG,IAAA,EAAM,QAAA,EAAS;AAAA,MACvF,EAAE,KAAA,EAAO,gBAAA,EAAkB,IAAA,EAAM,IAAA,CAAK,UAAU,CAAA,EAAG,IAAA,EAAM,OAAA,CAAQ,YAAY,CAAA,EAAG,IAAA,EAAM,SAAA;AAAU,KAClG;AACA,IAAA,OAAO,IAAA,CACJ,OAAO,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,IAAA,IAAQ,MAAM,CAAA,CAAE,IAAI,CAAC,CAAA,CACtC,GAAA,CAAI,CAAC,EAAE,IAAA,EAAM,OAAO,GAAG,IAAA,OAAW,IAAI,CAAA;AAAA,EAC3C,CAAA;AAIA,EAAA,MAAM,gBAAgB,MAAiB;AAAA,IACrC,EAAE,KAAA,EAAO,WAAA,EAAa,IAAA,EAAM,IAAA,CAAK,MAAM,CAAA,EAAG,IAAA,EAAM,OAAA,CAAQ,oBAAoB,CAAA;AAAE,GAChF;AAEA,EAAA,MAAM,IAAA,GAAO,KAAK,IAAA,IAAQ,cAAA;AAC1B,EAAA,MAAM,KAAA,GACJ,SAAS,UAAA,GACL,aAAA,KACA,IAAA,KAAS,UAAA,GACP,aAAA,EAAc,GACd,iBAAA,EAAkB;AAE1B,EAAA,IAAI,KAAK,WAAA,EAAa;AACpB,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,KAAA,EAAO,SAAA;AAAA,MACP,IAAA,EAAM,KAAK,UAAU,CAAA;AAAA,MACrB,IAAA,EAAM,KAAK,WAAA,CAAY,IAAA;AAAA,MACvB,OAAA,EAAS,KAAK,WAAA,CAAY;AAAA,KAC3B,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,KAAA;AACT;AClVA,IAAM,QAAA,GAAW,CAAC,CAAA,KAChB,CAAA,IAAK,kCAAA,CAAmC,KAAK,CAAA,CAAE,IAAA,EAAM,CAAA,GAAI,CAAA,GAAI,GAAA;AAE/D,IAAM,cAAgC,CAAC,EAAE,IAAA,EAAM,QAAA,EAAU,GAAG,IAAA,EAAK,qBAC/DP,cAAAA,CAAC,OAAE,IAAA,EAAM,QAAA,CAAS,IAAI,CAAA,EAAI,GAAG,MAC1B,QAAA,EACH,CAAA;AAkBF,IAAM,qBAAA,mBAAwB,IAAI,GAAA,CAAI,CAAC,KAAK,CAAC,CAAA;AAEtC,SAAS,eAAA,CAAgB,UAAkB,IAAA,EAAuB;AACvE,EAAA,IAAI,UAAA,GAAa,IAAA;AACjB,EAAA,IAAI,YAAA,GAAe,EAAA;AACnB,EAAA,IAAI,eAAA,CAAgB,IAAA,CAAK,IAAI,CAAA,EAAG;AAC9B,IAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,KAAA;AAC1C,IAAA,IAAI;AACF,MAAA,MAAM,CAAA,GAAI,IAAI,GAAA,CAAI,IAAI,CAAA;AACtB,MAAA,IAAI,CAAA,CAAE,IAAA,KAAS,MAAA,CAAO,QAAA,CAAS,MAAM,OAAO,KAAA;AAC5C,MAAA,UAAA,GAAa,CAAA,CAAE,QAAA;AACf,MAAA,YAAA,GAAe,CAAA,CAAE,MAAA;AAAA,IACnB,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF,CAAA,MAAO;AACL,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,OAAA,CAAQ,GAAG,CAAA;AAC3B,IAAA,IAAI,MAAM,CAAA,EAAG;AACX,MAAA,UAAA,GAAa,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,IAAK,GAAA;AAClC,MAAA,YAAA,GAAe,IAAA,CAAK,MAAM,EAAE,CAAA;AAAA,IAC9B;AAAA,EACF;AAKA,EAAA,MAAM,IAAA,GAAO,IAAI,eAAA,CAAgB,YAAY,CAAA;AAC7C,EAAA,KAAA,MAAW,CAAA,IAAK,qBAAA,EAAuB,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA;AACpD,EAAA,IAAI,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,CAAE,SAAS,CAAA,EAAG;AAC/B,IAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,KAAA;AAC1C,IAAA,IAAI,QAAA,KAAa,YAAY,OAAO,KAAA;AACpC,IAAA,MAAM,IAAA,GAAO,IAAI,eAAA,CAAgB,MAAA,CAAO,SAAS,MAAM,CAAA;AACvD,IAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,CAAA,IAAK,IAAA,EAAM,IAAI,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,EAAG,OAAO,KAAA;AACzD,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,IAAI,UAAA,KAAe,GAAA,EAAK,OAAO,QAAA,KAAa,GAAA;AAC5C,EAAA,OAAO,aAAa,UAAA,IAAc,QAAA,CAAS,UAAA,CAAW,CAAA,EAAG,UAAU,CAAA,CAAA,CAAG,CAAA;AACxE;AAOA,SAAS,UAAA,CAAW,MAAe,KAAA,EAAuB;AACxD,EAAA,OAAO,KAAK,IAAA,IAAQ,CAAA,UAAA,EAAa,KAAK,CAAA,CAAA,EAAI,KAAK,KAAK,CAAA,CAAA;AACtD;AAGA,SAAS,cAAA,CACP,IAAA,EACA,QAAA,EACA,QAAA,EACS;AACT,EAAA,OAAA,CAAQ,IAAA,CAAK,QAAA,IAAY,EAAC,EAAG,IAAA;AAAA,IAC3B,CAAC,WACE,KAAA,CAAM,IAAA,GAAO,SAAS,QAAA,EAAU,KAAA,CAAM,IAAI,CAAA,GAAI,KAAA;AAAA,IAAA,CAE9C,KAAA,CAAM,QAAA,IAAY,EAAC,EAAG,IAAA;AAAA,MAAK,CAAC,SAC3B,IAAA,CAAK,IAAA,GAAO,SAAS,QAAA,EAAU,IAAA,CAAK,IAAI,CAAA,GAAI;AAAA;AAC9C,GACJ;AACF;AAMO,SAAS,eAAe,KAAA,EAAuB;AACpD,EAAA,MAAM,CAAA,GAAI,MAAM,WAAA,EAAY;AAC5B,EAAA,IAAI,CAAA,KAAM,gBAAgB,CAAA,KAAM,MAAA;AAC9B,IAAA,OAAO,6BAAA;AACT,EAAA,IAAI,CAAA,KAAM,aAAa,CAAA,KAAM,OAAA;AAC3B,IAAA,OAAO,6BAAA;AACT,EAAA,IAAI,CAAA,KAAM,OAAA,IAAW,CAAA,KAAM,aAAA,IAAiB,CAAA,KAAM,KAAA;AAChD,IAAA,OAAO,6BAAA;AACT,EAAA,OAAO,4CAAA;AACT;AAyGA,IAAM,gBAAA,GAAmB,uBAAA;AAElB,SAAS,UAAA,CAAW;AAAA,EACzB,QAAA;AAAA,EACA,KAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,EAAoB;AAClB,EAAA,MAAM,OAAO,aAAA,IAAiB,WAAA;AAC9B,EAAA,MAAM,QAAA,GAAW,IAAI,QAAA,IAAY,eAAA;AACjC,EAAA,MAAM,WAAW,IAAA,EAAM,IAAA;AACvB,EAAA,MAAM,KAAA,GAAQ,KAAK,UAAA,IAAc,gBAAA;AAGjC,EAAA,MAAM,UAAA,GAAa,iBAAA,CAAkB,GAAA,EAAK,OAAO,CAAA;AAOjD,EAAA,MAAM,cAAA,GAAiBQ,cAAQ,MAAM;AACnC,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,GAAA,CAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACzC,MAAA,MAAM,IAAA,GAAO,GAAA,CAAI,KAAA,CAAM,CAAC,CAAA;AACxB,MAAA,IAAI,IAAA,CAAK,QAAA,IAAY,IAAA,CAAK,QAAA,CAAS,MAAA,GAAS,KAAK,cAAA,CAAe,IAAA,EAAM,QAAA,EAAU,QAAQ,CAAA,EAAG;AACzF,QAAA,OAAO,UAAA,CAAW,MAAM,CAAC,CAAA;AAAA,MAC3B;AAAA,IACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT,GAAG,CAAC,GAAA,CAAI,KAAA,EAAO,QAAA,EAAU,QAAQ,CAAC,CAAA;AAMlC,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI5B,eAAwB,cAAc,CAAA;AACxE,EAAAC,gBAAU,MAAM;AACd,IAAA,YAAA,CAAa,cAAc,CAAA;AAAA,EAC7B,CAAA,EAAG,CAAC,cAAc,CAAC,CAAA;AACnB,EAAA,MAAM,WAAA,GAAc,CAAC,GAAA,KACnB,YAAA,CAAa,CAAC,IAAA,KAAU,IAAA,KAAS,GAAA,GAAM,IAAA,GAAO,GAAI,CAAA;AAEpD,EAAA,uBACEkB,eAAAA,CAAC,OAAA,EAAA,EAAM,SAAA,EAAU,iIAAA,EAEf,QAAA,EAAA;AAAA,oBAAAC,cAAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,MAAM,QAAA,IAAY,GAAA;AAAA,QACxB,SAAA,EAAU,uDAAA;AAAA,QAET,QAAA,EAAA,KAAA,CAAM,0BACLA,cAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,KAAK,KAAA,CAAM,OAAA;AAAA,YACX,GAAA,EAAK,KAAA,CAAM,OAAA,IAAW,KAAA,CAAM,KAAA;AAAA,YAC5B,SAAA,EAAW,KAAA;AAAA,YACX,SAAA,EAAU;AAAA;AAAA,SACZ,mBAEAD,eAAAA,CAAAK,mBAAAA,EAAA,EACE,QAAA,EAAA;AAAA,0BAAAJ,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,gIAAA,EACb,gBAAM,UAAA,EACT,CAAA;AAAA,0BACAD,eAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,6BAAA,EACd,QAAA,EAAA;AAAA,4BAAAC,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,gFAAA,EACb,gBAAM,KAAA,EACT,CAAA;AAAA,YACC,KAAA,CAAM,2BACLA,cAAAA,CAAC,UAAK,SAAA,EAAU,iFAAA,EACb,QAAA,EAAA,KAAA,CAAM,QAAA,EACT,CAAA,GACE;AAAA,WAAA,EACN;AAAA,SAAA,EACF;AAAA;AAAA,KAEJ;AAAA,oBAGAD,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gDAAA,EAEZ,QAAA,EAAA;AAAA,MAAA,GAAA,mBACCA,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,MAAA,EACb,QAAA,EAAA;AAAA,wBAAAA,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,6CAAA,EACb,QAAA,EAAA;AAAA,0BAAAC,cAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,iFAAA,EAAkF,QAAA,EAAA,cAAA,EAE/F,CAAA;AAAA,UACC,GAAA,CAAI,EAAA,IAAM,CAAC,GAAA,CAAI,OAAA,mBAAUA,cAAAA,CAAC,eAAA,EAAA,EAAgB,EAAA,EAAI,GAAA,CAAI,EAAA,EAAI,CAAA,GAAK;AAAA,SAAA,EAC9D,CAAA;AAAA,QACC,IAAI,OAAA,mBACHD,eAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,sIAAA,EACb,QAAA,EAAA;AAAA,0BAAAC,cAAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,aAAA,EAAW,IAAA;AAAA,cACX,SAAA,EAAU;AAAA;AAAA,WACZ;AAAA,0BACAA,cAAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,aAAA,EAAW,IAAA;AAAA,cACX,SAAA,EAAU;AAAA;AAAA,WACZ;AAAA,0BACAA,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,WAAU,QAAA,EAAA,sBAAA,EAAoB;AAAA,SAAA,EAChD,CAAA,GACE,GAAA,CAAI,aAAA,IAAiB,GAAA,CAAI,cAAc,MAAA,GAAS,CAAA,IAAK,GAAA,CAAI,QAAA,mBAC3DD,eAAAA,CAAC,SAAA,EAAA,EAAQ,kBAAA,EAAgB,IAAA,EAAC,WAAU,gBAAA,EAClC,QAAA,EAAA;AAAA,0BAAAA,eAAAA,CAAC,SAAA,EAAA,EAAQ,SAAA,EAAU,kSAAA,EACjB,QAAA,EAAA;AAAA,4BAAAA,eAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mCAAA,EAEd,QAAA,EAAA;AAAA,8BAAAC,cAAAA;AAAA,gBAAC,MAAA;AAAA,gBAAA;AAAA,kBACC,KAAA,EAAO,EAAE,eAAA,EAAiB,KAAA,EAAM;AAAA,kBAChC,SAAA,EAAU,iHAAA;AAAA,kBAET,uCACCA,cAAAA,CAAC,SAAI,GAAA,EAAK,UAAA,EAAY,KAAI,EAAA,EAAG,SAAA,EAAU,4BAAA,EAA6B,CAAA,GAAA,CAEnE,IAAI,IAAA,IAAQ,KAAA,EAAO,MAAM,CAAA,EAAG,CAAC,EAAE,WAAA;AAAY;AAAA,eAEhD;AAAA,8BACAA,cAAAA;AAAA,gBAAC,MAAA;AAAA,gBAAA;AAAA,kBACC,KAAA,EAAO,IAAI,IAAA,IAAQ,MAAA;AAAA,kBACnB,SAAA,EAAU,gCAAA;AAAA,kBAET,cAAI,IAAA,IAAQ;AAAA;AAAA;AACf,aAAA,EACF,CAAA;AAAA,4BACAA,eAAC,WAAA,EAAA,EAAY;AAAA,WAAA,EACf,CAAA;AAAA,0BACAA,eAAC,KAAA,EAAA,EAAI,SAAA,EAAU,6KACZ,QAAA,EAAA,GAAA,CAAI,aAAA,CAAc,GAAA,CAAI,CAAC,CAAA,KAAM;AAC5B,YAAA,MAAM,QAAA,GAAW,CAAA,CAAE,EAAA,KAAO,GAAA,CAAI,EAAA;AAC9B,YAAA,uBACED,eAAAA;AAAA,cAAC,QAAA;AAAA,cAAA;AAAA,gBAEC,IAAA,EAAK,QAAA;AAAA,gBACL,OAAA,EAAS,CAAC,CAAA,KAAM;AAEd,kBAAA,CAAA,CAAE,aAAA,CAAc,OAAA,CAAQ,SAAS,CAAA,EAAG,gBAAgB,MAAM,CAAA;AAC1D,kBAAA,IAAI,CAAC,QAAA,EAAU,GAAA,CAAI,QAAA,GAAW,EAAE,EAAE,CAAA;AAAA,gBACpC,CAAA;AAAA,gBACA,cAAA,EAAc,WAAW,MAAA,GAAS,MAAA;AAAA,gBAClC,SAAA,EAAW;AAAA,kBACT,8DAAA;AAAA,kBACA,WACI,kDAAA,GACA;AAAA,iBACN,CAAE,KAAK,GAAG,CAAA;AAAA,gBAEV,QAAA,EAAA;AAAA,kCAAAC,cAAAA;AAAA,oBAAC,MAAA;AAAA,oBAAA;AAAA,sBACC,KAAA,EAAO,EAAE,eAAA,EAAiB,CAAA,CAAE,cAAc,gBAAA,EAAiB;AAAA,sBAC3D,SAAA,EAAU,iHAAA;AAAA,sBAET,QAAA,EAAA,iBAAA,CAAkB,CAAA,CAAE,OAAO,CAAA,mBAC1BA,cAAAA;AAAA,wBAAC,KAAA;AAAA,wBAAA;AAAA,0BACC,GAAA,EAAK,iBAAA,CAAkB,CAAA,CAAE,OAAO,CAAA;AAAA,0BAChC,GAAA,EAAI,EAAA;AAAA,0BACJ,SAAA,EAAU;AAAA;AAAA,uBACZ,GAAA,CAEC,EAAE,IAAA,IAAQ,KAAA,EAAO,MAAM,CAAA,EAAG,CAAC,EAAE,WAAA;AAAY;AAAA,mBAE9C;AAAA,kCACAA,cAAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAO,CAAA,CAAE,QAAQ,CAAA,CAAE,EAAA,EAAI,SAAA,EAAU,UAAA,EACpC,YAAE,IAAA,IAAQ,CAAA,CAAE,GAAG,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,EAC5B;AAAA;AAAA,eAAA;AAAA,cA/BK,CAAA,CAAE;AAAA,aAgCT;AAAA,UAEJ,CAAC,CAAA,EACH;AAAA,SAAA,EACF,oBAEAD,eAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,SAAS,GAAA,CAAI,OAAA;AAAA,YACb,SAAA,EAAU,sOAAA;AAAA,YAEV,QAAA,EAAA;AAAA,8BAAAA,eAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mCAAA,EAEd,QAAA,EAAA;AAAA,gCAAAC,cAAAA;AAAA,kBAAC,MAAA;AAAA,kBAAA;AAAA,oBACC,KAAA,EAAO,EAAE,eAAA,EAAiB,KAAA,EAAM;AAAA,oBAChC,SAAA,EAAU,iHAAA;AAAA,oBAET,uCACCA,cAAAA,CAAC,SAAI,GAAA,EAAK,UAAA,EAAY,KAAI,EAAA,EAAG,SAAA,EAAU,4BAAA,EAA6B,CAAA,GAAA,CAEnE,IAAI,IAAA,IAAQ,KAAA,EAAO,MAAM,CAAA,EAAG,CAAC,EAAE,WAAA;AAAY;AAAA,iBAEhD;AAAA,gCACAA,cAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,gCAAA,EACb,QAAA,EAAA,GAAA,CAAI,QAAQ,kBAAA,EACf;AAAA,eAAA,EACF,CAAA;AAAA,8BACAA,eAAC,WAAA,EAAA,EAAY;AAAA;AAAA;AAAA;AACf,OAAA,EAEJ,CAAA,GACE,IAAA;AAAA,MAGH,IAAA,mBACCA,cAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,MAAA,EACZ,QAAA,EAAA,IAAA,CAAK,WAAW,IAAA,CAAK,OAAA,CAAQ,SAAS,CAAA,IAAK,IAAA,CAAK,2BAC/CD,eAAAA,CAAC,aAAQ,kBAAA,EAAgB,IAAA,EAAC,WAAU,gBAAA,EAClC,QAAA,EAAA;AAAA,wBAAAA,eAAAA,CAAC,SAAA,EAAA,EAAQ,SAAA,EAAU,qNAAA,EACjB,QAAA,EAAA;AAAA,0BAAAA,eAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,2BAAA,EACb,QAAA,EAAA;AAAA,YAAA,QAAA,mBAAWC,cAAAA,CAAC,QAAA,EAAA,EAAS,MAAM,EAAA,EAAI,SAAA,EAAU,YAAW,CAAA,GAAK,IAAA;AAAA,4BAC1DA,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,0CAAA,EAA4C,eAAK,KAAA,EAAM;AAAA,WAAA,EACzE,CAAA;AAAA,0BACAA,eAAC,WAAA,EAAA,EAAY;AAAA,SAAA,EACf,CAAA;AAAA,wBACAA,eAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oKACZ,QAAA,EAAA,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,CAAC,GAAA,KAAQ;AACzB,UAAA,MAAM,QAAA,GAAW,GAAA,CAAI,KAAA,KAAU,IAAA,CAAK,KAAA;AACpC,UAAA,MAAM,UAAU,GAAA,CAAI,IAAA;AACpB,UAAA,uBACED,eAAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cAEC,IAAA,EAAK,QAAA;AAAA,cACL,OAAA,EAAS,CAAC,CAAA,KAAM;AACd,gBAAA,CAAA,CAAE,aAAA,CAAc,OAAA,CAAQ,SAAS,CAAA,EAAG,gBAAgB,MAAM,CAAA;AAC1D,gBAAA,IAAI,CAAC,QAAA,EAAU,IAAA,CAAK,QAAA,GAAW,IAAI,EAAE,CAAA;AAAA,cACvC,CAAA;AAAA,cACA,cAAA,EAAc,WAAW,MAAA,GAAS,MAAA;AAAA,cAClC,SAAA,EAAW;AAAA,gBACT,8DAAA;AAAA,gBACA,WACI,kDAAA,GACA;AAAA,eACN,CAAE,KAAK,GAAG,CAAA;AAAA,cAET,QAAA,EAAA;AAAA,gBAAA,OAAA,mBAAUC,cAAAA,CAAC,OAAA,EAAA,EAAQ,MAAM,EAAA,EAAI,SAAA,EAAU,yBAAwB,CAAA,GAAK,IAAA;AAAA,gBACpE,GAAA,CAAI;AAAA;AAAA,aAAA;AAAA,YAfA,GAAA,CAAI;AAAA,WAgBX;AAAA,QAEJ,CAAC,CAAA,EACH;AAAA,OAAA,EACF,oBAEAD,eAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,SAAA,EAAU,6HAAA;AAAA,UAEV,QAAA,EAAA;AAAA,4BAAAA,eAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,2BAAA,EACb,QAAA,EAAA;AAAA,cAAA,QAAA,mBAAWC,cAAAA,CAAC,QAAA,EAAA,EAAS,MAAM,EAAA,EAAI,SAAA,EAAU,YAAW,CAAA,GAAK,IAAA;AAAA,8BAC1DA,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,0CAAA,EAA4C,eAAK,KAAA,EAAM;AAAA,aAAA,EACzE,CAAA;AAAA,4BACAA,eAAC,WAAA,EAAA,EAAY;AAAA;AAAA;AAAA,SAGnB,CAAA,GACE,IAAA;AAAA,sBAGJD,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAA,EACZ,QAAA,EAAA;AAAA,QAAA,GAAA,CAAI,UAAA,mBACHC,cAAAA,CAAC,GAAA,EAAA,EAAE,WAAU,2FAAA,EACV,QAAA,EAAA,GAAA,CAAI,YACP,CAAA,GACE,IAAA;AAAA,QACH,GAAA,CAAI,KAAA,CAAM,GAAA,CAAI,CAAC,MAAM,GAAA,KAAQ;AAE5B,UAAA,IAAI,IAAA,CAAK,QAAA,IAAY,IAAA,CAAK,QAAA,CAAS,SAAS,CAAA,EAAG;AAC7C,YAAA,MAAM,GAAA,GAAM,UAAA,CAAW,IAAA,EAAM,GAAG,CAAA;AAChC,YAAA,MAAM,aAAa,IAAA,CAAK,IAAA,GAAO,SAAS,QAAA,EAAU,IAAA,CAAK,IAAI,CAAA,GAAI,KAAA;AAC/D,YAAA,MAAM,YAAA,GAAe,UAAA,IAAc,cAAA,CAAe,IAAA,EAAM,UAAU,QAAQ,CAAA;AAC1E,YAAA,uBACEA,cAAAA;AAAA,cAAC,QAAA;AAAA,cAAA;AAAA,gBAEC,IAAA;AAAA,gBACA,MAAA,EAAQ,YAAA;AAAA,gBACR,MAAM,SAAA,KAAc,GAAA;AAAA,gBACpB,QAAA,EAAU,MAAM,WAAA,CAAY,GAAG,CAAA;AAAA,gBAC/B,QAAA;AAAA,gBACA,QAAA;AAAA,gBACA;AAAA,eAAA;AAAA,cAPK;AAAA,aAQP;AAAA,UAEJ;AACA,UAAA,MAAM,SAAS,IAAA,CAAK,IAAA,GAAO,SAAS,QAAA,EAAU,IAAA,CAAK,IAAI,CAAA,GAAI,KAAA;AAC3D,UAAA,uBACEA,cAAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cAEC,IAAA;AAAA,cACA,MAAA;AAAA,cACA;AAAA,aAAA;AAAA,YAHK,KAAK,IAAA,IAAQ,CAAA,IAAA,EAAO,GAAG,CAAA,CAAA,EAAI,KAAK,KAAK,CAAA;AAAA,WAI5C;AAAA,QAEJ,CAAC;AAAA,OAAA,EACH;AAAA,KAAA,EACF,CAAA;AAAA,IAGC,MAAA,mBACCD,eAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,6DAAA,EACZ,QAAA,EAAA;AAAA,MAAA,MAAA,CAAO,KAAA,IAAS,OAAO,KAAA,CAAM,MAAA,GAAS,oBACrCC,cAAAA,CAAC,SAAI,SAAA,EAAU,4DAAA,EACZ,iBAAO,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,EAAG,GAAA,qBACpBD,eAAAA,CAAC,MAAA,EAAA,EAAmB,WAAU,kCAAA,EAC3B,QAAA,EAAA;AAAA,QAAA,GAAA,GAAM,oBAAIC,cAAAA,CAAC,UAAK,SAAA,EAAU,2BAAA,EAA4B,eAAC,CAAA,GAAU,IAAA;AAAA,wBAClEA,cAAAA;AAAA,UAAC,GAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAM,QAAA,CAAS,CAAA,CAAE,IAAI,CAAA;AAAA,YACrB,SAAA,EAAU,yFAAA;AAAA,YAET,QAAA,EAAA,CAAA,CAAE;AAAA;AAAA;AACL,OAAA,EAAA,EAPS,CAAA,CAAE,KAQb,CACD,CAAA,EACH,CAAA,GACE,IAAA;AAAA,MACH,OAAO,QAAA,mBACRD,eAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,0HAAA,EAEb,QAAA,EAAA;AAAA,wBAAAA,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2BAAA,EACb,QAAA,EAAA;AAAA,0BAAAC,cAAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAW;AAAA,gBACT,oDAAA;AAAA,gBACA,cAAA,CAAe,OAAO,QAAQ;AAAA,eAChC,CAAE,KAAK,GAAG,CAAA;AAAA,cAET,QAAA,EAAA,MAAA,CAAO;AAAA;AAAA,WACV;AAAA,UACC,MAAA,CAAO,MAAA,mBACND,eAAAA,CAAAK,qBAAA,EACE,QAAA,EAAA;AAAA,4BAAAJ,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,2BAAA,EAA4B,QAAA,EAAA,GAAA,EAAC,CAAA;AAAA,4BAC7CA,cAAAA,CAAC,MAAA,EAAA,EAAM,iBAAO,MAAA,CAAO,KAAA,CAAM,EAAE,CAAA,EAAE;AAAA,WAAA,EACjC,CAAA,GACE,IAAA;AAAA,UACH,MAAA,CAAO,OAAA,mBACND,eAAAA,CAAAK,qBAAA,EACE,QAAA,EAAA;AAAA,4BAAAJ,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,2BAAA,EAA4B,QAAA,EAAA,GAAA,EAAC,CAAA;AAAA,4BAC7CD,gBAAC,MAAA,EAAA,EAAK,QAAA,EAAA;AAAA,cAAA,GAAA;AAAA,cAAE,MAAA,CAAO;AAAA,aAAA,EAAQ;AAAA,WAAA,EACzB,CAAA,GACE;AAAA,SAAA,EACN,CAAA;AAAA,QAEC,MAAA,CAAO,cAAc,MAAA,CAAO,YAAA,mBAC3BA,eAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,2BAAA,EACZ,QAAA,EAAA;AAAA,UAAA,MAAA,CAAO,UAAA,mBACNC,cAAAA,CAAC,MAAA,EAAA,EACE,QAAA,EAAA,IAAI,KAAK,MAAA,CAAO,UAAU,CAAA,CAAE,kBAAA,CAAmB,MAAA,EAAW;AAAA,YACzD,KAAA,EAAO,OAAA;AAAA,YACP,GAAA,EAAK;AAAA,WACN,GACH,CAAA,GACE,IAAA;AAAA,UACH,MAAA,CAAO,UAAA,IAAc,MAAA,CAAO,YAAA,mBAC3BA,eAAC,MAAA,EAAA,EAAK,SAAA,EAAU,2BAAA,EAA4B,QAAA,EAAA,GAAA,EAAC,CAAA,GAC3C,IAAA;AAAA,UACH,MAAA,CAAO,YAAA,mBACNA,cAAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,MAAA,CAAO,YAAA,CAAa,KAAA,CAAM,KAAK,CAAA,CAAE,CAAC,CAAA,EAAE,CAAA,GACzC;AAAA,SAAA,EACN,CAAA,GACE;AAAA,OAAA,EACN,CAAA,GACI;AAAA,KAAA,EACN,CAAA,GACE;AAAA,GAAA,EACN,CAAA;AAEJ;AAIA,SAAS,WAAA,CAAY,EAAE,SAAA,EAAU,GAA4B,EAAC,EAAG;AAC/D,EAAA,uBACEA,cAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,EAAA;AAAA,MACP,MAAA,EAAQ,EAAA;AAAA,MACR,OAAA,EAAQ,WAAA;AAAA,MACR,IAAA,EAAK,MAAA;AAAA,MACL,MAAA,EAAO,cAAA;AAAA,MACP,WAAA,EAAa,CAAA;AAAA,MACb,aAAA,EAAc,OAAA;AAAA,MACd,cAAA,EAAe,OAAA;AAAA,MACf,WAAW,SAAA,IAAa,qBAAA;AAAA,MACxB,aAAA,EAAY,MAAA;AAAA,MAEZ,QAAA,kBAAAA,cAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,cAAA,EAAe;AAAA;AAAA,GACzB;AAEJ;AAWA,IAAM,kBAAA,GAAqB,gDAAA;AAE3B,SAAS,MAAA,CAAO;AAAA,EACd,IAAA;AAAA,EACA,MAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA,GAAU;AACZ,CAAA,EAKG;AACD,EAAA,MAAM,OAAO,IAAA,CAAK,IAAA;AAClB,EAAA,MAAM,QAAQ,OAAA,KAAY,KAAA;AAC1B,EAAA,MAAM,aAAA,GAAgB,QAClB,+EAAA,GACA,uDAAA;AACJ,EAAA,MAAM,cAAA,GAAiB;AAAA,IACrB,4DAAA;AAAA,IACA,SAAS,aAAA,GAAgB;AAAA,GAC3B,CAAE,KAAK,GAAG,CAAA;AAEV,EAAA,MAAM,UAAA,GAAa,QAAQ,yBAAA,GAA4B,mBAAA;AACvD,EAAA,MAAM,QAAA,GAAW,QAAQ,EAAA,GAAK,EAAA;AAG9B,EAAA,MAAM,SAAA,GAAY,MAAA,IAAU,CAAC,KAAA,GAAQ,YAAA,GAAe,cAAA;AAEpD,EAAA,MAAM,KAAA,mBACJD,eAAAA,CAAAK,mBAAAA,EAAA,EACG,QAAA,EAAA;AAAA,IAAA,CAAC,yBACAJ,cAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,aAAA,EAAY,MAAA;AAAA,QACZ,SAAA,EAAU,sGAAA;AAAA,QACV,KAAA,EAAO,EAAE,UAAA,EAAY,kBAAA;AAAmB;AAAA,KAC1C,GACE,IAAA;AAAA,oBACJD,eAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAW,CAAA,oDAAA,EAAuD,UAAU,CAAA,CAAA,EAC/E,QAAA,EAAA;AAAA,MAAA,IAAA,mBAAOC,cAAAA,CAAC,IAAA,EAAA,EAAK,MAAM,QAAA,EAAU,SAAA,EAAW,WAAW,CAAA,GAAK,IAAA;AAAA,MACxD,IAAA,CAAK;AAAA,KAAA,EACR;AAAA,GAAA,EACF,CAAA;AAMF,EAAA,IAAI,KAAK,QAAA,EAAU;AACjB,IAAA,uBACEA,cAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,eAAA,EAAc,MAAA;AAAA,QACd,OAAO,IAAA,CAAK,aAAA;AAAA,QACZ,SAAA,EAAW,GAAG,cAAc,CAAA,8BAAA,CAAA;AAAA,QAE3B,QAAA,EAAA;AAAA;AAAA,KACH;AAAA,EAEJ;AAEA,EAAA,IAAI,IAAA,CAAK,OAAA,IAAW,CAAC,IAAA,CAAK,IAAA,EAAM;AAC9B,IAAA,uBACEA,cAAAA,CAAC,QAAA,EAAA,EAAO,IAAA,EAAK,QAAA,EAAS,OAAA,EAAS,IAAA,CAAK,OAAA,EAAS,SAAA,EAAW,CAAA,iBAAA,EAAoB,cAAc,CAAA,CAAA,EACvF,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,EAEJ;AAEA,EAAA,uBACEA,cAAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAM,KAAK,IAAA,IAAQ,GAAA;AAAA,MACnB,cAAA,EAAc,SAAS,MAAA,GAAS,MAAA;AAAA,MAChC,SAAA,EAAW,cAAA;AAAA,MAEV,QAAA,EAAA;AAAA;AAAA,GACH;AAEJ;AAeA,SAAS,QAAA,CAAS;AAAA,EAChB,IAAA;AAAA,EACA,MAAA;AAAA,EACA,IAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAQG;AACD,EAAA,MAAM,OAAO,IAAA,CAAK,IAAA;AAClB,EAAA,MAAM,aAAA,GAAgB;AAAA,IACpB,kEAAA;AAAA,IACA,OAAO,cAAA,GAAiB,YAAA;AAAA,IACxB,MAAA,GACI,uDAAA,GACA,IAAA,GACE,wDAAA,GACA;AAAA,GACR,CAAE,KAAK,GAAG,CAAA;AAEV,EAAA,uBACED,gBAAC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAAA,eAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QAML,SAAS,MAAM;AACb,UAAA,QAAA,EAAS;AACT,UAAA,IAAA,CAAK,OAAA,IAAU;AAAA,QACjB,CAAA;AAAA,QACA,eAAA,EAAe,IAAA;AAAA,QACf,SAAA,EAAW,aAAA;AAAA,QAIV,QAAA,EAAA;AAAA,UAAA,CAAC,MAAA,IAAU,CAAC,IAAA,mBACXC,cAAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,aAAA,EAAY,MAAA;AAAA,cACZ,SAAA,EAAU,sGAAA;AAAA,cACV,KAAA,EAAO,EAAE,UAAA,EAAY,kBAAA;AAAmB;AAAA,WAC1C,GACE,IAAA;AAAA,0BACJD,eAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,uEAAA,EACb,QAAA,EAAA;AAAA,YAAA,IAAA,mBACCC,eAAC,IAAA,EAAA,EAAK,IAAA,EAAM,IAAI,SAAA,EAAW,MAAA,GAAS,YAAA,GAAe,cAAA,EAAgB,CAAA,GACjE,IAAA;AAAA,4BACJA,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,QAAA,EAAU,eAAK,KAAA,EAAM,CAAA;AAAA,4BACrCA,cAAAA;AAAA,cAAC,WAAA;AAAA,cAAA;AAAA,gBACC,SAAA,EAAW;AAAA,kBACT,uDAAA;AAAA,kBACA,OAAO,YAAA,GAAe;AAAA,iBACxB,CAAE,KAAK,GAAG;AAAA;AAAA;AACZ,WAAA,EACF;AAAA;AAAA;AAAA,KACF;AAAA,IAEC,uBACCA,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qEACb,QAAA,kBAAAA,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBACZ,QAAA,EAAA,IAAA,CAAK,QAAA,CAAU,GAAA,CAAI,CAAC,OAAO,CAAA,KAAM;AAChC,MAAA,MAAM,cAAc,KAAA,CAAM,IAAA,GAAO,SAAS,QAAA,EAAU,KAAA,CAAM,IAAI,CAAA,GAAI,KAAA;AAKlE,MAAA,IAAI,KAAA,CAAM,QAAA,IAAY,KAAA,CAAM,QAAA,CAAS,SAAS,CAAA,EAAG;AAC/C,QAAA,uBACEA,cAAAA;AAAA,UAAC,WAAA;AAAA,UAAA;AAAA,YAEC,IAAA,EAAM,KAAA;AAAA,YACN,QAAA;AAAA,YACA,QAAA;AAAA,YACA;AAAA,WAAA;AAAA,UAJK,MAAM,IAAA,IAAQ,CAAA,OAAA,EAAU,CAAC,CAAA,CAAA,EAAI,MAAM,KAAK,CAAA;AAAA,SAK/C;AAAA,MAEJ;AACA,MAAA,uBACEA,cAAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UAEC,IAAA,EAAM,KAAA;AAAA,UACN,MAAA,EAAQ,WAAA;AAAA,UACR,IAAA;AAAA,UACA,OAAA,EAAQ;AAAA,SAAA;AAAA,QAJH,MAAM,IAAA,IAAQ,CAAA,IAAA,EAAO,CAAC,CAAA,CAAA,EAAI,MAAM,KAAK,CAAA;AAAA,OAK5C;AAAA,IAEJ,CAAC,CAAA,EACH,CAAA,EACF,CAAA,GACE;AAAA,GAAA,EACN,CAAA;AAEJ;AAMA,SAAS,WAAA,CAAY;AAAA,EACnB,IAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAKG;AACD,EAAA,MAAM,UAAA,GAAA,CACH,KAAK,IAAA,GAAO,QAAA,CAAS,UAAU,IAAA,CAAK,IAAI,CAAA,GAAI,KAAA,KAAA,CAC5C,IAAA,CAAK,QAAA,IAAY,EAAC,EAAG,IAAA,CAAK,CAAC,CAAA,KAAO,CAAA,CAAE,IAAA,GAAO,SAAS,QAAA,EAAU,CAAA,CAAE,IAAI,CAAA,GAAI,KAAM,CAAA;AACjF,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIpB,eAAS,UAAU,CAAA;AAC3C,EAAAC,gBAAU,MAAM;AACd,IAAA,IAAI,UAAA,UAAoB,IAAI,CAAA;AAAA,EAC9B,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AACf,EAAA,MAAM,OAAO,IAAA,CAAK,IAAA;AAElB,EAAA,uBACEkB,gBAAC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAAA,eAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,SAAS,MAAM,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAC,CAAC,CAAA;AAAA,QAChC,eAAA,EAAe,IAAA;AAAA,QACf,SAAA,EAAW;AAAA,UACT,mGAAA;AAAA,UACA,aACI,oCAAA,GACA;AAAA,SACN,CAAE,KAAK,GAAG,CAAA;AAAA,QAET,QAAA,EAAA;AAAA,UAAA,IAAA,mBAAOC,cAAAA,CAAC,IAAA,EAAA,EAAK,MAAM,EAAA,EAAI,SAAA,EAAU,yBAAwB,CAAA,GAAK,IAAA;AAAA,0BAC/DA,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,QAAA,EAAU,eAAK,KAAA,EAAM,CAAA;AAAA,0BACrCA,cAAAA;AAAA,YAAC,WAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAW;AAAA,gBACT,uDAAA;AAAA,gBACA,OAAO,YAAA,GAAe;AAAA,eACxB,CAAE,KAAK,GAAG;AAAA;AAAA;AACZ;AAAA;AAAA,KACF;AAAA,IACC,IAAA,mBACCA,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qEAAA,EACZ,QAAA,EAAA,IAAA,CAAK,QAAA,CAAU,GAAA,CAAI,CAAC,IAAA,EAAM,CAAA,qBACzBA,cAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QAEC,IAAA,EAAM,IAAA;AAAA,QACN,QAAQ,IAAA,CAAK,IAAA,GAAO,SAAS,QAAA,EAAU,IAAA,CAAK,IAAI,CAAA,GAAI,KAAA;AAAA,QACpD,IAAA;AAAA,QACA,OAAA,EAAQ;AAAA,OAAA;AAAA,MAJH,KAAK,IAAA,IAAQ,CAAA,OAAA,EAAU,CAAC,CAAA,CAAA,EAAI,KAAK,KAAK,CAAA;AAAA,KAM9C,GACH,CAAA,GACE;AAAA,GAAA,EACN,CAAA;AAEJ;AAIA,SAAS,eAAA,CAAgB,EAAE,EAAA,EAAG,EAAmB;AAC/C,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIpB,eAAS,KAAK,CAAA;AAC1C,EAAA,uBACEoB,cAAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,QAAA;AAAA,MACL,SAAS,MAAM;AACb,QAAA,IAAI;AACF,UAAA,KAAK,SAAA,CAAU,SAAA,EAAW,SAAA,CAAU,EAAE,CAAA;AAAA,QACxC,CAAA,CAAA,MAAQ;AAAA,QAER;AACA,QAAA,SAAA,CAAU,IAAI,CAAA;AACd,QAAA,UAAA,CAAW,MAAM,SAAA,CAAU,KAAK,CAAA,EAAG,IAAI,CAAA;AAAA,MACzC,CAAA;AAAA,MACA,KAAA,EAAM,sBAAA;AAAA,MACN,SAAA,EAAU,kFAAA;AAAA,MAET,mBAAS,QAAA,GAAW,CAAA,GAAA,EAAM,EAAA,CAAG,KAAA,CAAM,EAAE,CAAC,CAAA;AAAA;AAAA,GACzC;AAEJ;AAiGO,SAAS,SAAA,CAAU;AAAA,EACxB,KAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EACA,IAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA,EAAmB;AAGjB,EAAA,MAAM,OAAA,GAAU,IAAA,EAAM,IAAA,EAAM,IAAA,EAAK,IAAK,EAAA;AACtC,EAAA,MAAM,cAAc,OAAA,CAAQ,MAAA,GAAS,KAAK,CAAC,OAAA,CAAQ,SAAS,GAAG,CAAA;AAC/D,EAAA,MAAM,cAAc,WAAA,GAAc,eAAA,CAAgB,OAAO,CAAA,GAAK,MAAM,KAAA,IAAS,WAAA;AAC7E,EAAA,MAAM,QAAA,GAAA,CAAY,WAAA,GAAc,OAAA,GAAW,IAAA,EAAM,KAAA,IAAS,KAAM,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,WAAA,EAAY;AACxF,EAAA,MAAM,SAAA,GAAY,WAAA,GACd,IAAA,EAAM,KAAA,IAAS,CAAC,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,IAAI,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,IAAA,CAAK,QAAK,CAAA,IAAK,QAAA,GACvE,CAAC,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,IAAI,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,IAAA,CAAK,QAAK,CAAA,IAAK,QAAA;AAC5D,EAAA,uBACED,eAAAA,CAAC,QAAA,EAAA,EAAO,SAAA,EAAU,kJAAA,EAChB,QAAA,EAAA;AAAA,oBAAAA,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,SAAA,EACb,QAAA,EAAA;AAAA,sBAAAC,cAAAA;AAAA,QAAC,IAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAU,8EAAA;AAAA,UACV,cAAA,EAAa,MAAA;AAAA,UAEZ,QAAA,EAAA;AAAA;AAAA,OACH;AAAA,MACC,WAAA,IAAe,WAAA,CAAY,MAAA,GAAS,CAAA,mBACnCA,cAAAA,CAAC,KAAA,EAAA,EAAI,YAAA,EAAW,YAAA,EAAa,WAAU,qEAAA,EACpC,QAAA,EAAA,WAAA,CAAY,GAAA,CAAI,CAAC,GAAG,CAAA,KAAM;AACzB,QAAA,MAAM,IAAA,GAAO,CAAA,KAAM,WAAA,CAAY,MAAA,GAAS,CAAA;AACxC,QAAA,uBACED,eAAAA,CAAC,MAAA,EAAA,EAA6B,SAAA,EAAU,mCAAA,EACrC,QAAA,EAAA;AAAA,UAAA,CAAA,GAAI,CAAA,mBACHC,cAAAA,CAAC,MAAA,EAAA,EAAK,eAAW,IAAA,EAAC,SAAA,EAAU,sCAAA,EAAuC,QAAA,EAAA,QAAA,EAEnE,CAAA,GACE,IAAA;AAAA,UACH,CAAA,CAAE,IAAA,IAAQ,CAAC,IAAA,mBACVA,cAAAA;AAAA,YAAC,GAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAM,QAAA,CAAS,CAAA,CAAE,IAAI,CAAA;AAAA,cACrB,SAAA,EAAU,+DAAA;AAAA,cAET,QAAA,EAAA,CAAA,CAAE;AAAA;AAAA,8BAGLA,cAAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,cAAA,EAAc,OAAO,MAAA,GAAS,MAAA;AAAA,cAC9B,SAAA,EAAW,CAAC,UAAA,EAAY,IAAA,GAAO,mCAAmC,EAAE,CAAA,CAAE,KAAK,GAAG,CAAA;AAAA,cAE7E,QAAA,EAAA,CAAA,CAAE;AAAA;AAAA;AACL,SAAA,EAAA,EAnBO,CAAA,EAAG,CAAA,CAAE,KAAK,CAAA,CAAA,EAAI,CAAC,CAAA,CAqB1B,CAAA;AAAA,MAEJ,CAAC,CAAA,EACH,CAAA,GACE,QAAA,mBACFA,eAAC,GAAA,EAAA,EAAE,SAAA,EAAU,4CAAA,EAA8C,QAAA,EAAA,QAAA,EAAS,CAAA,GAClE;AAAA,KAAA,EACN,CAAA;AAAA,oBAEAD,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sEAAA,EACZ,QAAA,EAAA;AAAA,MAAA,WAAA,IAAe,WAAA,CAAY,MAAA,GAAS,CAAA,GACjC,WAAA,CAAY,IAAI,CAAC,MAAA,qBACfC,cAAAA,CAAC,qBAAA,EAAA,EAAuC,MAAA,EAAA,EAAZ,MAAA,CAAO,GAAqB,CACzD,CAAA,GACD,IAAA;AAAA,MACH,OAAA;AAAA,MACA,WAAA;AAAA,sBAKDD,eAAAA,CAAC,SAAA,EAAA,EAAQ,kBAAA,EAAgB,IAAA,EAAC,WAAU,qBAAA,EAClC,QAAA,EAAA;AAAA,wBAAAA,eAAAA,CAAC,SAAA,EAAA,EAAQ,SAAA,EAAU,0LAAA,EAGjB,QAAA,EAAA;AAAA,0BAAAC,cAAAA,CAAC,UAAK,SAAA,EAAU,6MAAA,EACb,gBAAM,SAAA,IAAa,IAAA,EAAM,4BACxBA,cAAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,GAAA,EAAM,IAAA,CAAK,SAAA,IAAa,IAAA,CAAK,SAAA;AAAA,cAC7B,GAAA,EAAI,EAAA;AAAA,cACJ,SAAA,EAAU;AAAA;AAAA,cAGZ,QAAA,EAEJ,CAAA;AAAA,0BACAD,eAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,uCAAA,EACd,QAAA,EAAA;AAAA,4BAAAC,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,sDAAA,EACb,QAAA,EAAA,WAAA,EACH,CAAA;AAAA,4BACAA,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qCAAqC,QAAA,EAAA,SAAA,EAAU;AAAA,WAAA,EACjE,CAAA;AAAA,0BACAA,eAAC,WAAA,EAAA,EAAY,CAAA;AAAA,0BACbA,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,0BACd,QAAA,kBAAAA,cAAAA;AAAA,YAAC,aAAA;AAAA,YAAA;AAAA,cACC,KAAA,EAAM,YAAA;AAAA,cACN,WAAA,kBACED,eAAAA,CAAAK,mBAAAA,EAAA,EACG,QAAA,EAAA;AAAA,gBAAA,WAAA,GAAc,OAAA,GAAU,MAAM,KAAA,IAAS,WAAA;AAAA,gBACvC,IAAA,EAAM,KAAA,mBACLL,eAAAA,CAAAK,qBAAA,EACE,QAAA,EAAA;AAAA,kCAAAJ,eAAC,IAAA,EAAA,EAAG,CAAA;AAAA,kBACH,IAAA,CAAK;AAAA,iBAAA,EACR,CAAA,GACE,IAAA;AAAA,gCACJA,eAAC,IAAA,EAAA,EAAG,CAAA;AAAA,gBAAE;AAAA,eAAA,EAER;AAAA;AAAA,WAEJ,EACF;AAAA,SAAA,EACF,CAAA;AAAA,wBASAD,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uMAAA,EACb,QAAA,EAAA;AAAA,0BAAAC,eAAC,gBAAA,EAAA,EAAiB,CAAA;AAAA,0BAClBD,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,mDAAA,EACd,QAAA,EAAA;AAAA,YAAA,QAAA,EAAU,gCACTA,eAAAA;AAAA,cAAC,GAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAM,QAAA,CAAS,QAAA,CAAS,aAAa,CAAA;AAAA,gBACrC,SAAA,EAAU,yIAAA;AAAA,gBAEV,QAAA,EAAA;AAAA,kCAAAC,eAAC,WAAA,EAAA,EAAY,CAAA;AAAA,kBAAE;AAAA;AAAA;AAAA,aAEjB,GACE,IAAA;AAAA,YACH,QAAA,EAAU,2CACTD,eAAAA;AAAA,cAAC,GAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAM,QAAA,CAAS,QAAA,CAAS,wBAAwB,CAAA;AAAA,gBAChD,SAAA,EAAU,6KAAA;AAAA,gBAEV,QAAA,EAAA;AAAA,kCAAAC,eAAC,aAAA,EAAA,EAAc,CAAA;AAAA,kBAAE;AAAA;AAAA;AAAA,aAEnB,GACE,IAAA;AAAA,YAEH,QAAA,EAAU,KAAA,IAAS,QAAA,CAAS,KAAA,CAAM,MAAA,GAAS,oBAC1CD,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,+CAAA,EACb,QAAA,EAAA;AAAA,8BAAAC,cAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,sFAAA,EAAuF,QAAA,EAAA,uBAAA,EAEpG,CAAA;AAAA,8BACAA,cAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,yBACX,QAAA,EAAA,QAAA,CAAS,KAAA,CAAM,GAAA,CAAI,CAAC,GAAG,CAAA,qBACtBD,eAAAA,CAAC,IAAA,EAAA,EAA0B,WAAU,6CAAA,EACnC,QAAA,EAAA;AAAA,gCAAAC,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,yHAAA,EACb,YAAE,IAAA,EACL,CAAA;AAAA,gBACC,EAAE,OAAA,mBACDD,eAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,2BAAA,EAA4B,QAAA,EAAA;AAAA,kBAAA,KAAA;AAAA,kBAAI,CAAA,CAAE;AAAA,iBAAA,EAAQ,CAAA,GACxD;AAAA,eAAA,EAAA,EANG,GAAG,CAAA,CAAE,IAAI,IAAI,CAAC,CAAA,CAOvB,CACD,CAAA,EACH;AAAA,aAAA,EACF,CAAA,GACE,IAAA;AAAA,YAEH,QAAA,EAAU,QAAA,IAAY,QAAA,CAAS,QAAA,CAAS,MAAA,GAAS,oBAChDA,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,+CAAA,EACb,QAAA,EAAA;AAAA,8BAAAC,cAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,sFAAA,EAAuF,QAAA,EAAA,UAAA,EAEpG,CAAA;AAAA,8BACAA,cAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,uBACX,QAAA,EAAA,QAAA,CAAS,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,qBACtBD,eAAAA,CAAC,IAAA,EAAA,EAAc,WAAU,2BAAA,EACvB,QAAA,EAAA;AAAA,gCAAAA,eAAAA;AAAA,kBAAC,QAAA;AAAA,kBAAA;AAAA,oBACC,IAAA,EAAK,QAAA;AAAA,oBACL,SAAS,MAAM;AACb,sBAAA,IAAI,CAAC,CAAA,CAAE,MAAA,EAAQ,QAAA,CAAS,eAAA,GAAkB,EAAE,EAAE,CAAA;AAAA,oBAChD,CAAA;AAAA,oBACA,SAAA,EAAU,uGAAA;AAAA,oBAEV,QAAA,EAAA;AAAA,sCAAAC,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kJAAA,EACb,QAAA,EAAA,CAAA,CAAE,SAAA,mBACDA,cAAAA,CAAC,KAAA,EAAA,EAAI,GAAA,EAAK,CAAA,CAAE,SAAA,EAAW,GAAA,EAAI,EAAA,EAAG,SAAA,EAAU,4BAAA,EAA6B,CAAA,GAAA,CAEpE,CAAA,CAAE,IAAA,IAAQ,CAAA,CAAE,KAAA,IAAS,GAAA,EAAK,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,WAAA,EAAY,EAEvD,CAAA;AAAA,sCACAD,eAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qCAAA,EACd,QAAA,EAAA;AAAA,wCAAAC,cAAAA;AAAA,0BAAC,MAAA;AAAA,0BAAA;AAAA,4BACC,SAAA,EAAW;AAAA,8BACT,gCAAA;AAAA,8BACA,CAAA,CAAE,SACE,oCAAA,GACA;AAAA,6BACN,CAAE,KAAK,GAAG,CAAA;AAAA,4BAET,QAAA,EAAA,CAAA,CAAE,QAAQ,CAAA,CAAE,KAAA,IAAS,EAAE,EAAA,CAAG,KAAA,CAAM,GAAG,CAAC;AAAA;AAAA,yBACvC;AAAA,wCACAA,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,4CAAA,EACb,YAAE,MAAA,GAAS,QAAA,GAAW,CAAA,CAAE,KAAA,IAAS,EAAA,EACpC;AAAA,uBAAA,EACF;AAAA;AAAA;AAAA,iBACF;AAAA,gBACC,CAAC,CAAA,CAAE,MAAA,IAAU,QAAA,CAAS,kCACrBA,cAAAA;AAAA,kBAAC,QAAA;AAAA,kBAAA;AAAA,oBACC,IAAA,EAAK,QAAA;AAAA,oBACL,cAAY,CAAA,OAAA,EAAU,CAAA,CAAE,IAAA,IAAQ,CAAA,CAAE,SAAS,SAAS,CAAA,CAAA;AAAA,oBACpD,OAAA,EAAS,MAAM,QAAA,CAAS,eAAA,GAAkB,EAAE,EAAE,CAAA;AAAA,oBAC9C,SAAA,EAAU,uFAAA;AAAA,oBAEV,QAAA,kBAAAA,eAAC,SAAA,EAAA,EAAU;AAAA;AAAA,iBACb,GACE;AAAA,eAAA,EAAA,EAxCG,CAAA,CAAE,EAyCX,CACD,CAAA,EACH,CAAA;AAAA,cACC,SAAS,cAAA,IAAkB,QAAA,CAAS,YAAA,GACnC,QAAA,CAAS,iCACPD,eAAAA;AAAA,gBAAC,GAAA;AAAA,gBAAA;AAAA,kBACC,IAAA,EAAM,QAAA,CAAS,QAAA,CAAS,cAAc,CAAA;AAAA,kBACtC,SAAA,EAAU,gJAAA;AAAA,kBAEV,QAAA,EAAA;AAAA,oCAAAC,eAAC,WAAA,EAAA,EAAY,CAAA;AAAA,oBAAE;AAAA;AAAA;AAAA,kCAIjBD,eAAAA;AAAA,gBAAC,QAAA;AAAA,gBAAA;AAAA,kBACC,IAAA,EAAK,QAAA;AAAA,kBACL,SAAS,QAAA,CAAS,YAAA;AAAA,kBAClB,SAAA,EAAU,iKAAA;AAAA,kBAEV,QAAA,EAAA;AAAA,oCAAAC,eAAC,WAAA,EAAA,EAAY,CAAA;AAAA,oBAAE;AAAA;AAAA;AAAA,eAEjB,GAEA;AAAA,aAAA,EACN,CAAA,GACE,IAAA;AAAA,YAEH,UAAU,KAAA,mBACTA,eAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uCACb,QAAA,kBAAAA,cAAAA;AAAA,cAAC,eAAA;AAAA,cAAA;AAAA,gBACC,KAAA,EAAO,SAAS,KAAA,CAAM,KAAA;AAAA,gBACtB,QAAA,EAAU,SAAS,KAAA,CAAM;AAAA;AAAA,eAE7B,CAAA,GACE;AAAA,WAAA,EACJ,CAAA;AAAA,UAEC,4BACCD,eAAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,QAAA;AAAA,cACL,OAAA,EAAS,SAAA;AAAA,cACT,SAAA,EAAU,+NAAA;AAAA,cAEV,QAAA,EAAA;AAAA,gCAAAC,eAAC,WAAA,EAAA,EAAY,CAAA;AAAA,gBAAE;AAAA;AAAA;AAAA,WAEjB,GACE;AAAA,SAAA,EACN;AAAA,OAAA,EACF,CAAA;AAAA,MACC,CAAC,eAAe,IAAA,mBACfA,eAAC,gBAAA,EAAA,EAAiB,WAAA,EAAa,QAAA,EAAU,aAAA,EAAe,CAAA,GACtD;AAAA,KAAA,EACN;AAAA,GAAA,EACF,CAAA;AAEJ;AAQA,SAAS,gBAAA,CAAiB,EAAE,WAAA,EAAY,EAA6B;AACnE,EAAA,MAAM,GAAA,GAAM,gCAAA;AACZ,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIpB,eAAS,IAAI,CAAA;AAC/C,EAAAC,gBAAU,MAAM;AACd,IAAA,IAAI;AACF,MAAA,YAAA,CAAa,cAAA,CAAe,OAAA,CAAQ,GAAG,CAAA,KAAM,GAAG,CAAA;AAAA,IAClD,CAAA,CAAA,MAAQ;AACN,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AACL,EAAA,IAAI,WAAW,OAAO,IAAA;AACtB,EAAA,uBACEkB,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wJAAA,EACb,QAAA,EAAA;AAAA,oBAAAC,cAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,aAAA,EAAW,IAAA;AAAA,QACX,SAAA,EAAU;AAAA;AAAA,KACZ;AAAA,oBACAA,cAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,wDAAuD,QAAA,EAAA,eAAA,EAEpE,CAAA;AAAA,oBACAA,cAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,yDAAwD,QAAA,EAAA,0EAAA,EAErE,CAAA;AAAA,oBACAD,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,8BAAA,EACZ,QAAA,EAAA;AAAA,MAAA,WAAA,mBACCC,cAAAA;AAAA,QAAC,GAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAM,SAAS,WAAW,CAAA;AAAA,UAC1B,SAAA,EAAU,2GAAA;AAAA,UACX,QAAA,EAAA;AAAA;AAAA,OAED,GACE,IAAA;AAAA,sBACJA,cAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,SAAS,MAAM;AACb,YAAA,YAAA,CAAa,IAAI,CAAA;AACjB,YAAA,IAAI;AACF,cAAA,cAAA,CAAe,OAAA,CAAQ,KAAK,GAAG,CAAA;AAAA,YACjC,CAAA,CAAA,MAAQ;AAAA,YAER;AAAA,UACF,CAAA;AAAA,UACA,SAAA,EAAU,6IAAA;AAAA,UACX,QAAA,EAAA;AAAA;AAAA;AAED,KAAA,EACF;AAAA,GAAA,EACF,CAAA;AAEJ;AAGA,SAAS,gBAAgB,IAAA,EAAsB;AAC7C,EAAA,MAAM,QAAQ,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA,CAAE,OAAO,OAAO,CAAA;AAC9C,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,MAAM,CAAC,CAAA;AACtC,EAAA,OAAO,CAAA,EAAG,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA,EAAI,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA,CAAE,CAAC,CAAA,CAAE,aAAa,CAAA,CAAA,CAAA;AAChE;AAEA,SAAS,WAAA,GAAc;AACrB,EAAA,uBACED,gBAAC,KAAA,EAAA,EAAI,KAAA,EAAO,IAAI,MAAA,EAAQ,EAAA,EAAI,SAAQ,WAAA,EAAY,IAAA,EAAK,QAAO,MAAA,EAAO,cAAA,EAAe,aAAa,CAAA,EAAG,aAAA,EAAc,SAAQ,cAAA,EAAe,OAAA,EAAQ,eAAW,IAAA,EACxJ,QAAA,EAAA;AAAA,oBAAAC,cAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,2CAAA,EAA4C,CAAA;AAAA,oBACpDA,eAAC,QAAA,EAAA,EAAO,EAAA,EAAG,MAAK,EAAA,EAAG,GAAA,EAAI,GAAE,GAAA,EAAI;AAAA,GAAA,EAC/B,CAAA;AAEJ;AAEA,SAAS,aAAA,GAAgB;AACvB,EAAA,uBACED,gBAAC,KAAA,EAAA,EAAI,KAAA,EAAO,IAAI,MAAA,EAAQ,EAAA,EAAI,SAAQ,WAAA,EAAY,IAAA,EAAK,QAAO,MAAA,EAAO,cAAA,EAAe,aAAa,CAAA,EAAG,aAAA,EAAc,SAAQ,cAAA,EAAe,OAAA,EAAQ,eAAW,IAAA,EACxJ,QAAA,EAAA;AAAA,oBAAAC,cAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,GAAA,EAAI,CAAA,EAAE,GAAA,EAAI,KAAA,EAAM,IAAA,EAAK,MAAA,EAAO,IAAA,EAAK,EAAA,EAAG,GAAA,EAAI,IAAG,GAAA,EAAI,CAAA;AAAA,oBACvDA,cAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,4CAAA,EAA6C;AAAA,GAAA,EACvD,CAAA;AAEJ;AAEA,SAAS,SAAA,GAAY;AACnB,EAAA,uBACED,gBAAC,KAAA,EAAA,EAAI,KAAA,EAAO,IAAI,MAAA,EAAQ,EAAA,EAAI,SAAQ,WAAA,EAAY,IAAA,EAAK,QAAO,MAAA,EAAO,cAAA,EAAe,aAAa,CAAA,EAAG,aAAA,EAAc,SAAQ,cAAA,EAAe,OAAA,EAAQ,eAAW,IAAA,EACxJ,QAAA,EAAA;AAAA,oBAAAC,cAAAA,CAAC,UAAA,EAAA,EAAS,MAAA,EAAO,cAAA,EAAe,CAAA;AAAA,oBAChCA,cAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,gFAAA,EAAiF;AAAA,GAAA,EAC3F,CAAA;AAEJ;AAEA,SAAS,WAAA,GAAc;AACrB,EAAA,uBACED,gBAAC,KAAA,EAAA,EAAI,KAAA,EAAO,IAAI,MAAA,EAAQ,EAAA,EAAI,SAAQ,WAAA,EAAY,IAAA,EAAK,QAAO,MAAA,EAAO,cAAA,EAAe,aAAa,CAAA,EAAG,aAAA,EAAc,SAAQ,cAAA,EAAe,OAAA,EAAQ,eAAW,IAAA,EACxJ,QAAA,EAAA;AAAA,oBAAAC,cAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,2CAAA,EAA4C,CAAA;AAAA,oBACpDA,eAAC,QAAA,EAAA,EAAO,EAAA,EAAG,OAAM,EAAA,EAAG,GAAA,EAAI,GAAE,GAAA,EAAI,CAAA;AAAA,oBAC9BA,cAAAA,CAAC,MAAA,EAAA,EAAK,EAAA,EAAG,IAAA,EAAK,IAAG,GAAA,EAAI,EAAA,EAAG,IAAA,EAAK,EAAA,EAAG,IAAA,EAAK,CAAA;AAAA,oBACrCA,cAAAA,CAAC,MAAA,EAAA,EAAK,EAAA,EAAG,IAAA,EAAK,IAAG,IAAA,EAAK,EAAA,EAAG,IAAA,EAAK,EAAA,EAAG,IAAA,EAAK;AAAA,GAAA,EACxC,CAAA;AAEJ;AAGA,SAAS,WAAA,GAAc;AACrB,EAAA,uBACED,eAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,EAAA;AAAA,MACP,MAAA,EAAQ,EAAA;AAAA,MACR,OAAA,EAAQ,WAAA;AAAA,MACR,IAAA,EAAK,MAAA;AAAA,MACL,MAAA,EAAO,cAAA;AAAA,MACP,WAAA,EAAa,CAAA;AAAA,MACb,aAAA,EAAc,OAAA;AAAA,MACd,cAAA,EAAe,OAAA;AAAA,MACf,aAAA,EAAY,MAAA;AAAA,MAEZ,QAAA,EAAA;AAAA,wBAAAC,cAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,yCAAA,EAA0C,CAAA;AAAA,wBAClDA,cAAAA,CAAC,UAAA,EAAA,EAAS,MAAA,EAAO,kBAAA,EAAmB,CAAA;AAAA,wBACpCA,cAAAA,CAAC,MAAA,EAAA,EAAK,EAAA,EAAG,IAAA,EAAK,IAAG,GAAA,EAAI,EAAA,EAAG,IAAA,EAAK,EAAA,EAAG,IAAA,EAAK;AAAA;AAAA;AAAA,GACvC;AAEJ;AAKA,SAAS,qBAAA,CAAsB,EAAE,MAAA,EAAO,EAAgC;AACtE,EAAA,MAAM,OAAO,MAAA,CAAO,IAAA;AAMpB,EAAA,MAAM,SAAA,GAAY,qBAAA,CAAsB,MAAA,CAAO,IAAA,IAAQ,SAAS,CAAA;AAIhE,EAAA,MAAM,SAAA,GAAY,sBAAA,CAAuB,MAAA,CAAO,IAAA,IAAQ,MAAM,CAAA;AAC9D,EAAA,MAAM,UAAA,GAAa,MAAA,CAAO,IAAA,GAAO,iBAAA,CAAkB,SAAS,CAAA,GAAI,IAAA;AAChE,EAAA,MAAM,QAAQ,UAAA,IAAc,IAAA;AAE5B,EAAA,MAAM,OAAA,mBACJD,eAAAA,CAAAK,mBAAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAAJ,cAAAA,CAAC,KAAA,EAAA,EAAM,IAAA,EAAM,EAAA,EAAI,WAAU,cAAA,EAAe,CAAA;AAAA,IACzC,OAAO,MAAA,CAAO,KAAA,KAAU,QAAA,IAAY,OAAO,KAAA,GAAQ,CAAA,mBAClDA,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iJAAA,EACb,QAAA,EAAA,MAAA,CAAO,OACV,CAAA,GACE,IAAA;AAAA,oBACJA,eAAC,aAAA,EAAA,EAAc,KAAA,EAAO,OAAO,KAAA,EAAO,WAAA,EAAa,OAAO,WAAA,EAAa;AAAA,GAAA,EACvE,CAAA;AAGF,EAAA,MAAM,aAAa,MAAA,CAAO,IAAA,GAAO,eAAe,IAAA,CAAK,MAAA,CAAO,IAAI,CAAA,GAAI,KAAA;AAEpE,EAAA,IAAI,OAAO,IAAA,EAAM;AACf,IAAA,uBACEA,cAAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,QAAA,CAAS,MAAA,CAAO,IAAI,CAAA;AAAA,QAC1B,cAAY,MAAA,CAAO,KAAA;AAAA,QACnB,SAAA;AAAA,QACC,GAAI,aAAa,EAAE,MAAA,EAAQ,UAAU,GAAA,EAAK,YAAA,KAAiB,EAAC;AAAA,QAE5D,QAAA,EAAA;AAAA;AAAA,KACH;AAAA,EAEJ;AAEA,EAAA,uBACEA,cAAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,QAAA;AAAA,MACL,SAAS,MAAA,CAAO,OAAA;AAAA,MAChB,cAAY,MAAA,CAAO,KAAA;AAAA,MACnB,SAAA;AAAA,MAEC,QAAA,EAAA;AAAA;AAAA,GACH;AAEJ;AAgMA,IAAM,oBAAA,GAAuB;AAAA,EAC3B,IAAA,EAAM,4EAAA;AAAA,EACN,SAAA,EAAW,kEAAA;AAAA,EACX,IAAA,EAAM;AACR,CAAA;AAWO,SAAS,aAAA,CAAc,EAAE,IAAA,EAAM,SAAA,EAAW,MAAK,EAAuB;AAC3E,EAAA,MAAM,IAAA,GAAO,QAAQ,oBAAA,CAAqB,IAAA;AAC1C,EAAA,MAAM,KAAA,GAAQ,aAAa,oBAAA,CAAqB,SAAA;AAChD,EAAA,MAAM,MAAA,GAAS,QAAQ,oBAAA,CAAqB,IAAA;AAC5C,EAAA,uBACED,eAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,MAAA;AAAA,MACL,SAAA,EAAU,sCAAA;AAAA,MACV,KAAA,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAML,UAAA,EAAY,gCAAA;AAAA,QACZ,KAAA,EAAO;AAAA,OACT;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAAC,cAAAA,CAAC,UAAM,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,wBACZA,cAAAA;AAAA,UAAC,GAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAM,SAAS,MAAM,CAAA;AAAA,YACrB,MAAA,EAAO,QAAA;AAAA,YACP,GAAA,EAAI,YAAA;AAAA,YACJ,SAAA,EAAU,qBAAA;AAAA,YACV,KAAA,EAAO,EAAE,KAAA,EAAO,kCAAA,EAAmC;AAAA,YAElD,QAAA,EAAA;AAAA;AAAA;AACH;AAAA;AAAA,GACF;AAEJ;AAuCA,SAAS,gCAAA,GAAmC;AAC1C,EAAAnB,gBAAU,MAAM;AACd,IAAA,MAAM,KAAA,GAAQ,CAAC,MAAA,KAAwB;AACrC,MAAA,QAAA,CAAS,gBAAA,CAAiB,iCAAiC,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA,KAAM;AAC1E,QAAA,IAAI,CAAC,UAAU,CAAC,CAAA,CAAE,SAAS,MAAM,CAAA,EAAG,CAAA,CAAE,eAAA,CAAgB,MAAM,CAAA;AAAA,MAC9D,CAAC,CAAA;AAAA,IACH,CAAA;AACA,IAAA,MAAM,aAAA,GAAgB,CAAC,CAAA,KAAkB,KAAA,CAAM,EAAE,MAAc,CAAA;AAC/D,IAAA,MAAM,KAAA,GAAQ,CAAC,CAAA,KAAqB;AAClC,MAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,QAAA,EAAU,KAAA,CAAM,IAAI,CAAA;AAAA,IACpC,CAAA;AACA,IAAA,QAAA,CAAS,gBAAA,CAAiB,aAAa,aAAa,CAAA;AACpD,IAAA,QAAA,CAAS,gBAAA,CAAiB,WAAW,KAAK,CAAA;AAC1C,IAAA,OAAO,MAAM;AACX,MAAA,QAAA,CAAS,mBAAA,CAAoB,aAAa,aAAa,CAAA;AACvD,MAAA,QAAA,CAAS,mBAAA,CAAoB,WAAW,KAAK,CAAA;AAAA,IAC/C,CAAA;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AACP;AAEO,SAAS,WAAA,CAAY;AAAA,EAC1B,OAAA;AAAA,EACA,MAAA;AAAA,EACA,UAAA;AAAA,EACA,cAAA,GAAiB,QAAA;AAAA,EACjB;AACF,CAAA,EAAqB;AACnB,EAAA,gCAAA,EAAiC;AACjC,EAAA,uBACEkB,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,0EAAA,EACb,QAAA,EAAA;AAAA,oBAAAC,cAAAA,CAAC,UAAA,EAAA,EAAY,GAAG,OAAA,EAAS,CAAA;AAAA,oBACzBD,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,eAAA,EACb,QAAA,EAAA;AAAA,sBAAAC,cAAAA,CAAC,SAAA,EAAA,EAAW,GAAG,MAAA,EAAQ,CAAA;AAAA,MACtB,6BAAaA,cAAAA,CAAC,aAAA,EAAA,EAAe,GAAG,YAAY,CAAA,GAAK,IAAA;AAAA,MACjD,cAAA,KAAmB,MAAA,GAClB,QAAA,mBAEAA,eAAC,MAAA,EAAA,EAAK,SAAA,EAAU,WAAA,EACd,QAAA,kBAAAA,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,mBAAA,EAAqB,UAAS,CAAA,EAC/C;AAAA,KAAA,EAEJ;AAAA,GAAA,EACF,CAAA;AAEJ;;;ACzzDO,IAAM,iBAAA,GAAoB,qBAAA;AAC1B,IAAM,sBAAA,GAAyB,KAAA;AAItC,IAAM,OAAA,GAAU,iEAAA;AAET,SAAS,QAAQ,CAAA,EAAyB;AAC/C,EAAA,OAAO,OAAO,CAAA,KAAM,QAAA,IAAY,QAAQ,IAAA,CAAK,CAAA,CAAE,MAAM,CAAA;AACvD;AAGO,SAAS,mBAAA,GAAqC;AACnD,EAAA,IAAI,OAAO,QAAA,KAAa,WAAA,EAAa,OAAO,IAAA;AAC5C,EAAA,IAAI;AACF,IAAA,MAAM,CAAA,GAAI,SAAS,MAAA,CAAO,KAAA;AAAA,MACxB,IAAI,MAAA,CAAO,CAAA,WAAA,EAAc,iBAAiB,CAAA,QAAA,CAAU;AAAA,KACtD;AACA,IAAA,MAAM,IAAI,CAAA,GAAI,kBAAA,CAAmB,CAAA,CAAE,CAAC,CAAC,CAAA,GAAI,IAAA;AACzC,IAAA,OAAO,OAAA,CAAQ,CAAC,CAAA,GAAI,CAAA,GAAI,IAAA;AAAA,EAC1B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAMO,SAAS,qBAAqB,KAAA,EAAqB;AACxD,EAAA,IAAI,OAAO,QAAA,KAAa,WAAA,IAAe,OAAO,WAAW,WAAA,EAAa;AACtE,EAAA,IAAI,CAAC,OAAA,CAAQ,KAAK,CAAA,EAAG;AACrB,EAAA,MAAM,IAAA,GAAO,OAAO,QAAA,CAAS,QAAA;AAC7B,EAAA,MAAM,UAAA,GAAa,0BAAA,CAA2B,IAAA,CAAK,IAAI,IAAI,2BAAA,GAA8B,EAAA;AACzF,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,QAAA,CAAS,QAAA,KAAa,WAAW,UAAA,GAAa,EAAA;AACpE,EAAA,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG,iBAAiB,CAAA,CAAA,EAAI,kBAAA;AAAA,IACxC;AAAA,GACD,CAAA,wCAAA,EAA2C,UAAU,CAAA,EAAG,MAAM,CAAA,CAAA;AACjE;AAMO,SAAS,qBAAqB,MAAA,EAAkD;AACrF,EAAA,IAAI,CAAC,QAAQ,OAAO,IAAA;AACpB,EAAA,IAAI;AACF,IAAA,MAAM,EAAA,GAAK,MAAA,CAAO,QAAA,CAAS,GAAG,CAAA,GAAI,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,GAAI,CAAC,CAAA,GAAI,MAAA;AAC1E,IAAA,MAAM,IAAI,IAAI,eAAA,CAAgB,EAAE,CAAA,CAAE,IAAI,sBAAsB,CAAA;AAC5D,IAAA,OAAO,OAAA,CAAQ,CAAC,CAAA,GAAI,CAAA,GAAI,IAAA;AAAA,EAC1B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAUO,SAAS,iBAAiB,MAAA,EAAuC;AACtE,EAAA,MAAM,OAAA,GAAU,oBAAA;AAAA,KACH,OAAO,MAAA,KAAW,WAAA,GAAc,MAAA,CAAO,SAAS,MAAA,GAAS,IAAA;AAAA,GACtE;AACA,EAAA,IAAI,SAAS,OAAO,OAAA;AACpB,EAAA,OAAO,mBAAA,EAAoB;AAC7B;;;AClEO,IAAM,uBAAA,GAA0B,sBAAA;AAChC,IAAM,kBAAA,GAAqB,sBAAA;AAG3B,IAAM,sBAAA,GAAyB,gBAAA;AAE/B,IAAM,mBAAA,GAA4C,MAAA;AAEzD,IAAMS,MAAAA,GAAyC,CAAC,MAAA,EAAQ,MAAA,EAAQ,MAAM,CAAA;AAE/D,SAAS,uBAAuB,CAAA,EAAuC;AAC5E,EAAA,OAAO,OAAO,CAAA,KAAM,QAAA,IAAaA,MAAAA,CAA4B,SAAS,CAAC,CAAA;AACzE;AAGO,SAAS,oBAAA,GAAoD;AAClE,EAAA,IAAI,OAAO,QAAA,KAAa,WAAA,EAAa,OAAO,IAAA;AAC5C,EAAA,IAAI;AACF,IAAA,MAAM,CAAA,GAAI,SAAS,MAAA,CAAO,KAAA;AAAA,MACxB,IAAI,MAAA,CAAO,CAAA,WAAA,EAAc,kBAAkB,CAAA,QAAA,CAAU;AAAA,KACvD;AACA,IAAA,MAAM,IAAI,CAAA,GAAI,kBAAA,CAAmB,CAAA,CAAE,CAAC,CAAC,CAAA,GAAI,IAAA;AACzC,IAAA,OAAO,sBAAA,CAAuB,CAAC,CAAA,GAAI,CAAA,GAAI,IAAA;AAAA,EACzC,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAMO,SAAS,sBAAsB,IAAA,EAAkC;AACtE,EAAA,IAAI,OAAO,QAAA,KAAa,WAAA,IAAe,OAAO,WAAW,WAAA,EAAa;AACtE,EAAA,MAAM,IAAA,GAAO,OAAO,QAAA,CAAS,QAAA;AAC7B,EAAA,MAAM,UAAA,GAAa,0BAAA,CAA2B,IAAA,CAAK,IAAI,IAAI,2BAAA,GAA8B,EAAA;AACzF,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,QAAA,CAAS,QAAA,KAAa,WAAW,UAAA,GAAa,EAAA;AACpE,EAAA,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG,kBAAkB,CAAA,CAAA,EAAI,kBAAA;AAAA,IACzC;AAAA,GACD,CAAA,wCAAA,EAA2C,UAAU,CAAA,EAAG,MAAM,CAAA,CAAA;AACjE;AAGO,SAAS,mBAAA,GAAmD;AACjE,EAAA,IAAI,OAAO,YAAA,KAAiB,WAAA,EAAa,OAAO,IAAA;AAChD,EAAA,IAAI;AACF,IAAA,MAAM,OAAA,GAAU,YAAA,CAAa,OAAA,CAAQ,uBAAuB,CAAA;AAC5D,IAAA,IAAI,sBAAA,CAAuB,OAAO,CAAA,EAAG,OAAO,OAAA;AAC5C,IAAA,MAAM,MAAA,GAAS,YAAA,CAAa,OAAA,CAAQ,sBAAsB,CAAA;AAC1D,IAAA,OAAO,sBAAA,CAAuB,MAAM,CAAA,GAAI,MAAA,GAAS,IAAA;AAAA,EACnD,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEO,SAAS,qBAAqB,IAAA,EAAkC;AACrE,EAAA,IAAI,OAAO,iBAAiB,WAAA,EAAa;AACzC,EAAA,IAAI;AACF,IAAA,YAAA,CAAa,OAAA,CAAQ,yBAAyB,IAAI,CAAA;AAAA,EACpD,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAGO,SAAS,iBAAA,GAA0C;AACxD,EAAA,OAAO,oBAAA,EAAqB,IAAK,mBAAA,EAAoB,IAAK,mBAAA;AAC5D;AAM2C,CAAA;AAAA,QAAA,EACjC,IAAA,CAAK,SAAA,CAAU,uBAAuB,CAAC,CAAA;AAAA;AAAA,kEAAA,EAEmB,kBAAkB,CAAA;AAAA;AAAA;AAAA;AAAA,gBAAA;;;AC1F/E,SAAS,iBAAA,CACd,KAAA,EACA,QAAA,EACA,IAAA,EACiB;AACjB,EAAA,MAAM,MAAA,GAAS,MAAM,MAAA,KAAW,OAAO,WAAW,WAAA,GAAc,MAAA,CAAO,SAAS,MAAA,GAAS,EAAA,CAAA;AACzF,EAAA,MAAM,MAAA,GAAS,MAAM,MAAA,KAAW,OAAO,WAAW,WAAA,GAAc,MAAA,CAAO,SAAS,MAAA,GAAS,EAAA,CAAA;AAGzF,EAAA,MAAM,OAAA,GAAU,CAAC,IAAA,KAA2B;AAC1C,IAAA,IAAI,CAAC,MAAM,OAAO,KAAA;AAClB,IAAA,IAAI,IAAA,GAAO,IAAA;AACX,IAAA,IAAI,KAAA,GAAQ,EAAA;AACZ,IAAA,IAAI,eAAA,CAAgB,IAAA,CAAK,IAAI,CAAA,EAAG;AAC9B,MAAA,IAAI;AACF,QAAA,MAAM,CAAA,GAAI,IAAI,GAAA,CAAI,IAAI,CAAA;AACtB,QAAA,IAAI,MAAA,IAAU,CAAA,CAAE,MAAA,KAAW,MAAA,EAAQ,OAAO,KAAA;AAC1C,QAAA,IAAA,GAAO,CAAA,CAAE,QAAA;AACT,QAAA,KAAA,GAAQ,CAAA,CAAE,MAAA;AAAA,MACZ,CAAA,CAAA,MAAQ;AACN,QAAA,OAAO,KAAA;AAAA,MACT;AAAA,IACF,CAAA,MAAO;AACL,MAAA,MAAM,EAAA,GAAK,IAAA,CAAK,OAAA,CAAQ,GAAG,CAAA;AAC3B,MAAA,IAAI,MAAM,CAAA,EAAG;AACX,QAAA,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,IAAK,GAAA;AAC5B,QAAA,KAAA,GAAQ,IAAA,CAAK,MAAM,EAAE,CAAA;AAAA,MACvB;AAAA,IACF;AACA,IAAA,IAAI,IAAA,KAAS,UAAU,OAAO,KAAA;AAC9B,IAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AACnB,IAAA,MAAM,IAAA,GAAO,IAAI,eAAA,CAAgB,KAAK,CAAA;AACtC,IAAA,MAAM,IAAA,GAAO,IAAI,eAAA,CAAgB,MAAM,CAAA;AACvC,IAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,CAAA,IAAK,IAAA,EAAM,IAAI,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,EAAG,OAAO,KAAA;AACzD,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AAGA,EAAA,MAAM,IAAA,GAAO,CAAC,KAAA,EAAkBC,MAAAA,KAAuC;AACrE,IAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,MAAA,MAAM,IAAA,GAAO,CAAC,GAAGA,MAAAA,EAAO,IAAI,CAAA;AAC5B,MAAA,IAAI,IAAA,CAAK,UAAU,MAAA,EAAQ;AACzB,QAAA,MAAM,MAAA,GAAS,IAAA,CAAK,IAAA,CAAK,QAAA,EAAU,IAAI,CAAA;AACvC,QAAA,IAAI,QAAQ,OAAO,MAAA;AAAA,MACrB;AACA,MAAA,IAAI,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AAAA,IACjC;AACA,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AAEA,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,EAAO,EAAE,CAAA;AAG5B,EAAA,MAAM,YAAY,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,UAAU,WAAW,CAAA;AAC3D,EAAA,MAAM,MAAA,GAA0B,CAAC,EAAE,KAAA,EAAO,aAAa,IAAA,EAAM,SAAA,EAAW,MAAM,CAAA;AAC9E,EAAA,IAAI,CAAC,OAAO,OAAO,MAAA;AACnB,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,IAAI,IAAA,CAAK,UAAU,WAAA,EAAa;AAChC,IAAA,MAAA,CAAO,IAAA,CAAK,EAAE,KAAA,EAAO,IAAA,CAAK,OAAO,IAAA,EAAM,IAAA,CAAK,MAAM,CAAA;AAAA,EACpD;AACA,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,MAAA,CAAO,MAAA,GAAS,CAAC,CAAA;AACrC,EAAA,IAAI,IAAA,SAAc,IAAA,CAA2B,IAAA;AAC7C,EAAA,OAAO,MAAA;AACT;;;ACzDO,SAAS,eAAe,KAAA,EAA2C;AACxE,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,IAAY,6BAA6B,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA;AACpF;AAEO,SAAS,gBAAgB,KAAA,EAMX;AACnB,EAAA,MAAM,UAAU,cAAA,CAAe,KAAA,CAAM,OAAO,CAAA,GAAI,IAAA,GAAO,MAAM,OAAA,IAAW,IAAA;AACxE,EAAA,MAAM,eAAe,cAAA,CAAe,KAAA,CAAM,YAAY,CAAA,GAAI,IAAA,GAAO,MAAM,YAAA,IAAgB,IAAA;AACvF,EAAA,OAAO;AAAA,IACL,UAAU,OAAA,IAAW,YAAA;AAAA,IACrB,KAAA,EAAO,MAAM,KAAA,IAAS,IAAA;AAAA,IACtB,SAAA,EAAW,MAAM,SAAA,IAAa,IAAA;AAAA,IAC9B,MAAA,EAAQ,MAAM,MAAA,IAAU;AAAA,GAC1B;AACF;;;ACDO,IAAM,aAAA,GAAgB,oBAAA;AAG7B,IAAM,cAAA,GAAiB,iBAAA;AAGvB,IAAM,OAAA,GAAU,GAAA;AAEhB,SAAS,eAAe,KAAA,EAAiD;AACvE,EAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AACnB,EAAA,MAAM,CAAA,GAAI,OAAO,KAAK,CAAA;AACtB,EAAA,OAAO,OAAO,QAAA,CAAS,CAAC,CAAA,IAAK,CAAA,GAAI,IAAI,CAAA,GAAI,IAAA;AAC3C;AAYO,SAAS,gBAAA,CACd,mBACA,QAAA,EACS;AACT,EAAA,MAAM,WAAA,GAAc,eAAe,iBAAiB,CAAA;AACpD,EAAA,IAAI,WAAA,KAAgB,MAAM,OAAO,KAAA;AACjC,EAAA,IAAI,QAAA,IAAY,QAAQ,CAAC,MAAA,CAAO,SAAS,QAAQ,CAAA,IAAK,QAAA,IAAY,CAAA,EAAG,OAAO,IAAA;AAE5E,EAAA,MAAM,MAAA,GAAS,QAAA,GAAW,IAAA,GAAO,QAAA,GAAW,GAAA,GAAO,QAAA;AACnD,EAAA,OAAO,MAAA,GAAS,WAAA;AAClB;AAGO,SAAS,gBAAA,GAAkC;AAChD,EAAA,IAAI,OAAO,QAAA,KAAa,WAAA,EAAa,OAAO,IAAA;AAC5C,EAAA,IAAI;AACF,IAAA,MAAM,CAAA,GAAI,SAAS,MAAA,CAAO,KAAA,CAAM,IAAI,MAAA,CAAO,CAAA,WAAA,EAAc,aAAa,CAAA,QAAA,CAAU,CAAC,CAAA;AACjF,IAAA,OAAO,eAAe,CAAA,GAAI,kBAAA,CAAmB,EAAE,CAAC,CAAC,IAAI,IAAI,CAAA;AAAA,EAC3D,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAWO,SAAS,eAAA,CAAgB,EAAA,GAAa,IAAA,CAAK,GAAA,EAAI,EAAS;AAC7D,EAAA,IAAI,OAAO,QAAA,KAAa,WAAA,IAAe,OAAO,WAAW,WAAA,EAAa;AACtE,EAAA,MAAM,IAAA,GAAO,OAAO,QAAA,CAAS,QAAA;AAC7B,EAAA,MAAM,UAAA,GAAa,0BAAA,CAA2B,IAAA,CAAK,IAAI,IAAI,2BAAA,GAA8B,EAAA;AACzF,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,QAAA,CAAS,QAAA,KAAa,WAAW,UAAA,GAAa,EAAA;AAIpE,EAAA,QAAA,CAAS,MAAA,GAAS,GAAG,aAAa,CAAA,CAAA,EAAI,EAAE,CAAA,uCAAA,EAA0C,UAAU,GAAG,MAAM,CAAA,CAAA;AACrG,EAAA,IAAI;AACF,IAAA,IAAI,gBAAA,CAAiB,cAAc,CAAA,CAAE,WAAA,CAAY,EAAE,CAAA;AAAA,EACrD,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAsCO,SAAS,WAAA,CACd,QAAA,EACA,OAAA,GAA8B,EAAC,EACnB;AACZ,EAAA,IAAI,OAAO,QAAA,KAAa,WAAA,IAAe,OAAO,WAAW,WAAA,EAAa;AACpE,IAAA,OAAO,MAAM;AAAA,IAAC,CAAA;AAAA,EAChB;AAEA,EAAA,MAAM,EAAE,QAAA,GAAW,IAAA,EAAM,UAAA,GAAa,SAAQ,GAAI,OAAA;AAKlD,EAAA,MAAM,QAAA,GAAW,kBAAiB,IAAK,CAAA;AACvC,EAAA,IAAI,IAAA,GAAO,KAAA;AAEX,EAAA,MAAM,IAAA,GAAO,CAAC,EAAA,KAAe;AAC3B,IAAA,IAAI,IAAA,EAAM;AACV,IAAA,IAAI,MAAM,QAAA,EAAU;AACpB,IAAA,IAAI,QAAA,IAAY,QAAQ,CAAC,gBAAA,CAAiB,OAAO,EAAE,CAAA,EAAG,QAAQ,CAAA,EAAG;AACjE,IAAA,IAAA,GAAO,IAAA;AACP,IAAA,OAAA,EAAQ;AACR,IAAA,QAAA,EAAS;AAAA,EACX,CAAA;AAEA,EAAA,MAAM,QAAQ,MAAM;AAClB,IAAA,MAAM,KAAK,gBAAA,EAAiB;AAC5B,IAAA,IAAI,EAAA,KAAO,IAAA,EAAM,IAAA,CAAK,EAAE,CAAA;AAAA,EAC1B,CAAA;AAEA,EAAA,IAAI,OAAA,GAAmC,IAAA;AACvC,EAAA,IAAI;AACF,IAAA,OAAA,GAAU,IAAI,iBAAiB,cAAc,CAAA;AAC7C,IAAA,OAAA,CAAQ,SAAA,GAAY,CAAC,KAAA,KAAU;AAC7B,MAAA,MAAM,KAAK,OAAO,KAAA,CAAM,SAAS,QAAA,GAAW,KAAA,CAAM,OAAO,gBAAA,EAAiB;AAC1E,MAAA,IAAI,EAAA,KAAO,IAAA,EAAM,IAAA,CAAK,EAAE,CAAA;AAAA,IAC1B,CAAA;AAAA,EACF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAA,GAAU,IAAA;AAAA,EACZ;AAEA,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,WAAA,CAAY,KAAA,EAAO,UAAU,CAAA;AAClD,EAAA,MAAA,CAAO,gBAAA,CAAiB,oBAAoB,KAAK,CAAA;AACjD,EAAA,MAAA,CAAO,gBAAA,CAAiB,SAAS,KAAK,CAAA;AACtC,EAAA,MAAA,CAAO,gBAAA,CAAiB,YAAY,KAAK,CAAA;AAEzC,EAAA,SAAS,OAAA,GAAU;AACjB,IAAA,MAAA,CAAO,cAAc,KAAK,CAAA;AAC1B,IAAA,MAAA,CAAO,mBAAA,CAAoB,oBAAoB,KAAK,CAAA;AACpD,IAAA,MAAA,CAAO,mBAAA,CAAoB,SAAS,KAAK,CAAA;AACzC,IAAA,MAAA,CAAO,mBAAA,CAAoB,YAAY,KAAK,CAAA;AAC5C,IAAA,IAAI;AACF,MAAA,OAAA,EAAS,KAAA,EAAM;AAAA,IACjB,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAEA,EAAA,OAAO,OAAA;AACT;AC1IA,IAAM,QAAA,GAA2B,KAAA;AAOjC,IAAM,oBAAA,GAAuB,eAAA;AA+BtB,IAAM,aAAA,GAGT;AAAA,EACF,KAAK,EAAE,KAAA,EAAO,gBAAgB,MAAA,EAAQ,6BAAA,EAA+B,eAAe,KAAA,EAAM;AAAA,EAC1F,UAAU,EAAE,KAAA,EAAO,YAAY,MAAA,EAAQ,kCAAA,EAAoC,eAAe,UAAA,EAAW;AAAA,EACrG,OAAO,EAAE,KAAA,EAAO,SAAS,MAAA,EAAQ,+BAAA,EAAiC,eAAe,OAAA,EAAQ;AAAA,EACzF,SAAS,EAAE,KAAA,EAAO,WAAW,MAAA,EAAQ,iCAAA,EAAmC,eAAe,SAAA,EAAU;AAAA,EACjG,OAAO,EAAE,KAAA,EAAO,SAAS,MAAA,EAAQ,+BAAA,EAAiC,eAAe,OAAA,EAAQ;AAAA,EACzF,SAAA,EAAW;AAAA,IACT,KAAA,EAAO,WAAA;AAAA,IACP,MAAA,EAAQ,uCAAA;AAAA,IACR,aAAA,EAAe,WAAA;AAAA,IACf,IAAA,EAAM;AAAA,GACR;AAAA;AAAA;AAAA;AAAA,EAIA,GAAA,EAAK,EAAE,KAAA,EAAO,eAAA,EAAiB,QAAQ,6BAAA,EAA+B,aAAA,EAAe,KAAA,EAAO,IAAA,EAAM,UAAA,EAAW;AAAA,EAC7G,SAAA,EAAW,EAAE,KAAA,EAAO,eAAA,EAAiB,QAAQ,mCAAA,EAAqC,aAAA,EAAe,WAAA,EAAa,IAAA,EAAM,UAAA,EAAW;AAAA,EAC/H,OAAA,EAAS,EAAE,KAAA,EAAO,kBAAA,EAAoB,QAAQ,iCAAA,EAAmC,aAAA,EAAe,SAAA,EAAW,IAAA,EAAM,UAAA,EAAW;AAAA,EAC5H,KAAA,EAAO,EAAE,KAAA,EAAO,cAAA,EAAgB,QAAQ,+BAAA,EAAiC,aAAA,EAAe,OAAA,EAAS,IAAA,EAAM,UAAA;AACzG;AAuFO,SAAS,gBAAA,CAAiB;AAAA,EAC/B,GAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA;AAAA,EACA,aAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA,GAAa,oBAAA;AAAA,EACb,SAAA;AAAA,EACA,IAAA;AAAA,EACA;AACF,CAAA,EAqBG;AACD,EAAA,MAAM,IAAA,GAAO,cAAc,GAAG,CAAA;AAC9B,EAAA,uBACEV,cAAAA;AAAA,IAAC,iBAAA;AAAA,IAAA;AAAA,MACC,eAAe,IAAA,CAAK,aAAA;AAAA,MACpB,WAAW,IAAA,EAAM,SAAA;AAAA,MACjB,UAAU,IAAA,EAAM,QAAA;AAAA,MAChB,KAAK,IAAA,EAAM,GAAA;AAAA,MACX,QAAA,EAAU;AAAA,QACR,QAAQ,OAAA,CAAQ,MAAA;AAAA,QAChB,QAAA,EAAU,QAAQ,QAAA,IAAY,IAAA;AAAA,QAC9B,OAAO,OAAA,CAAQ,KAAA;AAAA,QACf,MAAM,OAAA,CAAQ;AAAA,OAChB;AAAA,MAEA,QAAA,kBAAAA,cAAAA;AAAA,QAAC,SAAA;AAAA,QAAA;AAAA,UACC,GAAA;AAAA,UACA,QAAA;AAAA,UACA,MAAA;AAAA,UACA,aAAA;AAAA,UACA,OAAA;AAAA,UACA,SAAA;AAAA,UACA,UAAA;AAAA,UACA,SAAA;AAAA,UACA,IAAA;AAAA,UAEC;AAAA;AAAA;AACH;AAAA,GACF;AAEJ;AAEA,SAAS,SAAA,CAAU;AAAA,EACjB,GAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA;AAAA,EACA,aAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,IAAA;AAAA,EACA;AACF,CAAA,EAWG;AACD,EAAA,MAAM,IAAA,GAAO,cAAc,GAAG,CAAA;AAC9B,EAAA,MAAM,SAAS,cAAA,EAAe;AAW9B,EAAA,MAAM,UAAA,GAAaG,aAAO,SAAS,CAAA;AACnC,EAAA,UAAA,CAAW,OAAA,GAAU,SAAA;AAGrB,EAAA,MAAM,aAAA,GAAgBA,aAAO,KAAK,CAAA;AAElC,EAAA,MAAM,aAAA,GAAgBE,kBAAY,MAAM;AACtC,IAAA,aAAA,CAAc,OAAA,GAAU,IAAA;AACxB,IAAA,eAAA,EAAgB;AAYhB,IAAA,UAAA,CAAW,OAAA,EAAQ;AACnB,IAAA,MAAA,CAAO,QAAA,CAAS,OAAO,UAAU,CAAA;AAAA,EACnC,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AAEf,EAAAxB,eAAAA;AAAA,IACE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAiBE,YAAY,MAAM;AAChB,QAAA,IAAI,cAAc,OAAA,EAAS;AAC3B,QAAA,MAAA,CAAO,QAAA,CAAS,OAAO,UAAU,CAAA;AAAA,MACnC,CAAC;AAAA,KAAA;AAAA,IACH,CAAC,UAAU;AAAA,GACb;AAIA,EAAA,MAAM,IAAA,GAAO,GAAA,KAAQ,QAAA,GAAW,IAAA,EAAM,IAAA,GAAO,MAAA;AAI7C,EAAA,MAAM,QAAA,GAAW,kBAAkB,EAAE,QAAA,EAAU,QAAQ,QAAA,EAAU,KAAA,EAAO,OAAA,CAAQ,KAAA,EAAO,CAAA;AACvF,EAAA,MAAM,kBAAkB,iBAAA,CAAkB;AAAA,IACxC,QAAQ,OAAA,CAAQ,MAAA;AAAA,IAChB,UAAU,QAAA,CAAS,QAAA;AAAA,IACnB,OAAO,QAAA,CAAS;AAAA,GACjB,CAAA;AACD,EAAA,MAAM,QAAA,GAAW,MAAM,QAAA,IAAY,eAAA;AACnC,EAAA,MAAM,MAAA,GAAS,eAAA,CAAgB,SAAA,IAAa,EAAE,CAAA;AAI9C,EAAA,MAAM,UAAU,IAAA,CAAK,IAAA;AACrB,EAAA,MAAM,cAAc,aAAA,CAAc,OAAA,GAAU,EAAE,YAAA,EAAc,OAAA,KAAY,MAAS,CAAA;AAEjF,EAAA,MAAM,IAAA,GAAO,MAAM,IAAA,IAAQ,WAAA;AAE3B,EAAA,MAAM,QAAA,GAAW,MAAA,EAAQ,IAAA,IAAQ,EAAC;AAClC,EAAA,MAAM,aAAA,GAAgB,SAAS,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,EAAA,KAAO,MAAA,EAAQ,KAAK,CAAA,IAAK,IAAA;AACtE,EAAA,MAAM,UAAA,GAAa,QAAQ,UAAA,IAAc,MAAA;AAMzC,EAAA,MAAM,UAA2B,OAAA,IAAW,cAAA;AAC5C,EAAA,MAAM,WAAA,GAAc,QAAQ,KAAA,IAAS,IAAA;AACrC,EAAA,MAAM,eAAA,GAAkB2B,aAAAA;AAAA,IACtB,MACE,mBAAA,CAAoB;AAAA,MAClB,WAAA,EAAa,cAAc,GAAA,CAAI,MAAA;AAAA,MAC/B,KAAA,EAAO,gBAAA;AAAA;AAAA;AAAA,MAGP,cAAc,IAAA,EAAM,YAAA;AAAA,MACpB,IAAA,EAAM,OAAA;AAAA,MACN;AAAA,KACD,CAAA;AAAA,IACH,CAAC,IAAA,EAAM,YAAA,EAAc,OAAA,EAAS,WAAW;AAAA,GAC3C;AAGA,EAAA,MAAM,QAAA,GAAW,MAAM,GAAA,IAAO,eAAA;AAK9B,EAAA,MAAM,kBAAA,GAAqBA,aAAAA;AAAA,IACzB,MAAM,kBAAkB,QAAA,EAAU,QAAA,EAAU,EAAE,MAAA,EAAQ,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAQ,CAAA;AAAA,IAC3E,CAAC,QAAA,EAAU,QAAA,EAAU,MAAA,EAAQ,KAAK,MAAM;AAAA,GAC1C;AACA,EAAA,MAAM,WAAA,GAAc,IAAA,GAAO,IAAA,CAAK,IAAA,EAAM,WAAA,GAAc,kBAAA;AAEpD,EAAA,uBACER,cAAAA;AAAA,IAAC,WAAA;AAAA,IAAA;AAAA,MACC,OAAA,EAAS;AAAA,QACP,QAAA;AAAA,QACA,KAAA,EAAO;AAAA,UACL,OAAA,EAAS,MAAM,YAAA,IAAgB,yCAAA;AAAA,UAC/B,OAAA,EAAS,UAAA;AAAA,UACT,UAAA,EAAY,GAAA;AAAA,UACZ,KAAA,EAAO;AAAA,SACT;AAAA,QACA,GAAA,EAAK;AAAA,UACH,KAAA,EACE,UAAA,KAAe,MAAA,GACX,QAAA,CAAS,GAAA,CAAI,CAAC,EAAE,QAAA,EAAU,IAAA,EAAM,GAAG,IAAA,EAAK,KAAM,IAAI,CAAA,GAClD;AAAA,SACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAMA,KAAK,aAAA,GACD;AAAA,UACE,MAAM,aAAA,CAAc,IAAA;AAAA,UACpB,IAAI,aAAA,CAAc,EAAA;AAAA,UAClB,SAAS,aAAA,CAAc,OAAA;AAAA,UACvB,YAAY,aAAA,CAAc,UAAA;AAAA,UAC1B,aAAA,EAAe,QAAA;AAAA,UACf,UAAU,MAAA,EAAQ;AAAA,YAEpB,MAAA,EAAQ,WAAA,GACN,EAAE,IAAA,EAAM,MAAM,EAAA,EAAI,IAAA,EAAM,OAAA,EAAS,IAAA,KACjC,EAAE,IAAA,EAAM,QAAQ,WAAA,EAAa,EAAA,EAAI,QAAQ,SAAA,EAAU;AAAA,QACzD,IAAA;AAAA,QACA,MAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,YAAY,EAAC;AAAA,MACb,gBAAgB,IAAA,EAAM,cAAA;AAAA,MACtB,MAAA,EAAQ;AAAA;AAAA;AAAA,QAGN,KAAA,EAAO,IAAA,EAAM,IAAA,EAAM,KAAA,IAAS,IAAA,CAAK,KAAA;AAAA,QACjC,WAAA;AAAA,QACA,IAAA,EAAM;AAAA,UACJ,MAAM,QAAA,CAAS,QAAA;AAAA,UACf,OAAO,QAAA,CAAS,KAAA;AAAA;AAAA;AAAA,UAGhB,SAAA,EAAW,QAAA,CAAS,SAAA,IAAa,IAAA,EAAM,iBAAA,IAAqB,IAAA;AAAA,UAC5D,MAAM,OAAA,CAAQ;AAAA,SAChB;AAAA,QACA,QAAA;AAAA,QACA,SAAA,EAAW,aAAA;AAAA;AAAA;AAAA;AAAA,QAIX,OAAA,kBACED,eAAAA,CAAAK,mBAAAA,EAAA,EACG,QAAA,EAAA;AAAA,UAAA,IAAA,EAAM,IAAA,EAAM,OAAA;AAAA,0BACbJ,eAAC,mBAAA,EAAA,EAAoB;AAAA,SAAA,EACvB;AAAA,OAEJ;AAAA,MAEC;AAAA;AAAA,GACH;AAEJ;ACxXO,IAAM,gBAAA,GAAwD;AAAA,EACnE,IAAA,EAAMW,SAAA;AAAA,EACN,KAAA,EAAOC,UAAA;AAAA,EACP,IAAA,EAAMlB,SAAAA;AAAA,EACN,aAAA,EAAeC,kBAAAA;AAAA,EACf,MAAA,EAAQkB,WAAA;AAAA,EACR,QAAA,EAAUC,aAAA;AAAA,EACV,QAAA,EAAUzB,aAAAA;AAAA,EACV,IAAA,EAAMJ,SAAAA;AAAA,EACN,IAAA,EAAM8B,SAAA;AAAA,EACN,MAAA,EAAQC,WAAA;AAAA,EACR,IAAA,EAAMC,UAAA;AAAA,EACN,QAAA,EAAUC,aAAA;AAAA,EACV,IAAA,EAAMC,SAAA;AAAA,EACN,KAAA,EAAOC,UAAA;AAAA,EACP,IAAA,EAAMvB,SAAAA;AAAA,EACN,QAAA,EAAUwB,cAAA;AAAA,EACV,SAAA,EAAWC,cAAA;AAAA,EACX,QAAA,EAAU1B,aAAAA;AAAA,EACV,UAAA,EAAY2B,eAAA;AAAA,EACZ,UAAA,EAAYC,eAAA;AAAA,EACZ,KAAA,EAAOC,WAAA;AAAA;AAAA,EAEP,KAAA,EAAOC,UAAA;AAAA,EACP,GAAA,EAAKC,QAAA;AAAA,EACL,MAAA,EAAQC,WAAA;AAAA,EACR,MAAA,EAAQC,WAAA;AAAA,EACR,IAAA,EAAMC;AACR;AAEA,IAAM,eAAA,GAAkB,eAAA;AAExB,IAAM,gBAAA,GAAmB,gBAAA;AACzB,IAAM,aAAA,GAAgB,6BAAA;AAwBtB,IAAM,kBAAA,GAAqB7B,oBAAkC,IAAI,CAAA;AAE1D,SAAS,cAAA,GAAqC;AACnD,EAAA,OAAOC,iBAAW,kBAAkB,CAAA;AACtC;AASA,SAAS,mBAAA,CAAoB;AAAA,EAC3B,aAAA;AAAA,EACA;AACF,CAAA,EAGG;AACD,EAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAS,cAAc,KAAA,EAAO,SAAA,KAAc,aAAA,EAAc;AACxE,EAAA,MAAM,WAAW,WAAA,EAAY;AAC7B,EAAA,MAAM,cAAc,mBAAA,EAAoB;AACxC,EAAA,MAAM,CAAC,KAAA,EAAO,aAAa,CAAA,GAAItB,eAAwB,IAAI,CAAA;AAC3D,EAAA,MAAM,CAAC,UAAA,EAAY,kBAAkB,CAAA,GAAIA,eAAyB,mBAAmB,CAAA;AACrF,EAAA,MAAM,aAAA,GAAgBuB,aAAO,KAAK,CAAA;AAQlC,EAAAtB,gBAAU,MAAM;AACd,IAAA,IAAI;AACF,MAAA,MAAM,SAAA,GAAY,gBAAA,EAAiB,IAAK,YAAA,CAAa,QAAQ,eAAe,CAAA;AAC5E,MAAA,IAAI,SAAA,gBAAyB,SAAS,CAAA;AAAA,IACxC,CAAA,CAAA,MAAQ;AAAA,IAER;AACA,IAAA,kBAAA,CAAmB,mBAAmB,CAAA;AAAA,EACxC,CAAA,EAAG,EAAE,CAAA;AAIL,EAAAA,gBAAU,MAAM;AACd,IAAA,IAAI,aAAA,CAAc,OAAA,IAAW,CAAC,QAAA,CAAS,EAAA,EAAI;AAC3C,IAAA,MAAM,IAAA,GAAO,SAAS,EAAA,CAAG,UAAA;AACzB,IAAA,IAAI,CAAC,sBAAA,CAAuB,IAAI,CAAA,EAAG;AACnC,IAAA,aAAA,CAAc,OAAA,GAAU,IAAA;AACxB,IAAA,kBAAA,CAAmB,IAAI,CAAA;AACvB,IAAA,qBAAA,CAAsB,IAAI,CAAA;AAC1B,IAAA,oBAAA,CAAqB,IAAI,CAAA;AAAA,EAC3B,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AAIb,EAAAA,gBAAU,MAAM;AACd,IAAA,MAAM,SAAA,GAAY,CAAC,CAAA,KAAoB;AACrC,MAAA,IAAI,EAAE,GAAA,KAAQ,uBAAA,IAA2B,sBAAA,CAAuB,CAAA,CAAE,QAAQ,CAAA,EAAG;AAC3E,QAAA,kBAAA,CAAmB,EAAE,QAAQ,CAAA;AAAA,MAC/B;AAAA,IACF,CAAA;AACA,IAAA,MAAM,SAAS,MAAM;AACnB,MAAA,MAAM,SAAS,oBAAA,EAAqB;AACpC,MAAA,IAAI,MAAA,qBAA2B,MAAM,CAAA;AAAA,IACvC,CAAA;AACA,IAAA,MAAA,CAAO,gBAAA,CAAiB,WAAW,SAAS,CAAA;AAC5C,IAAA,MAAA,CAAO,gBAAA,CAAiB,SAAS,MAAM,CAAA;AACvC,IAAA,QAAA,CAAS,gBAAA,CAAiB,oBAAoB,MAAM,CAAA;AACpD,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,mBAAA,CAAoB,WAAW,SAAS,CAAA;AAC/C,MAAA,MAAA,CAAO,mBAAA,CAAoB,SAAS,MAAM,CAAA;AAC1C,MAAA,QAAA,CAAS,mBAAA,CAAoB,oBAAoB,MAAM,CAAA;AAAA,IACzD,CAAA;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAGL,EAAAA,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,IAAA,IAAQ,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG;AAChC,IAAA,aAAA,CAAc,CAAC,IAAA,KAAU,IAAA,IAAQ,IAAA,CAAK,KAAK,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,IAAI,CAAA,GAAI,IAAA,GAAO,IAAA,CAAK,CAAC,EAAE,EAAG,CAAA;AAAA,EACvF,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAA,MAAM,QAAA,GAAWwB,iBAAAA,CAAY,CAAC,EAAA,KAAe;AAC3C,IAAA,aAAA,CAAc,EAAE,CAAA;AAChB,IAAA,IAAI;AACF,MAAA,YAAA,CAAa,OAAA,CAAQ,iBAAiB,EAAE,CAAA;AAAA,IAC1C,CAAA,CAAA,MAAQ;AAAA,IAER;AAEA,IAAA,oBAAA,CAAqB,EAAE,CAAA;AAAA,EACzB,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,aAAA,GAAgBA,iBAAAA;AAAA,IACpB,CAAC,CAAA,KAAsB;AACrB,MAAA,kBAAA,CAAmB,CAAC,CAAA;AACpB,MAAA,oBAAA,CAAqB,CAAC,CAAA;AAEtB,MAAA,qBAAA,CAAsB,CAAC,CAAA;AAGvB,MAAA,WAAA,GAAc,gBAAA,EAAkB;AAAA,QAC9B,MAAA,EAAQ,OAAA;AAAA,QACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,QAC9C,MAAM,IAAA,CAAK,SAAA,CAAU,EAAE,UAAA,EAAY,GAAG;AAAA,OACvC,CAAA,EAAG,KAAA,CAAM,MAAM;AAAA,MAAC,CAAC,CAAA;AAAA,IACpB,CAAA;AAAA,IACA,CAAC,WAAW;AAAA,GACd;AAEA,EAAA,MAAM,KAAA,GAAQG,cAAqB,MAAM;AAIvC,IAAA,IAAI,aAAA,EAAe;AACjB,MAAA,OAAO;AAAA,QACL,OAAO,aAAA,CAAc,KAAA;AAAA,QACrB,UAAU,aAAA,CAAc,QAAA;AAAA,QACxB,IAAA,EACE,cAAc,IAAA,IAAA,CACb,IAAA,IAAQ,EAAC,EAAG,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,UACvB,IAAI,CAAA,CAAE,EAAA;AAAA,UACN,MAAM,CAAA,CAAE,IAAA;AAAA,UACR,SAAS,CAAA,CAAE,OAAA;AAAA,UACX,YAAY,CAAA,CAAE,UAAA;AAAA,UACd,MAAM,CAAA,CAAE,IAAA;AAAA,UACR,OAAA,EAAS,EAAE,OAAA,IAAW;AAAA,SACxB,CAAE,CAAA;AAAA,QACJ,WAAA,EAAa,KAAA;AAAA,QACb,UAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF;AACA,IAAA,OAAO;AAAA,MACL,KAAA;AAAA,MACA,QAAA;AAAA,MACA,OAAO,IAAA,IAAQ,EAAC,EAAG,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,QAC7B,IAAI,CAAA,CAAE,EAAA;AAAA,QACN,MAAM,CAAA,CAAE,IAAA;AAAA,QACR,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,YAAY,CAAA,CAAE,UAAA;AAAA,QACd,MAAM,CAAA,CAAE,IAAA;AAAA,QACR,OAAA,EAAS,EAAE,OAAA,IAAW;AAAA,OACxB,CAAE,CAAA;AAAA;AAAA;AAAA,MAGF,WAAA,EAAa,YAAA,IAAgB,CAAC,SAAA,IAAa,CAAC,IAAA;AAAA,MAC5C,UAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF,CAAA,EAAG,CAAC,aAAA,EAAe,KAAA,EAAO,QAAA,EAAU,MAAM,YAAA,EAAc,SAAA,EAAW,UAAA,EAAY,aAAa,CAAC,CAAA;AAM7F,EAAA,MAAM,cAAc,KAAA,CAAM,KAAA;AAC1B,EAAA3B,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,CAAQ,WAAW,CAAA,EAAG;AAC3B,IAAA,oBAAA,CAAqB,WAAqB,CAAA;AAC1C,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,MAAA,CAAO,SAAS,IAAI,CAAA;AACxC,MAAA,IAAI,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,sBAAsB,MAAM,WAAA,EAAa;AAChE,QAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,sBAAA,EAAwB,WAAqB,CAAA;AAClE,QAAA,MAAA,CAAO,OAAA,CAAQ,aAAa,MAAA,CAAO,OAAA,CAAQ,OAAO,EAAA,EAAI,GAAA,CAAI,UAAU,CAAA;AAAA,MACtE;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF,CAAA,EAAG,CAAC,WAAW,CAAC,CAAA;AAEhB,EAAA,uBAAOmB,cAAAA,CAAC,kBAAA,CAAmB,QAAA,EAAnB,EAA4B,OAAe,QAAA,EAAS,CAAA;AAC9D;AAoBA,SAAS,WAAA,CAAY;AAAA,EACnB,aAAA;AAAA,EACA,aAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAMG;AACD,EAAA,MAAM,OAAA,GAAUQ,aAAAA;AAAA,IACd,MACEuB,6BAAA,CAAqB;AAAA,MACnB,QAAA,EAAU,QAAA,EAAU,QAAA,IAAY,CAAA,EAAG,aAAa,CAAA,SAAA,CAAA;AAAA;AAAA,MAEhD,YAAA,EAAc,QAAA,EAAU,YAAA,KAAiB,YAAY,EAAA,CAAA;AAAA,MACrD,GAAI,UAAU,KAAA,GAAQ,EAAE,OAAO,QAAA,CAAS,KAAA,KAAU;AAAC,KACpD,CAAA;AAAA,IACH,CAAC,aAAA,EAAe,QAAA,EAAU,UAAU,QAAA,EAAU,YAAA,EAAc,UAAU,KAAK;AAAA,GAC7E;AAEA,EAAA,MAAM,IAAA,GAAOvB,aAAAA;AAAA,IACX,OAAO;AAAA,MACL,IAAI,QAAA,CAAS,MAAA;AAAA,MACb,KAAA,EAAO,SAAS,KAAA,IAAS,EAAA;AAAA,MACzB,QAAA,EAAU,SAAS,QAAA,IAAY;AAAA,KACjC,CAAA;AAAA,IACA,CAAC,QAAA,CAAS,MAAA,EAAQ,QAAA,CAAS,KAAA,EAAO,SAAS,QAAQ;AAAA,GACrD;AAEA,EAAA,MAAM,MAAA,GAASA,aAAAA;AAAA,IACb,OAAO;AAAA,MACL,aAAA;AAAA,MACA,MAAM,QAAA,CAAS,IAAA,CAAK,WAAA,EAAY,KAAM,UAAU,OAAA,GAAU,UAAA;AAAA,MAC1D,SAAA,EAAW,IAAA;AAAA,MACX,WAAA,EAAa,MAAM,MAAA,CAAO,QAAA,CAAS;AAAA,KACrC,CAAA;AAAA,IACA,CAAC,aAAA,EAAe,QAAA,CAAS,IAAI;AAAA,GAC/B;AAIA,EAAA,IAAI,UAAU,aAAA,EAAe,uBAAOR,cAAAA,CAAC,mBAAiB,QAAA,EAAS,CAAA;AAE/D,EAAA,uBACEA,cAAAA,CAACgC,yBAAA,EAAA,EAAiB,OAAA,EAAkB,IAAA,EAAY,QAC9C,QAAA,kBAAAhC,cAAAA,CAAC,eAAA,EAAA,EAAiB,QAAA,EAAS,CAAA,EAC7B,CAAA;AAEJ;AAKA,IAAM,uBAAuBC,mBAAAA,CAAyD;AAAA,EACpF,KAAA,EAAO,KAAA;AAAA,EACP,WAAW,MAAM;AAAA,EAAC;AACpB,CAAC,CAAA;AAaD,SAAS,eAAA,CAAgB,EAAE,QAAA,EAAS,EAA4B;AAC9D,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIrB,eAAS,KAAK,CAAA;AAChD,EAAA,MAAM,YAAYyB,iBAAAA,CAAY,MAAM,aAAa,IAAI,CAAA,EAAG,EAAE,CAAA;AAC1D,EAAA,MAAM,QAAA,GAAWG,aAAAA,CAAQ,OAAO,EAAE,KAAA,EAAO,MAAM,SAAA,EAAU,CAAA,EAAI,CAAC,SAAS,CAAC,CAAA;AAExE,EAAA,uBACET,eAAAA,CAAC,oBAAA,CAAqB,QAAA,EAArB,EAA8B,OAAO,QAAA,EACnC,QAAA,EAAA;AAAA,IAAA,QAAA;AAAA,IAIA,SAAA,mBAAYC,cAAAA,CAACiC,8BAAA,EAAA,EAAsB,IAAA,EAAI,IAAA,EAAC,OAAA,EAAS,MAAM,YAAA,CAAa,KAAK,CAAA,EAAG,CAAA,GAAK,IAAA;AAAA,oBAClFjC,eAACkC,wBAAA,EAAA,EAAgB;AAAA,GAAA,EACnB,CAAA;AAEJ;AASO,SAAS,iBAAA,CAAkB;AAAA,EAChC,aAAA;AAAA,EACA,aAAA,GAAgB,aAAA;AAAA,EAChB,SAAA,EAAW,iBAAA;AAAA,EACX,QAAA;AAAA,EACA,GAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAeG;AACD,EAAA,MAAM,cAAA,GAAiB1B,aAAAA;AAAA,IACrB,MACE,OAAO,IAAA,EAAM,IAAA,KAAS;AACpB,MAAA,MAAM,MAAM,MAAM,KAAA,CAAM,GAAG,aAAa,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,EAAI;AAAA,QAClD,MAAA,EAAQ,MAAM,MAAA,IAAU,KAAA;AAAA,QACxB,SAAS,IAAA,EAAM,OAAA;AAAA,QACf,MAAM,IAAA,EAAM;AAAA,OACb,CAAA;AACD,MAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,MAAM,IAAI,KAAA,CAAM,CAAA,OAAA,EAAU,IAAI,CAAA,EAAA,EAAK,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AAC5D,MAAA,IAAI,GAAA,CAAI,MAAA,KAAW,GAAA,EAAK,OAAO,IAAA;AAC/B,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,MAAA,OAAO,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA,GAAI,IAAA;AAAA,IACnC,CAAA;AAAA,IACF,CAAC,aAAa;AAAA,GAChB;AACA,EAAA,MAAM,YAAY,iBAAA,IAAqB,cAAA;AAEvC,EAAA,uBACER,eAAC,iBAAA,EAAA,EAAkB,SAAA,EACjB,0BAAAA,cAAAA,CAAC,mBAAA,EAAA,EAAoB,aAAA,EAAe,GAAA,EAClC,QAAA,kBAAAA,cAAAA;AAAA,IAAC,WAAA;AAAA,IAAA;AAAA,MACC,aAAA;AAAA,MACA,aAAA;AAAA,MACA,QAAA;AAAA,MACA,QAAA;AAAA,MAEC;AAAA;AAAA,KAEL,CAAA,EACF,CAAA;AAEJ;AAIO,SAAS,mBAAA,GAAsB;AACpC,EAAA,MAAM,QAAQ,cAAA,EAAe;AAC7B,EAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AACnB,EAAA,uBACED,eAAAA,CAAAK,mBAAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAAJ,cAAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAO,KAAA,CAAM,KAAA,EAAO,CAAA;AAAA,oBAChCA,eAAC,gBAAA,EAAA,EAAiB,KAAA,EAAO,MAAM,UAAA,EAAY,QAAA,EAAU,MAAM,aAAA,EAAe,CAAA;AAAA,oBAC1EA,cAAAA;AAAA,MAAC,gBAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAM,UAAA;AAAA,QACN,WAAA,EAAY,kDAAA;AAAA,QAEZ,QAAA,kBAAAA,eAAC,kBAAA,EAAA,EAAmB;AAAA;AAAA,KACtB;AAAA,oBACAA,cAAAA,CAAC,aAAA,EAAA,EAAc,KAAA,EAAO,MAAM,KAAA,EAAO,CAAA;AAAA,oBACnCA,cAAAA,CAAC,mBAAA,EAAA,EAAoB,KAAA,EAAO,MAAM,KAAA,EAAO;AAAA,GAAA,EAC3C,CAAA;AAEJ;AAOA,SAAS,kBAAA,GAAqB;AAC5B,EAAA,MAAM,EAAE,KAAA,EAAO,SAAA,EAAU,GAAIE,iBAAW,oBAAoB,CAAA;AAC5D,EAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AACnB,EAAA,uBAAOF,cAAAA,CAACmC,qBAAA,EAAA,EAAa,QAAA,EAAS,WAAA,EAAY,aAAa,SAAA,EAAW,CAAA;AACpE;AAGO,SAAS,eAAA,GAA2B;AACzC,EAAA,MAAM,QAAQ,cAAA,EAAe;AAC7B,EAAA,OAAA,CAAQ,KAAA,EAAO,IAAA,IAAQ,EAAC,EAAG,IAAA,CAAK,CAAC,CAAA,KAAM,QAAA,CAAS,IAAA,CAAK,CAAA,CAAE,OAAA,IAAW,EAAE,CAAC,CAAA;AACvE;AAEA,IAAM,YAAA,GAAgC;AAAA,EACpC,EAAE,OAAO,SAAA,EAAW,IAAA,EAAM,GAAG,aAAa,CAAA,eAAA,CAAA,EAAmB,UAAU,IAAA,EAAK;AAAA,EAC5E,EAAE,OAAO,OAAA,EAAS,IAAA,EAAM,GAAG,aAAa,CAAA,qBAAA,CAAA,EAAyB,UAAU,IAAA,EAAK;AAAA,EAChF;AAAA,IACE,KAAA,EAAO,eAAA;AAAA,IACP,IAAA,EAAM,0DAAA;AAAA,IACN,QAAA,EAAU;AAAA;AAEd,CAAA;AAOO,SAAS,gBAAgB,IAAA,EAMlB;AACZ,EAAA,MAAM,eAAe,eAAA,EAAgB;AACrC,EAAA,OAAO3B,aAAAA;AAAA,IACL,MAAO,YAAA,GAAe,EAAE,KAAA,EAAO,YAAA,EAAc,GAAG,IAAA,EAAK,GAAI,EAAE,KAAA,EAAO,YAAA,EAAa;AAAA,IAC/E,CAAC,YAAA,EAAc,IAAA,CAAK,QAAA,EAAU,IAAA,CAAK,OAAA,EAAS,IAAA,CAAK,MAAA,EAAQ,IAAA,CAAK,UAAA,EAAY,IAAA,CAAK,YAAY;AAAA,GAC7F;AACF;AAYO,SAAS,kBAAkB,QAAA,EAGb;AACnB,EAAA,MAAM,EAAE,EAAA,EAAI,MAAA,EAAO,GAAI,WAAA,EAAY;AACnC,EAAA,OAAO,eAAA,CAAgB;AAAA,IACrB,SAAS,EAAA,EAAI,QAAA;AAAA,IACb,cAAc,QAAA,EAAU,QAAA;AAAA,IACxB,OAAO,QAAA,EAAU,KAAA;AAAA,IACjB,WAAW,EAAA,EAAI,SAAA;AAAA,IACf;AAAA,GACD,CAAA;AACH;AAsBO,SAAS,iBAAA,CAAkB;AAAA,EAChC,MAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAIgB;AACd,EAAA,MAAM,QAAQ,cAAA,EAAe;AAC7B,EAAA,MAAM,QAAQ,kBAAA,EAAmB;AACjC,EAAA,MAAM,SAAA,GAAY,KAAA,EAAO,IAAA,CAAK,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,EAAA,KAAO,KAAA,CAAM,KAAK,CAAA,IAAK,IAAA;AACnE,EAAA,MAAM,SAAA,GAAY,SAAA,GAAY,CAAA,KAAA,EAAQ,SAAA,CAAU,EAAE,CAAA,CAAA,GAAK,EAAA;AACvD,EAAA,OAAO;AAAA;AAAA,IAEL,aAAA,EAAe,GAAG,aAAa,CAAA,WAAA,CAAA;AAAA,IAC/B,wBAAA,EAA0B,CAAA,EAAG,aAAa,CAAA,sBAAA,EAAyB,SAAS,CAAA,CAAA;AAAA,IAC5E,KAAA,EAAA,CAAQ,KAAA,EAAO,IAAA,IAAQ,EAAC,EACrB,OAAO,CAAC,CAAA,KAAM,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,IAAI,EACjC,GAAA,CAAI,CAAC,CAAA,MAAO,EAAE,IAAA,EAAO,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,IAAA,EAAiB,OAAA,EAAS,CAAA,CAAE,IAAA,EAAK,CAAE,CAAA;AAAA,IAC1E,QAAA,EAAU,CAAC,EAAE,EAAA,EAAI,MAAA,EAAQ,IAAA,EAAM,QAAA,EAAU,KAAA,EAAO,SAAA,EAAW,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,CAAA;AAAA,IAC/E,cAAA,EAAgB,GAAG,aAAa,CAAA,oBAAA,CAAA;AAAA,IAChC,OAAO,EAAE,KAAA,EAAO,MAAM,KAAA,EAAO,QAAA,EAAU,MAAM,QAAA;AAAS,GACxD;AACF;AAUA,IAAM,SAAA,GAOA;AAAA,EACJ;AAAA,IACE,EAAA,EAAI,cAAA;AAAA,IACJ,KAAA,EAAO,mBAAA;AAAA,IACP,IAAA,EAAMI,UAAA;AAAA,IACN,IAAA,EAAM,GAAG,aAAa,CAAA,uBAAA,CAAA;AAAA,IACtB,QAAA,EAAU;AAAA,GACZ;AAAA,EACA;AAAA,IACE,EAAA,EAAI,UAAA;AAAA,IACJ,KAAA,EAAO,eAAA;AAAA,IACP,IAAA,EAAMS,cAAA;AAAA,IACN,IAAA,EAAM,GAAG,aAAa,CAAA,mBAAA,CAAA;AAAA,IACtB,QAAA,EAAU;AAAA,GACZ;AAAA,EACA;AAAA;AAAA;AAAA,IAGE,EAAA,EAAI,UAAA;AAAA,IACJ,KAAA,EAAO,eAAA;AAAA,IACP,IAAA,EAAMS,SAAA;AAAA,IACN,IAAA,EAAM,wCAAA;AAAA,IACN,QAAA,EAAU;AAAA;AAEd,CAAA;AAkCO,SAAS,aAAA,CAAc,GAAA,GAAwB,EAAC,EAAY;AACjE,EAAA,MAAM,EAAE,cAAA,GAAiB,cAAA,EAAgB,YAAA,EAAa,GACpD,OAAO,GAAA,KAAQ,QAAA,GAAW,EAAE,cAAA,EAAgB,GAAA,EAAK,YAAA,EAAc,QAAU,GAAI,GAAA;AAC/E,EAAA,MAAM,GAAA,GAAM5B,iBAAW,kBAAkB,CAAA;AACzC,EAAA,MAAM,MAAM,mBAAA,EAAoB;AAChC,EAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,IAAS,IAAA;AAC5B,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAItB,eAAyC,IAAI,CAAA;AAC7E,EAAA,MAAM,CAAC,cAAA,EAAgB,iBAAiB,CAAA,GAAIA,eAAwB,IAAI,CAAA;AAGxE,EAAAC,gBAAU,MAAM;AACd,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,YAAA,CAAa,OAAA,CAAQ,gBAAgB,CAAA;AACpD,MAAA,IAAI,MAAA,IAAU,SAAA,CAAU,IAAA,CAAK,CAAC,CAAA,KAAM,EAAE,EAAA,KAAO,MAAM,CAAA,EAAG,iBAAA,CAAkB,MAAM,CAAA;AAAA,IAChF,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAAA,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,GAAA,IAAO,CAAC,KAAA,EAAO;AACpB,IAAA,IAAI,SAAA,GAAY,KAAA;AAChB,IAAA,GAAA,CAAI,IAAA,EAAM,EAAE,OAAA,EAAS,EAAE,gBAAA,EAAkB,KAAA,EAAM,EAAG,CAAA,CAC/C,IAAA,CAAK,CAAC,IAAA,KAAS;AACd,MAAA,IAAI,SAAA,EAAW;AACf,MAAA,MAAM,KAAA,GAAS,MAAqD,KAAA,IAAS,IAAA;AAC7E,MAAA,WAAA,CAAY,KAAK,CAAA;AAAA,IACnB,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AAAA,IAEb,CAAC,CAAA;AACH,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AAAA,IACd,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,GAAA,EAAK,KAAK,CAAC,CAAA;AAEf,EAAA,MAAM,OAAA,GAAU,UAAU,MAAA,CAAO,CAAC,MAAM,QAAA,GAAW,CAAA,CAAE,EAAE,CAAC,CAAA;AAKxD,EAAA,MAAM,MAAA,GAAS,YAAA,GAAe,SAAA,CAAU,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,EAAA,KAAO,YAAY,CAAA,IAAK,IAAA,GAAO,IAAA;AACrF,EAAA,MAAM,QAAA,GAAW,cAAA,GACb,OAAA,CAAQ,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,EAAA,KAAO,cAAc,CAAA,IAAK,IAAA,GAChD,IAAA;AACJ,EAAA,MAAM,OAAA,GACJ,MAAA,IACA,QAAA,IACA,OAAA,CAAQ,CAAC,CAAA,IACT,SAAA,CAAU,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,EAAA,KAAO,cAAc,CAAA,IAC7C,UAAU,CAAC,CAAA;AACb,EAAA,MAAM,MAAA,GAAS,KAAA,GAAQ,CAAA,KAAA,EAAQ,KAAK,CAAA,CAAA,GAAK,EAAA;AAEzC,EAAA,OAAO;AAAA,IACL,OAAO,OAAA,CAAQ,KAAA;AAAA,IACf,MAAM,OAAA,CAAQ,IAAA;AAAA,IACd,SACE,OAAA,CAAQ,MAAA,GAAS,IACb,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,MAAO,EAAE,IAAI,CAAA,CAAE,EAAA,EAAI,OAAO,CAAA,CAAE,KAAA,EAAO,MAAM,CAAA,CAAE,IAAA,GAAO,CAAA,GAC/D,MAAA;AAAA,IACN,QAAA,EACE,OAAA,CAAQ,MAAA,GAAS,CAAA,GACb,CAAC,EAAA,KAAe;AACd,MAAA,MAAM,MAAM,SAAA,CAAU,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,EAAE,CAAA;AAC7C,MAAA,IAAI,CAAC,GAAA,EAAK;AAGV,MAAA,iBAAA,CAAkB,EAAE,CAAA;AACpB,MAAA,IAAI;AACF,QAAA,YAAA,CAAa,OAAA,CAAQ,kBAAkB,EAAE,CAAA;AAAA,MAC3C,CAAA,CAAA,MAAQ;AAAA,MAER;AACA,MAAA,MAAM,MAAM,GAAA,CAAI,IAAA,CAAK,QAAA,CAAS,GAAG,IAAI,GAAA,GAAM,GAAA;AAC3C,MAAA,MAAA,CAAO,QAAA,CAAS,MAAA;AAAA,QACd,GAAA,CAAI,QAAA,IAAY,MAAA,GAAS,CAAA,EAAG,IAAI,IAAI,CAAA,EAAG,GAAG,CAAA,EAAG,MAAA,CAAO,KAAA,CAAM,CAAC,CAAC,KAAK,GAAA,CAAI;AAAA,OACvE;AAAA,IACF,CAAA,GACA;AAAA,GACR;AACF","file":"app-chrome.cjs","sourcesContent":["import { useEffect, useState } from 'react'\n\n/**\n * The six canonical top-bar action slots (Reference/Global-Rules v9 → top-bar\n * icons). Each slot's GLYPH is unique and comes from the Brand API\n * `topbarIcons.items.*` tokens, exposed as `--topbar-icon-<slot>` CSS vars\n * whose value is the brand-icon NAME. Every OTHER property — size, gap, color,\n * hover, selected — is universal across all six slots.\n */\nexport type TopBarIconSlot =\n | 'comms-fuel'\n | 'apps'\n | 'notifications'\n | 'alerts'\n | 'support'\n | 'dark-mode'\n\n/**\n * Reads the glyph NAME for a slot from its `--topbar-icon-<slot>` CSS var.\n *\n * Runs in an effect because the Brand stylesheet is appended to <head> at\n * runtime (Global Rules forbids baking it into the build), so the var is not\n * resolvable during SSR or the first synchronous render. The MutationObserver\n * re-reads once the stylesheet lands so the glyph upgrades from the caller's\n * fallback without a reload.\n *\n * Returns null when the slot has no Brand glyph — callers render their own\n * fallback icon in that case.\n */\nexport function useTopBarIconSlotGlyph(slot: TopBarIconSlot): string | null {\n const [name, setName] = useState<string | null>(null)\n\n useEffect(() => {\n if (typeof window === 'undefined') return\n\n const read = () => {\n const raw = window\n .getComputedStyle(document.documentElement)\n .getPropertyValue(`--topbar-icon-${slot}`)\n .trim()\n // Brand may emit the name quoted (e.g. \"bell\"); strip the quotes.\n .replace(/^['\"]|['\"]$/g, '')\n setName(raw.length > 0 ? raw : null)\n }\n\n read()\n\n const observer = new MutationObserver(read)\n observer.observe(document.head, { childList: true, subtree: true })\n return () => observer.disconnect()\n }, [slot])\n\n return name\n}\n\n/** Path to a brand-icon SVG in the consuming app's public dir. */\nexport function brandIconSrc(name: string, basePath = '/brand/icons/') {\n return `${basePath}${name}.svg`\n}\n","import type { ComponentType } from 'react'\nimport {\n FiAlertCircle,\n FiBattery,\n FiBatteryCharging,\n FiAlertTriangle,\n FiBell,\n FiGrid,\n FiHelpCircle,\n FiInfo,\n FiLifeBuoy,\n FiMail,\n FiMessageSquare,\n FiMoon,\n FiSettings,\n FiSun,\n FiUser,\n FiZap,\n} from 'react-icons/fi'\n\nexport type GlyphComponent = ComponentType<{ size?: number | string; className?: string }>\n\n/**\n * Brand-glyph registry: maps the icon NAME the Brand API emits (e.g.\n * `--topbar-icon-comms-fuel: bolt`) to a component.\n *\n * These names are Feather/Lucide icon names, NOT asset filenames — there is no\n * `/brand/icons/<name>.svg` for them in any app, and treating them as URLs\n * renders a broken image. Resolving them against the icon library the shell\n * already depends on keeps every app consistent with zero vendored assets.\n *\n * Aliases are included where Brand and Feather disagree on a name (`bolt` vs\n * `zap`, `life-buoy` vs `life-ring`).\n */\nconst GLYPHS: Record<string, GlyphComponent> = {\n // Communications Fuel reads as a LEVEL, so its glyph is a battery. `bolt`/\n // `zap` stay mapped for older Brand values.\n 'battery-charging': FiBatteryCharging,\n battery: FiBattery,\n fuel: FiBatteryCharging,\n bolt: FiZap,\n zap: FiZap,\n grid: FiGrid,\n apps: FiGrid,\n bell: FiBell,\n notification: FiBell,\n 'alert-triangle': FiAlertTriangle,\n alert: FiAlertTriangle,\n 'alert-circle': FiAlertCircle,\n 'life-buoy': FiLifeBuoy,\n 'life-ring': FiLifeBuoy,\n support: FiLifeBuoy,\n 'help-circle': FiHelpCircle,\n moon: FiMoon,\n sun: FiSun,\n info: FiInfo,\n mail: FiMail,\n 'message-square': FiMessageSquare,\n settings: FiSettings,\n user: FiUser,\n}\n\n/**\n * Resolve a Brand glyph name to a component. Returns null for an unknown name\n * so the caller renders its own fallback — an unrecognized token must never\n * produce a broken or empty icon.\n */\nexport function resolveBrandGlyph(name: string | null | undefined): GlyphComponent | null {\n if (!name) return null\n return GLYPHS[name.trim().toLowerCase()] ?? null\n}\n\n/** Names the registry knows — exported for tests and tooling. */\nexport const KNOWN_BRAND_GLYPHS = Object.keys(GLYPHS)\n","// Universal theme preference — the ONE cross-app contract.\n//\n// One theme choice (Light / Dark / System) follows the authenticated user\n// across every Politogy app + subdomain. Three layers cooperate:\n// 1. VRM Core `profiles.theme_preference` — source of truth, persisted via\n// the chrome API (`PATCH me/preferences { themePreference }`) and read\n// back from `GET me` (`themePreference`).\n// 2. `.politogyvrm.com` cookie `politogy_theme` — zero-flash pre-paint\n// vehicle that crosses subdomains (auth session cookies are host-only).\n// 3. localStorage `politogy_theme` — offline fallback store.\n//\n// Ported verbatim from contacts/apps/web/src/lib/theme.ts (the origin of the\n// contract) so every app runs the identical behavior from npm. This module is\n// server-safe (no 'use client'): layouts import THEME_PREPAINT_SCRIPT for the\n// pre-paint inline script. The client-side hook lives in ./native\n// (useThemePreference).\n\nexport type ThemePreference = 'light' | 'dark' | 'system'\n\n// Single converged key for BOTH the localStorage store and the\n// cross-subdomain cookie, so a choice in one app is the same key in the next.\nexport const THEME_STORAGE_KEY = 'politogy_theme'\nexport const THEME_COOKIE = 'politogy_theme'\n\n// A local choice that has NOT yet reached VRM Core `profiles.theme_preference`.\n//\n// Politogy ID (auth.politogyvrm.com) has no chrome-API session to PATCH, so a\n// theme picked on the login screen only ever lands in the cookie. Without this\n// marker the next app booted the stale profile value through the reconcile step\n// below and overwrote the user's fresh choice — the \"I set System and it keeps\n// going back to Light\" bug (HITL 2026-07-23). The flag rides the same\n// cross-subdomain cookie so the first app that CAN talk to the chrome API\n// pushes the choice up instead of pulling the stale one down.\nexport const THEME_PENDING_COOKIE = 'politogy_theme_pending'\n\nconst VALID: readonly ThemePreference[] = ['light', 'dark', 'system']\n\nexport function isThemePreference(v: unknown): v is ThemePreference {\n return typeof v === 'string' && (VALID as readonly string[]).includes(v)\n}\n\n/** Read the shared cookie (browser only; null on the server or when unset). */\nexport function readThemeCookie(): ThemePreference | null {\n if (typeof document === 'undefined') return null\n try {\n const m = document.cookie.match(\n new RegExp(`(?:^|;\\\\s*)${THEME_COOKIE}=([^;]+)`),\n )\n const v = m ? decodeURIComponent(m[1]) : null\n return isThemePreference(v) ? v : null\n } catch {\n return null\n }\n}\n\n// Set the cross-subdomain cookie. On a *.politogyvrm.com host we scope it to\n// the parent domain so every app subdomain reads it; on any other host\n// (localhost, *.pages.dev preview) we fall back to a host-only cookie so\n// local/preview theming still works without a mismatched Domain attribute\n// (which browsers silently drop). 1-year, SameSite=Lax, Secure on https.\nexport function writeThemeCookie(pref: ThemePreference): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const host = window.location.hostname\n const onParentDomain = /(^|\\.)politogyvrm\\.com$/i.test(host)\n const domainAttr = onParentDomain ? '; Domain=.politogyvrm.com' : ''\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n document.cookie = `${THEME_COOKIE}=${encodeURIComponent(\n pref,\n )}; Path=/; Max-Age=31536000; SameSite=Lax${domainAttr}${secure}`\n}\n\n// Write an arbitrary cross-subdomain cookie with the same scoping rules as the\n// theme cookie itself (parent domain on *.politogyvrm.com, host-only elsewhere).\nfunction writeSharedCookie(name: string, value: string, maxAgeSeconds: number): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n document.cookie = `${name}=${encodeURIComponent(\n value,\n )}; Path=/; Max-Age=${maxAgeSeconds}; SameSite=Lax${domainAttr}${secure}`\n}\n\n/**\n * Mark the current cookie value as a local choice that still has to reach the\n * user's profile. Call this from any surface that changes the theme WITHOUT a\n * chrome-API session (Politogy ID's login screen is the only one today).\n */\nexport function markThemeChoicePending(pref: ThemePreference): void {\n writeSharedCookie(THEME_PENDING_COOKIE, pref, 31536000)\n}\n\n/** The pending (not-yet-persisted) local choice, if any. */\nexport function readPendingThemeChoice(): ThemePreference | null {\n if (typeof document === 'undefined') return null\n try {\n const m = document.cookie.match(\n new RegExp(`(?:^|;\\\\s*)${THEME_PENDING_COOKIE}=([^;]+)`),\n )\n const v = m ? decodeURIComponent(m[1]) : null\n return isThemePreference(v) ? v : null\n } catch {\n return null\n }\n}\n\n/** Clear the pending marker once the choice has been written to the profile. */\nexport function clearPendingThemeChoice(): void {\n writeSharedCookie(THEME_PENDING_COOKIE, '', 0)\n}\n\n/** Resolve a preference to the concrete light/dark it renders as right now. */\nexport function resolveTheme(pref: ThemePreference): 'light' | 'dark' {\n if (pref === 'system') {\n try {\n return window.matchMedia('(prefers-color-scheme: dark)').matches\n ? 'dark'\n : 'light'\n } catch {\n return 'light'\n }\n }\n return pref\n}\n\n/**\n * Read the stored preference the way the pre-paint script does — cookie →\n * localStorage → `'system'`. Kept in lockstep with THEME_PREPAINT_SCRIPT so a\n * runtime reader can never disagree with what was applied before paint.\n */\nexport function readStoredThemePreference(): ThemePreference {\n const cookie = readThemeCookie()\n if (cookie) return cookie\n try {\n const stored = window.localStorage.getItem(THEME_STORAGE_KEY)\n if (isThemePreference(stored)) return stored\n } catch {\n /* localStorage may be unavailable (private mode) */\n }\n return 'system'\n}\n\n/**\n * The concrete light/dark the document is rendering as right now.\n *\n * This is the value anything theme-derived must follow — notably Chakra's\n * `colorMode`. Chakra used to be pinned to light while this resolved to dark,\n * which rendered dark chrome tokens over light Chakra content (the \"dark\n * labels on a light page\" desync).\n */\nexport function readResolvedTheme(): 'light' | 'dark' {\n return resolveTheme(readStoredThemePreference())\n}\n\n/** Apply a preference to the document (`.dark` class + color-scheme). */\nexport function applyThemePreference(pref: ThemePreference): void {\n if (typeof document === 'undefined') return\n const resolved = resolveTheme(pref)\n const d = document.documentElement\n d.classList.toggle('dark', resolved === 'dark')\n try {\n d.style.colorScheme = resolved\n } catch {\n /* non-fatal */\n }\n}\n\n// Inline pre-paint script — render it in <head> (or as the first child of\n// <body>) so the theme applies before first paint. Resolves the preference\n// from cookie → localStorage → OS, applies the `.dark` class + `color-scheme`,\n// and seeds localStorage from the cookie so the app hydrates to the synced\n// value (the cross-subdomain flash fix). Self-contained, dependency-free, and\n// wrapped so any failure is silent (never blocks paint).\nexport const THEME_PREPAINT_SCRIPT = `(function(){try{\nvar KEY=${JSON.stringify(THEME_STORAGE_KEY)};\nvar VALID=[\"light\",\"dark\",\"system\"];\nfunction fromCookie(){try{var m=document.cookie.match(/(?:^|;\\\\s*)${THEME_COOKIE}=([^;]+)/);return m?decodeURIComponent(m[1]):null;}catch(e){return null;}}\nvar cookie=fromCookie();\nvar ls=null;try{ls=localStorage.getItem(KEY);}catch(e){}\nvar pref=cookie||ls||\"system\";\nif(VALID.indexOf(pref)===-1)pref=\"system\";\nif(cookie&&cookie!==ls){try{localStorage.setItem(KEY,cookie);}catch(e){}}\nvar resolved=pref;\nif(pref===\"system\"){try{resolved=window.matchMedia(\"(prefers-color-scheme: dark)\").matches?\"dark\":\"light\";}catch(e){resolved=\"light\";}}\nvar d=document.documentElement;\nif(resolved===\"dark\"){d.classList.add(\"dark\");}else{d.classList.remove(\"dark\");}\ntry{d.style.colorScheme=resolved;}catch(e){}\n}catch(e){}})();`\n","// ---------------------------------------------------------------------------\n// Native chrome actions — Tailwind-only top-bar widgets (Fuel, Notifications,\n// Support, Navigation-display) backed by the shared chrome API\n// (politogy-contacts-api on Railway). Zero Chakra, zero router, zero fetch\n// opinion: the consuming app injects ONE fetcher via <NavChromeProvider> —\n// typically a same-origin proxy route that attaches its own session's Bearer\n// token server-side — and every widget in every app runs this exact code.\n//\n// Data endpoints (paths are relative; the app's fetcher owns the base URL):\n// GET communications/fuel-status (header x-contacts-org: <core org id>)\n// GET notifications (header x-contacts-org: <core org id>)\n// GET orgs\n// POST support { message }\n//\n// Loading states follow Global-Rules \"Loading & Async States\": the chrome\n// (button, popover frame, labels) always renders; only the VALUE area shows a\n// skeleton shimmer — never a spinner, never a blank panel.\n// ---------------------------------------------------------------------------\n\n'use client'\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n useSyncExternalStore,\n type ComponentType,\n type ReactNode,\n} from 'react'\nimport { createPortal } from 'react-dom'\n\nimport { useTopBarIconSlotGlyph, type TopBarIconSlot } from '../lib/topbarIconSlot'\nimport { resolveBrandGlyph } from '../lib/brandGlyphs'\nimport {\n applyThemePreference,\n isThemePreference,\n readThemeCookie,\n writeThemeCookie,\n readPendingThemeChoice,\n markThemeChoicePending,\n clearPendingThemeChoice,\n THEME_STORAGE_KEY,\n type ThemePreference as SharedThemePreference,\n} from '../theme-preference'\n\ntype NavIconLike = ComponentType<{ size?: number; className?: string }>\n\n// ---------------------------------------------------------------------------\n// Core-app deep links. The billing surface lives on the VRM-core app; we would\n// derive its origin from POLITOGY_APPS.vrm, but that registry lives in\n// ../app-chrome which imports THIS module — so pulling it in here would create\n// an import cycle. One local constant instead (kept in step with the registry's\n// `vrm` origin).\n// ---------------------------------------------------------------------------\n\nexport const CORE_APP_ORIGIN = 'https://app.politogyvrm.com'\n/** Text/Email fuel top-up page (SMS Signal + Email Broadcast). */\nexport const CORE_BILLING_PATH = '/organization-settings/subscription-billing/text-email'\nconst CORE_BILLING_URL = `${CORE_APP_ORIGIN}${CORE_BILLING_PATH}`\nconst QUARANTINED_CONTACTS_URL = `${CORE_APP_ORIGIN}/relationship/contacts/quarantined`\n\n/**\n * Stamp the active org onto a cross-app link, the same `?org=<uuid>` selector\n * the nav tree and Mode pill use. A bare link into VRM core drops a multi-org\n * user into whatever org core defaults to, which is a different account than\n * the one whose fuel / quarantine counts they just clicked.\n */\nfunction withOrgParam(url: string, orgId: string | null | undefined): string {\n if (!orgId) return url\n return `${url}${url.includes('?') ? '&' : '?'}org=${orgId}`\n}\n\n/** Scope the quarantined-contacts view to one sender. */\nfunction withPhoneParam(url: string, phone: string | null | undefined): string {\n if (!phone) return url\n return `${url}${url.includes('?') ? '&' : '?'}phone=${encodeURIComponent(phone)}`\n}\n\n/**\n * Resolve an organization logo URL for rendering in ANY app.\n *\n * `organizations.logo_url` is authored by VRM core and stored as a ROOT-RELATIVE\n * core route — `/api/storage/public?bucket=organization-logos&path=<org>/logo.png`\n * (the signed-storage proxy). VRM core renders it correctly because that path\n * resolves against its own origin; every other app resolves it against its own\n * origin (forms.politogyvrm.com/api/storage/public), gets a 404, and shows a\n * broken image. The chrome API passes the stored value through verbatim, so the\n * resolution belongs here — one definition for every app, core included.\n *\n * Absolute URLs (http/https/data/blob) pass through untouched.\n */\nexport function resolveOrgLogoUrl(url: string | null | undefined): string | undefined {\n const raw = url?.trim()\n if (!raw) return undefined\n if (/^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i.test(raw)) return raw\n return `${CORE_APP_ORIGIN}${raw.startsWith('/') ? '' : '/'}${raw}`\n}\n\n// ---------------------------------------------------------------------------\n// Shared 32×32 circular top-bar button chrome — the ONE definition of the\n// top-bar trigger (Global Rules: no slot hand-rolls its own trigger/badge).\n// NavTopBar's structured actionsList buttons use this same builder.\n// ---------------------------------------------------------------------------\n\nexport function topBarIconButtonClass(tone: 'default' | 'warning' | 'danger' = 'default'): string {\n const toneClass =\n tone === 'danger' || tone === 'warning'\n ? 'text-[color:var(--color-race-red)] hover:text-[color:var(--color-race-red)]'\n : 'text-[color:var(--topbar-icon-color,var(--muted))] hover:text-[color:var(--topbar-icon-hover-color,var(--foreground))] hover:bg-[color:var(--topbar-icon-hover-bg,transparent)]'\n return [\n // `group/tbtip` powers the shared <TopBarTooltip> rendered inside the trigger.\n 'group/tbtip relative flex items-center justify-center rounded-full border border-[color:var(--line)] transition',\n 'h-[var(--topbar-icon-button-size,32px)] w-[var(--topbar-icon-button-size,32px)]',\n toneClass,\n ].join(' ')\n}\n\n/** The shared count badge — one definition, used by every slot. */\n// ---------------------------------------------------------------------------\n// Top-bar panel registry.\n//\n// The top bar hosts two KINDS of surface: panels (opened deliberately by the\n// user from an icon) and transient nudges (the low-fuel hint, the new-reply\n// toast) that appear on their own. They are separate components under separate\n// triggers, so nothing stopped a nudge from covering an open panel — measured\n// in production: the reply toast over the notifications header, and the\n// low-fuel nudge over the same header from the fuel trigger two icons away.\n//\n// A module-scoped counter is enough: any nudge can ask \"is a panel open?\"\n// without the slots having to know about each other.\n// ---------------------------------------------------------------------------\nlet openPanelCount = 0\nconst panelListeners = new Set<() => void>()\nconst emitPanelChange = () => panelListeners.forEach((l) => l())\n\nfunction setPanelOpenGlobal(open: boolean) {\n openPanelCount = Math.max(0, openPanelCount + (open ? 1 : -1))\n emitPanelChange()\n}\n\n/** True while ANY top-bar panel is open. Nudges use it to stay out of the way. */\nexport function useAnyTopBarPanelOpen() {\n return useSyncExternalStore(\n (cb) => {\n panelListeners.add(cb)\n return () => panelListeners.delete(cb)\n },\n () => openPanelCount > 0,\n () => false,\n )\n}\n\nexport function TopBarCountBadge({ count }: { count: number }) {\n if (!(count > 0)) return null\n return (\n <span className=\"absolute -top-1 -right-1 flex h-4 min-w-4 items-center justify-center rounded-full bg-[color:var(--color-race-red)] px-1 text-[10px] font-normal leading-none text-white\">\n {count > 99 ? '99+' : count}\n </span>\n )\n}\n\n/**\n * The shared hover tooltip every top-bar control renders BELOW itself: an\n * up-pointing arrow at the icon, a bold title line and a muted description.\n * Pure CSS (group-hover) so it works on <a>, <button> and <summary> triggers.\n * The trigger must carry `group/tbtip relative` (topBarIconButtonClass does).\n */\nexport function TopBarTooltip({\n title,\n description,\n}: {\n title: string\n description?: ReactNode\n}) {\n return (\n <span\n role=\"tooltip\"\n className=\"pointer-events-none absolute left-1/2 top-full z-50 mt-2 hidden w-max max-w-56 -translate-x-1/2 flex-col rounded-lg border border-[color:var(--line)] bg-[color:var(--panel-elevated)] px-3 py-2 text-left shadow-[var(--shadow-soft)] group-hover/tbtip:flex\"\n >\n {/* Arrow pointing up at the icon */}\n <span\n aria-hidden\n className=\"absolute -top-[5px] left-1/2 h-2.5 w-2.5 -translate-x-1/2 rotate-45 border-l border-t border-[color:var(--line)] bg-[color:var(--panel-elevated)]\"\n />\n <span className=\"text-xs font-semibold text-[color:var(--foreground)]\">{title}</span>\n {description ? (\n <span className=\"mt-0.5 text-[11px] leading-snug text-[color:var(--muted)]\">\n {description}\n </span>\n ) : null}\n </span>\n )\n}\n\n/**\n * The up-pointing arrow every top-bar panel renders, anchored under its\n * trigger icon (panels are right-aligned, so the arrow sits at the trigger's\n * center: 16px in from the panel's right edge). One definition — every menu\n * points at its own icon identically.\n */\nexport function TopBarPanelArrow() {\n return (\n <span\n aria-hidden\n className=\"absolute -top-[5px] right-[11px] h-2.5 w-2.5 rotate-45 border-l border-t border-[color:var(--line)] bg-[color:var(--panel-elevated)]\"\n />\n )\n}\n\n/**\n * Wrapper for third-party top-bar widgets that ship their own launcher button\n * (e.g. DevNotes). Normalizes the trigger to the universal 32px circular slot\n * (chrome.css `.topbar-widget-slot`) and adds the standard tooltip.\n */\nexport function TopBarWidgetSlot({\n title,\n description,\n children,\n}: {\n title: string\n description?: string\n children: ReactNode\n}) {\n return (\n <span className=\"topbar-widget-slot group/tbtip relative inline-flex\">\n {children}\n <TopBarTooltip title={title} description={description} />\n </span>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Theme control — Light / System / Dark, rendered inside the account menu.\n// Controlled: the app owns persistence (profile + cross-subdomain cookie).\n// ---------------------------------------------------------------------------\n\nexport type ThemePreference = SharedThemePreference\n\nconst THEME_OPTIONS: { value: ThemePreference; label: string }[] = [\n { value: 'light', label: 'Light' },\n { value: 'system', label: 'System' },\n { value: 'dark', label: 'Dark' },\n]\n\nexport function NavThemeControl({\n value,\n onChange,\n}: {\n value: ThemePreference\n onChange: (next: ThemePreference) => void\n}) {\n return (\n <div className=\"px-4 py-3\">\n <p className=\"mb-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Appearance\n </p>\n <div\n role=\"radiogroup\"\n aria-label=\"Appearance\"\n className=\"flex overflow-hidden rounded-full border border-[color:var(--line)]\"\n >\n {THEME_OPTIONS.map((opt) => (\n <button\n key={opt.value}\n type=\"button\"\n role=\"radio\"\n aria-checked={value === opt.value}\n onClick={() => onChange(opt.value)}\n className={[\n 'flex-1 px-3 py-1.5 text-xs font-semibold transition',\n value === opt.value\n ? 'bg-[color:var(--color-race-red)] text-white'\n : 'text-[color:var(--muted)] hover:bg-[color:var(--panel)] hover:text-[color:var(--foreground)]',\n ].join(' ')}\n >\n {opt.label}\n </button>\n ))}\n </div>\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Chrome data context — the injected fetcher.\n// ---------------------------------------------------------------------------\n\nexport type NavChromeFetcher = (\n path: string,\n init?: { method?: string; headers?: Record<string, string>; body?: string },\n) => Promise<unknown>\n\n/** GET me — the authenticated user's chrome identity from the shared API.\n * userName prefers the VRM-core profile full name over token claims. */\nexport type ChromeMe = {\n user: string | null\n userName: string | null\n avatarUrl: string | null\n themePreference: string | null\n /** Universal navigation-display choice ('menu'|'tabs'|'both'); null when\n * unset or when the profile column is absent in this environment. */\n navDisplay: string | null\n account?: string | null\n accountName?: string | null\n role?: string | null\n /** Contact reply-to, when the profile carries them (optional/tolerant). */\n email?: string | null\n phone?: string | null\n}\n\ntype NavChromeContextValue = {\n fetchJson: NavChromeFetcher\n me: ChromeMe | null\n meLoaded: boolean\n}\n\nconst NavChromeContext = createContext<NavChromeContextValue | null>(null)\n\nexport function NavChromeProvider({\n fetchJson,\n children,\n}: {\n fetchJson: NavChromeFetcher\n children: ReactNode\n}) {\n // ONE `me` fetch per provider — identity (profile name/avatar) and the\n // theme reconciliation both hang off it.\n const [me, setMe] = useState<ChromeMe | null>(null)\n const [meLoaded, setMeLoaded] = useState(false)\n useEffect(() => {\n let cancelled = false\n fetchJson('me')\n .then((data) => {\n if (!cancelled) setMe(data as ChromeMe)\n })\n .catch(() => {\n /* degraded: session identity stands in */\n })\n .finally(() => {\n if (!cancelled) setMeLoaded(true)\n })\n return () => {\n cancelled = true\n }\n }, [fetchJson])\n\n return (\n <NavChromeContext.Provider value={{ fetchJson, me, meLoaded }}>\n {children}\n </NavChromeContext.Provider>\n )\n}\n\n/** The authenticated user's chrome identity (profile name / avatar / theme). */\nexport function useChromeMe(): { me: ChromeMe | null; loaded: boolean } {\n const ctx = useContext(NavChromeContext)\n return { me: ctx?.me ?? null, loaded: ctx?.meLoaded ?? false }\n}\n\n/** The injected chrome fetcher (null outside <NavChromeProvider>). */\nexport function useNavChromeFetcher(): NavChromeFetcher | null {\n return useContext(NavChromeContext)?.fetchJson ?? null\n}\n\nfunction useNavChrome(component: string): NavChromeContextValue {\n const ctx = useContext(NavChromeContext)\n if (!ctx) {\n throw new Error(\n `${component} must be rendered inside <NavChromeProvider> (inject the chrome API fetcher there).`,\n )\n }\n return ctx\n}\n\n// ---------------------------------------------------------------------------\n// Data shapes (mirror of politogy-contacts-api responses).\n// ---------------------------------------------------------------------------\n\nexport type FuelChannelStatus = {\n remainingUnits: number\n rawBalanceUnits: number\n usedUnits: number\n lowFuel: boolean\n lowFuelThreshold: number\n}\n\nexport type CommunicationsFuelStatus = {\n organizationId: string\n signal: FuelChannelStatus\n broadcast: FuelChannelStatus\n combinedAvailableCredits: number\n}\n\nexport type ChromeNotificationAlert = {\n id: string\n title: string\n description: string\n href: string | null\n kind: string\n}\n\nexport type ChromeNotificationReply = {\n id: string\n contactId: string | null\n name: string\n preview: string\n /** Optional deep-link to the conversation; the new-reply toast opens it. */\n href?: string\n /**\n * Optional arrival timestamp. Present, it lets the trigger badge count a\n * reply as \"unseen\" only when it is newer than the last time the panel was\n * opened; absent (older payloads), replies simply don't survive the first\n * open as unseen. Tolerated either way.\n */\n createdAt?: string\n}\n\n/** A running or finished contact import surfaced in the notifications panel. */\nexport type ChromeNotificationImport = {\n id: string\n label: string\n /** 0–100 progress, or null when indeterminate (no bar rendered). */\n percent: number | null\n status: 'active' | 'completed'\n href: string | null\n}\n\n/** A cluster of quarantined contacts sharing one phone number. */\nexport type ChromeNotificationQuarantine = {\n phone: string\n count: number\n /** Upstream may omit it; the row already renders conditionally on it. */\n latestAt: string | null\n}\n\nexport type ChromeNotificationsPayload = {\n organizationId: string\n alerts: ChromeNotificationAlert[]\n replies: ChromeNotificationReply[]\n /** Optional — running/finished imports (tolerant when absent). */\n imports?: ChromeNotificationImport[]\n /** Optional — clustered quarantined contacts (tolerant when absent). */\n quarantined?: ChromeNotificationQuarantine[]\n}\n\nexport type ChromeOrgSummary = {\n id: string\n name: string | null\n logoUrl: string | null\n brandColor: string | null\n role: string | null\n /** Un-mapped VRM-core membership role (e.g. \"super_admin\"). */\n rawRole?: string | null\n}\n\n/**\n * Fetch the signed-in user's VRM-core organizations through the injected\n * fetcher. Exposed as a hook so the org switcher in the sidebar and the\n * org-scoped widgets share one request.\n */\nexport function useChromeOrgs(): {\n orgs: ChromeOrgSummary[] | null\n loading: boolean\n error: boolean\n} {\n const { fetchJson } = useNavChrome('useChromeOrgs')\n const [orgs, setOrgs] = useState<ChromeOrgSummary[] | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState(false)\n\n useEffect(() => {\n let cancelled = false\n setLoading(true)\n setError(false)\n fetchJson('orgs')\n .then((data) => {\n if (cancelled) return\n const list = (data as { orgs?: ChromeOrgSummary[] })?.orgs ?? []\n setOrgs(list)\n })\n .catch(() => {\n if (!cancelled) setError(true)\n })\n .finally(() => {\n if (!cancelled) setLoading(false)\n })\n return () => {\n cancelled = true\n }\n }, [fetchJson])\n\n return { orgs, loading, error }\n}\n\n// ---------------------------------------------------------------------------\n// Internal building blocks.\n// ---------------------------------------------------------------------------\n\n/** Value-area skeleton shimmer (chrome/labels stay static per Global Rules). */\nfunction ValueSkeleton({ className }: { className?: string }) {\n return (\n <span\n aria-hidden\n className={[\n 'inline-block animate-pulse rounded bg-[color:var(--panel-elevated)]',\n className ?? 'h-4 w-16',\n ].join(' ')}\n />\n )\n}\n\n/** Slot-driven glyph: Brand-token name when resolvable, fallback otherwise. */\nfunction SlotGlyph({\n slot,\n fallback: Fallback,\n size = 20,\n}: {\n slot?: TopBarIconSlot\n fallback: NavIconLike\n size?: number\n}) {\n const glyphName = useTopBarIconSlotGlyph(slot ?? 'apps')\n const BrandGlyph = slot ? resolveBrandGlyph(glyphName) : null\n const Glyph = BrandGlyph ?? Fallback\n return <Glyph size={size} className=\"text-current\" />\n}\n\n/**\n * A top-bar popover: the shared circular trigger + a right-aligned panel.\n * Closes on outside click / Escape. Purely presentational.\n *\n * EXPORTED so an app with a richer panel than the stock actions can render it\n * inside the SHARED chrome — same 32px trigger, same tooltip, same badge, same\n * panel surface and arrow — instead of hand-rolling a trigger and drifting.\n * This is the enabling step for folding VRM's Fuel breakdown, import-progress,\n * alerts and reply-feed panels into the shared cluster one at a time, without\n * dropping capability (shell-nav-handoff §4; UI-Platform forbids migrating an\n * app to a rendering that loses an element it already ships).\n */\nexport function TopBarPopover({\n label,\n description,\n slot,\n fallbackIcon,\n badge,\n tone,\n onOpen,\n openToken,\n onOpenChange,\n children,\n panelClassName,\n}: {\n label: string\n description?: string\n slot?: TopBarIconSlot\n fallbackIcon: NavIconLike\n badge?: number\n tone?: 'default' | 'warning' | 'danger'\n onOpen?: () => void\n /**\n * Imperative \"open\" signal: whenever this number CHANGES the panel opens\n * (and `onOpen` fires). Lets a sibling — e.g. the notifications toast — open\n * the panel without owning the popover's state. Undefined disables it.\n */\n openToken?: number\n /**\n * Notified on every open/close. A sibling surface anchored to the same\n * trigger (e.g. the notifications toast) must know when the panel is open so\n * the two never render on top of each other — Reference/UI-Platform gives\n * every top-bar panel ONE surface anchored to its trigger, so a second\n * surface at the same anchor always occludes it.\n */\n onOpenChange?: (open: boolean) => void\n children: ReactNode\n panelClassName?: string\n}) {\n const [open, setOpen] = useState(false)\n const onOpenChangeRef = useRef(onOpenChange)\n onOpenChangeRef.current = onOpenChange\n useEffect(() => {\n onOpenChangeRef.current?.(open)\n if (!open) return\n setPanelOpenGlobal(true)\n return () => setPanelOpenGlobal(false)\n }, [open])\n const rootRef = useRef<HTMLDivElement | null>(null)\n const lastOpenTokenRef = useRef(openToken)\n\n // React to external open signals (skips the initial value on mount).\n useEffect(() => {\n if (openToken === undefined) return\n if (openToken === lastOpenTokenRef.current) return\n lastOpenTokenRef.current = openToken\n setOpen((v) => {\n if (!v) onOpen?.()\n return true\n })\n }, [openToken, onOpen])\n\n useEffect(() => {\n if (!open) return\n const onDocClick = (e: MouseEvent) => {\n if (rootRef.current && !rootRef.current.contains(e.target as Node)) setOpen(false)\n }\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') setOpen(false)\n }\n document.addEventListener('mousedown', onDocClick)\n document.addEventListener('keydown', onKey)\n return () => {\n document.removeEventListener('mousedown', onDocClick)\n document.removeEventListener('keydown', onKey)\n }\n }, [open])\n\n return (\n <div ref={rootRef} className=\"relative\">\n <button\n type=\"button\"\n aria-label={label}\n aria-expanded={open}\n className={topBarIconButtonClass(tone)}\n onClick={() => {\n setOpen((v) => {\n const next = !v\n if (next) onOpen?.()\n return next\n })\n }}\n >\n <SlotGlyph slot={slot} fallback={fallbackIcon} />\n {typeof badge === 'number' ? <TopBarCountBadge count={badge} /> : null}\n {!open ? <TopBarTooltip title={label} description={description} /> : null}\n </button>\n {open ? (\n <div\n className={[\n 'absolute right-0 z-40 mt-2 rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] shadow-[var(--shadow-soft)]',\n panelClassName ?? 'w-80',\n ].join(' ')}\n >\n <TopBarPanelArrow />\n <div className=\"overflow-hidden rounded-xl\">{children}</div>\n </div>\n ) : null}\n </div>\n )\n}\n\n// Inline fallback glyphs (Feather-style paths) so the package needs no icon dep.\nfunction BatteryGlyph({ size = 20, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <rect x=\"1\" y=\"6\" width=\"18\" height=\"12\" rx=\"2\" ry=\"2\" />\n <line x1=\"23\" y1=\"10\" x2=\"23\" y2=\"14\" />\n <line x1=\"5\" y1=\"10\" x2=\"5\" y2=\"14\" />\n <line x1=\"9\" y1=\"10\" x2=\"9\" y2=\"14\" />\n </svg>\n )\n}\n\nfunction BellGlyph({ size = 20, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <path d=\"M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9\" />\n <path d=\"M13.73 21a2 2 0 0 1-3.46 0\" />\n </svg>\n )\n}\n\nfunction LifeBuoyGlyph({ size = 20, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <circle cx=\"12\" cy=\"12\" r=\"4\" />\n <line x1=\"4.93\" y1=\"4.93\" x2=\"9.17\" y2=\"9.17\" />\n <line x1=\"14.83\" y1=\"14.83\" x2=\"19.07\" y2=\"19.07\" />\n <line x1=\"14.83\" y1=\"9.17\" x2=\"19.07\" y2=\"4.93\" />\n <line x1=\"4.93\" y1=\"19.07\" x2=\"9.17\" y2=\"14.83\" />\n </svg>\n )\n}\n\nfunction LayoutGlyph({ size = 20, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\" />\n <line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\" />\n <line x1=\"9\" y1=\"21\" x2=\"9\" y2=\"9\" />\n </svg>\n )\n}\n\nfunction PlusGlyph({ size = 14, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2.5} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n )\n}\n\nfunction XGlyph({ size = 14, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2.5} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n )\n}\n\nfunction CheckGlyph({ size = 14, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2.5} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n )\n}\n\n// ---------------------------------------------------------------------------\n// FuelAction — Communications Fuel balance (battery glyph + popover meters).\n// ---------------------------------------------------------------------------\n\nconst LOW_FUEL_HINT_DISMISSED_KEY = 'politogy_low_fuel_hint_dismissed'\n\nfunction FuelRow({\n label,\n channel,\n loading,\n addHref,\n addLabel,\n}: {\n label: string\n channel: FuelChannelStatus | null\n loading: boolean\n /** Billing deep-link for the small \"+\" top-up button (omit to hide it). */\n addHref?: string\n addLabel?: string\n}) {\n const remaining = channel?.remainingUnits ?? 0\n const total = channel ? Math.max(channel.rawBalanceUnits, channel.remainingUnits) : 0\n const ratio = total > 0 ? Math.min(100, Math.max(0, (remaining / total) * 100)) : 0\n const low = channel?.lowFuel ?? false\n\n return (\n <div className=\"w-full\">\n <div className=\"mb-1 flex items-center justify-between gap-2\">\n <span className=\"text-xs font-semibold text-[color:var(--foreground)]\">{label}</span>\n <div className=\"flex items-center gap-2\">\n {loading ? (\n <ValueSkeleton className=\"h-3.5 w-14\" />\n ) : (\n <span\n className={[\n 'text-xs font-semibold tabular-nums',\n low ? 'text-[color:var(--color-race-red)]' : 'text-[color:var(--muted)]',\n ].join(' ')}\n >\n {remaining.toLocaleString()} left\n </span>\n )}\n {addHref ? (\n <a\n href={addHref}\n aria-label={addLabel}\n className=\"flex h-5 w-5 items-center justify-center rounded-full border border-[color:var(--line)] text-[color:var(--muted)] transition hover:border-[color:var(--foreground)] hover:text-[color:var(--foreground)]\"\n >\n <PlusGlyph />\n </a>\n ) : null}\n </div>\n </div>\n <div className=\"h-1.5 w-full overflow-hidden rounded-full bg-[color:var(--panel)]\">\n {loading ? (\n <div className=\"h-full w-full animate-pulse bg-[color:var(--line)]\" />\n ) : (\n <div\n className={[\n 'h-full rounded-full transition-[width]',\n low ? 'bg-[color:var(--color-race-red)]' : 'bg-[color:var(--color-ok,#00A651)]',\n ].join(' ')}\n style={{ width: `${ratio}%` }}\n />\n )}\n </div>\n </div>\n )\n}\n\n/**\n * The low-fuel nudge: a small bubble anchored below the fuel trigger (arrow up)\n * with a \"Buy More Fuel\" deep-link. Dismissible; the dismissal persists for the\n * session (sessionStorage) so it never re-appears until a fresh session — and\n * the flag clears once fuel is no longer low, so a later drain can nudge again.\n */\nfunction LowFuelHint({ lowFuel, orgId }: { lowFuel: boolean; orgId: string | null }) {\n const [dismissed, setDismissed] = useState<boolean>(() => {\n if (typeof window === 'undefined') return false\n try {\n return window.sessionStorage.getItem(LOW_FUEL_HINT_DISMISSED_KEY) === '1'\n } catch {\n return false\n }\n })\n\n useEffect(() => {\n if (lowFuel) return\n try {\n window.sessionStorage.removeItem(LOW_FUEL_HINT_DISMISSED_KEY)\n } catch {\n /* unavailable */\n }\n }, [lowFuel])\n\n // Yield to any open panel: the nudge is wider than its own trigger and the\n // panels are right-aligned, so it lands on top of whichever one is open\n // (measured on contacts: it covered the notifications panel's header).\n const panelOpen = useAnyTopBarPanelOpen()\n\n if (!lowFuel || dismissed || panelOpen) return null\n\n const dismiss = () => {\n try {\n window.sessionStorage.setItem(LOW_FUEL_HINT_DISMISSED_KEY, '1')\n } catch {\n /* unavailable */\n }\n setDismissed(true)\n }\n\n return (\n <div\n role=\"status\"\n className=\"absolute right-0 top-[calc(100%+10px)] z-50 w-60 rounded-lg border border-[color:var(--color-race-red)] bg-[color:var(--color-race-red)] px-3 py-2 text-white shadow-[var(--shadow-soft)]\"\n onClick={(e) => e.stopPropagation()}\n >\n {/* Arrow pointing up at the fuel button (mirrors TopBarPanelArrow's offset). */}\n <span\n aria-hidden\n className=\"absolute -top-[5px] right-[11px] h-2.5 w-2.5 rotate-45 bg-[color:var(--color-race-red)]\"\n />\n <div className=\"flex items-start gap-2\">\n <div className=\"flex-1\">\n <p className=\"text-sm font-semibold\">You’re low on fuel</p>\n <a\n href={withOrgParam(CORE_BILLING_URL, orgId)}\n className=\"mt-1 inline-block text-sm font-bold underline hover:opacity-90\"\n >\n Buy More Fuel\n </a>\n </div>\n <button\n type=\"button\"\n aria-label=\"Dismiss low fuel notice\"\n onClick={dismiss}\n className=\"flex h-5 w-5 shrink-0 items-center justify-center rounded-full text-white/90 transition hover:bg-white/20\"\n >\n <XGlyph />\n </button>\n </div>\n </div>\n )\n}\n\nexport function FuelAction({ orgId }: { orgId: string | null }) {\n const { fetchJson } = useNavChrome('FuelAction')\n const [fuel, setFuel] = useState<CommunicationsFuelStatus | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState(false)\n\n useEffect(() => {\n let cancelled = false\n setLoading(true)\n setError(false)\n setFuel(null)\n fetchJson('communications/fuel-status', {\n headers: orgId ? { 'x-contacts-org': orgId } : undefined,\n })\n .then((data) => {\n if (cancelled) return\n setFuel((data as { fuel?: CommunicationsFuelStatus | null })?.fuel ?? null)\n })\n .catch(() => {\n if (!cancelled) setError(true)\n })\n .finally(() => {\n if (!cancelled) setLoading(false)\n })\n return () => {\n cancelled = true\n }\n }, [fetchJson, orgId])\n\n const low = !!fuel && (fuel.signal.lowFuel || fuel.broadcast.lowFuel)\n\n return (\n // The nudge anchors to the trigger, so it sits OUTSIDE the popover panel in\n // its own relative wrapper (same shape the VRM widget used).\n <div className=\"relative inline-flex\">\n <TopBarPopover\n label=\"Communications Fuel\"\n description=\"Remaining SMS and email sending balance for the active organization.\"\n slot=\"comms-fuel\"\n fallbackIcon={BatteryGlyph}\n tone={low ? 'warning' : 'default'}\n >\n <div className=\"px-4 py-3\">\n <p className=\"mb-3 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Communications Fuel\n </p>\n {error || (!loading && !fuel) ? (\n <p className=\"text-sm text-[color:var(--muted)]\">\n Fuel balance is unavailable right now.\n </p>\n ) : (\n <div className=\"flex flex-col gap-3\">\n <FuelRow\n label=\"SMS Signal\"\n channel={fuel?.signal ?? null}\n loading={loading}\n addHref={withOrgParam(CORE_BILLING_URL, orgId)}\n addLabel=\"Add SMS Signal fuel\"\n />\n <FuelRow\n label=\"Email Broadcast\"\n channel={fuel?.broadcast ?? null}\n loading={loading}\n addHref={withOrgParam(CORE_BILLING_URL, orgId)}\n addLabel=\"Add Email Broadcast fuel\"\n />\n </div>\n )}\n </div>\n </TopBarPopover>\n <LowFuelHint lowFuel={low} orgId={orgId} />\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// NotificationsAction — bell + count badge + alerts/replies popover.\n// ---------------------------------------------------------------------------\n\n/** Per-org read/seen state, persisted client-side (localStorage). */\ntype NotifState = {\n readAlertIds: string[]\n lastSeenAt: string | null\n /** Reply ids already surfaced as a toast, so none re-toasts (capped ~50). */\n toastedReplyIds: string[]\n}\n\nfunction notifStateKey(orgId: string | null): string {\n return `politogy_chrome_notif_state:${orgId ?? 'none'}`\n}\n\nfunction readNotifState(orgId: string | null): NotifState {\n const empty: NotifState = { readAlertIds: [], lastSeenAt: null, toastedReplyIds: [] }\n if (typeof window === 'undefined') return empty\n try {\n const raw = window.localStorage.getItem(notifStateKey(orgId))\n if (!raw) return empty\n const parsed = JSON.parse(raw) as Partial<NotifState>\n return {\n readAlertIds: Array.isArray(parsed?.readAlertIds)\n ? parsed.readAlertIds.filter((id): id is string => typeof id === 'string')\n : [],\n lastSeenAt: typeof parsed?.lastSeenAt === 'string' ? parsed.lastSeenAt : null,\n toastedReplyIds: Array.isArray(parsed?.toastedReplyIds)\n ? parsed.toastedReplyIds.filter((id): id is string => typeof id === 'string')\n : [],\n }\n } catch {\n return empty\n }\n}\n\nfunction writeNotifState(orgId: string | null, state: NotifState): void {\n if (typeof window === 'undefined') return\n try {\n window.localStorage.setItem(notifStateKey(orgId), JSON.stringify(state))\n } catch {\n /* unavailable */\n }\n}\n\nconst TEN_DLC_REDIRECTED_KEY = 'politogy_10dlc_redirected'\n\n/** Format a raw phone into US (XXX) XXX-XXXX; leave anything else as-is. */\nfunction formatPhone(raw: string): string {\n const digits = raw.replace(/\\D/g, '')\n const ten = digits.length === 11 && digits.startsWith('1') ? digits.slice(1) : digits\n if (ten.length === 10) return `(${ten.slice(0, 3)}) ${ten.slice(3, 6)}-${ten.slice(6)}`\n return raw\n}\n\nfunction ImportRow({ imp }: { imp: ChromeNotificationImport }) {\n const pct = imp.percent == null ? null : Math.max(0, Math.min(100, imp.percent))\n return (\n <>\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"truncate text-sm text-[color:var(--foreground)]\">{imp.label}</span>\n {pct != null ? (\n <span className=\"shrink-0 text-xs tabular-nums text-[color:var(--muted)]\">\n {Math.round(pct)}%\n </span>\n ) : null}\n </div>\n {pct != null ? (\n <div className=\"mt-1 h-1 w-full overflow-hidden rounded-full bg-[color:var(--panel)]\">\n <div\n className=\"h-full rounded-full bg-[color:var(--color-race-red)] transition-[width]\"\n style={{ width: `${pct}%` }}\n />\n </div>\n ) : null}\n </>\n )\n}\n\n/**\n * Transient \"new reply\" toast anchored below the bell. Dark bubble with an\n * up-arrow, sender + preview; auto-fades after ~12s; clicking activates it.\n * Mirrors VRM's NewTextBellPopup. Purely presentational — the parent owns which\n * reply shows and what a click does.\n */\nfunction NewReplyToast({\n reply,\n onActivate,\n onClose,\n ttlMs = 12000,\n}: {\n reply: ChromeNotificationReply\n onActivate: () => void\n onClose: () => void\n ttlMs?: number\n}) {\n const [visible, setVisible] = useState(false)\n const onCloseRef = useRef(onClose)\n onCloseRef.current = onClose\n\n useEffect(() => {\n setVisible(true)\n const fadeAt = Math.max(0, ttlMs - 450)\n const t1 = window.setTimeout(() => setVisible(false), fadeAt)\n const t2 = window.setTimeout(() => onCloseRef.current(), ttlMs)\n return () => {\n window.clearTimeout(t1)\n window.clearTimeout(t2)\n }\n }, [ttlMs])\n\n const activate = () => {\n setVisible(false)\n onActivate()\n }\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n aria-label=\"Open new reply\"\n onClick={activate}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n activate()\n }\n }}\n className=\"absolute right-[-6px] top-[calc(100%+12px)] z-50 min-w-[240px] max-w-[320px] cursor-pointer rounded-xl bg-[#161616] px-4 py-3 text-white shadow-[var(--shadow-soft)]\"\n style={{\n opacity: visible ? 1 : 0,\n transform: visible ? 'translateY(0px)' : 'translateY(-4px)',\n transition: 'opacity 250ms ease, transform 250ms ease',\n }}\n >\n {/* Up-arrow pointing at the bell. */}\n <span\n aria-hidden\n className=\"absolute right-[18px] top-[-7px] h-0 w-0 border-x-[8px] border-x-transparent border-b-[8px] border-b-[#161616]\"\n />\n <p className=\"truncate text-sm font-semibold\">{reply.name}</p>\n <p className=\"mt-1 truncate text-xs opacity-85\">{reply.preview}</p>\n </div>\n )\n}\n\nexport function NotificationsAction({ orgId }: { orgId: string | null }) {\n const { fetchJson } = useNavChrome('NotificationsAction')\n const [payload, setPayload] = useState<ChromeNotificationsPayload | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState(false)\n const [notif, setNotif] = useState<NotifState>(() => readNotifState(orgId))\n const [toastReply, setToastReply] = useState<ChromeNotificationReply | null>(null)\n const [openToken, setOpenToken] = useState(0)\n const [panelOpen, setPanelOpen] = useState(false)\n // Also yield to a panel opened from a NEIGHBOURING trigger — the fuel panel\n // is right-aligned and wide enough to sit under the bell.\n const anyPanelOpen = useAnyTopBarPanelOpen()\n\n // Re-hydrate the read/seen watermark whenever the active org changes.\n useEffect(() => {\n setNotif(readNotifState(orgId))\n setToastReply(null)\n }, [orgId])\n\n useEffect(() => {\n let cancelled = false\n setLoading(true)\n setError(false)\n setPayload(null)\n fetchJson('notifications', {\n headers: orgId ? { 'x-contacts-org': orgId } : undefined,\n })\n .then((data) => {\n if (!cancelled) setPayload(data as ChromeNotificationsPayload)\n })\n .catch(() => {\n if (!cancelled) setError(true)\n })\n .finally(() => {\n if (!cancelled) setLoading(false)\n })\n return () => {\n cancelled = true\n }\n }, [fetchJson, orgId])\n\n // 10DLC registration auto-redirect — once per session, and ONLY when the\n // alert's href is same-origin with the current page (other origins just show\n // the alert; the core app navigates to its own settings). Mirrors VRM.\n useEffect(() => {\n if (!payload || typeof window === 'undefined') return\n const alert = payload.alerts.find((a) => a.kind === '10dlc_registration' && a.href)\n if (!alert?.href) return\n try {\n if (window.sessionStorage.getItem(TEN_DLC_REDIRECTED_KEY) === '1') return\n } catch {\n return\n }\n let target: URL\n try {\n target = new URL(alert.href, window.location.href)\n } catch {\n return\n }\n if (target.origin !== window.location.origin) return\n try {\n window.sessionStorage.setItem(TEN_DLC_REDIRECTED_KEY, '1')\n } catch {\n /* unavailable */\n }\n window.location.assign(alert.href)\n }, [payload])\n\n const markRead = useCallback(\n (id: string) => {\n setNotif((prev) => {\n if (prev.readAlertIds.includes(id)) return prev\n const next = { ...prev, readAlertIds: [...prev.readAlertIds, id] }\n writeNotifState(orgId, next)\n return next\n })\n },\n [orgId],\n )\n\n const markUnread = useCallback(\n (id: string) => {\n setNotif((prev) => {\n if (!prev.readAlertIds.includes(id)) return prev\n const next = { ...prev, readAlertIds: prev.readAlertIds.filter((x) => x !== id) }\n writeNotifState(orgId, next)\n return next\n })\n },\n [orgId],\n )\n\n // Opening the panel advances the \"last seen\" watermark (replies are seen).\n const onOpen = useCallback(() => {\n // The panel shows the reply the toast was previewing, so the toast has\n // nothing left to say — retire it rather than let it cover the panel.\n setToastReply(null)\n setNotif((prev) => {\n const next = { ...prev, lastSeenAt: new Date().toISOString() }\n writeNotifState(orgId, next)\n return next\n })\n }, [orgId])\n\n const alerts = payload?.alerts ?? []\n const replies = payload?.replies ?? []\n const imports = payload?.imports ?? []\n const quarantined = payload?.quarantined ?? []\n\n // New-reply toast: surface the newest reply that is (a) newer than the seen\n // watermark and (b) not already toasted this org. One at a time; the id is\n // recorded so a re-render / re-fetch never re-toasts it (capped at 50).\n useEffect(() => {\n if (!payload || toastReply || panelOpen) return\n const candidate = replies\n .filter((r) => {\n if (!r.createdAt) return false\n if (notif.lastSeenAt && r.createdAt <= notif.lastSeenAt) return false\n return !notif.toastedReplyIds.includes(r.id)\n })\n .sort((a, b) => (a.createdAt! < b.createdAt! ? 1 : -1))[0]\n if (!candidate) return\n setToastReply(candidate)\n setNotif((prev) => {\n const next = {\n ...prev,\n toastedReplyIds: [candidate.id, ...prev.toastedReplyIds].slice(0, 50),\n }\n writeNotifState(orgId, next)\n return next\n })\n }, [payload, replies, toastReply, panelOpen, notif.lastSeenAt, notif.toastedReplyIds, orgId])\n\n // Toast click: navigate to the reply's href when it carries one; otherwise\n // open the notifications panel (which also advances the seen watermark).\n const onToastActivate = useCallback(() => {\n const href = toastReply?.href\n setToastReply(null)\n if (href && typeof window !== 'undefined') {\n window.location.assign(href)\n return\n }\n setOpenToken((t) => t + 1)\n }, [toastReply])\n\n // Badge: UNREAD alerts + replies newer than the last-seen watermark. A reply\n // with no timestamp counts before the first open, then is treated as seen.\n const unreadAlertCount = alerts.filter((a) => !notif.readAlertIds.includes(a.id)).length\n const unseenReplyCount = replies.filter((r) => {\n if (!notif.lastSeenAt) return true\n if (!r.createdAt) return false\n return r.createdAt > notif.lastSeenAt\n }).length\n const badgeCount = unreadAlertCount + unseenReplyCount\n\n const isEmpty =\n alerts.length === 0 && replies.length === 0 && imports.length === 0 && quarantined.length === 0\n\n return (\n // Relative wrapper so the new-reply toast anchors to the bell trigger,\n // outside the popover panel (same pattern as the fuel low-fuel nudge).\n <div className=\"relative inline-flex\">\n <TopBarPopover\n label=\"Alerts & Notifications\"\n description=\"System alerts and recent activity for the active organization.\"\n slot=\"notifications\"\n fallbackIcon={BellGlyph}\n badge={loading ? 0 : badgeCount}\n onOpen={onOpen}\n openToken={openToken}\n onOpenChange={setPanelOpen}\n >\n <div className=\"px-4 py-3\">\n <p className=\"mb-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Notifications\n </p>\n {loading ? (\n <div className=\"flex flex-col gap-2 py-1\">\n <ValueSkeleton className=\"h-4 w-full\" />\n <ValueSkeleton className=\"h-4 w-3/4\" />\n </div>\n ) : error ? (\n <p className=\"text-sm text-[color:var(--muted)]\">\n Notifications are unavailable right now.\n </p>\n ) : isEmpty ? (\n <p className=\"py-1 text-sm text-[color:var(--muted)]\">You’re all caught up.</p>\n ) : (\n <div className=\"flex max-h-80 flex-col gap-2 overflow-y-auto\">\n {/* Alerts (with per-item read toggle) + replies — unchanged order. */}\n {alerts.length > 0 || replies.length > 0 ? (\n <ul className=\"flex flex-col gap-1\">\n {alerts.map((a) => {\n const isRead = notif.readAlertIds.includes(a.id)\n return (\n <li key={a.id} className={isRead ? 'opacity-50' : undefined}>\n <div className=\"flex items-start gap-1 rounded-lg px-2 py-2 hover:bg-[color:var(--panel)]\">\n <a\n href={a.href ?? '#'}\n onClick={() => markRead(a.id)}\n className=\"block min-w-0 flex-1\"\n >\n <p className=\"text-sm font-semibold text-[color:var(--foreground)]\">\n {a.title}\n </p>\n <p className=\"text-xs text-[color:var(--muted)]\">{a.description}</p>\n </a>\n <button\n type=\"button\"\n aria-label={isRead ? 'Mark as unread' : 'Mark as read'}\n onClick={() => (isRead ? markUnread(a.id) : markRead(a.id))}\n className=\"mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full text-[color:var(--muted)] transition hover:bg-[color:var(--panel-elevated)] hover:text-[color:var(--foreground)]\"\n >\n <CheckGlyph />\n </button>\n </div>\n </li>\n )\n })}\n {replies.map((r) => (\n <li key={r.id} className=\"rounded-lg px-2 py-2 hover:bg-[color:var(--panel)]\">\n <p className=\"text-sm font-semibold text-[color:var(--foreground)]\">{r.name}</p>\n <p className=\"truncate text-xs text-[color:var(--muted)]\">{r.preview}</p>\n </li>\n ))}\n </ul>\n ) : null}\n\n {/* Imports — running/finished contact imports. */}\n {imports.length > 0 ? (\n <div>\n <p className=\"mb-1 px-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Imports\n </p>\n <ul className=\"flex flex-col gap-1\">\n {imports.map((imp) => (\n <li key={imp.id} className=\"rounded-lg px-2 py-2 hover:bg-[color:var(--panel)]\">\n {imp.href ? (\n <a href={imp.href} className=\"block\">\n <ImportRow imp={imp} />\n </a>\n ) : (\n <ImportRow imp={imp} />\n )}\n </li>\n ))}\n </ul>\n </div>\n ) : null}\n\n {/* Quarantined contact clusters. */}\n {quarantined.length > 0 ? (\n <div>\n <div className=\"mb-1 flex items-center justify-between px-2\">\n <p className=\"text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Quarantined Contacts\n </p>\n <a\n href={withOrgParam(QUARANTINED_CONTACTS_URL, orgId)}\n className=\"text-[11px] font-semibold text-[color:var(--color-race-red)] hover:underline\"\n >\n View all\n </a>\n </div>\n <ul className=\"flex flex-col gap-1\">\n {/* Each row is a REAL link, not a div with a hover class. It\n used to carry a hover highlight on a non-interactive <li>,\n so the row advertised interactivity and then did nothing\n when clicked (reported 2026-08-03). An affordance has to\n lead somewhere: the row opens the quarantined-contacts\n view filtered to that number — the same destination as\n \"View all\", scoped. Being an <a> makes it keyboard\n focusable and Enter-activatable for free. */}\n {quarantined.map((q) => (\n <li key={q.phone}>\n <a\n href={withPhoneParam(withOrgParam(QUARANTINED_CONTACTS_URL, orgId), q.phone)}\n aria-label={`Review ${q.count} quarantined message${q.count === 1 ? '' : 's'} from ${formatPhone(q.phone)}`}\n className=\"block rounded-lg px-2 py-2 transition hover:bg-[color:var(--nav-row-hover)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--color-race-red)]\"\n >\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-sm font-semibold text-[color:var(--foreground)]\">\n {formatPhone(q.phone)}\n </span>\n {/* Same geometry as the shared TopBarCountBadge (16px\n circle, 10px/400, px-1); it sits in flow rather\n than absolutely on a 32px trigger, because this is\n a list row and not a top-bar icon. */}\n <span className=\"flex h-4 min-w-4 items-center justify-center rounded-full bg-[color:var(--panel)] px-1 text-[10px] font-normal leading-none tabular-nums text-[color:var(--muted)]\">\n {q.count > 99 ? '99+' : q.count}\n </span>\n </div>\n {q.latestAt ? (\n <p className=\"text-xs text-[color:var(--muted)]\">\n {new Date(q.latestAt).toLocaleString()}\n </p>\n ) : null}\n </a>\n </li>\n ))}\n </ul>\n </div>\n ) : null}\n </div>\n )}\n </div>\n </TopBarPopover>\n {/* Only ONE surface at this anchor at a time: the toast yields to the panel\n (both hang off the bell trigger, so rendering both means the toast sits\n on the panel's header — Reference/UI-Platform, one surface per trigger). */}\n {toastReply && !panelOpen && !anyPanelOpen ? (\n <NewReplyToast\n reply={toastReply}\n onActivate={onToastActivate}\n onClose={() => setToastReply(null)}\n />\n ) : null}\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// SupportAction — life-buoy trigger + the shared support-request modal\n// (never a mailto:, never an app-local form — Reference/UI-Platform).\n// ---------------------------------------------------------------------------\n\n/**\n * Compose the delivered support message: the user's note, then a context block\n * carrying the page, URL and active org — plus a Reply-to line when the user\n * had to supply contact details the profile was missing. The upstream contract\n * stays `POST support { message }`; this just enriches the text (VRM parity).\n */\nfunction composeSupportMessage(input: {\n note: string\n pageTitle: string\n url: string\n orgName?: string | null\n replyEmail?: string\n replyPhone?: string\n}): string {\n const ctx = [`Page: ${input.pageTitle || 'Unknown'}`, `URL: ${input.url}`]\n if (input.orgName) ctx.push(`Org: ${input.orgName}`)\n const reply = [input.replyEmail?.trim(), input.replyPhone?.trim()].filter(Boolean).join(' / ')\n if (reply) ctx.push(`Reply-to: ${reply}`)\n return `${input.note.trim()}\\n\\n---\\n${ctx.join('\\n')}`\n}\n\nexport function SupportAction({ orgId }: { orgId?: string | null } = {}) {\n const { fetchJson } = useNavChrome('SupportAction')\n const { me, loaded } = useChromeMe()\n const { orgs } = useChromeOrgs()\n const [open, setOpen] = useState(false)\n const [message, setMessage] = useState('')\n const [email, setEmail] = useState('')\n const [phone, setPhone] = useState('')\n const [showEmailError, setShowEmailError] = useState(false)\n const [state, setState] = useState<'idle' | 'sending' | 'sent' | 'error'>('idle')\n\n // The profile knows email/phone unless the chrome `me` loaded without them —\n // then we collect the missing one(s) in the modal (email required, phone not).\n const meEmail = me?.email ?? null\n const mePhone = me?.phone ?? null\n const missingEmail = loaded && !meEmail\n const missingPhone = loaded && !mePhone\n\n const activeOrg =\n (orgId ? orgs?.find((o) => o.id === orgId) : null) ??\n (orgs && orgs.length === 1 ? orgs[0] : null)\n const orgName = activeOrg?.name ?? null\n\n const close = useCallback(() => {\n setOpen(false)\n setState('idle')\n setMessage('')\n setShowEmailError(false)\n }, [])\n\n // Seed the contact inputs from the profile whenever the modal opens.\n useEffect(() => {\n if (!open) return\n setEmail(meEmail ?? '')\n setPhone(mePhone ?? '')\n setShowEmailError(false)\n }, [open, meEmail, mePhone])\n\n useEffect(() => {\n if (!open) return\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') close()\n }\n document.addEventListener('keydown', onKey)\n return () => document.removeEventListener('keydown', onKey)\n }, [open, close])\n\n const submit = async () => {\n if (!message.trim() || state === 'sending') return\n\n const resolvedEmail = (missingEmail ? email : meEmail ?? '').trim()\n const resolvedPhone = (missingPhone ? phone : mePhone ?? '').trim()\n // Email is required when the profile didn't carry one.\n if (missingEmail && !resolvedEmail) {\n setShowEmailError(true)\n return\n }\n setShowEmailError(false)\n\n const collectedContact = missingEmail || missingPhone\n const fullMessage = composeSupportMessage({\n note: message,\n pageTitle: typeof document !== 'undefined' ? document.title : '',\n url: typeof window !== 'undefined' ? window.location.href : '',\n orgName,\n replyEmail: collectedContact ? resolvedEmail : undefined,\n replyPhone: collectedContact ? resolvedPhone : undefined,\n })\n\n setState('sending')\n try {\n await fetchJson('support', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ message: fullMessage }),\n })\n setState('sent')\n } catch {\n setState('error')\n }\n }\n\n return (\n <>\n <button\n type=\"button\"\n aria-label=\"Support\"\n className={topBarIconButtonClass()}\n onClick={() => setOpen(true)}\n >\n <SlotGlyph slot=\"support\" fallback={LifeBuoyGlyph} />\n <TopBarTooltip\n title=\"Support\"\n description=\"Send a support request to the Politogy team.\"\n />\n </button>\n {open && typeof document !== 'undefined'\n ? createPortal(\n <div\n // Portaled to <body>: the top bar's backdrop-blur creates a CSS\n // containing block, so a fixed-position descendant would center on\n // the HEADER (rendering off-screen) instead of the viewport.\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Support request\"\n onMouseDown={(e) => {\n if (e.target === e.currentTarget) close()\n }}\n >\n <div className=\"w-full max-w-md rounded-2xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] p-6 shadow-[var(--shadow-soft)]\">\n <h2 className=\"text-lg font-bold tracking-[-0.01em] text-[color:var(--foreground)]\">\n Contact Support\n </h2>\n {state === 'sent' ? (\n <>\n <p className=\"mt-3 text-sm text-[color:var(--muted)]\">\n Your request was sent. The team will reply by email.\n </p>\n <div className=\"mt-5 flex justify-end\">\n <button\n type=\"button\"\n onClick={close}\n className=\"rounded-full bg-[color:var(--color-race-red)] px-4 py-2 text-sm font-semibold text-white hover:opacity-90\"\n >\n Done\n </button>\n </div>\n </>\n ) : (\n <>\n <p className=\"mt-1 text-sm text-[color:var(--muted)]\">\n Describe the problem or question. Your account details ride along\n automatically.\n </p>\n {missingEmail ? (\n <label className=\"mt-4 block\">\n <span className=\"mb-1 block text-xs font-semibold text-[color:var(--foreground)]\">\n Your email\n </span>\n <input\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n placeholder=\"you@example.com\"\n className=\"w-full rounded-lg border border-[color:var(--line)] bg-[color:var(--panel)] px-3 py-2 text-sm text-[color:var(--foreground)] placeholder:text-[color:var(--muted)] focus:outline-none focus:ring-2 focus:ring-[color:var(--color-race-red)]\"\n />\n {showEmailError ? (\n <span className=\"mt-1 block text-xs text-[color:var(--color-race-red)]\">\n Enter an email so support can reply.\n </span>\n ) : null}\n </label>\n ) : null}\n {missingPhone ? (\n <label className=\"mt-3 block\">\n <span className=\"mb-1 block text-xs font-semibold text-[color:var(--foreground)]\">\n Your phone — optional\n </span>\n <input\n type=\"tel\"\n value={phone}\n onChange={(e) => setPhone(e.target.value)}\n placeholder=\"(503) 555-1212\"\n className=\"w-full rounded-lg border border-[color:var(--line)] bg-[color:var(--panel)] px-3 py-2 text-sm text-[color:var(--foreground)] placeholder:text-[color:var(--muted)] focus:outline-none focus:ring-2 focus:ring-[color:var(--color-race-red)]\"\n />\n </label>\n ) : null}\n <textarea\n value={message}\n onChange={(e) => setMessage(e.target.value)}\n rows={5}\n placeholder=\"How can we help?\"\n className=\"mt-4 w-full resize-y rounded-lg border border-[color:var(--line)] bg-[color:var(--panel)] px-3 py-2 text-sm text-[color:var(--foreground)] placeholder:text-[color:var(--muted)] focus:outline-none focus:ring-2 focus:ring-[color:var(--color-race-red)]\"\n />\n {state === 'error' ? (\n <p className=\"mt-2 text-sm text-[color:var(--color-race-red)]\">\n Sending failed — try again.\n </p>\n ) : null}\n <div className=\"mt-4 flex justify-end gap-2\">\n <button\n type=\"button\"\n onClick={close}\n className=\"rounded-full border border-[color:var(--line)] px-4 py-2 text-sm font-semibold text-[color:var(--foreground)] hover:bg-[color:var(--panel)]\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={submit}\n disabled={!message.trim() || state === 'sending'}\n className=\"rounded-full bg-[color:var(--color-race-red)] px-4 py-2 text-sm font-semibold text-white transition hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {state === 'sending' ? 'Sending…' : 'Send request'}\n </button>\n </div>\n </>\n )}\n </div>\n </div>,\n document.body,\n )\n : null}\n </>\n )\n}\n\n// ---------------------------------------------------------------------------\n// NavDisplayAction — the Menu / Tabs / Both navigation-display switcher.\n// Controlled: the app owns persistence (localStorage/profile) and layout\n// consequences (sub-menu visibility, tab strip visibility).\n// ---------------------------------------------------------------------------\n\nexport type NavDisplayMode = 'menu' | 'tabs' | 'both'\n\nconst NAV_DISPLAY_OPTIONS: { value: NavDisplayMode; label: string }[] = [\n { value: 'menu', label: 'Sub Menu' },\n { value: 'tabs', label: 'Tabs Only' },\n { value: 'both', label: 'Both' },\n]\n\nexport function NavDisplayAction({\n value,\n onChange,\n}: {\n value: NavDisplayMode\n onChange: (next: NavDisplayMode) => void\n}) {\n return (\n <TopBarPopover\n label=\"Navigation Display\"\n description=\"Show navigation as a sub-menu, tabs, or both.\"\n fallbackIcon={LayoutGlyph}\n panelClassName=\"w-44\"\n >\n <div className=\"py-1\" role=\"radiogroup\" aria-label=\"Navigation display\">\n {NAV_DISPLAY_OPTIONS.map((opt) => (\n <button\n key={opt.value}\n type=\"button\"\n role=\"radio\"\n aria-checked={value === opt.value}\n onClick={() => onChange(opt.value)}\n className={[\n 'flex w-full items-center justify-between px-4 py-2 text-left text-sm font-medium',\n value === opt.value\n ? 'text-[color:var(--color-race-red)]'\n : 'text-[color:var(--foreground)] hover:bg-[color:var(--panel)]',\n ].join(' ')}\n >\n {opt.label}\n {value === opt.value ? <span aria-hidden>✓</span> : null}\n </button>\n ))}\n </div>\n </TopBarPopover>\n )\n}\n\n// ---------------------------------------------------------------------------\n// useThemePreference — the cross-app theme state machine (Task: theme derived\n// from the Auth system, live across tabs and apps).\n//\n// boot : cookie → localStorage → \"system\" (the pre-paint script already\n// painted this), then ONCE per session reconcile against the\n// profile value from `GET me` (authoritative) when a fetcher is\n// available.\n// change : apply + localStorage + cross-subdomain cookie + best-effort\n// `PATCH me/preferences { themePreference }`.\n// sync : same-app tabs via the `storage` event; other-app tabs re-read the\n// shared cookie on focus/visibility; `system` follows live OS\n// changes via matchMedia.\n// ---------------------------------------------------------------------------\n\nexport function useThemePreference(): {\n value: ThemePreference\n setValue: (next: ThemePreference) => void\n} {\n const ctx = useContext(NavChromeContext)\n const fetchJson = ctx?.fetchJson ?? null\n const [value, setValueState] = useState<ThemePreference>('system')\n const reconciled = useRef(false)\n\n // Boot: cookie → localStorage → system.\n useEffect(() => {\n const cookie = readThemeCookie()\n let ls: string | null = null\n try {\n ls = localStorage.getItem(THEME_STORAGE_KEY)\n } catch {\n /* unavailable */\n }\n const pref = cookie ?? (isThemePreference(ls) ? ls : null) ?? 'system'\n setValueState(pref)\n applyThemePreference(pref)\n }, [])\n\n // Once per session: converge on the profile's saved choice (authoritative),\n // reusing the provider's single `me` fetch.\n const meCtx = useContext(NavChromeContext)\n useEffect(() => {\n if (reconciled.current) return\n // A choice made where no chrome-API session exists (Politogy ID's login\n // screen) is still only in the cookie. Push it UP rather than pulling the\n // stale profile value DOWN — otherwise the user's fresh pick is silently\n // reverted on the next app they open (HITL 2026-07-23: \"I set System and it\n // keeps switching back to Light\").\n const pending = readPendingThemeChoice()\n if (pending) {\n // Only latch once the profile write has actually been attempted, so a\n // later `me` arrival still gets a chance to persist it.\n if (meCtx?.me) reconciled.current = true\n setValueState(pending)\n applyThemePreference(pending)\n writeThemeCookie(pending)\n try {\n localStorage.setItem(THEME_STORAGE_KEY, pending)\n } catch {\n /* unavailable */\n }\n if (!meCtx?.me) return\n fetchJson?.('me/preferences', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ themePreference: pending }),\n })\n .then(() => clearPendingThemeChoice())\n .catch(() => {})\n return\n }\n const pref = meCtx?.me?.themePreference\n if (isThemePreference(pref)) {\n reconciled.current = true\n setValueState(pref)\n applyThemePreference(pref)\n writeThemeCookie(pref)\n try {\n localStorage.setItem(THEME_STORAGE_KEY, pref)\n } catch {\n /* unavailable */\n }\n }\n }, [meCtx?.me])\n\n // Live sync: storage events (same-app tabs), focus/visibility cookie\n // re-reads (other-app tabs), and OS changes while on \"system\".\n useEffect(() => {\n const onStorage = (e: StorageEvent) => {\n if (e.key === THEME_STORAGE_KEY && isThemePreference(e.newValue)) {\n setValueState(e.newValue)\n applyThemePreference(e.newValue)\n }\n }\n const onWake = () => {\n const cookie = readThemeCookie()\n if (cookie) {\n setValueState((prev) => {\n if (cookie !== prev) applyThemePreference(cookie)\n return cookie\n })\n }\n }\n window.addEventListener('storage', onStorage)\n window.addEventListener('focus', onWake)\n document.addEventListener('visibilitychange', onWake)\n return () => {\n window.removeEventListener('storage', onStorage)\n window.removeEventListener('focus', onWake)\n document.removeEventListener('visibilitychange', onWake)\n }\n }, [])\n\n // Follow the OS while set to \"system\".\n useEffect(() => {\n if (value !== 'system') return\n let mq: MediaQueryList\n try {\n mq = window.matchMedia('(prefers-color-scheme: dark)')\n } catch {\n return\n }\n const onChange = () => applyThemePreference('system')\n mq.addEventListener('change', onChange)\n return () => mq.removeEventListener('change', onChange)\n }, [value])\n\n const setValue = useCallback(\n (next: ThemePreference) => {\n setValueState(next)\n applyThemePreference(next)\n writeThemeCookie(next)\n try {\n localStorage.setItem(THEME_STORAGE_KEY, next)\n } catch {\n /* unavailable */\n }\n // Best-effort profile persistence — a theme toggle never errors. Until it\n // lands, the choice stays marked pending so the next app pushes it up\n // instead of reconciling the stale profile value back down.\n markThemeChoicePending(next)\n fetchJson?.('me/preferences', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ themePreference: next }),\n })\n .then(() => clearPendingThemeChoice())\n .catch(() => {})\n },\n [fetchJson],\n )\n\n return { value, setValue }\n}\n","import type { NavIcon, NavItem } from './index'\n\n// ---------------------------------------------------------------------------\n// standardPolitogyNav — the canonical Politogy VRM menu, per operating Mode.\n//\n// This is the single source of truth for the navigation every politogy app\n// renders. The RELATIONSHIP tree is extracted verbatim from VRM core's\n// relationship-mode sidebar (`getRelationshipLinkItems`); the CAMPAIGN and\n// PETITION trees mirror VRM core's mode-scoped menus. Apps consume the same\n// menu everywhere; an app that owns one of the items (e.g. the standalone\n// Contacts app) nests its own pages as that item's children while every other\n// entry links out to another *.politogyvrm.com app as an absolute URL —\n// full-page navigation with SSO shared across the domain.\n//\n// Which tree an app renders is NOT the user's live mode selection — it is the\n// app's own mode, mapped from the app registry (see `POLITOGY_APPS[app].mode`).\n// A campaign-scoped app (a2p / phonebank / canvass / signs) always renders the\n// Campaign tree; an unscoped app (forms / surveys / polls / contacts) always\n// renders Relationship, exactly as before. Switching modes is a full-page\n// navigation between mode homes (the Mode pill's job), and each destination is\n// itself pinned — so the tree is deterministic from app identity, never a\n// value an app has to pass.\n// ---------------------------------------------------------------------------\n\n/**\n * Icon slots used by the standard menus. The shell stays icon-library-agnostic:\n * callers map each key to their own icon components (lucide, react-icons, …).\n * A missing key simply renders that row without an icon.\n */\nexport type StandardNavIconKey =\n | 'home'\n | 'users'\n | 'mail'\n | 'messageSquare'\n | 'layout'\n | 'activity'\n | 'lifeBuoy'\n | 'grid'\n | 'list'\n | 'upload'\n | 'edit'\n | 'fileText'\n | 'send'\n | 'clock'\n | 'user'\n | 'barChart'\n | 'briefcase'\n | 'settings'\n | 'creditCard'\n | 'dollarSign'\n | 'share'\n // Campaign / Petition mode slots.\n | 'phone'\n | 'map'\n | 'mapPin'\n | 'target'\n | 'flag'\n\n/** The operating Mode whose nav tree to build. Defaults to `relationship`. */\nexport type StandardNavMode = 'relationship' | 'campaign' | 'petition'\n\n/**\n * Per-feature availability for the Campaign tree. Campaign Mode ships its apps\n * incrementally: a disabled feature is omitted from the nav entirely (rather\n * than rendered as a dead/disabled row), and its flag flips to `true` in a\n * later patch release as the app goes live. Dashboard and Voter Contact are\n * core-hosted and always present, so they carry no flag.\n */\nexport interface CampaignFeatureAvailability {\n a2p: boolean\n phonebank: boolean\n canvass: boolean\n signs: boolean\n tribes: boolean\n polling: boolean\n}\n\n/**\n * Launch state at this shell version: every Campaign feature is deployed and\n * live (a2p / phonebank / canvass / signs .politogyvrm.com all serve the app\n * behind SSO as of 2026-07-24), so no row is hidden. The flags remain so a\n * future feature can ship dark, and so a caller can hide one per-deployment.\n */\nexport const CAMPAIGN_FEATURE_AVAILABILITY: CampaignFeatureAvailability = {\n a2p: true,\n phonebank: true,\n canvass: true,\n signs: true,\n tribes: true,\n polling: true,\n}\n\n/** Absolute origins for the standalone Campaign / Petition apps. */\nconst A2P_ORIGIN = 'https://a2p.politogyvrm.com/'\nconst PHONEBANK_ORIGIN = 'https://phonebank.politogyvrm.com/'\nconst CANVASS_ORIGIN = 'https://canvass.politogyvrm.com/'\nconst SIGNS_ORIGIN = 'https://signs.politogyvrm.com/'\nconst POLLS_ORIGIN = 'https://polls.politogyvrm.com/'\n// Tribes is a page inside the standalone Contacts app (Specs/Tribes: Tribes is\n// implemented as an extension of Contacts). Matches app-shell.tsx's `/tribes`.\nconst CONTACTS_TRIBES = 'https://contacts.politogyvrm.com/tribes'\n// Petition Mode is its own standalone app on its own subdomain (the petitions\n// repo deploys production to petition-mode.politogyvrm.com).\nconst PETITION_MODE_ORIGIN = 'https://petition-mode.politogyvrm.com/'\n\nexport interface StandardNavOptions {\n /** VRM core origin, e.g. \"https://app.politogyvrm.com\". Trailing slash OK. */\n coreBaseUrl: string\n /** Icon component per slot; omitted slots render icon-less rows. */\n icons?: Partial<Record<StandardNavIconKey, NavIcon>>\n /**\n * App-local override for the \"Contacts\" item. `children` are used verbatim\n * (NOT absolutized) so the owning app nests its own routes; `href` (also\n * verbatim) feeds active-detection for the group header. When omitted, the\n * item carries VRM core's own contacts sub-pages as absolute links.\n * (Relationship tree only.)\n */\n contactsItem?: { href?: string; children?: NavItem[] }\n /**\n * The trailing \"Support\" row. VRM core opens its SupportRequestModal here;\n * other apps supply their own handler (`onClick`) or a link (`href`).\n * Omitted or `false` → no Support row. Appended to every mode's tree.\n */\n supportItem?: { onClick?: () => void; href?: string } | false\n /**\n * Which mode's tree to build. Default `relationship`, whose output is\n * byte-for-byte what this function produced before modes existed.\n */\n mode?: StandardNavMode\n /**\n * Active organization id (full UUID). EVERY link in EVERY tree carries it as\n * `?org=<uuid>` — the same convention the Mode switcher and My Account menu\n * use — so the destination app opens on the same org instead of the user's\n * default one. Omit it only when the caller genuinely has no active org yet.\n */\n activeOrgId?: string | null\n /**\n * Per-feature Campaign availability overrides, merged over\n * `CAMPAIGN_FEATURE_AVAILABILITY`. Only meaningful for the Campaign tree.\n */\n campaignAvailability?: Partial<CampaignFeatureAvailability>\n}\n\n/** Core-relative route + icon slot for one standard entry. */\ntype CoreLeaf = { label: string; icon: StandardNavIconKey; path: string }\n\n/**\n * One sub-item of a standalone app, as a path RELATIVE to that app's origin\n * (`''` is the app root). Resolved against the origin and given the active-org\n * query param, exactly like the parent row it hangs under.\n */\ntype CrossAppLeaf = { label: string; icon: StandardNavIconKey; path: string }\n\nconst CONTACTS_DEFAULT_CHILDREN: CoreLeaf[] = [\n { label: 'Dashboard', icon: 'grid', path: '/relationship/contacts/dashboard' },\n { label: 'All Contacts', icon: 'list', path: '/relationship/contacts/all' },\n { label: 'Tribes', icon: 'users', path: '/relationship/contacts/groups' },\n { label: 'Import', icon: 'upload', path: '/relationship/contacts/import' },\n { label: 'Import History', icon: 'fileText', path: '/relationship/contacts/import-history' },\n { label: 'Merge Rules', icon: 'layout', path: '/relationship/contacts/merge-rules' },\n]\n\nconst EMAIL_CHILDREN: CoreLeaf[] = [\n { label: 'Dashboard', icon: 'grid', path: '/relationship/email/dashboard' },\n { label: 'Create & Edit', icon: 'edit', path: '/relationship/email/create-and-edit' },\n { label: 'Sender Information', icon: 'mail', path: '/relationship/email/inbox' },\n { label: 'Recipients', icon: 'user', path: '/relationship/email/send-to' },\n { label: 'Send & Automate', icon: 'clock', path: '/relationship/email/send-and-automate' },\n { label: 'Statistics', icon: 'barChart', path: '/relationship/email/statistics' },\n]\n\nconst SMS_CHILDREN: CoreLeaf[] = [\n { label: 'Dashboard', icon: 'grid', path: '/relationship/sms-mms-blast/dashboard' },\n { label: 'Compose & Send', icon: 'send', path: '/relationship/sms-mms-blast/compose-and-send' },\n { label: 'Conversations', icon: 'messageSquare', path: '/relationship/sms-mms-blast/conversations' },\n]\n\nconst CTA_CHILDREN: CoreLeaf[] = [\n { label: 'Dashboard', icon: 'grid', path: '/relationship/cta-database/dashboard' },\n { label: 'Create & Edit', icon: 'edit', path: '/relationship/cta-creator/create-and-edit' },\n { label: 'Submissions', icon: 'fileText', path: '/relationship/cta-submissions/submissions' },\n]\n\n// Organization Settings — promoted from the My Account menu into the left nav\n// (HITL directive 2026-07-23). Mirrors the main app's page IA exactly:\n// /organization-settings/:tab, with Subscription & Billing carrying its own\n// third level (/organization-settings/subscription-billing/:tab). This is the\n// canonical depth-3 example the nav renderers support.\ntype CoreBranch = CoreLeaf & { children?: CoreLeaf[] }\n\nconst ORG_SETTINGS_CHILDREN: CoreBranch[] = [\n { label: 'General', icon: 'settings', path: '/organization-settings' },\n {\n label: 'Subscription & Billing',\n icon: 'creditCard',\n path: '/organization-settings/subscription-billing',\n children: [\n { label: 'Current Plan', icon: 'fileText', path: '/organization-settings/subscription-billing/current-plan' },\n { label: 'SMS, MMS & Email Usage', icon: 'activity', path: '/organization-settings/subscription-billing/text-email' },\n { label: 'Wallet', icon: 'dollarSign', path: '/organization-settings/subscription-billing/wallet' },\n { label: '10DLC', icon: 'messageSquare', path: '/organization-settings/subscription-billing/10dlc' },\n { label: 'Billing History', icon: 'clock', path: '/organization-settings/subscription-billing/billing-history' },\n ],\n },\n { label: 'Email', icon: 'mail', path: '/organization-settings/email-settings' },\n { label: 'Users', icon: 'users', path: '/organization-settings/users' },\n { label: 'Shared Links', icon: 'share', path: '/organization-settings/shared-links' },\n]\n\n// The NEW standalone acquisition apps (forms./surveys./polls.politogyvrm.com)\n// replace the legacy in-core \"Forms & Surveys\" system (HITL directive\n// 2026-07-23; removal plan: politogy/docs/legacy-forms-removal-plan.md).\n// Absolute cross-app links — SSO carries the session.\nconst APP_FORMS_CHILDREN = [\n { label: 'Forms', icon: 'list' as const, href: 'https://forms.politogyvrm.com/?tab=forms' },\n { label: 'Canvas', icon: 'edit' as const, href: 'https://forms.politogyvrm.com/?tab=canvas' },\n { label: 'Submissions', icon: 'fileText' as const, href: 'https://forms.politogyvrm.com/?tab=submissions' },\n]\n// The Surveys sub-menu mirrors the app's tab strip: Surveys / Canvas / Results.\n// Canvas and Results are survey-scoped routes (/surveys/:id/canvas), so with no\n// survey selected the list page carries a ?view= param — distinct hrefs, so\n// active-detection singles out exactly one (identical hrefs were the earlier\n// all-active bug; query params ARE compared, hashes are not).\nconst APP_SURVEYS_CHILDREN = [\n { label: 'Surveys', icon: 'list' as const, href: 'https://surveys.politogyvrm.com/surveys' },\n { label: 'Canvas', icon: 'edit' as const, href: 'https://surveys.politogyvrm.com/surveys?view=canvas' },\n { label: 'Results', icon: 'barChart' as const, href: 'https://surveys.politogyvrm.com/surveys?view=results' },\n]\nconst APP_POLLS_CHILDREN = [\n { label: 'Command Center', icon: 'grid' as const, href: 'https://polls.politogyvrm.com/' },\n { label: 'New Poll', icon: 'edit' as const, href: 'https://polls.politogyvrm.com/polls/new' },\n]\n\n// ---------------------------------------------------------------------------\n// Campaign app sub-navigation.\n//\n// Reference/UI-Platform v13 (Left bar → Navigation): \"The canonical VRM nav\n// tree — PARENT GROUPS WITH SUB-ITEMS. The app's own pages nest under their\n// group.\" The Campaign tree shipped as eight flat rows with no `children`, so\n// the Navigation Display control's \"Both\" and \"Sub Menu\" modes had nothing to\n// expand in the left bar of a2p / phonebank / canvass / signs — the three modes\n// rendered an identical sidebar and the control looked broken.\n//\n// Each list below is the app's OWN section list, taken verbatim from that app's\n// in-app tab strip (its `components/Shell.tsx`), so the sidebar sub-menu and the\n// page tab strip name the same sections in the same order — the sidebar/tab\n// agreement Reference/UI-Platform exists to enforce.\n// ---------------------------------------------------------------------------\n\n/** a2p/components/Shell.tsx `TABS` — the six A2P tabs. */\nconst APP_A2P_CHILDREN: CrossAppLeaf[] = [\n { label: 'Dashboard', icon: 'grid', path: 'dashboard' },\n { label: 'Compose', icon: 'edit', path: 'compose' },\n { label: 'Recipients', icon: 'user', path: 'recipients' },\n { label: 'Tech Check', icon: 'activity', path: 'tech-check' },\n { label: 'Status', icon: 'clock', path: 'status' },\n { label: 'Conversations', icon: 'messageSquare', path: 'conversations' },\n]\n\n/** phonebank/components/Shell.tsx `NAV` — the Manager console's sections. */\nconst APP_PHONEBANK_CHILDREN: CrossAppLeaf[] = [\n { label: 'Dashboard', icon: 'grid', path: '' },\n { label: 'Campaigns', icon: 'phone', path: 'campaigns' },\n { label: 'Inbound', icon: 'messageSquare', path: 'inbound' },\n { label: 'Reports', icon: 'barChart', path: 'reports' },\n]\n\n/** canvass/components/Shell.tsx `SECTIONS` — the manager console's sections. */\nconst APP_CANVASS_CHILDREN: CrossAppLeaf[] = [\n { label: 'Dashboard', icon: 'grid', path: '' },\n { label: 'Campaigns', icon: 'target', path: 'campaigns' },\n { label: 'Canvassers', icon: 'users', path: 'canvassers' },\n]\n\n/**\n * signs/components/Shell.tsx `SECTIONS`. Review Queue is Manager+ in the app's\n * tab strip; the shared tree carries no role input, so the row is listed for\n * everyone and the ROUTE enforces it — /review renders a \"available to Managers\n * and Admins\" notice and loads no queue data for a volunteer (signs\n * app/review/page.tsx). Listing it keeps sidebar and tab strip identical for the\n * managers who use it rather than re-opening per-app nav drift.\n */\nconst APP_SIGNS_CHILDREN: CrossAppLeaf[] = [\n { label: 'Map', icon: 'map', path: '' },\n { label: 'Placements', icon: 'list', path: 'placements' },\n { label: 'Review Queue', icon: 'fileText', path: 'review' },\n { label: 'Recovery', icon: 'flag', path: 'recovery' },\n { label: 'Reports', icon: 'barChart', path: 'reports' },\n]\n\n/**\n * Build the standard Politogy VRM menu for the given `mode` (default\n * `relationship`), in the exact order and wording the main app renders it. See\n * `StandardNavOptions` for the app-specific hooks (`contactsItem`,\n * `supportItem`) and the Campaign inputs (`activeOrgId`, `campaignAvailability`).\n */\nexport function standardPolitogyNav(opts: StandardNavOptions): NavItem[] {\n const base = opts.coreBaseUrl.replace(/\\/+$/, '')\n const abs = (path: string): string => `${base}${path.startsWith('/') ? path : `/${path}`}`\n const icon = (key: StandardNavIconKey): NavIcon | undefined => opts.icons?.[key]\n\n // EVERY link this tree emits leaves the current app (core routes are\n // cross-app for a standalone app, and the app-owned rows are supplied by the\n // caller), so each one carries the active org as `?org=<full-uuid>` — the\n // full id is the only collision-free selector (contacts-api matches exact id\n // first, then a short suffix that can collide across a user's orgs). Without\n // it a multi-org user following a bare cross-app link lands in whatever org\n // the destination defaults to; the cookie is only the fallback for a bare\n // URL, the param is the explicit selector. Active-detection ignores `org`\n // (isNavItemActive's ACTIVE_IGNORED_PARAMS) so stamping it selects nothing\n // differently, and it keeps the org in the address bar for bookmarking.\n const orgParam = opts.activeOrgId ? `org=${opts.activeOrgId}` : ''\n const withOrg = (url: string): string =>\n orgParam ? `${url}${url.includes('?') ? '&' : '?'}${orgParam}` : url\n\n const leaves = (children: CoreLeaf[]): NavItem[] =>\n children.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(abs(c.path)) }))\n const branches = (children: CoreBranch[]): NavItem[] =>\n children.map((c) => ({\n label: c.label,\n icon: icon(c.icon),\n href: withOrg(abs(c.path)),\n children: c.children ? leaves(c.children) : undefined,\n }))\n\n const buildRelationship = (): NavItem[] => {\n const contacts: NavItem = opts.contactsItem\n ? {\n label: 'Contacts',\n icon: icon('users'),\n href: opts.contactsItem.href,\n children: opts.contactsItem.children,\n }\n : {\n label: 'Contacts',\n icon: icon('users'),\n href: withOrg(abs('/relationship/contacts/dashboard')),\n children: leaves(CONTACTS_DEFAULT_CHILDREN),\n }\n\n return [\n { label: 'Dashboard', icon: icon('home'), href: withOrg(abs('/relationship/dashboard')) },\n contacts,\n {\n label: 'Email Broadcast',\n icon: icon('mail'),\n href: withOrg(abs('/relationship/email/dashboard')),\n children: leaves(EMAIL_CHILDREN),\n },\n {\n label: 'SMS/MMS Blast',\n icon: icon('messageSquare'),\n href: withOrg(abs('/relationship/sms-mms-blast/dashboard')),\n children: leaves(SMS_CHILDREN),\n },\n // These two carry no top-level href in VRM core (parent row only toggles).\n { label: 'Calls to Action', icon: icon('layout'), children: leaves(CTA_CHILDREN) },\n {\n label: 'Forms',\n icon: icon('activity'),\n href: withOrg('https://forms.politogyvrm.com/'),\n children: APP_FORMS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) })),\n },\n {\n label: 'Surveys',\n icon: icon('fileText'),\n href: withOrg('https://surveys.politogyvrm.com/surveys'),\n children: APP_SURVEYS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) })),\n },\n {\n label: 'Polls',\n icon: icon('barChart'),\n href: withOrg('https://polls.politogyvrm.com/'),\n children: APP_POLLS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) })),\n },\n {\n label: 'Organization Settings',\n icon: icon('briefcase'),\n href: withOrg(abs('/organization-settings')),\n children: branches(ORG_SETTINGS_CHILDREN),\n },\n ]\n }\n\n // Campaign tree — Dashboard + the 7 Campaign Mode features. Dashboard and\n // Voter Contact are core-hosted (VRM core /campaign/*); the rest link out to\n // standalone apps and are gated by CAMPAIGN_FEATURE_AVAILABILITY.\n const buildCampaign = (): NavItem[] => {\n const avail: CampaignFeatureAvailability = {\n ...CAMPAIGN_FEATURE_AVAILABILITY,\n ...opts.campaignAvailability,\n }\n // Sub-items of a standalone app: `origin` + the app-relative path, carrying\n // the active org the way the parent row does. Trailing slash on the origin\n // is normalized so `''` yields the app root and `x` yields `/x`.\n const appLeaves = (origin: string, children: CrossAppLeaf[]): NavItem[] => {\n const base = origin.replace(/\\/+$/, '')\n return children.map((c) => ({\n label: c.label,\n icon: icon(c.icon),\n href: withOrg(c.path ? `${base}/${c.path}` : `${base}/`),\n }))\n }\n type Gated = NavItem & { flag?: keyof CampaignFeatureAvailability }\n const rows: Gated[] = [\n { label: 'Dashboard', icon: icon('home'), href: withOrg(abs('/campaign/dashboard')) },\n { label: 'Voter Contact', icon: icon('target'), href: withOrg(abs('/campaign/campaigns')) },\n {\n label: 'A2P',\n icon: icon('messageSquare'),\n href: withOrg(A2P_ORIGIN),\n children: appLeaves(A2P_ORIGIN, APP_A2P_CHILDREN),\n flag: 'a2p',\n },\n {\n label: 'Phone Banking',\n icon: icon('phone'),\n href: withOrg(PHONEBANK_ORIGIN),\n children: appLeaves(PHONEBANK_ORIGIN, APP_PHONEBANK_CHILDREN),\n flag: 'phonebank',\n },\n {\n label: 'Field Canvassing',\n icon: icon('map'),\n href: withOrg(CANVASS_ORIGIN),\n children: appLeaves(CANVASS_ORIGIN, APP_CANVASS_CHILDREN),\n flag: 'canvass',\n },\n {\n label: 'Sign Mapping',\n icon: icon('mapPin'),\n href: withOrg(SIGNS_ORIGIN),\n children: appLeaves(SIGNS_ORIGIN, APP_SIGNS_CHILDREN),\n flag: 'signs',\n },\n { label: 'Tribes', icon: icon('users'), href: withOrg(CONTACTS_TRIBES), flag: 'tribes' },\n { label: 'Polling Engine', icon: icon('barChart'), href: withOrg(POLLS_ORIGIN), flag: 'polling' },\n ]\n return rows\n .filter((r) => !r.flag || avail[r.flag])\n .map(({ flag: _flag, ...item }) => item)\n }\n\n // Petition tree — minimal: the Petition Mode home (its own standalone app).\n // Labeled Dashboard so the shared breadcrumb trail anchors correctly.\n const buildPetition = (): NavItem[] => [\n { label: 'Dashboard', icon: icon('home'), href: withOrg(PETITION_MODE_ORIGIN) },\n ]\n\n const mode = opts.mode ?? 'relationship'\n const items =\n mode === 'campaign'\n ? buildCampaign()\n : mode === 'petition'\n ? buildPetition()\n : buildRelationship()\n\n if (opts.supportItem) {\n items.push({\n label: 'Support',\n icon: icon('lifeBuoy'),\n href: opts.supportItem.href,\n onClick: opts.supportItem.onClick,\n })\n }\n\n return items\n}\n","// ---------------------------------------------------------------------------\n// Framework-agnostic chrome (sidebar + top navbar) for @the-portland-company/shell.\n//\n// The other chrome in this package (ShellChrome, Sidebar, Header, …) is built\n// on Chakra UI v2 + react-router and targets Vite SPAs. That stack cannot be\n// imported into a Next.js / React 19 / Tailwind app. This \"native\" module is a\n// dependency-light alternative: pure React (no Chakra, no emotion, no\n// react-router, no icon library) whose styling is driven entirely by the CSS\n// design tokens shipped in `@the-portland-company/shell/chrome.css`.\n//\n// It is a FAITHFUL VISUAL TWIN of the Chakra chrome (Sidebar.tsx / Header.tsx /\n// OrgPill / ModePill / NavItem / UserMenu): same 240px sidebar, brand-logo\n// slot, \"ORGANIZATION\" org pill, mode pill, solid active nav rows, pipe-\n// separated footer links + commit string, and an avatar+name+email+chevron user\n// menu — so an app rendering this looks identical to the main VRM app.\n//\n// Every app concern (nav items, org, mode, user, links, icons, the routing\n// Link component, the theme toggle) is injected via props, so both the Contacts\n// app (Next.js) and the VRM app could consume the same components.\n// ---------------------------------------------------------------------------\n\nimport type { ComponentType, CSSProperties, ReactNode } from 'react'\nimport { useEffect, useMemo, useState } from 'react'\nimport { useTopBarIconSlotGlyph, type TopBarIconSlot } from '../lib/topbarIconSlot'\nimport { resolveBrandGlyph } from '../lib/brandGlyphs'\nimport { topBarIconButtonClass, TopBarTooltip, TopBarPanelArrow, NavThemeControl, resolveOrgLogoUrl, type ThemePreference } from './chromeActions'\n\n// Data-backed top-bar widgets (Fuel, Notifications, Support, Nav-display) +\n// the injected-fetcher provider they hang off. One implementation for every app.\nexport {\n NavChromeProvider,\n CORE_APP_ORIGIN,\n CORE_BILLING_PATH,\n FuelAction,\n NotificationsAction,\n SupportAction,\n NavDisplayAction,\n NavThemeControl,\n TopBarCountBadge,\n TopBarPanelArrow,\n TopBarTooltip,\n TopBarWidgetSlot,\n TopBarPopover,\n topBarIconButtonClass,\n resolveOrgLogoUrl,\n useChromeMe,\n useChromeOrgs,\n useNavChromeFetcher,\n useThemePreference,\n} from './chromeActions'\nexport type {\n ChromeMe,\n NavChromeFetcher,\n NavDisplayMode,\n ThemePreference,\n ChromeOrgSummary,\n ChromeNotificationsPayload,\n ChromeNotificationAlert,\n ChromeNotificationReply,\n ChromeNotificationImport,\n ChromeNotificationQuarantine,\n CommunicationsFuelStatus,\n FuelChannelStatus,\n} from './chromeActions'\n\n// An icon is any component that accepts an optional size + className. This\n// matches both `lucide-react` and `react-icons` icon signatures, so consuming\n// apps pass their own icon set without this package depending on one.\nexport type NavIcon = ComponentType<{ size?: number; className?: string }>\n\nexport type NavItem = {\n /** Route to link to. Optional when `onClick` is supplied (renders a button). */\n href?: string\n label: string\n icon?: NavIcon\n /**\n * When supplied the row renders as a `<button>` (styled identically to the\n * link rows) instead of a routed link — used for actions like \"Support\".\n */\n onClick?: () => void\n /**\n * Disables the row: non-interactive and dimmed, with `disabledTitle` shown as\n * a hover tooltip explaining why. Mirrors `NavTab`'s existing contract so a\n * gated row looks the same whether it renders in the sidebar or a tab strip.\n * Without this, an app that gates a section (VRM dims Email / SMS until setup\n * is complete) had no way to express it and the row rendered fully clickable\n * (shell-nav-handoff §3).\n */\n disabled?: boolean\n /** Tooltip for a disabled row — say why, and how to resolve it. */\n disabledTitle?: string\n /**\n * Nested sub-items. When present, the row becomes an expandable GROUP header.\n * Clicking it always toggles the children open/closed and rotates the\n * right-aligned chevron; if the item ALSO carries an `onClick`, that runs too,\n * so a parent can navigate to its section dashboard while expanding\n * (shell-nav-handoff §2). An `href` alone never navigates from a group header. The sidebar runs a single-open accordion (opening one group closes\n * the others) and auto-expands whichever group contains the active route —\n * mirroring the main VRM app's Chakra sidebar. Children render as smaller nav\n * rows on a lighter panel and support both `href` links and `onClick` actions.\n */\n children?: NavItem[]\n}\n\n// The routing primitive is injected so each app supplies its own (Next.js\n// `<Link>`, react-router `<Link>`, or a plain `<a>`). Defaults to an anchor.\nexport type NavLinkProps = {\n href: string\n className?: string\n 'aria-current'?: 'page' | undefined\n children: ReactNode\n // Optional passthrough attributes so the same injected link can back a\n // routed nav row OR a routed tab (which needs ARIA tab semantics + inline\n // token geometry). Next.js `<Link>`, react-router `<Link>` and a plain <a>\n // all accept these DOM props, and DefaultLink spreads them onto its anchor.\n role?: string\n 'aria-selected'?: boolean\n 'aria-label'?: string\n title?: string\n style?: CSSProperties\n}\nexport type NavLinkComponent = ComponentType<NavLinkProps>\n\n/**\n * URL-scheme allow-list for host-supplied hrefs. React does not neutralize\n * `javascript:`/`data:` schemes on anchor href, so any app-supplied nav/footer/\n * action href must be validated before it reaches the DOM. Permits absolute\n * http(s), mailto/tel, and in-app relative targets; everything else → '#'.\n */\nconst safeHref = (h?: string) =>\n h && /^(https?:|mailto:|tel:|\\/|#|\\.)/i.test(h.trim()) ? h : '#'\n\nconst DefaultLink: NavLinkComponent = ({ href, children, ...rest }) => (\n <a href={safeHref(href)} {...rest}>\n {children}\n </a>\n)\n\n/**\n * Default active-route test. Handles three href shapes so the CURRENT app's\n * item + sub-item select correctly in the cross-app menu (HITL 2026-07-23):\n * - relative path: exact for \"/\", prefix otherwise (legacy behavior);\n * - absolute URL: active only when its host matches window.location.host,\n * then compared by path (and query, when the href carries one — e.g.\n * forms' /?tab=canvas sub-items);\n * - query-only relative hrefs likewise compare location.search.\n *\n * The `org` param is EXCLUDED from the query comparison. Campaign / Petition\n * links carry `?org=<last6>` purely to hand the active organization to the\n * destination app (`standardPolitogyNav`'s `activeOrgId`); it scopes data, it\n * does not identify a page. Comparing it would deselect every campaign row the\n * moment an org is active, because the app's own URL bar carries no `org=`.\n */\nconst ACTIVE_IGNORED_PARAMS = new Set(['org'])\n\nexport function isNavItemActive(pathname: string, href: string): boolean {\n let targetPath = href\n let targetSearch = ''\n if (/^https?:\\/\\//i.test(href)) {\n if (typeof window === 'undefined') return false\n try {\n const u = new URL(href)\n if (u.host !== window.location.host) return false\n targetPath = u.pathname\n targetSearch = u.search\n } catch {\n return false\n }\n } else {\n const qi = href.indexOf('?')\n if (qi >= 0) {\n targetPath = href.slice(0, qi) || '/'\n targetSearch = href.slice(qi)\n }\n }\n // Every IDENTIFYING key=value in the target query must be present in the\n // location. Once the scoping params are dropped a link like\n // \"https://signs.politogyvrm.com/placements?org=abc123\" is a plain path href\n // again and falls through to the path rules below.\n const want = new URLSearchParams(targetSearch)\n for (const k of ACTIVE_IGNORED_PARAMS) want.delete(k)\n if (Array.from(want).length > 0) {\n if (typeof window === 'undefined') return false\n if (pathname !== targetPath) return false\n const have = new URLSearchParams(window.location.search)\n for (const [k, v] of want) if (have.get(k) !== v) return false\n return true\n }\n if (targetPath === '/') return pathname === '/'\n return pathname === targetPath || pathname.startsWith(`${targetPath}/`)\n}\n\n/**\n * Stable identity for an expandable nav group's accordion state. Prefers the\n * item's href; falls back to an index-scoped label so two groups can never\n * collide even when they share a label and have no href.\n */\nfunction groupKeyOf(item: NavItem, index: number): string {\n return item.href ?? `nav-group-${index}-${item.label}`\n}\n\n/** True when any of a group's children links to the active route. */\nfunction hasActiveChild(\n item: NavItem,\n pathname: string,\n activeFn: (pathname: string, href: string) => boolean,\n): boolean {\n return (item.children ?? []).some(\n (child) =>\n (child.href ? activeFn(pathname, child.href) : false) ||\n // Depth-3: a grandchild owning the route also opens the top group.\n (child.children ?? []).some((leaf) =>\n leaf.href ? activeFn(pathname, leaf.href) : false,\n ),\n )\n}\n\n/**\n * Color-coded tone classes for the sidebar environment chip, matching the main\n * VRM app: prod red, staging orange, local/dev green, unknown gray.\n */\nexport function envChipClasses(label: string): string {\n const l = label.toLowerCase()\n if (l === 'production' || l === 'prod')\n return 'bg-[#fee2e2] text-[#ef4444]'\n if (l === 'staging' || l === 'stage')\n return 'bg-[#ffedd5] text-[#f97316]'\n if (l === 'local' || l === 'development' || l === 'dev')\n return 'bg-[#dcfce7] text-[#22c55e]'\n return 'bg-[rgba(107,114,128,0.16)] text-[#6b7280]'\n}\n\n// ---------------------------------------------------------------------------\n\nexport type NavBrand = {\n /** Where the logo links to. Defaults to \"/\". */\n homeHref?: string\n /**\n * Brand logo image src. When supplied this renders as the wordmark logo\n * (matching the main app's BrandLogo), and `badgeLabel`/`title`/`subtitle`\n * are used only as the no-image fallback.\n */\n logoSrc?: string\n logoAlt?: string\n /** Short label shown inside the brand badge fallback (e.g. \"P\"). */\n badgeLabel: string\n title: string\n subtitle?: string\n}\n\nexport type NavOrgOption = {\n id: string\n name: string | null\n logoUrl?: string | null\n brandColor?: string | null\n role?: string | null\n}\n\nexport type NavOrg = {\n name: string | null\n /** Full org id. When present, a copy affordance is shown by the label. */\n id?: string | null\n /** Optional org logo for the pill badge; falls back to initials. */\n logoUrl?: string | null\n /** Solid pill background (the org's brand color). Defaults to race red. */\n brandColor?: string | null\n onClick?: () => void\n /**\n * The user's organizations. When present (even one), the pill renders as a\n * dropdown SWITCHER (Reference/UI-Platform \"Organization selector\": never a\n * static label in a multi-org app); selecting one calls `onSwitch(id)`.\n */\n organizations?: NavOrgOption[]\n onSwitch?: (id: string) => void\n /**\n * The active org is still resolving from the chrome API. Renders a skeleton\n * pill instead of a name. Required because the app's own workspace label is\n * NOT the organization: showing it while the real org loads flashes a wrong\n * value (Global Rules — async values shimmer, they never render a stand-in).\n */\n loading?: boolean\n}\n\nexport type NavModeOption = {\n id: string\n label: string\n icon?: NavIcon\n}\n\nexport type NavMode = {\n label: string\n icon?: NavIcon\n /**\n * Entitled modes for the active organization. With more than one option the\n * pill renders as a SELECTOR (dropdown); with zero/one it stays the classic\n * disabled single-mode pill. Selecting calls onSelect(id).\n */\n options?: NavModeOption[]\n onSelect?: (id: string) => void\n}\n\nexport type NavFooterLink = { label: string; href: string; external?: boolean }\n\nexport type NavFooter = {\n /**\n * Build metadata (env chip / commit / version / date / author). OPTIONAL:\n * omit envLabel/version/commit to render a links-only footer — apps show\n * the meta block to Super Administrators only (Reference/UI-Platform).\n */\n envLabel?: string\n version?: string\n commit?: string\n links?: NavFooterLink[]\n /** ISO date (or any Date-parseable string) of the deployed commit. */\n commitDate?: string\n /** Full name of the commit author (only the first name is shown). */\n commitAuthor?: string\n}\n\nexport type NavSidebarProps = {\n pathname: string\n brand: NavBrand\n nav: {\n groupLabel?: string\n items: NavItem[]\n isActive?: (pathname: string, href: string) => boolean\n }\n org?: NavOrg | null\n mode?: NavMode | null\n footer?: NavFooter | null\n linkComponent?: NavLinkComponent\n}\n\n// Default org-pill background — race red, matching the main app's fallback\n// (mode primary) when an org has no explicit brand color.\nconst ORG_PILL_DEFAULT = 'var(--color-race-red)'\n\nexport function NavSidebar({\n pathname,\n brand,\n nav,\n org,\n mode,\n footer,\n linkComponent,\n}: NavSidebarProps) {\n const Link = linkComponent ?? DefaultLink\n const activeFn = nav.isActive ?? isNavItemActive\n const ModeIcon = mode?.icon\n const orgBg = org?.brandColor || ORG_PILL_DEFAULT\n // Core stores logo_url as a core-relative storage route; resolve it against\n // the core origin so it loads in EVERY app, not just app.politogyvrm.com.\n const orgLogoSrc = resolveOrgLogoUrl(org?.logoUrl)\n\n // Single-open accordion for expandable nav groups, mirroring the main VRM\n // app's Chakra sidebar. `activeGroupKey` is the group (if any) that owns the\n // current route; deriving it as a primitive string keeps the auto-expand\n // effect from firing when `nav.items` is a fresh array reference each render\n // (which would otherwise clobber a manual toggle).\n const activeGroupKey = useMemo(() => {\n for (let i = 0; i < nav.items.length; i++) {\n const item = nav.items[i]\n if (item.children && item.children.length > 0 && hasActiveChild(item, pathname, activeFn)) {\n return groupKeyOf(item, i)\n }\n }\n return null\n }, [nav.items, pathname, activeFn])\n\n // Seed the open group from the active route on first paint (no expand flash),\n // then keep it synced as the route changes. Manual toggles between route\n // changes are preserved because the effect only reruns when the *derived*\n // active group actually changes.\n const [openGroup, setOpenGroup] = useState<string | null>(activeGroupKey)\n useEffect(() => {\n setOpenGroup(activeGroupKey)\n }, [activeGroupKey])\n const toggleGroup = (key: string) =>\n setOpenGroup((prev) => (prev === key ? null : key))\n\n return (\n <aside className=\"fixed inset-y-0 left-0 z-30 hidden w-[240px] flex-col border-r border-[color:var(--line)] bg-[color:var(--nav-surface)] lg:flex\">\n {/* Brand — logo image (preferred) or badge fallback */}\n <Link\n href={brand.homeHref ?? '/'}\n className=\"flex h-[64px] flex-shrink-0 items-center gap-2.5 px-6\"\n >\n {brand.logoSrc ? (\n <img\n src={brand.logoSrc}\n alt={brand.logoAlt ?? brand.title}\n draggable={false}\n className=\"h-10 w-auto object-contain\"\n />\n ) : (\n <>\n <span className=\"flex h-9 w-9 items-center justify-center rounded-xl bg-[color:var(--color-race-red)] text-base font-black text-white shadow-sm\">\n {brand.badgeLabel}\n </span>\n <span className=\"flex flex-col leading-tight\">\n <span className=\"text-base font-extrabold tracking-[-0.01em] text-[color:var(--color-race-red)]\">\n {brand.title}\n </span>\n {brand.subtitle ? (\n <span className=\"text-[11px] font-semibold uppercase tracking-[0.16em] text-[color:var(--muted)]\">\n {brand.subtitle}\n </span>\n ) : null}\n </span>\n </>\n )}\n </Link>\n\n {/* Scroll region: org pill, mode pill, nav */}\n <div className=\"flex flex-1 flex-col overflow-y-auto px-4 pb-2\">\n {/* Organization switcher */}\n {org ? (\n <div className=\"mb-3\">\n <div className=\"mb-2 flex items-center justify-between px-1\">\n <p className=\"text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Organization\n </p>\n {org.id && !org.loading ? <OrgIdCopyButton id={org.id} /> : null}\n </div>\n {org.loading ? (\n <div className=\"flex w-full items-center gap-2.5 rounded-md border border-[color:var(--line)] bg-[color:var(--panel-elevated)] px-2.5 py-2 shadow-sm\">\n <span\n aria-hidden\n className=\"h-7 w-7 shrink-0 animate-pulse rounded-full bg-[color:var(--panel)]\"\n />\n <span\n aria-hidden\n className=\"h-4 flex-1 animate-pulse rounded bg-[color:var(--panel)]\"\n />\n <span className=\"sr-only\">Loading organization</span>\n </div>\n ) : org.organizations && org.organizations.length > 0 && org.onSwitch ? (\n <details data-nav-details className=\"group relative\">\n <summary className=\"flex w-full cursor-pointer list-none items-center justify-between gap-2 rounded-md border border-[color:var(--line)] bg-[color:var(--panel-elevated)] px-2.5 py-2 text-left text-[color:var(--foreground)] shadow-sm transition hover:bg-[color:var(--panel)] [&::-webkit-details-marker]:hidden\">\n <span className=\"flex min-w-0 items-center gap-2.5\">\n {/* Only the circular badge carries the org's brand color. */}\n <span\n style={{ backgroundColor: orgBg }}\n className=\"flex h-7 w-7 shrink-0 items-center justify-center overflow-hidden rounded-full text-[11px] font-bold text-white\"\n >\n {orgLogoSrc ? (\n <img src={orgLogoSrc} alt=\"\" className=\"h-full w-full object-cover\" />\n ) : (\n (org.name ?? 'Org').slice(0, 2).toUpperCase()\n )}\n </span>\n <span\n title={org.name ?? undefined}\n className=\"truncate text-sm font-semibold\"\n >\n {org.name ?? 'No organizations'}\n </span>\n </span>\n <ChevronDown />\n </summary>\n <div className=\"absolute left-0 right-0 z-40 mt-1 max-h-72 overflow-y-auto rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] py-1 shadow-[var(--shadow-soft)]\">\n {org.organizations.map((o) => {\n const selected = o.id === org.id\n return (\n <button\n key={o.id}\n type=\"button\"\n onClick={(e) => {\n // Close the <details> popover, then switch.\n e.currentTarget.closest('details')?.removeAttribute('open')\n if (!selected) org.onSwitch?.(o.id)\n }}\n aria-current={selected ? 'true' : undefined}\n className={[\n 'flex w-full items-center gap-2.5 px-3 py-2 text-left text-sm',\n selected\n ? 'font-semibold text-[color:var(--color-race-red)]'\n : 'font-medium text-[color:var(--foreground)] hover:bg-[color:var(--panel)]',\n ].join(' ')}\n >\n <span\n style={{ backgroundColor: o.brandColor || ORG_PILL_DEFAULT }}\n className=\"flex h-6 w-6 shrink-0 items-center justify-center overflow-hidden rounded-full text-[10px] font-bold text-white\"\n >\n {resolveOrgLogoUrl(o.logoUrl) ? (\n <img\n src={resolveOrgLogoUrl(o.logoUrl)}\n alt=\"\"\n className=\"h-full w-full object-cover\"\n />\n ) : (\n (o.name ?? 'Org').slice(0, 2).toUpperCase()\n )}\n </span>\n <span title={o.name ?? o.id} className=\"truncate\">\n {o.name ?? o.id.slice(0, 8)}\n </span>\n </button>\n )\n })}\n </div>\n </details>\n ) : (\n <button\n type=\"button\"\n onClick={org.onClick}\n className=\"flex w-full items-center justify-between gap-2 rounded-md border border-[color:var(--line)] bg-[color:var(--panel-elevated)] px-2.5 py-2 text-left text-[color:var(--foreground)] shadow-sm transition hover:bg-[color:var(--panel)]\"\n >\n <span className=\"flex min-w-0 items-center gap-2.5\">\n {/* Only the circular badge carries the org's brand color. */}\n <span\n style={{ backgroundColor: orgBg }}\n className=\"flex h-7 w-7 shrink-0 items-center justify-center overflow-hidden rounded-full text-[11px] font-bold text-white\"\n >\n {orgLogoSrc ? (\n <img src={orgLogoSrc} alt=\"\" className=\"h-full w-full object-cover\" />\n ) : (\n (org.name ?? 'Org').slice(0, 2).toUpperCase()\n )}\n </span>\n <span className=\"truncate text-sm font-semibold\">\n {org.name ?? 'No organizations'}\n </span>\n </span>\n <ChevronDown />\n </button>\n )}\n </div>\n ) : null}\n\n {/* Mode pill — a SELECTOR when the org is entitled to >1 mode. */}\n {mode ? (\n <div className=\"mb-4\">\n {mode.options && mode.options.length > 1 && mode.onSelect ? (\n <details data-nav-details className=\"group relative\">\n <summary className=\"flex w-full cursor-pointer list-none items-center justify-between gap-2 rounded-md bg-[color:var(--color-race-red)] px-2.5 py-2 text-white shadow-sm transition hover:opacity-95 [&::-webkit-details-marker]:hidden\">\n <span className=\"flex items-center gap-2.5\">\n {ModeIcon ? <ModeIcon size={16} className=\"shrink-0\" /> : null}\n <span className=\"text-sm font-semibold tracking-[-0.01em]\">{mode.label}</span>\n </span>\n <ChevronDown />\n </summary>\n <div className=\"absolute left-0 right-0 z-40 mt-1 overflow-hidden rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] py-1 shadow-[var(--shadow-soft)]\">\n {mode.options.map((opt) => {\n const selected = opt.label === mode.label\n const OptIcon = opt.icon\n return (\n <button\n key={opt.id}\n type=\"button\"\n onClick={(e) => {\n e.currentTarget.closest('details')?.removeAttribute('open')\n if (!selected) mode.onSelect?.(opt.id)\n }}\n aria-current={selected ? 'true' : undefined}\n className={[\n 'flex w-full items-center gap-2.5 px-3 py-2 text-left text-sm',\n selected\n ? 'font-semibold text-[color:var(--color-race-red)]'\n : 'font-medium text-[color:var(--foreground)] hover:bg-[color:var(--panel)]',\n ].join(' ')}\n >\n {OptIcon ? <OptIcon size={15} className=\"shrink-0 text-current\" /> : null}\n {opt.label}\n </button>\n )\n })}\n </div>\n </details>\n ) : (\n <button\n type=\"button\"\n className=\"flex w-full items-center justify-between gap-2 rounded-md bg-[color:var(--color-race-red)] px-2.5 py-2 text-white shadow-sm\"\n >\n <span className=\"flex items-center gap-2.5\">\n {ModeIcon ? <ModeIcon size={16} className=\"shrink-0\" /> : null}\n <span className=\"text-sm font-semibold tracking-[-0.01em]\">{mode.label}</span>\n </span>\n <ChevronDown />\n </button>\n )}\n </div>\n ) : null}\n\n {/* Nav list */}\n <nav className=\"flex flex-col gap-1\">\n {nav.groupLabel ? (\n <p className=\"px-2 pb-1 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n {nav.groupLabel}\n </p>\n ) : null}\n {nav.items.map((item, idx) => {\n // Expandable group: renders a toggle header + collapsible children.\n if (item.children && item.children.length > 0) {\n const key = groupKeyOf(item, idx)\n const selfActive = item.href ? activeFn(pathname, item.href) : false\n const parentActive = selfActive || hasActiveChild(item, pathname, activeFn)\n return (\n <NavGroup\n key={key}\n item={item}\n active={parentActive}\n open={openGroup === key}\n onToggle={() => toggleGroup(key)}\n pathname={pathname}\n activeFn={activeFn}\n Link={Link}\n />\n )\n }\n const active = item.href ? activeFn(pathname, item.href) : false\n return (\n <NavRow\n key={item.href ?? `nav-${idx}-${item.label}`}\n item={item}\n active={active}\n Link={Link}\n />\n )\n })}\n </nav>\n </div>\n\n {/* Footer — pipe-separated links + commit/version string */}\n {footer ? (\n <div className=\"flex-shrink-0 border-t border-[color:var(--line)] px-4 py-3\">\n {footer.links && footer.links.length > 0 ? (\n <div className=\"flex flex-wrap items-center justify-center gap-1.5 text-xs\">\n {footer.links.map((l, idx) => (\n <span key={l.label} className=\"inline-flex items-center gap-1.5\">\n {idx > 0 ? <span className=\"text-[color:var(--muted)]\">|</span> : null}\n <a\n href={safeHref(l.href)}\n className=\"font-medium text-[color:var(--foreground)] opacity-80 hover:opacity-100 hover:underline\"\n >\n {l.label}\n </a>\n </span>\n ))}\n </div>\n ) : null}\n {footer.envLabel ? (\n <div className=\"mt-1.5 flex flex-col items-center gap-0.5 font-[family-name:var(--font-plex-mono)] text-[10px] text-[color:var(--muted)]\">\n {/* Row 1: env chip | commit | version */}\n <div className=\"flex items-center gap-1.5\">\n <span\n className={[\n 'rounded-md px-1.5 py-0.5 text-[10px] font-semibold',\n envChipClasses(footer.envLabel),\n ].join(' ')}\n >\n {footer.envLabel}\n </span>\n {footer.commit ? (\n <>\n <span className=\"text-[color:var(--muted)]\">|</span>\n <span>{footer.commit.slice(-4)}</span>\n </>\n ) : null}\n {footer.version ? (\n <>\n <span className=\"text-[color:var(--muted)]\">|</span>\n <span>v{footer.version}</span>\n </>\n ) : null}\n </div>\n {/* Row 2: date | author (only when supplied) */}\n {footer.commitDate || footer.commitAuthor ? (\n <div className=\"flex items-center gap-1.5\">\n {footer.commitDate ? (\n <span>\n {new Date(footer.commitDate).toLocaleDateString(undefined, {\n month: 'short',\n day: 'numeric',\n })}\n </span>\n ) : null}\n {footer.commitDate && footer.commitAuthor ? (\n <span className=\"text-[color:var(--muted)]\">|</span>\n ) : null}\n {footer.commitAuthor ? (\n <span>{footer.commitAuthor.split(/\\s+/)[0]}</span>\n ) : null}\n </div>\n ) : null}\n </div>\n ) : null}\n </div>\n ) : null}\n </aside>\n )\n}\n\n// Inline chevron-down (mirrors lucide `ChevronDown`) — no icon dependency.\n// Callers may override `className` to add a rotation (used by expandable groups).\nfunction ChevronDown({ className }: { className?: string } = {}) {\n return (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className ?? 'shrink-0 opacity-80'}\n aria-hidden=\"true\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n )\n}\n\n// A single sidebar nav row. Renders as a routed <Link> (href) or a <button>\n// (onClick), styled identically. Inactive rows animate a left→right gradient\n// sweep on hover (matching the main app); active rows keep solid race-red.\n//\n// `variant=\"sub\"` renders the smaller child rows inside an expanded group: a\n// tighter row whose ACTIVE state is a lighter elevated surface with race-red\n// text (not a solid-red fill — that stays reserved for top-level/parent rows,\n// exactly as the main VRM app's Chakra sidebar treats active sub-items).\n// Specs race-red ramp (hover → active primary).\nconst NAV_HOVER_GRADIENT = 'linear-gradient(90deg,#EA4751 0%,#E63946 100%)'\n\nfunction NavRow({\n item,\n active,\n Link,\n variant = 'top',\n}: {\n item: NavItem\n active: boolean\n Link: NavLinkComponent\n variant?: 'top' | 'sub'\n}) {\n const Icon = item.icon\n const isSub = variant === 'sub'\n const activeClasses = isSub\n ? 'bg-[color:var(--panel-elevated)] text-[color:var(--color-race-red)] shadow-sm'\n : 'bg-[color:var(--color-race-red)] text-white shadow-sm'\n const wrapperClasses = [\n 'group relative block overflow-hidden rounded-md transition',\n active ? activeClasses : 'text-[color:var(--muted)] hover:text-white',\n ].join(' ')\n\n const rowPadding = isSub ? 'px-3 py-1.5 text-[13px]' : 'px-3 py-2 text-sm'\n const iconSize = isSub ? 16 : 18\n // Top-level active rows use white glyphs on the red fill; sub-item active\n // rows inherit the race-red text color via `text-current`.\n const iconClass = active && !isSub ? 'text-white' : 'text-current'\n\n const inner = (\n <>\n {!active ? (\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-y-0 left-0 w-0 transition-[width] duration-300 group-hover:w-full\"\n style={{ background: NAV_HOVER_GRADIENT }}\n />\n ) : null}\n <span className={`relative z-10 flex items-center gap-3 font-semibold ${rowPadding}`}>\n {Icon ? <Icon size={iconSize} className={iconClass} /> : null}\n {item.label}\n </span>\n </>\n )\n\n // A gated row renders as a non-interactive span: dimmed, not focusable, and\n // carrying its reason as a tooltip. Same treatment a disabled NavTab gets, so\n // gating reads identically in the sidebar and in a tab strip.\n if (item.disabled) {\n return (\n <span\n aria-disabled=\"true\"\n title={item.disabledTitle}\n className={`${wrapperClasses} cursor-not-allowed opacity-50`}\n >\n {inner}\n </span>\n )\n }\n\n if (item.onClick && !item.href) {\n return (\n <button type=\"button\" onClick={item.onClick} className={`w-full text-left ${wrapperClasses}`}>\n {inner}\n </button>\n )\n }\n\n return (\n <Link\n href={item.href ?? '#'}\n aria-current={active ? 'page' : undefined}\n className={wrapperClasses}\n >\n {inner}\n </Link>\n )\n}\n\n// An expandable nav GROUP: a toggle header + a collapsible list of child rows.\n// Faithful twin of the main VRM app's Chakra accordion (Sidebar.tsx /\n// NavItem.tsx):\n// - Clicking the header toggles the children — it never navigates, even when\n// the group carries an `href`.\n// - A right-aligned chevron rotates 180° when open.\n// - The header goes solid race-red (white text) when the group owns the active\n// route (its own href OR any child), matching top-level active rows; when\n// merely open it lifts onto the `--panel` surface; otherwise it's a muted row\n// with the same left→right gradient hover sweep as every other nav row.\n// - Children sit on the lighter `--panel` surface, indented and rounded, each\n// rendered through the SAME injected LinkComponent (or as a button for\n// `onClick` children) via <NavRow variant=\"sub\" />.\nfunction NavGroup({\n item,\n active,\n open,\n onToggle,\n pathname,\n activeFn,\n Link,\n}: {\n item: NavItem\n active: boolean\n open: boolean\n onToggle: () => void\n pathname: string\n activeFn: (pathname: string, href: string) => boolean\n Link: NavLinkComponent\n}) {\n const Icon = item.icon\n const headerClasses = [\n 'group relative block w-full overflow-hidden text-left transition',\n open ? 'rounded-t-md' : 'rounded-md',\n active\n ? 'bg-[color:var(--color-race-red)] text-white shadow-sm'\n : open\n ? 'bg-[color:var(--panel)] text-[color:var(--foreground)]'\n : 'text-[color:var(--muted)] hover:text-white',\n ].join(' ')\n\n return (\n <div>\n <button\n type=\"button\"\n // A group header ALWAYS toggles. When the item also carries its own\n // onClick, that runs too — so a parent can navigate to its section\n // dashboard (e.g. Email Broadcast → /relationship/email/dashboard) and\n // expand in one click. Existing apps pass no parent onClick, so their\n // behavior is unchanged (shell-nav-handoff §2).\n onClick={() => {\n onToggle()\n item.onClick?.()\n }}\n aria-expanded={open}\n className={headerClasses}\n >\n {/* Hover sweep only when CLOSED and inactive — an expanded group keeps\n its raised/selected background intact through hover and hover-out. */}\n {!active && !open ? (\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-y-0 left-0 w-0 transition-[width] duration-300 group-hover:w-full\"\n style={{ background: NAV_HOVER_GRADIENT }}\n />\n ) : null}\n <span className=\"relative z-10 flex items-center gap-3 px-3 py-2 text-sm font-semibold\">\n {Icon ? (\n <Icon size={18} className={active ? 'text-white' : 'text-current'} />\n ) : null}\n <span className=\"flex-1\">{item.label}</span>\n <ChevronDown\n className={[\n 'shrink-0 opacity-80 transition-transform duration-200',\n open ? 'rotate-180' : '',\n ].join(' ')}\n />\n </span>\n </button>\n\n {open ? (\n <div className=\"overflow-hidden rounded-b-md bg-[color:var(--nav-submenu-bg)] p-1\">\n <div className=\"flex flex-col gap-0.5\">\n {item.children!.map((child, i) => {\n const childActive = child.href ? activeFn(pathname, child.href) : false\n // Depth-3: a child that carries its own children renders as a\n // NESTED collapsible sub-group (e.g. Organization Settings →\n // Subscription & Billing → Wallet). Deeper levels are not\n // rendered — three is the platform maximum.\n if (child.children && child.children.length > 0) {\n return (\n <NavSubGroup\n key={child.href ?? `subgrp-${i}-${child.label}`}\n item={child}\n pathname={pathname}\n activeFn={activeFn}\n Link={Link}\n />\n )\n }\n return (\n <NavRow\n key={child.href ?? `sub-${i}-${child.label}`}\n item={child}\n active={childActive}\n Link={Link}\n variant=\"sub\"\n />\n )\n })}\n </div>\n </div>\n ) : null}\n </div>\n )\n}\n\n// A second-level group INSIDE an expanded group — the depth-3 renderer\n// (Reference/UI-Platform: sub-sub items). Auto-expands when it owns the active\n// route; otherwise toggles locally. Grandchildren render as further-indented\n// sub rows on the same panel surface.\nfunction NavSubGroup({\n item,\n pathname,\n activeFn,\n Link,\n}: {\n item: NavItem\n pathname: string\n activeFn: (pathname: string, href: string) => boolean\n Link: NavLinkComponent\n}) {\n const ownsActive =\n (item.href ? activeFn(pathname, item.href) : false) ||\n (item.children ?? []).some((c) => (c.href ? activeFn(pathname, c.href) : false))\n const [open, setOpen] = useState(ownsActive)\n useEffect(() => {\n if (ownsActive) setOpen(true)\n }, [ownsActive])\n const Icon = item.icon\n\n return (\n <div>\n <button\n type=\"button\"\n onClick={() => setOpen((v) => !v)}\n aria-expanded={open}\n className={[\n 'flex w-full items-center gap-2.5 rounded px-3 py-1.5 text-left text-[13px] font-medium transition',\n ownsActive\n ? 'text-[color:var(--color-race-red)]'\n : 'text-[color:var(--muted)] hover:bg-[color:var(--nav-row-hover)] hover:text-[color:var(--foreground)]',\n ].join(' ')}\n >\n {Icon ? <Icon size={15} className=\"shrink-0 text-current\" /> : null}\n <span className=\"flex-1\">{item.label}</span>\n <ChevronDown\n className={[\n 'shrink-0 opacity-70 transition-transform duration-200',\n open ? 'rotate-180' : '',\n ].join(' ')}\n />\n </button>\n {open ? (\n <div className=\"ml-4 flex flex-col gap-0.5 border-l border-[color:var(--line)] pl-2\">\n {item.children!.map((leaf, i) => (\n <NavRow\n key={leaf.href ?? `subsub-${i}-${leaf.label}`}\n item={leaf}\n active={leaf.href ? activeFn(pathname, leaf.href) : false}\n Link={Link}\n variant=\"sub\"\n />\n ))}\n </div>\n ) : null}\n </div>\n )\n}\n\n// Right-aligned copy affordance for the org id, shown beside the \"Organization\"\n// label. Copies the full id and briefly swaps its text to \"Copied\".\nfunction OrgIdCopyButton({ id }: { id: string }) {\n const [copied, setCopied] = useState(false)\n return (\n <button\n type=\"button\"\n onClick={() => {\n try {\n void navigator.clipboard?.writeText(id)\n } catch {\n /* clipboard unavailable — ignore */\n }\n setCopied(true)\n setTimeout(() => setCopied(false), 1500)\n }}\n title=\"Copy organization id\"\n className=\"rounded px-1 text-[11px] text-[color:var(--muted)] hover:bg-[color:var(--panel)]\"\n >\n {copied ? 'Copied' : `...${id.slice(-8)}`}\n </button>\n )\n}\n\n// ---------------------------------------------------------------------------\n\nexport type NavUser = {\n name: string | null\n email?: string | null\n /** Profile PHOTO url — highest-precedence avatar source. */\n avatarUrl?: string | null\n /** Memoji url — used when no photo is set; falls back to initials. */\n memojiUrl?: string | null\n tier?: string | null\n role?: string | null\n}\n\nexport type NavTopBarAction = {\n key: string\n /**\n * Canonical top-bar slot. When set, the glyph is sourced by NAME from the\n * Brand API via `--topbar-icon-<slot>`; `icon` becomes the fallback used\n * until the runtime Brand stylesheet lands (or when the token is unset).\n */\n slot?: TopBarIconSlot\n icon: NavIcon\n label: string\n onClick?: () => void\n href?: string\n badge?: number | null\n tone?: 'default' | 'warning' | 'danger'\n /** Tooltip body shown under the icon (label is the tooltip title). */\n description?: string\n}\n\nexport type NavLinkedAccount = {\n id: string\n name: string | null\n email?: string | null\n avatarUrl?: string | null\n active?: boolean\n}\n\nexport type NavRoleBadge = {\n role: string\n orgName?: string | null\n}\n\n/**\n * The My Account menu (avatar dropdown) — mirrors the main VRM app's user\n * menu: My Profile / Organization Settings links, a ROLES & ORGANIZATIONS\n * section, an ACCOUNTS switcher, an optional theme control, then Sign out.\n * Every section renders only when its data is supplied.\n */\nexport type NavUserMenu = {\n myProfileHref?: string\n organizationSettingsHref?: string\n roles?: NavRoleBadge[]\n accounts?: NavLinkedAccount[]\n onSwitchAccount?: (id: string) => void\n onRemoveAccount?: (id: string) => void\n addAccountHref?: string\n onAddAccount?: () => void\n /** Theme preference segmented control (Light / System / Dark). */\n theme?: {\n value: ThemePreference\n onChange: (next: ThemePreference) => void\n }\n}\n\nexport type NavBreadcrumb = {\n label: string\n href?: string\n}\n\nexport type NavTopBarProps = {\n title: string\n subtitle?: string\n /**\n * Breadcrumb trail rendered UNDER the page title (Reference/UI-Platform:\n * every page and sub-page/tab shows its location). Last crumb = current\n * location (non-link); earlier crumbs may carry hrefs.\n */\n breadcrumbs?: NavBreadcrumb[]\n user?: NavUser | null\n userMenu?: NavUserMenu\n onSignOut?: () => void\n /**\n * Structured icon-button action cluster (32×32 circular buttons with optional\n * count badges), rendered before the `actions` slot. Matches the main app's\n * topbar action icons.\n */\n actionsList?: NavTopBarAction[]\n /** App-specific action cluster rendered left of the theme toggle. */\n actions?: ReactNode\n /** Theme toggle slot (injected so this package needs no theme dependency). */\n themeToggle?: ReactNode\n}\n\nexport function NavTopBar({\n title,\n subtitle,\n breadcrumbs,\n user,\n userMenu,\n onSignOut,\n actionsList,\n actions,\n themeToggle,\n}: NavTopBarProps) {\n // Real name = anything that isn't empty and isn't an email address. The\n // trigger shows \"First L.\" — never the email on both lines.\n const rawName = user?.name?.trim() || ''\n const hasRealName = rawName.length > 0 && !rawName.includes('@')\n const displayName = hasRealName ? formatFirstLast(rawName) : (user?.email ?? 'Signed in')\n const initials = (hasRealName ? rawName : (user?.email ?? 'P')).slice(0, 2).toUpperCase()\n const secondary = hasRealName\n ? user?.email || [user?.tier, user?.role].filter(Boolean).join(' · ') || 'member'\n : [user?.tier, user?.role].filter(Boolean).join(' · ') || 'member'\n return (\n <header className=\"sticky top-0 z-20 flex h-20 items-center justify-between gap-4 border-b border-[color:var(--line)] bg-[color:var(--panel)] px-4 backdrop-blur-xl\">\n <div className=\"min-w-0\">\n <h1\n className=\"truncate text-lg font-bold tracking-[-0.01em] text-[color:var(--foreground)]\"\n data-display=\"true\"\n >\n {title}\n </h1>\n {breadcrumbs && breadcrumbs.length > 0 ? (\n <nav aria-label=\"Breadcrumb\" className=\"flex min-w-0 items-center gap-1.5 text-sm text-[color:var(--muted)]\">\n {breadcrumbs.map((b, i) => {\n const last = i === breadcrumbs.length - 1\n return (\n <span key={`${b.label}-${i}`} className=\"flex min-w-0 items-center gap-1.5\">\n {i > 0 ? (\n <span aria-hidden className=\"text-[color:var(--muted)] opacity-60\">\n ›\n </span>\n ) : null}\n {b.href && !last ? (\n <a\n href={safeHref(b.href)}\n className=\"truncate hover:text-[color:var(--foreground)] hover:underline\"\n >\n {b.label}\n </a>\n ) : (\n <span\n aria-current={last ? 'page' : undefined}\n className={['truncate', last ? 'text-[color:var(--foreground)]' : ''].join(' ')}\n >\n {b.label}\n </span>\n )}\n </span>\n )\n })}\n </nav>\n ) : subtitle ? (\n <p className=\"truncate text-sm text-[color:var(--muted)]\">{subtitle}</p>\n ) : null}\n </div>\n\n <div className=\"relative flex shrink-0 items-center gap-[var(--topbar-icon-gap,8px)]\">\n {actionsList && actionsList.length > 0\n ? actionsList.map((action) => (\n <NavTopBarActionButton key={action.key} action={action} />\n ))\n : null}\n {actions}\n {themeToggle}\n\n {/* My Account menu — avatar + name/email + chevron trigger, with the\n full account dropdown (profile/org links, roles, account switcher,\n appearance, sign out). Native <details> popover. */}\n <details data-nav-details className=\"group/acct relative\">\n <summary className=\"group/tbtip relative flex cursor-pointer list-none items-center gap-2.5 rounded-full py-1 pl-1 pr-2 transition hover:bg-[color:var(--panel-elevated)] [&::-webkit-details-marker]:hidden\">\n {/* Same circle size as every top-bar icon button (one shared var).\n Avatar precedence: photo → memoji → initials. */}\n <span className=\"flex h-[var(--topbar-icon-button-size,32px)] w-[var(--topbar-icon-button-size,32px)] items-center justify-center overflow-hidden rounded-full bg-[color:var(--color-race-red)] text-xs font-bold text-white\">\n {user?.avatarUrl || user?.memojiUrl ? (\n <img\n src={(user.avatarUrl || user.memojiUrl) as string}\n alt=\"\"\n className=\"h-full w-full object-cover\"\n />\n ) : (\n initials\n )}\n </span>\n <span className=\"hidden flex-col leading-tight md:flex\">\n <span className=\"text-sm font-semibold text-[color:var(--foreground)]\">\n {displayName}\n </span>\n <span className=\"text-xs text-[color:var(--muted)]\">{secondary}</span>\n </span>\n <ChevronDown />\n <span className=\"group-open/acct:hidden\">\n <TopBarTooltip\n title=\"My Account\"\n description={\n <>\n {hasRealName ? rawName : user?.email ?? 'Signed in'}\n {user?.email ? (\n <>\n <br />\n {user.email}\n </>\n ) : null}\n <br />\n Profile, organizations, appearance and sign out.\n </>\n }\n />\n </span>\n </summary>\n {/*\n The menu grows with the user's data — roles, linked accounts, the\n theme control — and on a short viewport (or a user in many orgs) it\n ran past the bottom of the screen with no way to scroll, putting\n Sign out permanently out of reach. Cap the panel at the viewport,\n scroll the SECTIONS, and keep Sign out outside that scroll area so\n it is always on screen no matter how long the list gets.\n */}\n <div className=\"absolute right-0 z-30 mt-2 flex max-h-[calc(100vh-5rem)] w-72 flex-col overflow-hidden rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] py-1 shadow-[var(--shadow-soft)]\">\n <TopBarPanelArrow />\n <div className=\"min-h-0 flex-1 overflow-y-auto overscroll-contain\">\n {userMenu?.myProfileHref ? (\n <a\n href={safeHref(userMenu.myProfileHref)}\n className=\"flex w-full items-center gap-2.5 px-4 py-2.5 text-left text-sm font-medium text-[color:var(--foreground)] hover:bg-[color:var(--panel)]\"\n >\n <ProfileIcon />\n My Profile\n </a>\n ) : null}\n {userMenu?.organizationSettingsHref ? (\n <a\n href={safeHref(userMenu.organizationSettingsHref)}\n className=\"flex w-full items-center gap-2.5 border-t border-[color:var(--line)] px-4 py-2.5 text-left text-sm font-medium text-[color:var(--foreground)] hover:bg-[color:var(--panel)]\"\n >\n <BriefcaseIcon />\n Organization Settings\n </a>\n ) : null}\n\n {userMenu?.roles && userMenu.roles.length > 0 ? (\n <div className=\"border-t border-[color:var(--line)] px-4 py-3\">\n <p className=\"mb-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Roles & Organizations\n </p>\n <ul className=\"flex flex-col gap-1.5\">\n {userMenu.roles.map((r, i) => (\n <li key={`${r.role}-${i}`} className=\"flex flex-wrap items-center gap-1.5 text-sm\">\n <span className=\"rounded-md bg-[color:var(--panel)] px-2 py-0.5 text-xs font-bold uppercase tracking-wide text-[color:var(--foreground)]\">\n {r.role}\n </span>\n {r.orgName ? (\n <span className=\"text-[color:var(--muted)]\">in {r.orgName}</span>\n ) : null}\n </li>\n ))}\n </ul>\n </div>\n ) : null}\n\n {userMenu?.accounts && userMenu.accounts.length > 0 ? (\n <div className=\"border-t border-[color:var(--line)] px-4 py-3\">\n <p className=\"mb-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Accounts\n </p>\n <ul className=\"flex flex-col gap-1\">\n {userMenu.accounts.map((a) => (\n <li key={a.id} className=\"flex items-center gap-2.5\">\n <button\n type=\"button\"\n onClick={() => {\n if (!a.active) userMenu.onSwitchAccount?.(a.id)\n }}\n className=\"flex min-w-0 flex-1 items-center gap-2.5 rounded-lg px-1 py-1 text-left hover:bg-[color:var(--panel)]\"\n >\n <span className=\"flex h-8 w-8 shrink-0 items-center justify-center overflow-hidden rounded-full bg-[color:var(--color-race-red)] text-[11px] font-bold text-white\">\n {a.avatarUrl ? (\n <img src={a.avatarUrl} alt=\"\" className=\"h-full w-full object-cover\" />\n ) : (\n (a.name ?? a.email ?? '?').slice(0, 2).toUpperCase()\n )}\n </span>\n <span className=\"flex min-w-0 flex-col leading-tight\">\n <span\n className={[\n 'truncate text-sm font-semibold',\n a.active\n ? 'text-[color:var(--color-race-red)]'\n : 'text-[color:var(--foreground)]',\n ].join(' ')}\n >\n {a.name ?? a.email ?? a.id.slice(0, 8)}\n </span>\n <span className=\"truncate text-xs text-[color:var(--muted)]\">\n {a.active ? 'Active' : a.email ?? ''}\n </span>\n </span>\n </button>\n {!a.active && userMenu.onRemoveAccount ? (\n <button\n type=\"button\"\n aria-label={`Remove ${a.name ?? a.email ?? 'account'}`}\n onClick={() => userMenu.onRemoveAccount?.(a.id)}\n className=\"shrink-0 rounded p-1 text-[color:var(--color-race-red)] hover:bg-[color:var(--panel)]\"\n >\n <TrashIcon />\n </button>\n ) : null}\n </li>\n ))}\n </ul>\n {userMenu.addAccountHref || userMenu.onAddAccount ? (\n userMenu.addAccountHref ? (\n <a\n href={safeHref(userMenu.addAccountHref)}\n className=\"mt-1.5 flex items-center gap-2.5 rounded-lg px-1 py-1.5 text-sm font-semibold text-[color:var(--color-race-red)] hover:bg-[color:var(--panel)]\"\n >\n <AddUserIcon />\n Add Account\n </a>\n ) : (\n <button\n type=\"button\"\n onClick={userMenu.onAddAccount}\n className=\"mt-1.5 flex w-full items-center gap-2.5 rounded-lg px-1 py-1.5 text-left text-sm font-semibold text-[color:var(--color-race-red)] hover:bg-[color:var(--panel)]\"\n >\n <AddUserIcon />\n Add Account\n </button>\n )\n ) : null}\n </div>\n ) : null}\n\n {userMenu?.theme ? (\n <div className=\"border-t border-[color:var(--line)]\">\n <NavThemeControl\n value={userMenu.theme.value}\n onChange={userMenu.theme.onChange}\n />\n </div>\n ) : null}\n </div>\n\n {onSignOut ? (\n <button\n type=\"button\"\n onClick={onSignOut}\n className=\"flex w-full shrink-0 items-center gap-2.5 border-t border-[color:var(--line)] px-4 py-2.5 text-left text-sm font-medium text-[color:var(--foreground)] hover:bg-[color:var(--panel)] hover:text-[color:var(--color-race-red)]\"\n >\n <SignOutIcon />\n Sign out\n </button>\n ) : null}\n </div>\n </details>\n {!hasRealName && user ? (\n <NamePromptBubble profileHref={userMenu?.myProfileHref} />\n ) : null}\n </div>\n </header>\n )\n}\n\n/**\n * Floating, per-session-dismissable bubble under the account trigger that\n * prompts a user with no display name to set their first + last name. The\n * arrow points up at the avatar; dismissal is remembered in sessionStorage\n * until they actually set a name.\n */\nfunction NamePromptBubble({ profileHref }: { profileHref?: string }) {\n const KEY = 'politogy_name_prompt_dismissed'\n const [dismissed, setDismissed] = useState(true)\n useEffect(() => {\n try {\n setDismissed(sessionStorage.getItem(KEY) === '1')\n } catch {\n setDismissed(false)\n }\n }, [])\n if (dismissed) return null\n return (\n <div className=\"absolute right-4 top-full z-30 mt-2 w-64 rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] p-3 shadow-[var(--shadow-soft)]\">\n <span\n aria-hidden\n className=\"absolute -top-[5px] right-[11px] h-2.5 w-2.5 rotate-45 border-l border-t border-[color:var(--line)] bg-[color:var(--panel-elevated)]\"\n />\n <p className=\"text-sm font-semibold text-[color:var(--foreground)]\">\n Add your name\n </p>\n <p className=\"mt-0.5 text-xs leading-snug text-[color:var(--muted)]\">\n Set your first and last name so teammates see you — not your email.\n </p>\n <div className=\"mt-2 flex items-center gap-2\">\n {profileHref ? (\n <a\n href={safeHref(profileHref)}\n className=\"rounded-full bg-[color:var(--color-race-red)] px-3 py-1 text-xs font-semibold text-white hover:opacity-90\"\n >\n Set name\n </a>\n ) : null}\n <button\n type=\"button\"\n onClick={() => {\n setDismissed(true)\n try {\n sessionStorage.setItem(KEY, '1')\n } catch {\n /* session-only dismiss */\n }\n }}\n className=\"rounded-full border border-[color:var(--line)] px-3 py-1 text-xs font-semibold text-[color:var(--foreground)] hover:bg-[color:var(--panel)]\"\n >\n Dismiss\n </button>\n </div>\n </div>\n )\n}\n\n/** \"Spencer Hill\" → \"Spencer H.\" — first name + last initial. */\nfunction formatFirstLast(name: string): string {\n const parts = name.split(/\\s+/).filter(Boolean)\n if (parts.length === 1) return parts[0]\n return `${parts[0]} ${parts[parts.length - 1][0].toUpperCase()}.`\n}\n\nfunction ProfileIcon() {\n return (\n <svg width={16} height={16} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <path d=\"M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2\" />\n <circle cx=\"12\" cy=\"7\" r=\"4\" />\n </svg>\n )\n}\n\nfunction BriefcaseIcon() {\n return (\n <svg width={16} height={16} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <rect x=\"2\" y=\"7\" width=\"20\" height=\"14\" rx=\"2\" ry=\"2\" />\n <path d=\"M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16\" />\n </svg>\n )\n}\n\nfunction TrashIcon() {\n return (\n <svg width={14} height={14} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <polyline points=\"3 6 5 6 21 6\" />\n <path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\" />\n </svg>\n )\n}\n\nfunction AddUserIcon() {\n return (\n <svg width={16} height={16} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <path d=\"M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2\" />\n <circle cx=\"8.5\" cy=\"7\" r=\"4\" />\n <line x1=\"20\" y1=\"8\" x2=\"20\" y2=\"14\" />\n <line x1=\"23\" y1=\"11\" x2=\"17\" y2=\"11\" />\n </svg>\n )\n}\n\n// Inline log-out glyph (mirrors lucide `LogOut`) to avoid an icon dependency.\nfunction SignOutIcon() {\n return (\n <svg\n width={15}\n height={15}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\" />\n <polyline points=\"16 17 21 12 16 7\" />\n <line x1=\"21\" x2=\"9\" y1=\"12\" y2=\"12\" />\n </svg>\n )\n}\n\n// A single 32×32 circular icon button for the top bar's structured action list.\n// Renders an <a> when `href` is present (external links open in a new tab),\n// otherwise a <button>. Shows a red count badge when `badge > 0`.\nfunction NavTopBarActionButton({ action }: { action: NavTopBarAction }) {\n const Icon = action.icon\n // Universal treatment (Global Rules v9): size, color and hover are a single\n // shared value across every top-bar slot — only the glyph varies per slot.\n // Tone is a semantic state, not a bespoke per-slot style. The class comes\n // from the ONE shared builder in chromeActions so the data-backed widgets\n // and this structured list can never drift apart.\n const className = topBarIconButtonClass(action.tone ?? 'default')\n\n // Per-slot glyph from Brand; `icon` is the fallback until the token resolves.\n // Brand emits Feather/Lucide glyph NAMES, not asset paths.\n const glyphName = useTopBarIconSlotGlyph(action.slot ?? 'apps')\n const BrandGlyph = action.slot ? resolveBrandGlyph(glyphName) : null\n const Glyph = BrandGlyph ?? Icon\n\n const content = (\n <>\n <Glyph size={20} className=\"text-current\" />\n {typeof action.badge === 'number' && action.badge > 0 ? (\n <span className=\"absolute -top-1 -right-1 flex h-4 min-w-4 items-center justify-center rounded-full bg-[color:var(--color-race-red)] px-1 text-[10px] text-white\">\n {action.badge}\n </span>\n ) : null}\n <TopBarTooltip title={action.label} description={action.description} />\n </>\n )\n\n const isExternal = action.href ? /^https?:\\/\\//.test(action.href) : false\n\n if (action.href) {\n return (\n <a\n href={safeHref(action.href)}\n aria-label={action.label}\n className={className}\n {...(isExternal ? { target: '_blank', rel: 'noreferrer' } : {})}\n >\n {content}\n </a>\n )\n }\n\n return (\n <button\n type=\"button\"\n onClick={action.onClick}\n aria-label={action.label}\n className={className}\n >\n {content}\n </button>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Icon-only tab strip — the standard secondary navigation the three Next.js\n// worker apps (Forms / Surveys / Polls) render below the top bar: a horizontal\n// row of icon-only tabs where the SELECTED tab merges into the content panel\n// below it (top/left/right border, no bottom border, sharing --tab-content-bg).\n//\n// A faithful twin of the hand-rolled `.tabstrip`/`.tab-strip` markup those apps\n// carried, promoted into the shell so every app renders the same accessible,\n// token-driven strip. All geometry is driven by the Brand `--tab-*` CSS vars\n// shipped in chrome.css (with literal fallbacks so the strip still renders in\n// an app that hasn't loaded the runtime tokens link yet):\n// --tab-height (row height) · --tab-icon-size (glyph) · --tab-radius (top\n// corners) · --tab-gap (between tabs) · --tab-content-bg (selected + panel\n// surface) · --tab-unselected-opacity (dimmed inactive tabs, default 0.6).\n// ---------------------------------------------------------------------------\n\nexport type NavTab = {\n /** Stable identity (used as the React key). */\n key: string\n /** Accessible name — becomes both the `title` tooltip and `aria-label`. */\n label: string\n icon: NavIcon\n /** Route to link to (rendered through `linkComponent`). */\n href?: string\n /** Click handler — rendered as a `<button>` when there's no `href`. */\n onSelect?: () => void\n /** Whether this tab is the active one (drives the merged-panel geometry). */\n selected?: boolean\n /**\n * Non-interactive, dimmed tab (e.g. Surveys' Canvas/Results before a survey\n * is chosen). Renders a non-navigating span; `disabledTitle` overrides the\n * tooltip to explain why (falls back to `label`).\n */\n disabled?: boolean\n disabledTitle?: string\n}\n\nexport type NavTabStripProps = {\n tabs: NavTab[]\n /** Accessible name for the tablist. */\n 'aria-label'?: string\n /** Routing primitive for `href` tabs (Next `<Link>`, etc). Defaults to <a>. */\n linkComponent?: NavLinkComponent\n /** Extra classes on the tablist container. */\n className?: string\n /**\n * Optional content panel rendered directly below the strip. When supplied it\n * renders on the shared `--tab-content-bg` surface with a square top-left\n * corner so the selected tab visually merges into it. Omit to render only the\n * strip and compose the panel yourself.\n */\n children?: ReactNode\n}\n\n/** Default icon glyph size — mirrors the `--tab-icon-size` token default. */\nconst TAB_ICON_SIZE = 18\n\nfunction NavTabButton({\n tab,\n Link,\n}: {\n tab: NavTab\n Link: NavLinkComponent\n}) {\n const { label, icon: Icon, href, onSelect, selected, disabled, disabledTitle } = tab\n const title = disabled ? disabledTitle ?? label : label\n\n // Base geometry shared by every state. Selected tabs sit above the content\n // panel (`z-10`) so their missing bottom border merges cleanly into it.\n const base =\n 'inline-flex shrink-0 items-center justify-center border border-b-0 transition-opacity'\n const stateClass = disabled\n ? 'cursor-not-allowed border-transparent opacity-40'\n : selected\n ? 'relative z-10 opacity-100 border-[color:var(--line)]'\n : 'border-transparent opacity-[var(--tab-unselected-opacity,0.6)] hover:opacity-90'\n const className = `${base} ${stateClass}`\n\n const style: CSSProperties = {\n height: 'var(--tab-height, 44px)',\n width: 'var(--tab-width, 3rem)',\n color: 'var(--foreground)',\n borderTopLeftRadius: 'var(--tab-radius, 12px)',\n borderTopRightRadius: 'var(--tab-radius, 12px)',\n ...(selected ? { background: 'var(--tab-content-bg)' } : null),\n }\n\n const glyph = <Icon size={TAB_ICON_SIZE} className=\"text-current\" />\n\n // Disabled: non-navigating span, still exposed as a tab for AT.\n if (disabled) {\n return (\n <span\n role=\"tab\"\n aria-selected={false}\n aria-disabled=\"true\"\n aria-label={label}\n title={title}\n className={className}\n style={style}\n >\n {glyph}\n </span>\n )\n }\n\n if (href) {\n return (\n <Link\n href={href}\n role=\"tab\"\n aria-selected={selected ? true : false}\n aria-label={label}\n title={title}\n className={className}\n style={style}\n >\n {glyph}\n </Link>\n )\n }\n\n return (\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={selected ? true : false}\n aria-label={label}\n title={title}\n onClick={onSelect}\n className={className}\n style={style}\n >\n {glyph}\n </button>\n )\n}\n\n/**\n * Icon-only, token-driven tab strip. Render it below `NavTopBar`; pass the\n * app's `Link` as `linkComponent` for `href` tabs. Supply `children` to get the\n * merged content panel, or omit it and compose your own panel on\n * `var(--tab-content-bg)`.\n */\nexport function NavTabStrip({\n tabs,\n 'aria-label': ariaLabel,\n linkComponent,\n className,\n children,\n}: NavTabStripProps) {\n const Link = linkComponent ?? DefaultLink\n return (\n <>\n <div\n role=\"tablist\"\n aria-label={ariaLabel}\n className={['flex items-end gap-[var(--tab-gap,8px)]', className]\n .filter(Boolean)\n .join(' ')}\n >\n {tabs.map((tab) => (\n <NavTabButton key={tab.key} tab={tab} Link={Link} />\n ))}\n </div>\n {children !== undefined ? (\n <div\n className=\"relative -mt-px border border-[color:var(--line)] p-5\"\n style={{\n background: 'var(--tab-content-bg)',\n borderTopLeftRadius: 0,\n borderTopRightRadius: 'var(--tab-radius, 12px)',\n borderBottomLeftRadius: 'var(--tab-radius, 12px)',\n borderBottomRightRadius: 'var(--tab-radius, 12px)',\n }}\n >\n {children}\n </div>\n ) : null}\n </>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Beta banner — a full-width amber NOTICE strip rendered directly below the top\n// bar (a semantic notice, not a chrome surface, so it keeps its amber hue in\n// both themes via the --beta-banner-* tokens in chrome.css). One line, centered,\n// with a bold + underlined link to the Beta Terms & Conditions.\n// ---------------------------------------------------------------------------\n\nconst BETA_BANNER_DEFAULTS = {\n text: 'Our product is in Beta. Thank you for participating in the Pilot Program. ',\n linkLabel: 'You can click here to see the Terms & Conditions for Beta users.',\n href: 'https://app.politogyvrm.com/beta-terms-and-conditions',\n} as const\n\nexport type NavBetaBannerProps = {\n /** Leading sentence(s) before the link. Defaults to the standard Beta copy. */\n text?: string\n /** Bold + underlined link label. Defaults to the standard Terms copy. */\n linkLabel?: string\n /** Terms & Conditions URL (opens in a new tab). Defaults to the app T&C page. */\n href?: string\n}\n\nexport function NavBetaBanner({ text, linkLabel, href }: NavBetaBannerProps) {\n const body = text ?? BETA_BANNER_DEFAULTS.text\n const label = linkLabel ?? BETA_BANNER_DEFAULTS.linkLabel\n const target = href ?? BETA_BANNER_DEFAULTS.href\n return (\n <div\n role=\"note\"\n className=\"w-full px-4 py-2 text-center text-sm\"\n style={{\n // Amber warning fill, matching the \"10DLC Registration Required\" notice\n // (HITL 2026-07-29). This used to fall through to `--color-accent`, the\n // brand RED, so a participation notice read as an error. The\n // --beta-banner-* tokens carry the amber defaults (chrome.css) and a\n // Brand edit still wins over them.\n background: 'var(--beta-banner-bg, #FEEBC8)',\n color: 'var(--beta-banner-text, #1A202C)',\n }}\n >\n <span>{body}</span>\n <a\n href={safeHref(target)}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"font-bold underline\"\n style={{ color: 'var(--beta-banner-text, #1A202C)' }}\n >\n {label}\n </a>\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n\nexport type NavAppShellProps = {\n sidebar: NavSidebarProps\n topBar: NavTopBarProps\n /**\n * When supplied, a full-width Beta notice strip renders directly below the top\n * bar. Presence of the prop enables it; all fields fall back to the standard\n * Beta copy + Terms & Conditions link.\n */\n betaBanner?: NavBetaBannerProps\n /**\n * How the content region wraps `children`.\n *\n * - `'padded'` (default, unchanged): `<main class=\"px-6 py-7\">` around a\n * `mx-auto max-w-7xl` container — what forms / surveys / polls / contacts\n * rely on.\n * - `'bare'`: render `children` directly, with no `<main>`, no gutter and no\n * max-width. For apps that already supply their own page container — VRM\n * wraps every page in the shell's `PageContainer`, which emits its OWN\n * `<main>` + `mx-auto max-w-*` + padding, so the default produced a NESTED\n * `<main>` (invalid HTML) and a doubled gutter on Org Settings, Email\n * Broadcast and SMS/MMS Blast (shell-nav-handoff §1).\n */\n contentWrapper?: 'padded' | 'bare'\n children: ReactNode\n}\n\n/**\n * Full chrome: branded left sidebar + sticky top navbar + scrollable content\n * region. Presentational only — wrap it in app-level auth/gating as needed.\n */\n/**\n * Closes any open chrome <details data-nav-details> (org switcher, mode\n * selector, My Account) when the pointer lands outside it or Escape is\n * pressed — dropdowns must deselect on outside click (HITL 2026-07-23).\n */\nfunction useCloseNavDetailsOnOutsideClick() {\n useEffect(() => {\n const close = (target: Node | null) => {\n document.querySelectorAll('details[data-nav-details][open]').forEach((d) => {\n if (!target || !d.contains(target)) d.removeAttribute('open')\n })\n }\n const onPointerDown = (e: MouseEvent) => close(e.target as Node)\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') close(null)\n }\n document.addEventListener('mousedown', onPointerDown)\n document.addEventListener('keydown', onKey)\n return () => {\n document.removeEventListener('mousedown', onPointerDown)\n document.removeEventListener('keydown', onKey)\n }\n }, [])\n}\n\nexport function NavAppShell({\n sidebar,\n topBar,\n betaBanner,\n contentWrapper = 'padded',\n children,\n}: NavAppShellProps) {\n useCloseNavDetailsOnOutsideClick()\n return (\n <div className=\"min-h-screen bg-[color:var(--background)] text-[color:var(--foreground)]\">\n <NavSidebar {...sidebar} />\n <div className=\"lg:pl-[240px]\">\n <NavTopBar {...topBar} />\n {betaBanner ? <NavBetaBanner {...betaBanner} /> : null}\n {contentWrapper === 'bare' ? (\n children\n ) : (\n <main className=\"px-6 py-7\">\n <div className=\"mx-auto max-w-7xl\">{children}</div>\n </main>\n )}\n </div>\n </div>\n )\n}\n\n// Canonical Politogy VRM menu — the standard nav structure every politogy app\n// renders, per operating Mode, with hooks for the app-owned \"Contacts\" item and\n// Support handler, plus the Campaign feature-availability config.\nexport {\n standardPolitogyNav,\n CAMPAIGN_FEATURE_AVAILABILITY,\n type StandardNavIconKey,\n type StandardNavOptions,\n type StandardNavMode,\n type CampaignFeatureAvailability,\n} from './standardNav'\n","// Universal active-organization selection — the ONE cross-app contract.\n//\n// A user belongs to many orgs; ONE active-org choice must follow them across\n// every Politogy app + subdomain so all apps resolve the SAME org (and campaign\n// apps don't land on a rel-only org and lock themselves). Layers cooperate,\n// mirroring the theme-preference contract:\n// 1. URL `?org=<uuid>` — the authoritative per-request selector. The shared\n// chrome stamps it onto every route so it is bookmarkable + shareable, and\n// each app forwards it to the chrome API as `x-contacts-org`.\n// 2. `.politogyvrm.com` cookie `politogy_active_org` — cross-subdomain vehicle\n// (auth session cookies are host-only) that remembers the LAST USED org so\n// a bare URL in the next app opens on the same org.\n//\n// The stored/most-authoritative value is the FULL org UUID: contacts-api\n// (auth/vrmMembership.selectRequestedMembership) matches the selector by EXACT\n// id first, then falls back to a short suffix that can COLLIDE across a user's\n// orgs — so the full UUID is the only collision-free selector.\n//\n// Server-safe (no 'use client'): constants/resolve helpers are importable from\n// server layouts; the cookie read/write helpers no-op on the server.\n\nexport const ACTIVE_ORG_COOKIE = 'politogy_active_org'\nexport const ACTIVE_ORG_QUERY_PARAM = 'org'\n\n// Loose UUID shape check — we only ever store ids that came from the user's own\n// authoritative membership list, so this just rejects obvious garbage.\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i\n\nexport function isOrgId(v: unknown): v is string {\n return typeof v === 'string' && UUID_RE.test(v.trim())\n}\n\n/** Read the shared active-org cookie (browser only; null on server or unset). */\nexport function readActiveOrgCookie(): string | null {\n if (typeof document === 'undefined') return null\n try {\n const m = document.cookie.match(\n new RegExp(`(?:^|;\\\\s*)${ACTIVE_ORG_COOKIE}=([^;]+)`),\n )\n const v = m ? decodeURIComponent(m[1]) : null\n return isOrgId(v) ? v : null\n } catch {\n return null\n }\n}\n\n// Write the cross-subdomain cookie with the SAME scoping rules as the theme\n// cookie: on a *.politogyvrm.com host scope to the parent domain so every app\n// subdomain reads it; on any other host (localhost, *.pages.dev preview) fall\n// back to a host-only cookie. 1-year, SameSite=Lax, Secure on https.\nexport function writeActiveOrgCookie(orgId: string): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n if (!isOrgId(orgId)) return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n document.cookie = `${ACTIVE_ORG_COOKIE}=${encodeURIComponent(\n orgId,\n )}; Path=/; Max-Age=31536000; SameSite=Lax${domainAttr}${secure}`\n}\n\n/**\n * Read the `?org=` selector from a URL search string (full UUID only). Accepts a\n * `location.search`-style string or a full URL.\n */\nexport function readActiveOrgFromUrl(search: string | null | undefined): string | null {\n if (!search) return null\n try {\n const qs = search.includes('?') ? search.slice(search.indexOf('?') + 1) : search\n const v = new URLSearchParams(qs).get(ACTIVE_ORG_QUERY_PARAM)\n return isOrgId(v) ? v : null\n } catch {\n return null\n }\n}\n\n/**\n * Resolve the active org with the cross-app precedence:\n * 1. `?org=<uuid>` in the current URL (explicit per-request selector)\n * 2. the `.politogyvrm.com` cookie (last used, cross-subdomain)\n * 3. null → let the app fall back to the chrome-API default (earliest-joined)\n * Pass `search` on the server (from the request URL); it defaults to\n * `window.location.search` in the browser.\n */\nexport function resolveActiveOrg(search?: string | null): string | null {\n const fromUrl = readActiveOrgFromUrl(\n search ?? (typeof window !== 'undefined' ? window.location.search : null),\n )\n if (fromUrl) return fromUrl\n return readActiveOrgCookie()\n}\n\n/** The canonical `?org=` query fragment for a full org id (no leading `?`/`&`). */\nexport function activeOrgParam(orgId: string | null | undefined): string {\n return isOrgId(orgId) ? `${ACTIVE_ORG_QUERY_PARAM}=${orgId}` : ''\n}\n\n/**\n * Return `url` with `?org=<uuid>` set/replaced. Used by the shared chrome to\n * stamp the active org onto every route so it is always present in the address\n * bar. Leaves the URL unchanged when `orgId` is not a valid id.\n */\nexport function withActiveOrgParam(url: string, orgId: string | null | undefined): string {\n if (!isOrgId(orgId)) return url\n try {\n // Support both absolute and relative URLs.\n const base = typeof window !== 'undefined' ? window.location.origin : 'https://politogyvrm.com'\n const u = new URL(url, base)\n u.searchParams.set(ACTIVE_ORG_QUERY_PARAM, orgId as string)\n // Preserve relative form when the input was relative.\n return /^https?:\\/\\//i.test(url) ? u.toString() : `${u.pathname}${u.search}${u.hash}`\n } catch {\n return url\n }\n}\n","// Universal navigation-display preference — the same cross-app contract as the\n// theme (see ./theme-preference, which this deliberately mirrors).\n//\n// The user's choice of how navigation renders (Menu / Tabs / Both) follows the\n// authenticated user across every Politogy app + subdomain. Three layers:\n// 1. VRM Core `profiles.nav_display_preference` — source of truth, persisted\n// via the chrome API (`PATCH me/preferences { navDisplay }`) and read back\n// from `GET me` (`navDisplay`).\n// 2. `.politogyvrm.com` cookie `politogy_nav_display` — the cross-subdomain\n// vehicle (app session cookies are host-only, and so is localStorage).\n// 3. localStorage — same-app fast reads and cross-tab `storage` events.\n//\n// Before this existed the preference lived ONLY in localStorage under\n// `vrm.navDisplay`, which is per-ORIGIN: every app subdomain kept its own copy\n// and a freshly opened app booted the default, so the setting appeared not to\n// hold when moving between apps. The legacy key is still read as a fallback so\n// an existing local choice survives the upgrade.\n//\n// Server-safe (no 'use client'): layouts may import NAV_DISPLAY_PREPAINT_SCRIPT.\n\nexport type NavDisplayPreference = 'menu' | 'tabs' | 'both'\n\n// One key for BOTH the localStorage store and the cross-subdomain cookie, so a\n// choice in one app is the same key in the next.\nexport const NAV_DISPLAY_STORAGE_KEY = 'politogy_nav_display'\nexport const NAV_DISPLAY_COOKIE = 'politogy_nav_display'\n\n/** Pre-0.37 host-only key. Read for migration; never written. */\nexport const LEGACY_NAV_DISPLAY_KEY = 'vrm.navDisplay'\n\nexport const NAV_DISPLAY_DEFAULT: NavDisplayPreference = 'both'\n\nconst VALID: readonly NavDisplayPreference[] = ['menu', 'tabs', 'both']\n\nexport function isNavDisplayPreference(v: unknown): v is NavDisplayPreference {\n return typeof v === 'string' && (VALID as readonly string[]).includes(v)\n}\n\n/** Read the shared cookie (browser only; null on the server or when unset). */\nexport function readNavDisplayCookie(): NavDisplayPreference | null {\n if (typeof document === 'undefined') return null\n try {\n const m = document.cookie.match(\n new RegExp(`(?:^|;\\\\s*)${NAV_DISPLAY_COOKIE}=([^;]+)`),\n )\n const v = m ? decodeURIComponent(m[1]) : null\n return isNavDisplayPreference(v) ? v : null\n } catch {\n return null\n }\n}\n\n// Same host-aware scoping as the theme cookie: parent domain on\n// *.politogyvrm.com so every app subdomain reads it, host-only elsewhere\n// (localhost, *.pages.dev preview) because browsers silently drop a mismatched\n// Domain attribute. 1-year, SameSite=Lax, Secure on https.\nexport function writeNavDisplayCookie(pref: NavDisplayPreference): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n document.cookie = `${NAV_DISPLAY_COOKIE}=${encodeURIComponent(\n pref,\n )}; Path=/; Max-Age=31536000; SameSite=Lax${domainAttr}${secure}`\n}\n\n/** Read the local store, falling back to the legacy host-only key. */\nexport function readNavDisplayLocal(): NavDisplayPreference | null {\n if (typeof localStorage === 'undefined') return null\n try {\n const current = localStorage.getItem(NAV_DISPLAY_STORAGE_KEY)\n if (isNavDisplayPreference(current)) return current\n const legacy = localStorage.getItem(LEGACY_NAV_DISPLAY_KEY)\n return isNavDisplayPreference(legacy) ? legacy : null\n } catch {\n return null\n }\n}\n\nexport function writeNavDisplayLocal(pref: NavDisplayPreference): void {\n if (typeof localStorage === 'undefined') return\n try {\n localStorage.setItem(NAV_DISPLAY_STORAGE_KEY, pref)\n } catch {\n /* storage unavailable */\n }\n}\n\n/** Boot precedence: cookie → localStorage (incl. legacy) → default. */\nexport function resolveNavDisplay(): NavDisplayPreference {\n return readNavDisplayCookie() ?? readNavDisplayLocal() ?? NAV_DISPLAY_DEFAULT\n}\n\n// Inline pre-paint script — optional, and the mirror of THEME_PREPAINT_SCRIPT.\n// Nav display has no paint-blocking visual (the frame is client-rendered), but\n// seeding localStorage from the cookie before hydration keeps the first render\n// on the synced value instead of the default. Self-contained and silent.\nexport const NAV_DISPLAY_PREPAINT_SCRIPT = `(function(){try{\nvar KEY=${JSON.stringify(NAV_DISPLAY_STORAGE_KEY)};\nvar VALID=[\"menu\",\"tabs\",\"both\"];\nfunction fromCookie(){try{var m=document.cookie.match(/(?:^|;\\\\s*)${NAV_DISPLAY_COOKIE}=([^;]+)/);return m?decodeURIComponent(m[1]):null;}catch(e){return null;}}\nvar cookie=fromCookie();\nif(cookie&&VALID.indexOf(cookie)!==-1){var ls=null;try{ls=localStorage.getItem(KEY);}catch(e){}\nif(cookie!==ls){try{localStorage.setItem(KEY,cookie);}catch(e){}}}\n}catch(e){}})();`\n","// Breadcrumb derivation — pure, dependency-free logic (no React, no DevNotes),\n// so it is importable from a server module and testable in isolation.\n//\n// The standard is Dashboard > Sub > Item (HITL 2026-07-23), derived from the\n// same nav tree the sidebar renders. Apps previously hand-built their own\n// trails and disagreed: forms rendered \"Forms > Dashboard\" while polls rendered\n// a lone \"Polls\" crumb under a \"Polls\" title (\"Polls / Polls\").\n\nimport type { NavBreadcrumb, NavItem } from '../native/index'\n\nexport function deriveBreadcrumbs(\n items: NavItem[],\n pathname: string,\n opts?: { search?: string; origin?: string },\n): NavBreadcrumb[] {\n const search = opts?.search ?? (typeof window !== 'undefined' ? window.location.search : '')\n const origin = opts?.origin ?? (typeof window !== 'undefined' ? window.location.origin : '')\n\n // Same-origin comparison: cross-app hrefs are absolute, local ones relative.\n const matches = (href?: string): boolean => {\n if (!href) return false\n let path = href\n let query = ''\n if (/^https?:\\/\\//i.test(href)) {\n try {\n const u = new URL(href)\n if (origin && u.origin !== origin) return false\n path = u.pathname\n query = u.search\n } catch {\n return false\n }\n } else {\n const qi = href.indexOf('?')\n if (qi >= 0) {\n path = href.slice(0, qi) || '/'\n query = href.slice(qi)\n }\n }\n if (path !== pathname) return false\n if (!query) return true\n const want = new URLSearchParams(query)\n const have = new URLSearchParams(search)\n for (const [k, v] of want) if (have.get(k) !== v) return false\n return true\n }\n\n // Depth-first walk for the deepest item owning the current route.\n const walk = (nodes: NavItem[], trail: NavItem[]): NavItem[] | null => {\n for (const node of nodes) {\n const here = [...trail, node]\n if (node.children?.length) {\n const deeper = walk(node.children, here)\n if (deeper) return deeper\n }\n if (matches(node.href)) return here\n }\n return null\n }\n\n const trail = walk(items, [])\n // Always anchored at Dashboard; the last crumb is the current location and\n // carries no href (the shell marks it aria-current=\"page\").\n const dashboard = items.find((i) => i.label === 'Dashboard')\n const crumbs: NavBreadcrumb[] = [{ label: 'Dashboard', href: dashboard?.href }]\n if (!trail) return crumbs\n for (const node of trail) {\n if (node.label === 'Dashboard') continue\n crumbs.push({ label: node.label, href: node.href })\n }\n const last = crumbs[crumbs.length - 1]\n if (last) delete (last as { href?: string }).href\n return crumbs\n}\n","// Identity resolution — pure logic, shared by the chrome hook.\n//\n// The chrome API (VRM-core profile) is the AUTHORITY for a user's display name;\n// what an app knows from its own session token is a pre-hydration fallback. An\n// email is never a name: forms passed `user.name ?? user.email`, so a user with\n// no name set had their email rendered as their name in the top bar and the\n// shell's \"add your name\" affordance never fired (HITL 2026-07-23).\n\nexport type ResolvedIdentity = {\n userName: string | null\n email: string | null\n avatarUrl: string | null\n loaded: boolean\n}\n\n/** True when a \"name\" is really just an email address. */\nexport function looksLikeEmail(value: string | null | undefined): boolean {\n return typeof value === 'string' && /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value.trim())\n}\n\nexport function resolveIdentity(input: {\n apiName?: string | null\n fallbackName?: string | null\n email?: string | null\n avatarUrl?: string | null\n loaded?: boolean\n}): ResolvedIdentity {\n const apiName = looksLikeEmail(input.apiName) ? null : input.apiName ?? null\n const fallbackName = looksLikeEmail(input.fallbackName) ? null : input.fallbackName ?? null\n return {\n userName: apiName ?? fallbackName,\n email: input.email ?? null,\n avatarUrl: input.avatarUrl ?? null,\n loaded: input.loaded ?? false,\n }\n}\n","// Universal sign-out propagation — the ONE cross-app logout contract.\n//\n// Every Politogy app holds its OWN host-only session cookie with a long sliding\n// window, so signing out of one app used to leave every other open tab — and\n// every other subdomain — signed in until its cookie happened to expire. A user\n// who signs out in Contacts and switches to the Forms tab they already had open\n// is still fully authenticated there. That is the bug this module closes.\n//\n// The vehicle mirrors the active-org contract: a `.politogyvrm.com` cookie that\n// every subdomain can read. It carries a single monotonic value — the epoch\n// milliseconds at which the user signed out.\n//\n// politogy_logout_at = <epoch ms of the most recent sign-out>\n//\n// Two layers cooperate, and BOTH are required:\n//\n// 1. SERVER (authoritative). Each app's middleware compares this cookie\n// against the session's `auth_time`. A session minted BEFORE the last\n// sign-out is dead, whatever its own expiry says — so a reload, a\n// bookmark, or a restored tab can never resurrect it. See\n// `isSessionRevoked`.\n//\n// 2. CLIENT (immediacy). Open tabs are not making requests, so the server\n// layer alone only takes effect on their next navigation. `watchLogout`\n// notices the cookie change within ~1s and navigates the tab out.\n//\n// The cookie is deliberately NOT HttpOnly: it holds no secret — just a\n// timestamp — and every tab on every subdomain must be able to read it from\n// JavaScript. It grants nothing; it only ever revokes.\n//\n// Server-safe (no 'use client'): the constants and `isSessionRevoked` are\n// importable from middleware and server components; the browser helpers no-op\n// on the server.\n\nexport const LOGOUT_COOKIE = 'politogy_logout_at'\n\n/** Same-origin instant channel; cross-subdomain falls back to the cookie poll. */\nconst LOGOUT_CHANNEL = 'politogy-logout'\n\n/** How often a tab re-reads the cookie. Cheap: a string compare, no I/O. */\nconst POLL_MS = 1000\n\nfunction parseTimestamp(value: string | null | undefined): number | null {\n if (!value) return null\n const n = Number(value)\n return Number.isFinite(n) && n > 0 ? n : null\n}\n\n/**\n * Server-side authority. Given the logout-cookie value and the moment this\n * session was authenticated, is the session revoked?\n *\n * `authTime` is the OIDC `auth_time` (seconds) or an equivalent millisecond\n * timestamp captured when the session was minted. Sessions with no recorded\n * auth time are treated as revoked whenever a logout is on record: we cannot\n * prove they postdate it, and failing closed is the only safe direction for a\n * sign-out.\n */\nexport function isSessionRevoked(\n logoutCookieValue: string | null | undefined,\n authTime: number | null | undefined,\n): boolean {\n const loggedOutAt = parseTimestamp(logoutCookieValue)\n if (loggedOutAt === null) return false\n if (authTime == null || !Number.isFinite(authTime) || authTime <= 0) return true\n // Accept either seconds (OIDC auth_time) or milliseconds.\n const authMs = authTime < 1e12 ? authTime * 1000 : authTime\n return authMs < loggedOutAt\n}\n\n/** Read the shared logout timestamp (browser only; null on server or unset). */\nexport function readLogoutCookie(): number | null {\n if (typeof document === 'undefined') return null\n try {\n const m = document.cookie.match(new RegExp(`(?:^|;\\\\s*)${LOGOUT_COOKIE}=([^;]+)`))\n return parseTimestamp(m ? decodeURIComponent(m[1]) : null)\n } catch {\n return null\n }\n}\n\n/**\n * Record a sign-out for every tab on every Politogy subdomain. Call this\n * BEFORE navigating to the app's sign-out route, so tabs that are already open\n * see it immediately rather than after the round trip.\n *\n * Scoping mirrors the active-org and theme cookies: parent-domain on\n * *.politogyvrm.com so all app subdomains read it, host-only anywhere else\n * (localhost, *.pages.dev previews).\n */\nexport function broadcastLogout(at: number = Date.now()): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n // 30 days: comfortably longer than the longest app session window, so a tab\n // resumed from sleep still sees the revocation. Shorter than that and a stale\n // session could outlive the signal that killed it.\n document.cookie = `${LOGOUT_COOKIE}=${at}; Path=/; Max-Age=2592000; SameSite=Lax${domainAttr}${secure}`\n try {\n new BroadcastChannel(LOGOUT_CHANNEL).postMessage(at)\n } catch {\n // No BroadcastChannel (older Safari) — the cookie poll covers it.\n }\n}\n\n/**\n * Clear the signal. Call after a successful LOGIN: the new session postdates\n * the old sign-out, and leaving the cookie behind would make every future\n * `isSessionRevoked` check depend on clock skew between the two.\n */\nexport function clearLogoutSignal(): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n document.cookie = `${LOGOUT_COOKIE}=; Path=/; Max-Age=0; SameSite=Lax${domainAttr}`\n}\n\nexport type WatchLogoutOptions = {\n /**\n * Sessions minted at or before this moment are revoked by a sign-out. Pass\n * the session's auth time; when omitted, ANY logout signal observed after the\n * watcher starts fires the callback (correct for an already-open tab, which\n * by definition authenticated earlier).\n */\n authTime?: number | null\n /** Poll interval override, for tests. */\n intervalMs?: number\n}\n\n/**\n * Watch for a sign-out that happened in ANY other tab or window, on this or any\n * sibling Politogy subdomain, and invoke `onLogout` once.\n *\n * Returns an unsubscribe function.\n *\n * Three signals, cheapest first:\n * - BroadcastChannel — instant, same-origin only.\n * - visibility/focus/pageshow — the moment a backgrounded tab is looked at.\n * - a ~1s cookie poll — the cross-subdomain path, and the backstop for a\n * visible tab the user is staring at but not interacting with.\n */\nexport function watchLogout(\n onLogout: () => void,\n options: WatchLogoutOptions = {},\n): () => void {\n if (typeof document === 'undefined' || typeof window === 'undefined') {\n return () => {}\n }\n\n const { authTime = null, intervalMs = POLL_MS } = options\n // Anything already on record when this tab started is not news: the server\n // layer decides whether THIS session is revoked, and it has already let the\n // page render. Only a signal newer than our baseline means \"someone just\n // signed out\".\n const baseline = readLogoutCookie() ?? 0\n let done = false\n\n const fire = (at: number) => {\n if (done) return\n if (at <= baseline) return\n if (authTime != null && !isSessionRevoked(String(at), authTime)) return\n done = true\n cleanup()\n onLogout()\n }\n\n const check = () => {\n const at = readLogoutCookie()\n if (at !== null) fire(at)\n }\n\n let channel: BroadcastChannel | null = null\n try {\n channel = new BroadcastChannel(LOGOUT_CHANNEL)\n channel.onmessage = (event) => {\n const at = typeof event.data === 'number' ? event.data : readLogoutCookie()\n if (at !== null) fire(at)\n }\n } catch {\n channel = null\n }\n\n const timer = window.setInterval(check, intervalMs)\n window.addEventListener('visibilitychange', check)\n window.addEventListener('focus', check)\n window.addEventListener('pageshow', check)\n\n function cleanup() {\n window.clearInterval(timer)\n window.removeEventListener('visibilitychange', check)\n window.removeEventListener('focus', check)\n window.removeEventListener('pageshow', check)\n try {\n channel?.close()\n } catch {\n /* already closed */\n }\n }\n\n return cleanup\n}\n","// ---------------------------------------------------------------------------\n// PolitogyAppFrame — ONE component that renders the entire app frame.\n//\n// Why this exists (HITL directive 2026-07-23): shipping the same npm package at\n// the same version is necessary but NOT sufficient. The package exposed\n// PRIMITIVES (NavAppShell + a dozen hooks) and every app hand-assembled them in\n// its own ~150-line Shell.tsx. Identical inputs were never guaranteed, so the\n// outputs diverged — measured on production: forms rendered its user's EMAIL as\n// their name, polls' breadcrumb read \"Polls / Polls\", forms and surveys pinned\n// the mode pill to a hardcoded \"relationship\", and each app declared its own\n// chrome CSS variables (surveys' accent was #C8102E where everyone else was\n// #E63946).\n//\n// The fix is to stop exporting assembly as an app responsibility. An app now\n// renders:\n//\n// <PolitogyAppFrame app=\"forms\" pathname={pathname} linkComponent={Link}\n// session={{ userId, email, role, accountName, accountId }}\n// onSignOut={signOut}>\n// {children}\n// </PolitogyAppFrame>\n//\n// and passes NOTHING about the chrome: no nav, no breadcrumbs, no title, no\n// mode, no user menu, no footer, no theme. Those are derived here, identically,\n// for every app. Anything an app cannot pass is something it cannot drift on.\n// ---------------------------------------------------------------------------\n\n'use client'\n\nimport { useCallback, useEffect, useMemo, useRef, type ReactNode } from 'react'\n\nimport { broadcastLogout, watchLogout } from '../logout-signal'\nimport {\n NavAppShell,\n standardPolitogyNav,\n type NavLinkComponent,\n} from '../native/index'\nimport {\n ChromeTopBarActions,\n PolitogyAppChrome,\n standardNavIcons,\n useChromeFooter,\n useChromeIdentity,\n useChromeMode,\n useChromeState,\n useChromeUserMenu,\n type ChromeDevNotesConfig,\n type ControlledOrgState,\n} from './index'\nimport type {\n NavBreadcrumb,\n NavChromeFetcher,\n NavItem,\n NavMode,\n NavUserMenu,\n} from '../native/index'\nimport type { StandardNavMode } from '../native/standardNav'\nimport { deriveBreadcrumbs } from '../lib/breadcrumbs'\n\n/**\n * The core app — the one that OWNS the canonical nav tree and routes in-app.\n * `PolitogyFrameData.core` is honored for this key and no other.\n */\nconst CORE_APP: PolitogyAppKey = 'vrm'\n\n/**\n * Template A convention: every feature app exposes GET /auth/signout, which\n * clears its session cookie and 302s to the IdP's end_session endpoint. Apps\n * that route sign-out elsewhere (core: /api/auth/logout) pass `signOutUrl`.\n */\nconst DEFAULT_SIGN_OUT_URL = '/auth/signout'\n\n/** Every app that renders the shared chrome. Keyed by its subdomain. */\nexport type PolitogyAppKey =\n | 'vrm'\n | 'contacts'\n | 'forms'\n | 'surveys'\n | 'polls'\n | 'petitions'\n // Campaign Mode standalone apps.\n | 'a2p'\n | 'phonebank'\n | 'canvass'\n | 'signs'\n\n/**\n * The operating Mode an app is scoped to, if any. It drives two things,\n * BOTH derived here from app identity so no app passes chrome config:\n * 1. the standardPolitogyNav tree the sidebar renders, and\n * 2. the static Mode pill the app shows (a campaign app shows a Campaign\n * pill, never Relationship).\n * An UNSCOPED app (no `mode`) keeps its prior behavior exactly: the\n * Relationship tree + an entitlement-driven Mode pill.\n */\nexport type PolitogyAppMode = StandardNavMode\n\n/**\n * The per-app registry — the ONLY place app identity lives. A new app adds a\n * row here and inherits every chrome behavior; it never re-derives one.\n */\nexport const POLITOGY_APPS: Record<\n PolitogyAppKey,\n { title: string; origin: string; storagePrefix: string; mode?: PolitogyAppMode }\n> = {\n vrm: { title: 'Politogy VRM', origin: 'https://app.politogyvrm.com', storagePrefix: 'vrm' },\n contacts: { title: 'Contacts', origin: 'https://contacts.politogyvrm.com', storagePrefix: 'contacts' },\n forms: { title: 'Forms', origin: 'https://forms.politogyvrm.com', storagePrefix: 'forms' },\n surveys: { title: 'Surveys', origin: 'https://surveys.politogyvrm.com', storagePrefix: 'surveys' },\n polls: { title: 'Polls', origin: 'https://polls.politogyvrm.com', storagePrefix: 'polls' },\n petitions: {\n title: 'Petitions',\n origin: 'https://petition-mode.politogyvrm.com',\n storagePrefix: 'petitions',\n mode: 'petition',\n },\n // Campaign Mode apps — each scoped to Campaign, so they render the Campaign\n // tree and a static Campaign pill. Not yet deployed; hidden from the Campaign\n // nav by CAMPAIGN_FEATURE_AVAILABILITY until their launch flips the flag.\n a2p: { title: 'A2P Messaging', origin: 'https://a2p.politogyvrm.com', storagePrefix: 'a2p', mode: 'campaign' },\n phonebank: { title: 'Phone Banking', origin: 'https://phonebank.politogyvrm.com', storagePrefix: 'phonebank', mode: 'campaign' },\n canvass: { title: 'Field Canvassing', origin: 'https://canvass.politogyvrm.com', storagePrefix: 'canvass', mode: 'campaign' },\n signs: { title: 'Sign Mapping', origin: 'https://signs.politogyvrm.com', storagePrefix: 'signs', mode: 'campaign' },\n}\n\nexport type PolitogyAppSession = {\n /** Stable IdP subject (`sub`). */\n userId: string\n email: string | null\n /** The app's own role string — feeds DevNotes admin gating. */\n role: string\n /** The app's own workspace label, used only until core orgs resolve. */\n accountName: string\n accountId: string\n /**\n * Pre-hydration display name ONLY. The chrome API is the authority; an email\n * passed here is discarded rather than rendered as a name.\n */\n userName?: string | null\n}\n\n/**\n * Optional DATA plumbing for apps whose session/auth differs — never styling.\n *\n * Everything here is about WHERE data comes from (which fetcher, which org\n * state, which routes an app owns), not what the chrome looks like. Adding a\n * visual option to this type would re-open the drift this component exists to\n * close.\n */\nexport type PolitogyFrameData = {\n /** Chrome-API fetcher override for apps that authenticate client-side. */\n fetchJson?: NavChromeFetcher\n /** DevNotes wiring override for those same direct-auth apps. */\n devNotes?: ChromeDevNotesConfig\n /** Controlled org state for apps that own active-org + switching. */\n org?: ControlledOrgState\n /** App-owned children for a standard nav entry this app owns (Contacts). */\n contactsItem?: { href?: string; children?: NavItem[] }\n /** Avatar fallback when the profile has no uploaded photo (memoji, default). */\n fallbackAvatarUrl?: string | null\n /**\n * CORE-ONLY frame inputs. **Honored only when `app` is the core app (`vrm`)\n * — silently ignored for every other app**, which is what keeps the\n * no-drift guarantee intact: a feature app cannot re-specify a chrome\n * element even by passing this, so the props are inert for it.\n *\n * Core is genuinely different, and pretending otherwise would have meant\n * REMOVING shipped behavior from app.politogyvrm.com to satisfy packaging —\n * which Reference/UI-Platform forbids (\"migration may not drop a shipped\n * element … extend the shell first, then migrate\"). Specifically, core:\n * - owns the canonical nav tree AND decorates it with live entitlement\n * state a static tree cannot express (10DLC gating, contact/group\n * counts, org-lock),\n * - routes in-app (react-router), so its rows must be app-relative paths,\n * not the absolute cross-app URLs `standardPolitogyNav` emits,\n * - publishes per-page title/breadcrumbs from 66 page components,\n * - switches Mode client-side rather than by full-page navigation,\n * - owns real linked-account switching (with its own modals).\n *\n * Everything here is still DATA or app-owned STATE. There is no styling\n * input, no ordering input, and no way to change the top-bar action cluster\n * — those stay identical for every app, core included.\n */\n core?: PolitogyCoreFrame\n}\n\n/** See `PolitogyFrameData.core` — core app (`vrm`) only. */\nexport type PolitogyCoreFrame = {\n /** The canonical nav tree, decorated with core's live entitlement state. */\n nav?: NavItem[]\n /** Per-page identity published by core's own pages. */\n page?: { title?: string; breadcrumbs?: NavBreadcrumb[]; actions?: ReactNode }\n /** Client-side Mode switching (core navigates in-app, not cross-origin). */\n mode?: NavMode\n /** Real linked-account switching + core's theme persistence. */\n userMenu?: NavUserMenu\n /** Mode-specific brand wordmark (core swaps it per operating Mode). */\n brandLogoSrc?: string\n /** Core wraps every page in PageContainer, which emits its own <main>. */\n contentWrapper?: 'padded' | 'bare'\n}\n\nexport type PolitogyBuildMeta = {\n envLabel?: string\n version?: string\n commit?: string\n commitDate?: string\n commitAuthor?: string\n}\n\nexport function PolitogyAppFrame({\n app,\n pathname,\n search,\n linkComponent,\n session,\n onSignOut,\n signOutUrl = DEFAULT_SIGN_OUT_URL,\n buildMeta,\n data,\n children,\n}: {\n app: PolitogyAppKey\n /** Current path from the app's router (Next: usePathname()). */\n pathname: string\n /** Current query string, when the app routes by query (forms' ?tab=). */\n search?: string\n /** The app's routing primitive (Next: <Link>). */\n linkComponent: NavLinkComponent\n session: PolitogyAppSession\n onSignOut: () => void\n /**\n * The app's sign-out ROUTE — a GET endpoint that clears the session cookie\n * and redirects to RP-initiated logout at the IdP. Defaults to the Template A\n * convention; core overrides it. This, not `onSignOut`, is what actually\n * signs the user out (see handleSignOut).\n */\n signOutUrl?: string\n buildMeta?: PolitogyBuildMeta\n /** Optional DATA plumbing (never styling) — see PolitogyFrameData. */\n data?: PolitogyFrameData\n children: ReactNode\n}) {\n const meta = POLITOGY_APPS[app]\n return (\n <PolitogyAppChrome\n storagePrefix={meta.storagePrefix}\n fetchJson={data?.fetchJson}\n devNotes={data?.devNotes}\n org={data?.org}\n identity={{\n userId: session.userId,\n userName: session.userName ?? null,\n email: session.email,\n role: session.role,\n }}\n >\n <FrameBody\n app={app}\n pathname={pathname}\n search={search}\n linkComponent={linkComponent}\n session={session}\n onSignOut={onSignOut}\n signOutUrl={signOutUrl}\n buildMeta={buildMeta}\n data={data}\n >\n {children}\n </FrameBody>\n </PolitogyAppChrome>\n )\n}\n\nfunction FrameBody({\n app,\n pathname,\n search,\n linkComponent,\n session,\n onSignOut,\n signOutUrl,\n buildMeta,\n data,\n children,\n}: {\n app: PolitogyAppKey\n pathname: string\n search?: string\n linkComponent: NavLinkComponent\n session: PolitogyAppSession\n onSignOut: () => void\n signOutUrl: string\n buildMeta?: PolitogyBuildMeta\n data?: PolitogyFrameData\n children: ReactNode\n}) {\n const meta = POLITOGY_APPS[app]\n const chrome = useChromeState()\n\n // Sign-out is a PLATFORM event, not an app event. Each app holds its own\n // host-only session cookie with a long sliding window, so without this a user\n // who signed out in one tab stayed fully signed in in every other open tab\n // and on every other subdomain. Announce the sign-out to all of them, then\n // run the app's own sign-out.\n //\n // Every app reaches sign-out through this frame, so wiring it here covers the\n // whole estate without an app having to opt in — the same guarantee the rest\n // of the chrome relies on.\n const signOutRef = useRef(onSignOut)\n signOutRef.current = onSignOut\n // This tab started the sign-out, so its own watcher must not also fire and\n // run the app's sign-out a second time concurrently.\n const signingOutRef = useRef(false)\n\n const handleSignOut = useCallback(() => {\n signingOutRef.current = true\n broadcastLogout()\n // Navigate to the app's sign-out ROUTE. Apps also pass an onSignOut\n // handler, but it cannot be relied on: they wire it as\n // `onSignOut={() => { void signOutAction(); }}`, and a server action\n // invoked outside a transition can never have its redirect() applied by\n // the client. Measured against production 2026-07-25: clicking Sign out\n // left the user signed in, and an app they had never opened authenticated\n // with no credentials — the IdP session was still alive because the\n // browser never reached its end-session endpoint.\n //\n // A plain navigation to a GET route cannot fail that way: the route drops\n // the session cookie and 302s to RP-initiated logout at the IdP.\n signOutRef.current()\n window.location.assign(signOutUrl)\n }, [signOutUrl])\n\n useEffect(\n () =>\n // A tab that learns of a sign-out elsewhere ends its own session for\n // real, by navigating to the same sign-out route.\n //\n // Measured against production before this landed: calling the app's\n // handler did nothing at all. Apps wire it as\n // `onSignOut={() => { void signOutAction(); }}` — a server action invoked\n // outside a transition, so the `redirect()` inside it can never be\n // applied by the client and the tab just sits there. Building cross-tab\n // logout on that path made the whole feature a no-op.\n //\n // A hard navigation cannot fail that way, and it hands the decision to\n // the authority rather than guessing: the app's middleware sees a session\n // whose auth_time predates `politogy_logout_at`, treats it as revoked,\n // and redirects to Politogy ID. Server-side truth decides; the client\n // only forces the request. No re-broadcast — the signal that woke us is\n // already on record for every tab.\n watchLogout(() => {\n if (signingOutRef.current) return\n window.location.assign(signOutUrl)\n }),\n [signOutUrl],\n )\n // Core-only inputs are read through this ONE gate. For every other app it is\n // undefined no matter what the app passed, so the \"an app cannot re-specify a\n // chrome element\" guarantee holds by construction, not by convention.\n const core = app === CORE_APP ? data?.core : undefined\n\n // Identity: chrome API wins, app claims are a fallback, an email is never a\n // name (that is what forms was rendering in the top right).\n const identity = useChromeIdentity({ userName: session.userName, email: session.email })\n const derivedUserMenu = useChromeUserMenu({\n userId: session.userId,\n userName: identity.userName,\n email: identity.email,\n })\n const userMenu = core?.userMenu ?? derivedUserMenu\n const footer = useChromeFooter(buildMeta ?? {})\n // A mode-scoped app (Campaign apps, Petitions) pins its pill to its own mode;\n // an unscoped app stays entitlement + user-selection driven. Either way no\n // app passes a mode — it is read from the registry (app identity).\n const appMode = meta.mode\n const derivedMode = useChromeMode(appMode ? { pinnedModeId: appMode } : undefined)\n // Core switches Mode client-side; every other app jumps to the mode's home.\n const mode = core?.mode ?? derivedMode\n\n const coreOrgs = chrome?.orgs ?? []\n const activeCoreOrg = coreOrgs.find((o) => o.id === chrome?.orgId) ?? null\n const navDisplay = chrome?.navDisplay ?? 'both'\n\n // The nav tree follows the app's OWN mode (registry), not the live pill\n // selection — so it is deterministic from app identity. Unscoped apps render\n // Relationship exactly as before. Cross-app links in the Campaign/Petition\n // trees carry the active org the way the switcher/account menu do.\n const navMode: StandardNavMode = appMode ?? 'relationship'\n const activeOrgId = chrome?.orgId ?? null\n const derivedNavItems = useMemo(\n () =>\n standardPolitogyNav({\n coreBaseUrl: POLITOGY_APPS.vrm.origin,\n icons: standardNavIcons,\n // An app that OWNS a standard nav entry (Contacts) nests its own routes\n // under it. This is routing data, not chrome configuration.\n contactsItem: data?.contactsItem,\n mode: navMode,\n activeOrgId,\n }),\n [data?.contactsItem, navMode, activeOrgId],\n )\n // Core supplies the canonical tree already decorated with its live gating\n // state (and with app-relative hrefs so its router handles them in-app).\n const navItems = core?.nav ?? derivedNavItems\n\n // Dashboard › Sub › Item, derived from the same tree the sidebar renders.\n // Core publishes its trail from the page itself, because a core page's\n // location is finer-grained than its nav row (e.g. a contact detail view).\n const derivedBreadcrumbs = useMemo(\n () => deriveBreadcrumbs(navItems, pathname, { search, origin: meta.origin }),\n [navItems, pathname, search, meta.origin],\n )\n const breadcrumbs = core ? core.page?.breadcrumbs : derivedBreadcrumbs\n\n return (\n <NavAppShell\n sidebar={{\n pathname,\n brand: {\n logoSrc: core?.brandLogoSrc ?? '/brand/logos/relationship-mode-logo.png',\n logoAlt: 'Politogy',\n badgeLabel: 'P',\n title: 'Politogy',\n },\n nav: {\n items:\n navDisplay === 'tabs'\n ? navItems.map(({ children: _sub, ...item }) => item)\n : navItems,\n },\n // The app's own workspace is NOT the organization — it is a per-app\n // bootstrap account with a different id in every app. Showing it while\n // the chrome API resolves flashed the wrong org on every load (\"not\n // connected to the account\"). Shimmer while in flight; only fall back\n // to the app label once the chrome lookup has actually failed.\n org: activeCoreOrg\n ? {\n name: activeCoreOrg.name,\n id: activeCoreOrg.id,\n logoUrl: activeCoreOrg.logoUrl,\n brandColor: activeCoreOrg.brandColor,\n organizations: coreOrgs,\n onSwitch: chrome?.setOrgId,\n }\n : chrome?.orgsLoading\n ? { name: null, id: null, loading: true }\n : { name: session.accountName, id: session.accountId },\n mode,\n footer,\n linkComponent,\n }}\n betaBanner={{}}\n contentWrapper={core?.contentWrapper}\n topBar={{\n // Core's pages publish their own identity; every other app is one\n // product surface and takes its registry title.\n title: core?.page?.title ?? meta.title,\n breadcrumbs,\n user: {\n name: identity.userName,\n email: identity.email,\n // The chrome API's avatar wins; the app may supply a fallback chain\n // (e.g. a stored memoji) for users with no uploaded photo.\n avatarUrl: identity.avatarUrl ?? data?.fallbackAvatarUrl ?? null,\n role: session.role,\n },\n userMenu,\n onSignOut: handleSignOut,\n // The action cluster is IDENTICAL everywhere — core included. Page\n // actions sit BEFORE it, never inside it, so the Alerts bell keeps its\n // required position: farthest right, immediately before My Account.\n actions: (\n <>\n {core?.page?.actions}\n <ChromeTopBarActions />\n </>\n ),\n }}\n >\n {children}\n </NavAppShell>\n )\n}\n","// ---------------------------------------------------------------------------\n// App chrome wiring — the ONE shared implementation of the per-app glue that\n// previously lived as a copied ChromeWidgets.tsx in every Next.js feature app\n// (forms / surveys / polls / contacts). Copies drifted (org dropdown, badges);\n// this module makes that class of drift impossible: apps configure, never\n// re-implement (Reference/UI-Platform: consume via npm, never vendored).\n//\n// Provides:\n// <PolitogyAppChrome> — NavChromeProvider (same-origin proxy fetcher) +\n// chrome state (active core org, nav display) +\n// DevNotes provider, in one wrapper.\n// <ChromeTopBarActions> — the canonical top-bar cluster, in canonical order\n// (Fuel · Nav display · DevNotes · Support · Alerts\n// LAST, immediately left of My Account).\n// useChromeState / useChromeUserMenu / useIsSuperAdmin / useChromeFooter.\n//\n// The app still owns: its session (the /api/chrome proxy), page frames, build\n// metadata (env/commit/version), tab strips, and its own icons.\n// ---------------------------------------------------------------------------\n\n'use client'\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react'\nimport {\n NavChromeProvider,\n FuelAction,\n NotificationsAction,\n SupportAction,\n NavDisplayAction,\n TopBarWidgetSlot,\n useChromeOrgs,\n useThemePreference,\n type NavChromeFetcher,\n type NavDisplayMode,\n type NavOrgOption,\n type NavUserMenu,\n type NavFooter,\n type NavFooterLink,\n} from '../native/index'\nimport {\n DevNotesProvider,\n DevNotesMenu,\n DevNotesOverlay,\n DevNotesTaskListModal,\n createDevNotesClient,\n type DevNotesConfig,\n} from '@the-portland-company/devnotes'\nimport {\n FiActivity,\n FiBarChart2,\n FiBriefcase,\n FiClock,\n FiCreditCard,\n FiDollarSign,\n FiEdit3,\n FiFileText,\n FiFlag,\n FiGrid,\n FiHome,\n FiLayout,\n FiLifeBuoy,\n FiList,\n FiMail,\n FiMap,\n FiMapPin,\n FiMessageSquare,\n FiPhone,\n FiSend,\n FiSettings,\n FiShare2,\n FiTarget,\n FiUpload,\n FiUser,\n FiUsers,\n} from 'react-icons/fi'\nimport { useChromeMe, useNavChromeFetcher } from '../native/index'\nimport {\n ACTIVE_ORG_QUERY_PARAM,\n isOrgId,\n resolveActiveOrg,\n writeActiveOrgCookie,\n} from '../active-org'\nimport {\n NAV_DISPLAY_DEFAULT,\n NAV_DISPLAY_STORAGE_KEY,\n isNavDisplayPreference,\n readNavDisplayCookie,\n resolveNavDisplay,\n writeNavDisplayCookie,\n writeNavDisplayLocal,\n} from '../nav-preference'\nimport type { StandardNavIconKey } from '../native/standardNav'\nimport type { NavBreadcrumb, NavIcon, NavItem, NavMode } from '../native/index'\n\n/**\n * The canonical icon map for standardPolitogyNav — ONE definition so every\n * app renders identical glyphs (including the Organization Settings branch:\n * briefcase / settings / creditCard / dollarSign / share).\n */\nexport const standardNavIcons: Record<StandardNavIconKey, NavIcon> = {\n home: FiHome,\n users: FiUsers,\n mail: FiMail,\n messageSquare: FiMessageSquare,\n layout: FiLayout,\n activity: FiActivity,\n lifeBuoy: FiLifeBuoy,\n grid: FiGrid,\n list: FiList,\n upload: FiUpload,\n edit: FiEdit3,\n fileText: FiFileText,\n send: FiSend,\n clock: FiClock,\n user: FiUser,\n barChart: FiBarChart2,\n briefcase: FiBriefcase,\n settings: FiSettings,\n creditCard: FiCreditCard,\n dollarSign: FiDollarSign,\n share: FiShare2,\n // Campaign / Petition mode slots.\n phone: FiPhone,\n map: FiMap,\n mapPin: FiMapPin,\n target: FiTarget,\n flag: FiFlag,\n}\n\nconst ORG_STORAGE_KEY = 'vrm.activeOrg'\n// The user's mode choice, shared by every app on the origin's localStorage.\nconst MODE_STORAGE_KEY = 'vrm.activeMode'\nconst CORE_BASE_URL = 'https://app.politogyvrm.com'\n\nexport type ChromeIdentity = {\n userId: string\n userName: string | null\n email: string | null\n /** The APP's own role string (any casing) — feeds DevNotes admin gating. */\n role: string\n}\n\ntype ChromeState = {\n orgId: string | null\n setOrgId: (id: string) => void\n orgs: (NavOrgOption & { rawRole?: string | null })[]\n /**\n * The org list is still in flight. Consumers must render a skeleton rather\n * than fall back to the app's own workspace label, which is a DIFFERENT\n * account and flashes as the wrong organization.\n */\n orgsLoading: boolean\n navDisplay: NavDisplayMode\n setNavDisplay: (m: NavDisplayMode) => void\n}\n\nconst ChromeStateContext = createContext<ChromeState | null>(null)\n\nexport function useChromeState(): ChromeState | null {\n return useContext(ChromeStateContext)\n}\n\nexport type ControlledOrgState = {\n orgId: string | null\n onSwitch: (id: string) => void\n /** Override the org list (e.g. the app's own session-scoped list). */\n orgs?: (NavOrgOption & { rawRole?: string | null })[]\n}\n\nfunction ChromeStateProvider({\n controlledOrg,\n children,\n}: {\n controlledOrg?: ControlledOrgState\n children: ReactNode\n}) {\n const { orgs, loading: orgsFetching, error: orgsError } = useChromeOrgs()\n const chromeMe = useChromeMe()\n const chromeFetch = useNavChromeFetcher()\n const [orgId, setOrgIdState] = useState<string | null>(null)\n const [navDisplay, setNavDisplayState] = useState<NavDisplayMode>(NAV_DISPLAY_DEFAULT)\n const navReconciled = useRef(false)\n\n // Boot: restore persisted choices. The cross-app active org (URL `?org=` or\n // the `.politogyvrm.com` cookie) wins over host-only localStorage so every\n // app + subdomain resolves the SAME org instead of each defaulting to its own\n // earliest-joined org. Nav display follows the same cross-subdomain contract\n // as theme (cookie → localStorage → default) — it used to be localStorage\n // only, which is per-origin, so it reset on every app the user opened.\n useEffect(() => {\n try {\n const storedOrg = resolveActiveOrg() ?? localStorage.getItem(ORG_STORAGE_KEY)\n if (storedOrg) setOrgIdState(storedOrg)\n } catch {\n /* storage unavailable */\n }\n setNavDisplayState(resolveNavDisplay())\n }, [])\n\n // Once per session: converge on the profile's saved choice (authoritative),\n // reusing the provider's single `me` fetch — the theme reconcile pattern.\n useEffect(() => {\n if (navReconciled.current || !chromeMe.me) return\n const pref = chromeMe.me.navDisplay\n if (!isNavDisplayPreference(pref)) return\n navReconciled.current = true\n setNavDisplayState(pref)\n writeNavDisplayCookie(pref)\n writeNavDisplayLocal(pref)\n }, [chromeMe])\n\n // Live sync: `storage` events for same-app tabs, cookie re-reads on\n // focus/visibility for tabs on OTHER app subdomains.\n useEffect(() => {\n const onStorage = (e: StorageEvent) => {\n if (e.key === NAV_DISPLAY_STORAGE_KEY && isNavDisplayPreference(e.newValue)) {\n setNavDisplayState(e.newValue)\n }\n }\n const onWake = () => {\n const cookie = readNavDisplayCookie()\n if (cookie) setNavDisplayState(cookie)\n }\n window.addEventListener('storage', onStorage)\n window.addEventListener('focus', onWake)\n document.addEventListener('visibilitychange', onWake)\n return () => {\n window.removeEventListener('storage', onStorage)\n window.removeEventListener('focus', onWake)\n document.removeEventListener('visibilitychange', onWake)\n }\n }, [])\n\n // Once orgs resolve: validate the stored org, default to the first.\n useEffect(() => {\n if (!orgs || orgs.length === 0) return\n setOrgIdState((prev) => (prev && orgs.some((o) => o.id === prev) ? prev : orgs[0].id))\n }, [orgs])\n\n const setOrgId = useCallback((id: string) => {\n setOrgIdState(id)\n try {\n localStorage.setItem(ORG_STORAGE_KEY, id)\n } catch {\n /* best effort */\n }\n // Remember the choice cross-subdomain so the next app opens on the same org.\n writeActiveOrgCookie(id)\n }, [])\n\n const setNavDisplay = useCallback(\n (m: NavDisplayMode) => {\n setNavDisplayState(m)\n writeNavDisplayLocal(m)\n // Cross-subdomain, so the next app opens on the same choice.\n writeNavDisplayCookie(m)\n // Best-effort durable persistence on the user's profile — a nav toggle\n // never errors, and the cookie already carries the choice meanwhile.\n chromeFetch?.('me/preferences', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ navDisplay: m }),\n })?.catch(() => {})\n },\n [chromeFetch],\n )\n\n const value = useMemo<ChromeState>(() => {\n // CONTROLLED mode (Contacts): the APP owns the active org + switching —\n // its switch does a full session re-scope. The shared widgets read the\n // app's state so there is exactly one org truth (unification directive).\n if (controlledOrg) {\n return {\n orgId: controlledOrg.orgId,\n setOrgId: controlledOrg.onSwitch,\n orgs:\n controlledOrg.orgs ??\n (orgs ?? []).map((o) => ({\n id: o.id,\n name: o.name,\n logoUrl: o.logoUrl,\n brandColor: o.brandColor,\n role: o.role,\n rawRole: o.rawRole ?? null,\n })),\n orgsLoading: false,\n navDisplay,\n setNavDisplay,\n }\n }\n return {\n orgId,\n setOrgId,\n orgs: (orgs ?? []).map((o) => ({\n id: o.id,\n name: o.name,\n logoUrl: o.logoUrl,\n brandColor: o.brandColor,\n role: o.role,\n rawRole: o.rawRole ?? null,\n })),\n // Loading until the fetch settles. On error we stop loading so the frame\n // falls back to the app label rather than shimmering forever.\n orgsLoading: orgsFetching && !orgsError && !orgs,\n navDisplay,\n setNavDisplay,\n }\n }, [controlledOrg, orgId, setOrgId, orgs, orgsFetching, orgsError, navDisplay, setNavDisplay])\n\n // Keep the shared cookie + address-bar `?org=` in sync with the ACTIVE org —\n // whichever path owns it, controlled (Contacts) or uncontrolled (feature\n // apps) — so every app + tab resolves the same org and every URL is\n // bookmarkable/shareable with its org context. Idempotent; no-op on server.\n const activeOrgId = value.orgId\n useEffect(() => {\n if (!isOrgId(activeOrgId)) return\n writeActiveOrgCookie(activeOrgId as string)\n try {\n const url = new URL(window.location.href)\n if (url.searchParams.get(ACTIVE_ORG_QUERY_PARAM) !== activeOrgId) {\n url.searchParams.set(ACTIVE_ORG_QUERY_PARAM, activeOrgId as string)\n window.history.replaceState(window.history.state, '', url.toString())\n }\n } catch {\n /* SSR / no window */\n }\n }, [activeOrgId])\n\n return <ChromeStateContext.Provider value={value}>{children}</ChromeStateContext.Provider>\n}\n\nexport type ChromeDevNotesConfig = {\n /** Override the DevNotes API base (default: `${proxyBasePath}/devnotes`). */\n basePath?: string\n /** Client-side token supplier (default: empty — same-origin proxy injects). */\n getAuthToken?: () => Promise<string> | string\n /** Custom fetch (e.g. credentials:'include' against a cross-origin API). */\n fetch?: typeof globalThis.fetch\n /**\n * The app already mounts its own `<DevNotesProvider>` ABOVE this chrome, so\n * the chrome must not mount a second one (VRM core, whose provider carries\n * capabilities the generic client has no equivalent for — user stories, its\n * own role gating). The working SURFACE still comes from here, so the\n * launcher, the overlay and the task modal behave identically everywhere;\n * only the data adapter is the app's.\n */\n providedByApp?: boolean\n}\n\nfunction AppDevNotes({\n storagePrefix,\n proxyBasePath,\n devNotes,\n identity,\n children,\n}: {\n storagePrefix: string\n proxyBasePath: string\n devNotes?: ChromeDevNotesConfig\n identity: ChromeIdentity\n children: ReactNode\n}) {\n const adapter = useMemo(\n () =>\n createDevNotesClient({\n basePath: devNotes?.basePath ?? `${proxyBasePath}/devnotes`,\n // Default: the same-origin proxy attaches the session's Bearer.\n getAuthToken: devNotes?.getAuthToken ?? (async () => ''),\n ...(devNotes?.fetch ? { fetch: devNotes.fetch } : {}),\n }),\n [proxyBasePath, devNotes?.basePath, devNotes?.getAuthToken, devNotes?.fetch],\n )\n\n const user = useMemo(\n () => ({\n id: identity.userId,\n email: identity.email ?? '',\n fullName: identity.userName ?? undefined,\n }),\n [identity.userId, identity.email, identity.userName],\n )\n\n const config = useMemo<DevNotesConfig>(\n () => ({\n storagePrefix,\n role: identity.role.toLowerCase() === 'admin' ? 'admin' : 'reporter',\n disableAi: true,\n getPagePath: () => window.location.pathname,\n }),\n [storagePrefix, identity.role],\n )\n\n // The app brought its own provider — mount only the surface, so a second\n // DevNotesProvider never shadows the app's adapter.\n if (devNotes?.providedByApp) return <DevNotesSurface>{children}</DevNotesSurface>\n\n return (\n <DevNotesProvider adapter={adapter} user={user} config={config}>\n <DevNotesSurface>{children}</DevNotesSurface>\n </DevNotesProvider>\n )\n}\n\n// \"View All Tasks\" is triggered from the menu in the top bar but the modal has\n// to render at the chrome ROOT, or it would be trapped inside the top bar's\n// stacking/blur context. The menu publishes the request through this context.\nconst DevNotesTasksContext = createContext<{ ready: boolean; openTasks: () => void }>({\n ready: false,\n openTasks: () => {},\n})\n\n/**\n * The DevNotes working surface, mounted once at the chrome root.\n *\n * `<DevNotesMenu>` only TOGGLES creation mode — `<DevNotesOverlay>` is what\n * renders the click-to-place capture layer, the report dots and the report\n * form. The shell shipped the provider and the menu but never the overlay, so\n * on every app that used this chrome (forms / surveys / polls) \"Create Task\"\n * closed the menu and did nothing at all: the mode flipped on with nothing\n * listening (HITL bug report 2026-07-23). Contacts didn't hit it only because\n * it still had its own hand-rolled surface.\n */\nfunction DevNotesSurface({ children }: { children: ReactNode }) {\n const [tasksOpen, setTasksOpen] = useState(false)\n const openTasks = useCallback(() => setTasksOpen(true), [])\n const tasksCtx = useMemo(() => ({ ready: true, openTasks }), [openTasks])\n\n return (\n <DevNotesTasksContext.Provider value={tasksCtx}>\n {children}\n {/* Mounted only while open: the modal loads data on mount regardless of\n its `open` prop, so keeping it unmounted avoids fetching every user's\n tasks before they ask for them. */}\n {tasksOpen ? <DevNotesTaskListModal open onClose={() => setTasksOpen(false)} /> : null}\n <DevNotesOverlay />\n </DevNotesTasksContext.Provider>\n )\n}\n\n/**\n * The app-chrome root. Wrap the authenticated frame once:\n *\n * <PolitogyAppChrome storagePrefix=\"forms\" identity={{userId, userName, email, role}}>\n * <ShellFrame …/>\n * </PolitogyAppChrome>\n */\nexport function PolitogyAppChrome({\n storagePrefix,\n proxyBasePath = '/api/chrome',\n fetchJson: fetchJsonOverride,\n devNotes,\n org,\n identity,\n children,\n}: {\n storagePrefix: string\n proxyBasePath?: string\n /**\n * Override the same-origin proxy fetcher for apps that talk to the chrome\n * API directly with their own auth (Contacts sends a client-side Bearer).\n * Paths stay relative ('orgs', 'me', …) — the override owns base + auth.\n */\n fetchJson?: NavChromeFetcher\n /** DevNotes wiring override for direct-auth apps (Contacts). */\n devNotes?: ChromeDevNotesConfig\n /** Controlled org state — the app owns active-org + switching (Contacts). */\n org?: ControlledOrgState\n identity: ChromeIdentity\n children: ReactNode\n}) {\n const proxyFetchJson = useMemo<NavChromeFetcher>(\n () =>\n async (path, init) => {\n const res = await fetch(`${proxyBasePath}/${path}`, {\n method: init?.method ?? 'GET',\n headers: init?.headers,\n body: init?.body,\n })\n if (!res.ok) throw new Error(`chrome ${path}: ${res.status}`)\n if (res.status === 204) return null\n const text = await res.text()\n return text ? JSON.parse(text) : null\n },\n [proxyBasePath],\n )\n const fetchJson = fetchJsonOverride ?? proxyFetchJson\n\n return (\n <NavChromeProvider fetchJson={fetchJson}>\n <ChromeStateProvider controlledOrg={org}>\n <AppDevNotes\n storagePrefix={storagePrefix}\n proxyBasePath={proxyBasePath}\n devNotes={devNotes}\n identity={identity}\n >\n {children}\n </AppDevNotes>\n </ChromeStateProvider>\n </NavChromeProvider>\n )\n}\n\n/** The standard top-bar action cluster. The Alerts bell renders LAST so it\n * sits farthest right, immediately left of the My Account badge. */\nexport function ChromeTopBarActions() {\n const state = useChromeState()\n if (!state) return null\n return (\n <>\n <FuelAction orgId={state.orgId} />\n <NavDisplayAction value={state.navDisplay} onChange={state.setNavDisplay} />\n <TopBarWidgetSlot\n title=\"DevNotes\"\n description=\"Capture bugs and notes, filed straight to Forge.\"\n >\n <ChromeDevNotesMenu />\n </TopBarWidgetSlot>\n <SupportAction orgId={state.orgId} />\n <NotificationsAction orgId={state.orgId} />\n </>\n )\n}\n\n/**\n * The DevNotes launcher. Renders nothing until the surface above is mounted, so\n * it never touches DevNotes context before the provider exists, and forwards\n * \"View All Tasks\" to the root-level modal.\n */\nfunction ChromeDevNotesMenu() {\n const { ready, openTasks } = useContext(DevNotesTasksContext)\n if (!ready) return null\n return <DevNotesMenu position=\"top-right\" onViewTasks={openTasks} />\n}\n\n/** True when any core-org membership carries a super-admin tier. */\nexport function useIsSuperAdmin(): boolean {\n const state = useChromeState()\n return (state?.orgs ?? []).some((o) => /super/i.test(o.rawRole ?? ''))\n}\n\nconst FOOTER_LINKS: NavFooterLink[] = [\n { label: 'Privacy', href: `${CORE_BASE_URL}/privacy-policy`, external: true },\n { label: 'Terms', href: `${CORE_BASE_URL}/terms-and-conditions`, external: true },\n {\n label: 'Subscriptions',\n href: 'https://politogyvrm.com/subscription-cancellation-policy',\n external: true,\n },\n]\n\n/**\n * Sidebar footer: legal links for everyone; build metadata (env / commit /\n * version / date / author) ONLY for Super Administrators\n * (Reference/UI-Platform). Pass the app's build-time metadata in.\n */\nexport function useChromeFooter(meta: {\n envLabel?: string\n version?: string\n commit?: string\n commitDate?: string\n commitAuthor?: string\n}): NavFooter {\n const isSuperAdmin = useIsSuperAdmin()\n return useMemo<NavFooter>(\n () => (isSuperAdmin ? { links: FOOTER_LINKS, ...meta } : { links: FOOTER_LINKS }),\n [isSuperAdmin, meta.envLabel, meta.version, meta.commit, meta.commitDate, meta.commitAuthor],\n )\n}\n\n// ---------------------------------------------------------------------------\n// Identity — resolved by the PACKAGE, from the chrome API.\n//\n// Apps used to pass a display name straight from their own session claims, and\n// forms passed `user.name ?? user.email` — so a user with no name set had their\n// EMAIL rendered as their name, and the chrome API's real profile name could\n// never win (HITL 2026-07-23). The chrome API is the authority; what the app\n// passes is a pre-hydration fallback only, and an email is never a name.\n// ---------------------------------------------------------------------------\n\nexport function useChromeIdentity(fallback?: {\n userName?: string | null\n email?: string | null\n}): ResolvedIdentity {\n const { me, loaded } = useChromeMe()\n return resolveIdentity({\n apiName: me?.userName,\n fallbackName: fallback?.userName,\n email: fallback?.email,\n avatarUrl: me?.avatarUrl,\n loaded,\n })\n}\n\n// Breadcrumbs live in ../lib/breadcrumbs (pure, dependency-free) and are\n// re-exported here so apps keep a single import surface.\nexport { deriveBreadcrumbs } from '../lib/breadcrumbs'\nexport { looksLikeEmail, resolveIdentity, type ResolvedIdentity } from '../lib/identity'\nimport { resolveIdentity, type ResolvedIdentity } from '../lib/identity'\n\n// ---------------------------------------------------------------------------\n// Breadcrumbs — derived by the PACKAGE from the nav tree + the current path.\n//\n// Every app hand-built its own trail, so they disagreed: forms rendered\n// \"Forms › Dashboard\" while polls rendered \"Polls\" under a \"Polls\" title\n// (\"Polls / Polls\"). The standard is Dashboard › Sub › Item (HITL 2026-07-23),\n// derived from the same nav tree the sidebar renders, so no app can drift.\n// ---------------------------------------------------------------------------\n\n/**\n * The My Account menu config — profile/org links into VRM core, real roles\n * from the user's core organizations, the signed-in account, and the shared\n * Light/System/Dark theme control (auth-derived, cross-app).\n */\nexport function useChromeUserMenu({\n userId,\n userName,\n email,\n}: {\n userId: string\n userName: string | null\n email: string | null\n}): NavUserMenu {\n const state = useChromeState()\n const theme = useThemePreference()\n const activeOrg = state?.orgs.find((o) => o.id === state.orgId) ?? null\n const orgSuffix = activeOrg ? `?org=${activeOrg.id}` : ''\n return {\n // My Profile is global — NOT org-suffixed (main-app ShellChromeBridge).\n myProfileHref: `${CORE_BASE_URL}/my-profile`,\n organizationSettingsHref: `${CORE_BASE_URL}/organization-settings${orgSuffix}`,\n roles: (state?.orgs ?? [])\n .filter((o) => o.rawRole || o.role)\n .map((o) => ({ role: (o.rawRole ?? o.role) as string, orgName: o.name })),\n accounts: [{ id: userId, name: userName, email, avatarUrl: null, active: true }],\n addAccountHref: `${CORE_BASE_URL}/my-profile#accounts`,\n theme: { value: theme.value, onChange: theme.setValue },\n }\n}\n\n// ---------------------------------------------------------------------------\n// Mode selector — entitlement-driven (HITL 2026-07-23: an org with multiple\n// active modes selects them from the left nav). Entitlements come from the\n// chrome API: GET me with the active org header → modes booleans\n// {relationship, campaign, petition, polling}. Selecting a mode navigates to\n// that mode's VRM-core dashboard carrying the active org.\n// ---------------------------------------------------------------------------\n\nconst MODE_DEFS: {\n id: string\n label: string\n icon: NavIcon\n /** Absolute destination, or a VRM-core path prefixed with CORE_BASE_URL. */\n href: string\n orgQuery: boolean\n}[] = [\n {\n id: 'relationship',\n label: 'Relationship Mode',\n icon: FiUsers,\n href: `${CORE_BASE_URL}/relationship/dashboard`,\n orgQuery: true,\n },\n {\n id: 'campaign',\n label: 'Campaign Mode',\n icon: FiBarChart2,\n href: `${CORE_BASE_URL}/campaign/dashboard`,\n orgQuery: true,\n },\n {\n // Petition Mode lives in its own standalone app on its own subdomain — the\n // petitions repo deploys production to petition-mode.politogyvrm.com.\n id: 'petition',\n label: 'Petition Mode',\n icon: FiFlag,\n href: 'https://petition-mode.politogyvrm.com/',\n orgQuery: true,\n },\n]\n\ntype ModeId = 'relationship' | 'campaign' | 'petition'\n\ntype UseChromeModeArg =\n | ModeId\n | {\n /** Pre-entitlement fallback for first paint (default 'relationship'). */\n fallbackModeId?: ModeId\n /**\n * Registry-pinned mode for a MODE-SCOPED app (e.g. the Campaign apps\n * a2p / phonebank / canvass / signs, from `POLITOGY_APPS[app].mode`). The\n * pill DISPLAYS this mode regardless of the cross-app selection, so a\n * campaign app never shows a Relationship pill. The switcher still appears\n * when the active org is entitled to more than one mode, so the user can\n * jump out to another mode's home.\n */\n pinnedModeId?: ModeId\n }\n\n/**\n * The active mode pill / selector.\n *\n * For an UNSCOPED app the current mode is the USER'S OWN SELECTION (persisted\n * cross-app in localStorage under `vrm.activeMode`), narrowed to what the active\n * org is entitled to — never a literal an app hardcodes. Apps used to call\n * `useChromeMode('relationship')`, which pinned the pill to Relationship even\n * for an org entitled to Campaign or Petition (HITL 2026-07-23); the string\n * argument now only supplies the pre-entitlement fallback for first paint.\n *\n * A MODE-SCOPED app passes `{ pinnedModeId }` so its pill displays that mode\n * (its own mode from the app registry) rather than the cross-app selection —\n * while a multi-mode org still gets the switcher to leave.\n */\nexport function useChromeMode(arg: UseChromeModeArg = {}): NavMode {\n const { fallbackModeId = 'relationship', pinnedModeId } =\n typeof arg === 'string' ? { fallbackModeId: arg, pinnedModeId: undefined } : arg\n const ctx = useContext(ChromeStateContext)\n const nav = useNavChromeFetcher()\n const orgId = ctx?.orgId ?? null\n const [entitled, setEntitled] = useState<Record<string, boolean> | null>(null)\n const [selectedModeId, setSelectedModeId] = useState<string | null>(null)\n\n // Restore the user's last mode choice (shared key across every app).\n useEffect(() => {\n try {\n const stored = localStorage.getItem(MODE_STORAGE_KEY)\n if (stored && MODE_DEFS.some((m) => m.id === stored)) setSelectedModeId(stored)\n } catch {\n /* storage unavailable */\n }\n }, [])\n\n useEffect(() => {\n if (!nav || !orgId) return\n let cancelled = false\n nav('me', { headers: { 'x-contacts-org': orgId } })\n .then((data) => {\n if (cancelled) return\n const modes = (data as { modes?: Record<string, boolean> | null })?.modes ?? null\n setEntitled(modes)\n })\n .catch(() => {\n /* entitlements unavailable — single-mode pill stands */\n })\n return () => {\n cancelled = true\n }\n }, [nav, orgId])\n\n const options = MODE_DEFS.filter((m) => entitled?.[m.id])\n // Resolution order: a registry pin (mode-scoped app) wins outright → then the\n // user's selection (if the org is still entitled to it) → the first entitled\n // mode → the app's fallback. Entitlements are async, so before they land the\n // pin/fallback holds the pill's shape (no layout shift).\n const pinned = pinnedModeId ? MODE_DEFS.find((m) => m.id === pinnedModeId) ?? null : null\n const selected = selectedModeId\n ? options.find((m) => m.id === selectedModeId) ?? null\n : null\n const current =\n pinned ??\n selected ??\n options[0] ??\n MODE_DEFS.find((m) => m.id === fallbackModeId) ??\n MODE_DEFS[0]\n const suffix = orgId ? `?org=${orgId}` : ''\n\n return {\n label: current.label,\n icon: current.icon,\n options:\n options.length > 1\n ? options.map((o) => ({ id: o.id, label: o.label, icon: o.icon }))\n : undefined,\n onSelect:\n options.length > 1\n ? (id: string) => {\n const def = MODE_DEFS.find((m) => m.id === id)\n if (!def) return\n // Remember the choice BEFORE navigating so the destination app —\n // and every app after it — opens in the mode the user picked.\n setSelectedModeId(id)\n try {\n localStorage.setItem(MODE_STORAGE_KEY, id)\n } catch {\n /* storage unavailable */\n }\n const sep = def.href.includes('?') ? '&' : '?'\n window.location.assign(\n def.orgQuery && suffix ? `${def.href}${sep}${suffix.slice(1)}` : def.href,\n )\n }\n : undefined,\n }\n}\n\n// The one-component app frame (see ./frame.tsx). Re-exported here so apps have\n// a single import surface: `@the-portland-company/shell/app-chrome`.\nexport {\n PolitogyAppFrame,\n POLITOGY_APPS,\n type PolitogyAppKey,\n type PolitogyAppMode,\n type PolitogyAppSession,\n type PolitogyBuildMeta,\n type PolitogyFrameData,\n} from './frame'\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/topbarIconSlot.ts","../src/lib/brandGlyphs.tsx","../src/theme-preference.ts","../src/native/chromeActions.tsx","../src/native/standardNav.ts","../src/native/index.tsx","../src/active-org.ts","../src/nav-preference.ts","../src/lib/breadcrumbs.ts","../src/lib/identity.ts","../src/logout-signal.ts","../src/app-chrome/frame.tsx","../src/app-chrome/index.tsx"],"names":["useState","useEffect","FiBatteryCharging","FiBattery","FiZap","FiGrid","FiBell","FiAlertTriangle","FiAlertCircle","FiLifeBuoy","FiHelpCircle","FiMoon","FiSun","FiInfo","FiMail","FiMessageSquare","FiSettings","FiUser","useSyncExternalStore","jsxs","jsx","createContext","useContext","useRef","Fragment","useCallback","createPortal","base","useMemo","VALID","trail","FiHome","FiUsers","FiLayout","FiActivity","FiList","FiUpload","FiEdit3","FiFileText","FiSend","FiClock","FiBarChart2","FiBriefcase","FiCreditCard","FiDollarSign","FiShare2","FiPhone","FiMap","FiMapPin","FiTarget","FiFlag","createDevNotesClient","DevNotesProvider","DevNotesTaskListModal","DevNotesOverlay","DevNotesMenu"],"mappings":"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","file":"app-chrome.cjs","sourcesContent":["import { useEffect, useState } from 'react'\n\n/**\n * The six canonical top-bar action slots (Reference/Global-Rules v9 → top-bar\n * icons). Each slot's GLYPH is unique and comes from the Brand API\n * `topbarIcons.items.*` tokens, exposed as `--topbar-icon-<slot>` CSS vars\n * whose value is the brand-icon NAME. Every OTHER property — size, gap, color,\n * hover, selected — is universal across all six slots.\n */\nexport type TopBarIconSlot =\n | 'comms-fuel'\n | 'apps'\n | 'notifications'\n | 'alerts'\n | 'support'\n | 'dark-mode'\n\n/**\n * Reads the glyph NAME for a slot from its `--topbar-icon-<slot>` CSS var.\n *\n * Runs in an effect because the Brand stylesheet is appended to <head> at\n * runtime (Global Rules forbids baking it into the build), so the var is not\n * resolvable during SSR or the first synchronous render. The MutationObserver\n * re-reads once the stylesheet lands so the glyph upgrades from the caller's\n * fallback without a reload.\n *\n * Returns null when the slot has no Brand glyph — callers render their own\n * fallback icon in that case.\n */\nexport function useTopBarIconSlotGlyph(slot: TopBarIconSlot): string | null {\n const [name, setName] = useState<string | null>(null)\n\n useEffect(() => {\n if (typeof window === 'undefined') return\n\n const read = () => {\n const raw = window\n .getComputedStyle(document.documentElement)\n .getPropertyValue(`--topbar-icon-${slot}`)\n .trim()\n // Brand may emit the name quoted (e.g. \"bell\"); strip the quotes.\n .replace(/^['\"]|['\"]$/g, '')\n setName(raw.length > 0 ? raw : null)\n }\n\n read()\n\n const observer = new MutationObserver(read)\n observer.observe(document.head, { childList: true, subtree: true })\n return () => observer.disconnect()\n }, [slot])\n\n return name\n}\n\n/** Path to a brand-icon SVG in the consuming app's public dir. */\nexport function brandIconSrc(name: string, basePath = '/brand/icons/') {\n return `${basePath}${name}.svg`\n}\n","import type { ComponentType } from 'react'\nimport {\n FiAlertCircle,\n FiBattery,\n FiBatteryCharging,\n FiAlertTriangle,\n FiBell,\n FiGrid,\n FiHelpCircle,\n FiInfo,\n FiLifeBuoy,\n FiMail,\n FiMessageSquare,\n FiMoon,\n FiSettings,\n FiSun,\n FiUser,\n FiZap,\n} from 'react-icons/fi'\n\nexport type GlyphComponent = ComponentType<{ size?: number | string; className?: string }>\n\n/**\n * Brand-glyph registry: maps the icon NAME the Brand API emits (e.g.\n * `--topbar-icon-comms-fuel: bolt`) to a component.\n *\n * These names are Feather/Lucide icon names, NOT asset filenames — there is no\n * `/brand/icons/<name>.svg` for them in any app, and treating them as URLs\n * renders a broken image. Resolving them against the icon library the shell\n * already depends on keeps every app consistent with zero vendored assets.\n *\n * Aliases are included where Brand and Feather disagree on a name (`bolt` vs\n * `zap`, `life-buoy` vs `life-ring`).\n */\nconst GLYPHS: Record<string, GlyphComponent> = {\n // Communications Fuel reads as a LEVEL, so its glyph is a battery. `bolt`/\n // `zap` stay mapped for older Brand values.\n 'battery-charging': FiBatteryCharging,\n battery: FiBattery,\n fuel: FiBatteryCharging,\n bolt: FiZap,\n zap: FiZap,\n grid: FiGrid,\n apps: FiGrid,\n bell: FiBell,\n notification: FiBell,\n 'alert-triangle': FiAlertTriangle,\n alert: FiAlertTriangle,\n 'alert-circle': FiAlertCircle,\n 'life-buoy': FiLifeBuoy,\n 'life-ring': FiLifeBuoy,\n support: FiLifeBuoy,\n 'help-circle': FiHelpCircle,\n moon: FiMoon,\n sun: FiSun,\n info: FiInfo,\n mail: FiMail,\n 'message-square': FiMessageSquare,\n settings: FiSettings,\n user: FiUser,\n}\n\n/**\n * Resolve a Brand glyph name to a component. Returns null for an unknown name\n * so the caller renders its own fallback — an unrecognized token must never\n * produce a broken or empty icon.\n */\nexport function resolveBrandGlyph(name: string | null | undefined): GlyphComponent | null {\n if (!name) return null\n return GLYPHS[name.trim().toLowerCase()] ?? null\n}\n\n/** Names the registry knows — exported for tests and tooling. */\nexport const KNOWN_BRAND_GLYPHS = Object.keys(GLYPHS)\n","// Universal theme preference — the ONE cross-app contract.\n//\n// One theme choice (Light / Dark / System) follows the authenticated user\n// across every Politogy app + subdomain. Three layers cooperate:\n// 1. VRM Core `profiles.theme_preference` — source of truth, persisted via\n// the chrome API (`PATCH me/preferences { themePreference }`) and read\n// back from `GET me` (`themePreference`).\n// 2. `.politogyvrm.com` cookie `politogy_theme` — zero-flash pre-paint\n// vehicle that crosses subdomains (auth session cookies are host-only).\n// 3. localStorage `politogy_theme` — offline fallback store.\n//\n// Ported verbatim from contacts/apps/web/src/lib/theme.ts (the origin of the\n// contract) so every app runs the identical behavior from npm. This module is\n// server-safe (no 'use client'): layouts import THEME_PREPAINT_SCRIPT for the\n// pre-paint inline script. The client-side hook lives in ./native\n// (useThemePreference).\n\nexport type ThemePreference = 'light' | 'dark' | 'system'\n\n// Single converged key for BOTH the localStorage store and the\n// cross-subdomain cookie, so a choice in one app is the same key in the next.\nexport const THEME_STORAGE_KEY = 'politogy_theme'\nexport const THEME_COOKIE = 'politogy_theme'\n\n// A local choice that has NOT yet reached VRM Core `profiles.theme_preference`.\n//\n// Politogy ID (auth.politogyvrm.com) has no chrome-API session to PATCH, so a\n// theme picked on the login screen only ever lands in the cookie. Without this\n// marker the next app booted the stale profile value through the reconcile step\n// below and overwrote the user's fresh choice — the \"I set System and it keeps\n// going back to Light\" bug (HITL 2026-07-23). The flag rides the same\n// cross-subdomain cookie so the first app that CAN talk to the chrome API\n// pushes the choice up instead of pulling the stale one down.\nexport const THEME_PENDING_COOKIE = 'politogy_theme_pending'\n\nconst VALID: readonly ThemePreference[] = ['light', 'dark', 'system']\n\nexport function isThemePreference(v: unknown): v is ThemePreference {\n return typeof v === 'string' && (VALID as readonly string[]).includes(v)\n}\n\n/** Read the shared cookie (browser only; null on the server or when unset). */\nexport function readThemeCookie(): ThemePreference | null {\n if (typeof document === 'undefined') return null\n try {\n const m = document.cookie.match(\n new RegExp(`(?:^|;\\\\s*)${THEME_COOKIE}=([^;]+)`),\n )\n const v = m ? decodeURIComponent(m[1]) : null\n return isThemePreference(v) ? v : null\n } catch {\n return null\n }\n}\n\n// Set the cross-subdomain cookie. On a *.politogyvrm.com host we scope it to\n// the parent domain so every app subdomain reads it; on any other host\n// (localhost, *.pages.dev preview) we fall back to a host-only cookie so\n// local/preview theming still works without a mismatched Domain attribute\n// (which browsers silently drop). 1-year, SameSite=Lax, Secure on https.\nexport function writeThemeCookie(pref: ThemePreference): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const host = window.location.hostname\n const onParentDomain = /(^|\\.)politogyvrm\\.com$/i.test(host)\n const domainAttr = onParentDomain ? '; Domain=.politogyvrm.com' : ''\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n document.cookie = `${THEME_COOKIE}=${encodeURIComponent(\n pref,\n )}; Path=/; Max-Age=31536000; SameSite=Lax${domainAttr}${secure}`\n}\n\n// Write an arbitrary cross-subdomain cookie with the same scoping rules as the\n// theme cookie itself (parent domain on *.politogyvrm.com, host-only elsewhere).\nfunction writeSharedCookie(name: string, value: string, maxAgeSeconds: number): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n document.cookie = `${name}=${encodeURIComponent(\n value,\n )}; Path=/; Max-Age=${maxAgeSeconds}; SameSite=Lax${domainAttr}${secure}`\n}\n\n/**\n * Mark the current cookie value as a local choice that still has to reach the\n * user's profile. Call this from any surface that changes the theme WITHOUT a\n * chrome-API session (Politogy ID's login screen is the only one today).\n */\nexport function markThemeChoicePending(pref: ThemePreference): void {\n writeSharedCookie(THEME_PENDING_COOKIE, pref, 31536000)\n}\n\n/** The pending (not-yet-persisted) local choice, if any. */\nexport function readPendingThemeChoice(): ThemePreference | null {\n if (typeof document === 'undefined') return null\n try {\n const m = document.cookie.match(\n new RegExp(`(?:^|;\\\\s*)${THEME_PENDING_COOKIE}=([^;]+)`),\n )\n const v = m ? decodeURIComponent(m[1]) : null\n return isThemePreference(v) ? v : null\n } catch {\n return null\n }\n}\n\n/** Clear the pending marker once the choice has been written to the profile. */\nexport function clearPendingThemeChoice(): void {\n writeSharedCookie(THEME_PENDING_COOKIE, '', 0)\n}\n\n/** Resolve a preference to the concrete light/dark it renders as right now. */\nexport function resolveTheme(pref: ThemePreference): 'light' | 'dark' {\n if (pref === 'system') {\n try {\n return window.matchMedia('(prefers-color-scheme: dark)').matches\n ? 'dark'\n : 'light'\n } catch {\n return 'light'\n }\n }\n return pref\n}\n\n/**\n * Read the stored preference the way the pre-paint script does — cookie →\n * localStorage → `'system'`. Kept in lockstep with THEME_PREPAINT_SCRIPT so a\n * runtime reader can never disagree with what was applied before paint.\n */\nexport function readStoredThemePreference(): ThemePreference {\n const cookie = readThemeCookie()\n if (cookie) return cookie\n try {\n const stored = window.localStorage.getItem(THEME_STORAGE_KEY)\n if (isThemePreference(stored)) return stored\n } catch {\n /* localStorage may be unavailable (private mode) */\n }\n return 'system'\n}\n\n/**\n * The concrete light/dark the document is rendering as right now.\n *\n * This is the value anything theme-derived must follow — notably Chakra's\n * `colorMode`. Chakra used to be pinned to light while this resolved to dark,\n * which rendered dark chrome tokens over light Chakra content (the \"dark\n * labels on a light page\" desync).\n */\nexport function readResolvedTheme(): 'light' | 'dark' {\n return resolveTheme(readStoredThemePreference())\n}\n\n/** Apply a preference to the document (`.dark` class + color-scheme). */\nexport function applyThemePreference(pref: ThemePreference): void {\n if (typeof document === 'undefined') return\n const resolved = resolveTheme(pref)\n const d = document.documentElement\n d.classList.toggle('dark', resolved === 'dark')\n try {\n d.style.colorScheme = resolved\n } catch {\n /* non-fatal */\n }\n}\n\n// Inline pre-paint script — render it in <head> (or as the first child of\n// <body>) so the theme applies before first paint. Resolves the preference\n// from cookie → localStorage → OS, applies the `.dark` class + `color-scheme`,\n// and seeds localStorage from the cookie so the app hydrates to the synced\n// value (the cross-subdomain flash fix). Self-contained, dependency-free, and\n// wrapped so any failure is silent (never blocks paint).\nexport const THEME_PREPAINT_SCRIPT = `(function(){try{\nvar KEY=${JSON.stringify(THEME_STORAGE_KEY)};\nvar VALID=[\"light\",\"dark\",\"system\"];\nfunction fromCookie(){try{var m=document.cookie.match(/(?:^|;\\\\s*)${THEME_COOKIE}=([^;]+)/);return m?decodeURIComponent(m[1]):null;}catch(e){return null;}}\nvar cookie=fromCookie();\nvar ls=null;try{ls=localStorage.getItem(KEY);}catch(e){}\nvar pref=cookie||ls||\"system\";\nif(VALID.indexOf(pref)===-1)pref=\"system\";\nif(cookie&&cookie!==ls){try{localStorage.setItem(KEY,cookie);}catch(e){}}\nvar resolved=pref;\nif(pref===\"system\"){try{resolved=window.matchMedia(\"(prefers-color-scheme: dark)\").matches?\"dark\":\"light\";}catch(e){resolved=\"light\";}}\nvar d=document.documentElement;\nif(resolved===\"dark\"){d.classList.add(\"dark\");}else{d.classList.remove(\"dark\");}\ntry{d.style.colorScheme=resolved;}catch(e){}\n}catch(e){}})();`\n","// ---------------------------------------------------------------------------\n// Native chrome actions — Tailwind-only top-bar widgets (Fuel, Notifications,\n// Support, Navigation-display) backed by the shared chrome API\n// (politogy-contacts-api on Railway). Zero Chakra, zero router, zero fetch\n// opinion: the consuming app injects ONE fetcher via <NavChromeProvider> —\n// typically a same-origin proxy route that attaches its own session's Bearer\n// token server-side — and every widget in every app runs this exact code.\n//\n// Data endpoints (paths are relative; the app's fetcher owns the base URL):\n// GET communications/fuel-status (header x-contacts-org: <core org id>)\n// GET notifications (header x-contacts-org: <core org id>)\n// GET orgs\n// POST support { message }\n//\n// Loading states follow Global-Rules \"Loading & Async States\": the chrome\n// (button, popover frame, labels) always renders; only the VALUE area shows a\n// skeleton shimmer — never a spinner, never a blank panel.\n// ---------------------------------------------------------------------------\n\n'use client'\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n useSyncExternalStore,\n type ComponentType,\n type ReactNode,\n} from 'react'\nimport { createPortal } from 'react-dom'\n\nimport { useTopBarIconSlotGlyph, type TopBarIconSlot } from '../lib/topbarIconSlot'\nimport { resolveBrandGlyph } from '../lib/brandGlyphs'\nimport {\n applyThemePreference,\n isThemePreference,\n readThemeCookie,\n writeThemeCookie,\n readPendingThemeChoice,\n markThemeChoicePending,\n clearPendingThemeChoice,\n THEME_STORAGE_KEY,\n type ThemePreference as SharedThemePreference,\n} from '../theme-preference'\n\ntype NavIconLike = ComponentType<{ size?: number; className?: string }>\n\n// ---------------------------------------------------------------------------\n// Core-app deep links. The billing surface lives on the VRM-core app; we would\n// derive its origin from POLITOGY_APPS.vrm, but that registry lives in\n// ../app-chrome which imports THIS module — so pulling it in here would create\n// an import cycle. One local constant instead (kept in step with the registry's\n// `vrm` origin).\n// ---------------------------------------------------------------------------\n\nexport const CORE_APP_ORIGIN = 'https://app.politogyvrm.com'\n/** Text/Email fuel top-up page (SMS Signal + Email Broadcast). */\nexport const CORE_BILLING_PATH = '/organization-settings/subscription-billing/text-email'\nconst CORE_BILLING_URL = `${CORE_APP_ORIGIN}${CORE_BILLING_PATH}`\nconst QUARANTINED_CONTACTS_URL = `${CORE_APP_ORIGIN}/relationship/contacts/quarantined`\n\n/**\n * Stamp the active org onto a cross-app link, the same `?org=<uuid>` selector\n * the nav tree and Mode pill use. A bare link into VRM core drops a multi-org\n * user into whatever org core defaults to, which is a different account than\n * the one whose fuel / quarantine counts they just clicked.\n */\nfunction withOrgParam(url: string, orgId: string | null | undefined): string {\n if (!orgId) return url\n return `${url}${url.includes('?') ? '&' : '?'}org=${orgId}`\n}\n\n/** Scope the quarantined-contacts view to one sender. */\nfunction withPhoneParam(url: string, phone: string | null | undefined): string {\n if (!phone) return url\n return `${url}${url.includes('?') ? '&' : '?'}phone=${encodeURIComponent(phone)}`\n}\n\n/**\n * Resolve an organization logo URL for rendering in ANY app.\n *\n * `organizations.logo_url` is authored by VRM core and stored as a ROOT-RELATIVE\n * core route — `/api/storage/public?bucket=organization-logos&path=<org>/logo.png`\n * (the signed-storage proxy). VRM core renders it correctly because that path\n * resolves against its own origin; every other app resolves it against its own\n * origin (forms.politogyvrm.com/api/storage/public), gets a 404, and shows a\n * broken image. The chrome API passes the stored value through verbatim, so the\n * resolution belongs here — one definition for every app, core included.\n *\n * Absolute URLs (http/https/data/blob) pass through untouched.\n */\nexport function resolveOrgLogoUrl(url: string | null | undefined): string | undefined {\n const raw = url?.trim()\n if (!raw) return undefined\n if (/^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i.test(raw)) return raw\n return `${CORE_APP_ORIGIN}${raw.startsWith('/') ? '' : '/'}${raw}`\n}\n\n// ---------------------------------------------------------------------------\n// Shared 32×32 circular top-bar button chrome — the ONE definition of the\n// top-bar trigger (Global Rules: no slot hand-rolls its own trigger/badge).\n// NavTopBar's structured actionsList buttons use this same builder.\n// ---------------------------------------------------------------------------\n\nexport function topBarIconButtonClass(tone: 'default' | 'warning' | 'danger' = 'default'): string {\n const toneClass =\n tone === 'danger' || tone === 'warning'\n ? 'text-[color:var(--color-race-red)] hover:text-[color:var(--color-race-red)]'\n : 'text-[color:var(--topbar-icon-color,var(--muted))] hover:text-[color:var(--topbar-icon-hover-color,var(--foreground))] hover:bg-[color:var(--topbar-icon-hover-bg,transparent)]'\n return [\n // `group/tbtip` powers the shared <TopBarTooltip> rendered inside the trigger.\n 'group/tbtip relative flex items-center justify-center rounded-full border border-[color:var(--line)] transition',\n 'h-[var(--topbar-icon-button-size,32px)] w-[var(--topbar-icon-button-size,32px)]',\n toneClass,\n ].join(' ')\n}\n\n/** The shared count badge — one definition, used by every slot. */\n// ---------------------------------------------------------------------------\n// Top-bar panel registry.\n//\n// The top bar hosts two KINDS of surface: panels (opened deliberately by the\n// user from an icon) and transient nudges (the low-fuel hint, the new-reply\n// toast) that appear on their own. They are separate components under separate\n// triggers, so nothing stopped a nudge from covering an open panel — measured\n// in production: the reply toast over the notifications header, and the\n// low-fuel nudge over the same header from the fuel trigger two icons away.\n//\n// A module-scoped counter is enough: any nudge can ask \"is a panel open?\"\n// without the slots having to know about each other.\n// ---------------------------------------------------------------------------\nlet openPanelCount = 0\nconst panelListeners = new Set<() => void>()\nconst emitPanelChange = () => panelListeners.forEach((l) => l())\n\nfunction setPanelOpenGlobal(open: boolean) {\n openPanelCount = Math.max(0, openPanelCount + (open ? 1 : -1))\n emitPanelChange()\n}\n\n/** True while ANY top-bar panel is open. Nudges use it to stay out of the way. */\nexport function useAnyTopBarPanelOpen() {\n return useSyncExternalStore(\n (cb) => {\n panelListeners.add(cb)\n return () => panelListeners.delete(cb)\n },\n () => openPanelCount > 0,\n () => false,\n )\n}\n\nexport function TopBarCountBadge({ count }: { count: number }) {\n if (!(count > 0)) return null\n return (\n <span className=\"absolute -top-1 -right-1 flex h-4 min-w-4 items-center justify-center rounded-full bg-[color:var(--color-race-red)] px-1 text-[10px] font-normal leading-none text-white\">\n {count > 99 ? '99+' : count}\n </span>\n )\n}\n\n/**\n * The shared hover tooltip every top-bar control renders BELOW itself: an\n * up-pointing arrow at the icon, a bold title line and a muted description.\n * Pure CSS (group-hover) so it works on <a>, <button> and <summary> triggers.\n * The trigger must carry `group/tbtip relative` (topBarIconButtonClass does).\n */\nexport function TopBarTooltip({\n title,\n description,\n}: {\n title: string\n description?: ReactNode\n}) {\n return (\n <span\n role=\"tooltip\"\n className=\"pointer-events-none absolute left-1/2 top-full z-50 mt-2 hidden w-max max-w-56 -translate-x-1/2 flex-col rounded-lg border border-[color:var(--line)] bg-[color:var(--panel-elevated)] px-3 py-2 text-left shadow-[var(--shadow-soft)] group-hover/tbtip:flex\"\n >\n {/* Arrow pointing up at the icon */}\n <span\n aria-hidden\n className=\"absolute -top-[5px] left-1/2 h-2.5 w-2.5 -translate-x-1/2 rotate-45 border-l border-t border-[color:var(--line)] bg-[color:var(--panel-elevated)]\"\n />\n <span className=\"text-xs font-semibold text-[color:var(--foreground)]\">{title}</span>\n {description ? (\n <span className=\"mt-0.5 text-[11px] leading-snug text-[color:var(--muted)]\">\n {description}\n </span>\n ) : null}\n </span>\n )\n}\n\n/**\n * The up-pointing arrow every top-bar panel renders, anchored under its\n * trigger icon (panels are right-aligned, so the arrow sits at the trigger's\n * center: 16px in from the panel's right edge). One definition — every menu\n * points at its own icon identically.\n */\nexport function TopBarPanelArrow() {\n return (\n <span\n aria-hidden\n className=\"absolute -top-[5px] right-[11px] h-2.5 w-2.5 rotate-45 border-l border-t border-[color:var(--line)] bg-[color:var(--panel-elevated)]\"\n />\n )\n}\n\n/**\n * Wrapper for third-party top-bar widgets that ship their own launcher button\n * (e.g. DevNotes). Normalizes the trigger to the universal 32px circular slot\n * (chrome.css `.topbar-widget-slot`) and adds the standard tooltip.\n */\nexport function TopBarWidgetSlot({\n title,\n description,\n children,\n}: {\n title: string\n description?: string\n children: ReactNode\n}) {\n return (\n <span className=\"topbar-widget-slot group/tbtip relative inline-flex\">\n {children}\n <TopBarTooltip title={title} description={description} />\n </span>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Theme control — Light / System / Dark, rendered inside the account menu.\n// Controlled: the app owns persistence (profile + cross-subdomain cookie).\n// ---------------------------------------------------------------------------\n\nexport type ThemePreference = SharedThemePreference\n\nconst THEME_OPTIONS: { value: ThemePreference; label: string }[] = [\n { value: 'light', label: 'Light' },\n { value: 'system', label: 'System' },\n { value: 'dark', label: 'Dark' },\n]\n\nexport function NavThemeControl({\n value,\n onChange,\n}: {\n value: ThemePreference\n onChange: (next: ThemePreference) => void\n}) {\n return (\n <div className=\"px-4 py-3\">\n <p className=\"mb-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Appearance\n </p>\n <div\n role=\"radiogroup\"\n aria-label=\"Appearance\"\n className=\"flex overflow-hidden rounded-full border border-[color:var(--line)]\"\n >\n {THEME_OPTIONS.map((opt) => (\n <button\n key={opt.value}\n type=\"button\"\n role=\"radio\"\n aria-checked={value === opt.value}\n onClick={() => onChange(opt.value)}\n className={[\n 'flex-1 px-3 py-1.5 text-xs font-semibold transition',\n value === opt.value\n ? 'bg-[color:var(--color-race-red)] text-white'\n : 'text-[color:var(--muted)] hover:bg-[color:var(--panel)] hover:text-[color:var(--foreground)]',\n ].join(' ')}\n >\n {opt.label}\n </button>\n ))}\n </div>\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Chrome data context — the injected fetcher.\n// ---------------------------------------------------------------------------\n\nexport type NavChromeFetcher = (\n path: string,\n init?: { method?: string; headers?: Record<string, string>; body?: string },\n) => Promise<unknown>\n\n/** GET me — the authenticated user's chrome identity from the shared API.\n * userName prefers the VRM-core profile full name over token claims. */\nexport type ChromeMe = {\n user: string | null\n userName: string | null\n avatarUrl: string | null\n themePreference: string | null\n /** Universal navigation-display choice ('menu'|'tabs'|'both'); null when\n * unset or when the profile column is absent in this environment. */\n navDisplay: string | null\n account?: string | null\n accountName?: string | null\n role?: string | null\n /** Contact reply-to, when the profile carries them (optional/tolerant). */\n email?: string | null\n phone?: string | null\n}\n\ntype NavChromeContextValue = {\n fetchJson: NavChromeFetcher\n me: ChromeMe | null\n meLoaded: boolean\n}\n\nconst NavChromeContext = createContext<NavChromeContextValue | null>(null)\n\nexport function NavChromeProvider({\n fetchJson,\n children,\n}: {\n fetchJson: NavChromeFetcher\n children: ReactNode\n}) {\n // ONE `me` fetch per provider — identity (profile name/avatar) and the\n // theme reconciliation both hang off it.\n const [me, setMe] = useState<ChromeMe | null>(null)\n const [meLoaded, setMeLoaded] = useState(false)\n useEffect(() => {\n let cancelled = false\n fetchJson('me')\n .then((data) => {\n if (!cancelled) setMe(data as ChromeMe)\n })\n .catch(() => {\n /* degraded: session identity stands in */\n })\n .finally(() => {\n if (!cancelled) setMeLoaded(true)\n })\n return () => {\n cancelled = true\n }\n }, [fetchJson])\n\n return (\n <NavChromeContext.Provider value={{ fetchJson, me, meLoaded }}>\n {children}\n </NavChromeContext.Provider>\n )\n}\n\n/** The authenticated user's chrome identity (profile name / avatar / theme). */\nexport function useChromeMe(): { me: ChromeMe | null; loaded: boolean } {\n const ctx = useContext(NavChromeContext)\n return { me: ctx?.me ?? null, loaded: ctx?.meLoaded ?? false }\n}\n\n/** The injected chrome fetcher (null outside <NavChromeProvider>). */\nexport function useNavChromeFetcher(): NavChromeFetcher | null {\n return useContext(NavChromeContext)?.fetchJson ?? null\n}\n\nfunction useNavChrome(component: string): NavChromeContextValue {\n const ctx = useContext(NavChromeContext)\n if (!ctx) {\n throw new Error(\n `${component} must be rendered inside <NavChromeProvider> (inject the chrome API fetcher there).`,\n )\n }\n return ctx\n}\n\n// ---------------------------------------------------------------------------\n// Data shapes (mirror of politogy-contacts-api responses).\n// ---------------------------------------------------------------------------\n\nexport type FuelChannelStatus = {\n remainingUnits: number\n rawBalanceUnits: number\n usedUnits: number\n lowFuel: boolean\n lowFuelThreshold: number\n}\n\nexport type CommunicationsFuelStatus = {\n organizationId: string\n signal: FuelChannelStatus\n broadcast: FuelChannelStatus\n combinedAvailableCredits: number\n}\n\nexport type ChromeNotificationAlert = {\n id: string\n title: string\n description: string\n href: string | null\n kind: string\n}\n\nexport type ChromeNotificationReply = {\n id: string\n contactId: string | null\n name: string\n preview: string\n /** Optional deep-link to the conversation; the new-reply toast opens it. */\n href?: string\n /**\n * Optional arrival timestamp. Present, it lets the trigger badge count a\n * reply as \"unseen\" only when it is newer than the last time the panel was\n * opened; absent (older payloads), replies simply don't survive the first\n * open as unseen. Tolerated either way.\n */\n createdAt?: string\n}\n\n/** A running or finished contact import surfaced in the notifications panel. */\nexport type ChromeNotificationImport = {\n id: string\n label: string\n /** 0–100 progress, or null when indeterminate (no bar rendered). */\n percent: number | null\n status: 'active' | 'completed'\n href: string | null\n}\n\n/** A cluster of quarantined contacts sharing one phone number. */\nexport type ChromeNotificationQuarantine = {\n phone: string\n count: number\n /** Upstream may omit it; the row already renders conditionally on it. */\n latestAt: string | null\n}\n\nexport type ChromeNotificationsPayload = {\n organizationId: string\n alerts: ChromeNotificationAlert[]\n replies: ChromeNotificationReply[]\n /** Optional — running/finished imports (tolerant when absent). */\n imports?: ChromeNotificationImport[]\n /** Optional — clustered quarantined contacts (tolerant when absent). */\n quarantined?: ChromeNotificationQuarantine[]\n}\n\nexport type ChromeOrgSummary = {\n id: string\n name: string | null\n logoUrl: string | null\n brandColor: string | null\n role: string | null\n /** Un-mapped VRM-core membership role (e.g. \"super_admin\"). */\n rawRole?: string | null\n}\n\n/**\n * Fetch the signed-in user's VRM-core organizations through the injected\n * fetcher. Exposed as a hook so the org switcher in the sidebar and the\n * org-scoped widgets share one request.\n */\nexport function useChromeOrgs(): {\n orgs: ChromeOrgSummary[] | null\n loading: boolean\n error: boolean\n} {\n const { fetchJson } = useNavChrome('useChromeOrgs')\n const [orgs, setOrgs] = useState<ChromeOrgSummary[] | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState(false)\n\n useEffect(() => {\n let cancelled = false\n setLoading(true)\n setError(false)\n fetchJson('orgs')\n .then((data) => {\n if (cancelled) return\n const list = (data as { orgs?: ChromeOrgSummary[] })?.orgs ?? []\n setOrgs(list)\n })\n .catch(() => {\n if (!cancelled) setError(true)\n })\n .finally(() => {\n if (!cancelled) setLoading(false)\n })\n return () => {\n cancelled = true\n }\n }, [fetchJson])\n\n return { orgs, loading, error }\n}\n\n// ---------------------------------------------------------------------------\n// Internal building blocks.\n// ---------------------------------------------------------------------------\n\n/** Value-area skeleton shimmer (chrome/labels stay static per Global Rules). */\nfunction ValueSkeleton({ className }: { className?: string }) {\n return (\n <span\n aria-hidden\n className={[\n 'inline-block animate-pulse rounded bg-[color:var(--panel-elevated)]',\n className ?? 'h-4 w-16',\n ].join(' ')}\n />\n )\n}\n\n/** Slot-driven glyph: Brand-token name when resolvable, fallback otherwise. */\nfunction SlotGlyph({\n slot,\n fallback: Fallback,\n size = 20,\n}: {\n slot?: TopBarIconSlot\n fallback: NavIconLike\n size?: number\n}) {\n const glyphName = useTopBarIconSlotGlyph(slot ?? 'apps')\n const BrandGlyph = slot ? resolveBrandGlyph(glyphName) : null\n const Glyph = BrandGlyph ?? Fallback\n return <Glyph size={size} className=\"text-current\" />\n}\n\n/**\n * A top-bar popover: the shared circular trigger + a right-aligned panel.\n * Closes on outside click / Escape. Purely presentational.\n *\n * EXPORTED so an app with a richer panel than the stock actions can render it\n * inside the SHARED chrome — same 32px trigger, same tooltip, same badge, same\n * panel surface and arrow — instead of hand-rolling a trigger and drifting.\n * This is the enabling step for folding VRM's Fuel breakdown, import-progress,\n * alerts and reply-feed panels into the shared cluster one at a time, without\n * dropping capability (shell-nav-handoff §4; UI-Platform forbids migrating an\n * app to a rendering that loses an element it already ships).\n */\nexport function TopBarPopover({\n label,\n description,\n slot,\n fallbackIcon,\n badge,\n tone,\n onOpen,\n openToken,\n onOpenChange,\n children,\n panelClassName,\n}: {\n label: string\n description?: string\n slot?: TopBarIconSlot\n fallbackIcon: NavIconLike\n badge?: number\n tone?: 'default' | 'warning' | 'danger'\n onOpen?: () => void\n /**\n * Imperative \"open\" signal: whenever this number CHANGES the panel opens\n * (and `onOpen` fires). Lets a sibling — e.g. the notifications toast — open\n * the panel without owning the popover's state. Undefined disables it.\n */\n openToken?: number\n /**\n * Notified on every open/close. A sibling surface anchored to the same\n * trigger (e.g. the notifications toast) must know when the panel is open so\n * the two never render on top of each other — Reference/UI-Platform gives\n * every top-bar panel ONE surface anchored to its trigger, so a second\n * surface at the same anchor always occludes it.\n */\n onOpenChange?: (open: boolean) => void\n children: ReactNode\n panelClassName?: string\n}) {\n const [open, setOpen] = useState(false)\n const onOpenChangeRef = useRef(onOpenChange)\n onOpenChangeRef.current = onOpenChange\n useEffect(() => {\n onOpenChangeRef.current?.(open)\n if (!open) return\n setPanelOpenGlobal(true)\n return () => setPanelOpenGlobal(false)\n }, [open])\n const rootRef = useRef<HTMLDivElement | null>(null)\n const lastOpenTokenRef = useRef(openToken)\n\n // React to external open signals (skips the initial value on mount).\n useEffect(() => {\n if (openToken === undefined) return\n if (openToken === lastOpenTokenRef.current) return\n lastOpenTokenRef.current = openToken\n setOpen((v) => {\n if (!v) onOpen?.()\n return true\n })\n }, [openToken, onOpen])\n\n useEffect(() => {\n if (!open) return\n const onDocClick = (e: MouseEvent) => {\n if (rootRef.current && !rootRef.current.contains(e.target as Node)) setOpen(false)\n }\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') setOpen(false)\n }\n document.addEventListener('mousedown', onDocClick)\n document.addEventListener('keydown', onKey)\n return () => {\n document.removeEventListener('mousedown', onDocClick)\n document.removeEventListener('keydown', onKey)\n }\n }, [open])\n\n return (\n <div ref={rootRef} className=\"relative\">\n <button\n type=\"button\"\n aria-label={label}\n aria-expanded={open}\n className={topBarIconButtonClass(tone)}\n onClick={() => {\n setOpen((v) => {\n const next = !v\n if (next) onOpen?.()\n return next\n })\n }}\n >\n <SlotGlyph slot={slot} fallback={fallbackIcon} />\n {typeof badge === 'number' ? <TopBarCountBadge count={badge} /> : null}\n {!open ? <TopBarTooltip title={label} description={description} /> : null}\n </button>\n {open ? (\n <div\n className={[\n 'absolute right-0 z-40 mt-2 rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] shadow-[var(--shadow-soft)]',\n panelClassName ?? 'w-80',\n ].join(' ')}\n >\n <TopBarPanelArrow />\n <div className=\"overflow-hidden rounded-xl\">{children}</div>\n </div>\n ) : null}\n </div>\n )\n}\n\n// Inline fallback glyphs (Feather-style paths) so the package needs no icon dep.\nfunction BatteryGlyph({ size = 20, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <rect x=\"1\" y=\"6\" width=\"18\" height=\"12\" rx=\"2\" ry=\"2\" />\n <line x1=\"23\" y1=\"10\" x2=\"23\" y2=\"14\" />\n <line x1=\"5\" y1=\"10\" x2=\"5\" y2=\"14\" />\n <line x1=\"9\" y1=\"10\" x2=\"9\" y2=\"14\" />\n </svg>\n )\n}\n\nfunction BellGlyph({ size = 20, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <path d=\"M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9\" />\n <path d=\"M13.73 21a2 2 0 0 1-3.46 0\" />\n </svg>\n )\n}\n\nfunction LifeBuoyGlyph({ size = 20, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <circle cx=\"12\" cy=\"12\" r=\"4\" />\n <line x1=\"4.93\" y1=\"4.93\" x2=\"9.17\" y2=\"9.17\" />\n <line x1=\"14.83\" y1=\"14.83\" x2=\"19.07\" y2=\"19.07\" />\n <line x1=\"14.83\" y1=\"9.17\" x2=\"19.07\" y2=\"4.93\" />\n <line x1=\"4.93\" y1=\"19.07\" x2=\"9.17\" y2=\"14.83\" />\n </svg>\n )\n}\n\nfunction LayoutGlyph({ size = 20, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\" />\n <line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\" />\n <line x1=\"9\" y1=\"21\" x2=\"9\" y2=\"9\" />\n </svg>\n )\n}\n\nfunction PlusGlyph({ size = 14, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2.5} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n )\n}\n\nfunction XGlyph({ size = 14, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2.5} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n )\n}\n\nfunction CheckGlyph({ size = 14, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2.5} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n )\n}\n\n// ---------------------------------------------------------------------------\n// FuelAction — Communications Fuel balance (battery glyph + popover meters).\n// ---------------------------------------------------------------------------\n\nconst LOW_FUEL_HINT_DISMISSED_KEY = 'politogy_low_fuel_hint_dismissed'\n\nfunction FuelRow({\n label,\n channel,\n loading,\n addHref,\n addLabel,\n}: {\n label: string\n channel: FuelChannelStatus | null\n loading: boolean\n /** Billing deep-link for the small \"+\" top-up button (omit to hide it). */\n addHref?: string\n addLabel?: string\n}) {\n const remaining = channel?.remainingUnits ?? 0\n const total = channel ? Math.max(channel.rawBalanceUnits, channel.remainingUnits) : 0\n const ratio = total > 0 ? Math.min(100, Math.max(0, (remaining / total) * 100)) : 0\n const low = channel?.lowFuel ?? false\n\n return (\n <div className=\"w-full\">\n <div className=\"mb-1 flex items-center justify-between gap-2\">\n <span className=\"text-xs font-semibold text-[color:var(--foreground)]\">{label}</span>\n <div className=\"flex items-center gap-2\">\n {loading ? (\n <ValueSkeleton className=\"h-3.5 w-14\" />\n ) : (\n <span\n className={[\n 'text-xs font-semibold tabular-nums',\n low ? 'text-[color:var(--color-race-red)]' : 'text-[color:var(--muted)]',\n ].join(' ')}\n >\n {remaining.toLocaleString()} left\n </span>\n )}\n {addHref ? (\n <a\n href={addHref}\n aria-label={addLabel}\n className=\"flex h-5 w-5 items-center justify-center rounded-full border border-[color:var(--line)] text-[color:var(--muted)] transition hover:border-[color:var(--foreground)] hover:text-[color:var(--foreground)]\"\n >\n <PlusGlyph />\n </a>\n ) : null}\n </div>\n </div>\n <div className=\"h-1.5 w-full overflow-hidden rounded-full bg-[color:var(--panel)]\">\n {loading ? (\n <div className=\"h-full w-full animate-pulse bg-[color:var(--line)]\" />\n ) : (\n <div\n className={[\n 'h-full rounded-full transition-[width]',\n low ? 'bg-[color:var(--color-race-red)]' : 'bg-[color:var(--color-ok,#00A651)]',\n ].join(' ')}\n style={{ width: `${ratio}%` }}\n />\n )}\n </div>\n </div>\n )\n}\n\n/**\n * The low-fuel nudge: a small bubble anchored below the fuel trigger (arrow up)\n * with a \"Buy More Fuel\" deep-link. Dismissible; the dismissal persists for the\n * session (sessionStorage) so it never re-appears until a fresh session — and\n * the flag clears once fuel is no longer low, so a later drain can nudge again.\n */\nfunction LowFuelHint({ lowFuel, orgId }: { lowFuel: boolean; orgId: string | null }) {\n const [dismissed, setDismissed] = useState<boolean>(() => {\n if (typeof window === 'undefined') return false\n try {\n return window.sessionStorage.getItem(LOW_FUEL_HINT_DISMISSED_KEY) === '1'\n } catch {\n return false\n }\n })\n\n useEffect(() => {\n if (lowFuel) return\n try {\n window.sessionStorage.removeItem(LOW_FUEL_HINT_DISMISSED_KEY)\n } catch {\n /* unavailable */\n }\n }, [lowFuel])\n\n // Yield to any open panel: the nudge is wider than its own trigger and the\n // panels are right-aligned, so it lands on top of whichever one is open\n // (measured on contacts: it covered the notifications panel's header).\n const panelOpen = useAnyTopBarPanelOpen()\n\n if (!lowFuel || dismissed || panelOpen) return null\n\n const dismiss = () => {\n try {\n window.sessionStorage.setItem(LOW_FUEL_HINT_DISMISSED_KEY, '1')\n } catch {\n /* unavailable */\n }\n setDismissed(true)\n }\n\n return (\n <div\n role=\"status\"\n className=\"absolute right-0 top-[calc(100%+10px)] z-50 w-60 rounded-lg border border-[color:var(--color-race-red)] bg-[color:var(--color-race-red)] px-3 py-2 text-white shadow-[var(--shadow-soft)]\"\n onClick={(e) => e.stopPropagation()}\n >\n {/* Arrow pointing up at the fuel button (mirrors TopBarPanelArrow's offset). */}\n <span\n aria-hidden\n className=\"absolute -top-[5px] right-[11px] h-2.5 w-2.5 rotate-45 bg-[color:var(--color-race-red)]\"\n />\n <div className=\"flex items-start gap-2\">\n <div className=\"flex-1\">\n <p className=\"text-sm font-semibold\">You’re low on fuel</p>\n <a\n href={withOrgParam(CORE_BILLING_URL, orgId)}\n className=\"mt-1 inline-block text-sm font-bold underline hover:opacity-90\"\n >\n Buy More Fuel\n </a>\n </div>\n <button\n type=\"button\"\n aria-label=\"Dismiss low fuel notice\"\n onClick={dismiss}\n className=\"flex h-5 w-5 shrink-0 items-center justify-center rounded-full text-white/90 transition hover:bg-white/20\"\n >\n <XGlyph />\n </button>\n </div>\n </div>\n )\n}\n\nexport function FuelAction({ orgId }: { orgId: string | null }) {\n const { fetchJson } = useNavChrome('FuelAction')\n const [fuel, setFuel] = useState<CommunicationsFuelStatus | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState(false)\n\n useEffect(() => {\n let cancelled = false\n setLoading(true)\n setError(false)\n setFuel(null)\n fetchJson('communications/fuel-status', {\n headers: orgId ? { 'x-contacts-org': orgId } : undefined,\n })\n .then((data) => {\n if (cancelled) return\n setFuel((data as { fuel?: CommunicationsFuelStatus | null })?.fuel ?? null)\n })\n .catch(() => {\n if (!cancelled) setError(true)\n })\n .finally(() => {\n if (!cancelled) setLoading(false)\n })\n return () => {\n cancelled = true\n }\n }, [fetchJson, orgId])\n\n const low = !!fuel && (fuel.signal.lowFuel || fuel.broadcast.lowFuel)\n\n return (\n // The nudge anchors to the trigger, so it sits OUTSIDE the popover panel in\n // its own relative wrapper (same shape the VRM widget used).\n <div className=\"relative inline-flex\">\n <TopBarPopover\n label=\"Communications Fuel\"\n description=\"Remaining SMS and email sending balance for the active organization.\"\n slot=\"comms-fuel\"\n fallbackIcon={BatteryGlyph}\n tone={low ? 'warning' : 'default'}\n >\n <div className=\"px-4 py-3\">\n <p className=\"mb-3 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Communications Fuel\n </p>\n {error || (!loading && !fuel) ? (\n <p className=\"text-sm text-[color:var(--muted)]\">\n Fuel balance is unavailable right now.\n </p>\n ) : (\n <div className=\"flex flex-col gap-3\">\n <FuelRow\n label=\"SMS Signal\"\n channel={fuel?.signal ?? null}\n loading={loading}\n addHref={withOrgParam(CORE_BILLING_URL, orgId)}\n addLabel=\"Add SMS Signal fuel\"\n />\n <FuelRow\n label=\"Email Broadcast\"\n channel={fuel?.broadcast ?? null}\n loading={loading}\n addHref={withOrgParam(CORE_BILLING_URL, orgId)}\n addLabel=\"Add Email Broadcast fuel\"\n />\n </div>\n )}\n </div>\n </TopBarPopover>\n <LowFuelHint lowFuel={low} orgId={orgId} />\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// NotificationsAction — bell + count badge + alerts/replies popover.\n// ---------------------------------------------------------------------------\n\n/** Per-org read/seen state, persisted client-side (localStorage). */\ntype NotifState = {\n readAlertIds: string[]\n lastSeenAt: string | null\n /** Reply ids already surfaced as a toast, so none re-toasts (capped ~50). */\n toastedReplyIds: string[]\n}\n\nfunction notifStateKey(orgId: string | null): string {\n return `politogy_chrome_notif_state:${orgId ?? 'none'}`\n}\n\nfunction readNotifState(orgId: string | null): NotifState {\n const empty: NotifState = { readAlertIds: [], lastSeenAt: null, toastedReplyIds: [] }\n if (typeof window === 'undefined') return empty\n try {\n const raw = window.localStorage.getItem(notifStateKey(orgId))\n if (!raw) return empty\n const parsed = JSON.parse(raw) as Partial<NotifState>\n return {\n readAlertIds: Array.isArray(parsed?.readAlertIds)\n ? parsed.readAlertIds.filter((id): id is string => typeof id === 'string')\n : [],\n lastSeenAt: typeof parsed?.lastSeenAt === 'string' ? parsed.lastSeenAt : null,\n toastedReplyIds: Array.isArray(parsed?.toastedReplyIds)\n ? parsed.toastedReplyIds.filter((id): id is string => typeof id === 'string')\n : [],\n }\n } catch {\n return empty\n }\n}\n\nfunction writeNotifState(orgId: string | null, state: NotifState): void {\n if (typeof window === 'undefined') return\n try {\n window.localStorage.setItem(notifStateKey(orgId), JSON.stringify(state))\n } catch {\n /* unavailable */\n }\n}\n\nconst TEN_DLC_REDIRECTED_KEY = 'politogy_10dlc_redirected'\n\n/** Format a raw phone into US (XXX) XXX-XXXX; leave anything else as-is. */\nfunction formatPhone(raw: string): string {\n const digits = raw.replace(/\\D/g, '')\n const ten = digits.length === 11 && digits.startsWith('1') ? digits.slice(1) : digits\n if (ten.length === 10) return `(${ten.slice(0, 3)}) ${ten.slice(3, 6)}-${ten.slice(6)}`\n return raw\n}\n\nfunction ImportRow({ imp }: { imp: ChromeNotificationImport }) {\n const pct = imp.percent == null ? null : Math.max(0, Math.min(100, imp.percent))\n return (\n <>\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"truncate text-sm text-[color:var(--foreground)]\">{imp.label}</span>\n {pct != null ? (\n <span className=\"shrink-0 text-xs tabular-nums text-[color:var(--muted)]\">\n {Math.round(pct)}%\n </span>\n ) : null}\n </div>\n {pct != null ? (\n <div className=\"mt-1 h-1 w-full overflow-hidden rounded-full bg-[color:var(--panel)]\">\n <div\n className=\"h-full rounded-full bg-[color:var(--color-race-red)] transition-[width]\"\n style={{ width: `${pct}%` }}\n />\n </div>\n ) : null}\n </>\n )\n}\n\n/**\n * Transient \"new reply\" toast anchored below the bell. Dark bubble with an\n * up-arrow, sender + preview; auto-fades after ~12s; clicking activates it.\n * Mirrors VRM's NewTextBellPopup. Purely presentational — the parent owns which\n * reply shows and what a click does.\n */\nfunction NewReplyToast({\n reply,\n onActivate,\n onClose,\n ttlMs = 12000,\n}: {\n reply: ChromeNotificationReply\n onActivate: () => void\n onClose: () => void\n ttlMs?: number\n}) {\n const [visible, setVisible] = useState(false)\n const onCloseRef = useRef(onClose)\n onCloseRef.current = onClose\n\n useEffect(() => {\n setVisible(true)\n const fadeAt = Math.max(0, ttlMs - 450)\n const t1 = window.setTimeout(() => setVisible(false), fadeAt)\n const t2 = window.setTimeout(() => onCloseRef.current(), ttlMs)\n return () => {\n window.clearTimeout(t1)\n window.clearTimeout(t2)\n }\n }, [ttlMs])\n\n const activate = () => {\n setVisible(false)\n onActivate()\n }\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n aria-label=\"Open new reply\"\n onClick={activate}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n activate()\n }\n }}\n className=\"absolute right-[-6px] top-[calc(100%+12px)] z-50 min-w-[240px] max-w-[320px] cursor-pointer rounded-xl bg-[#161616] px-4 py-3 text-white shadow-[var(--shadow-soft)]\"\n style={{\n opacity: visible ? 1 : 0,\n transform: visible ? 'translateY(0px)' : 'translateY(-4px)',\n transition: 'opacity 250ms ease, transform 250ms ease',\n }}\n >\n {/* Up-arrow pointing at the bell. */}\n <span\n aria-hidden\n className=\"absolute right-[18px] top-[-7px] h-0 w-0 border-x-[8px] border-x-transparent border-b-[8px] border-b-[#161616]\"\n />\n <p className=\"truncate text-sm font-semibold\">{reply.name}</p>\n <p className=\"mt-1 truncate text-xs opacity-85\">{reply.preview}</p>\n </div>\n )\n}\n\nexport function NotificationsAction({ orgId }: { orgId: string | null }) {\n const { fetchJson } = useNavChrome('NotificationsAction')\n const [payload, setPayload] = useState<ChromeNotificationsPayload | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState(false)\n const [notif, setNotif] = useState<NotifState>(() => readNotifState(orgId))\n const [toastReply, setToastReply] = useState<ChromeNotificationReply | null>(null)\n const [openToken, setOpenToken] = useState(0)\n const [panelOpen, setPanelOpen] = useState(false)\n // Also yield to a panel opened from a NEIGHBOURING trigger — the fuel panel\n // is right-aligned and wide enough to sit under the bell.\n const anyPanelOpen = useAnyTopBarPanelOpen()\n\n // Re-hydrate the read/seen watermark whenever the active org changes.\n useEffect(() => {\n setNotif(readNotifState(orgId))\n setToastReply(null)\n }, [orgId])\n\n useEffect(() => {\n let cancelled = false\n setLoading(true)\n setError(false)\n setPayload(null)\n fetchJson('notifications', {\n headers: orgId ? { 'x-contacts-org': orgId } : undefined,\n })\n .then((data) => {\n if (!cancelled) setPayload(data as ChromeNotificationsPayload)\n })\n .catch(() => {\n if (!cancelled) setError(true)\n })\n .finally(() => {\n if (!cancelled) setLoading(false)\n })\n return () => {\n cancelled = true\n }\n }, [fetchJson, orgId])\n\n // 10DLC registration auto-redirect — once per session, and ONLY when the\n // alert's href is same-origin with the current page (other origins just show\n // the alert; the core app navigates to its own settings). Mirrors VRM.\n useEffect(() => {\n if (!payload || typeof window === 'undefined') return\n const alert = payload.alerts.find((a) => a.kind === '10dlc_registration' && a.href)\n if (!alert?.href) return\n try {\n if (window.sessionStorage.getItem(TEN_DLC_REDIRECTED_KEY) === '1') return\n } catch {\n return\n }\n let target: URL\n try {\n target = new URL(alert.href, window.location.href)\n } catch {\n return\n }\n if (target.origin !== window.location.origin) return\n try {\n window.sessionStorage.setItem(TEN_DLC_REDIRECTED_KEY, '1')\n } catch {\n /* unavailable */\n }\n window.location.assign(alert.href)\n }, [payload])\n\n const markRead = useCallback(\n (id: string) => {\n setNotif((prev) => {\n if (prev.readAlertIds.includes(id)) return prev\n const next = { ...prev, readAlertIds: [...prev.readAlertIds, id] }\n writeNotifState(orgId, next)\n return next\n })\n },\n [orgId],\n )\n\n const markUnread = useCallback(\n (id: string) => {\n setNotif((prev) => {\n if (!prev.readAlertIds.includes(id)) return prev\n const next = { ...prev, readAlertIds: prev.readAlertIds.filter((x) => x !== id) }\n writeNotifState(orgId, next)\n return next\n })\n },\n [orgId],\n )\n\n // Opening the panel advances the \"last seen\" watermark (replies are seen).\n const onOpen = useCallback(() => {\n // The panel shows the reply the toast was previewing, so the toast has\n // nothing left to say — retire it rather than let it cover the panel.\n setToastReply(null)\n setNotif((prev) => {\n const next = { ...prev, lastSeenAt: new Date().toISOString() }\n writeNotifState(orgId, next)\n return next\n })\n }, [orgId])\n\n const alerts = payload?.alerts ?? []\n const replies = payload?.replies ?? []\n const imports = payload?.imports ?? []\n const quarantined = payload?.quarantined ?? []\n\n // New-reply toast: surface the newest reply that is (a) newer than the seen\n // watermark and (b) not already toasted this org. One at a time; the id is\n // recorded so a re-render / re-fetch never re-toasts it (capped at 50).\n useEffect(() => {\n if (!payload || toastReply || panelOpen) return\n const candidate = replies\n .filter((r) => {\n if (!r.createdAt) return false\n if (notif.lastSeenAt && r.createdAt <= notif.lastSeenAt) return false\n return !notif.toastedReplyIds.includes(r.id)\n })\n .sort((a, b) => (a.createdAt! < b.createdAt! ? 1 : -1))[0]\n if (!candidate) return\n setToastReply(candidate)\n setNotif((prev) => {\n const next = {\n ...prev,\n toastedReplyIds: [candidate.id, ...prev.toastedReplyIds].slice(0, 50),\n }\n writeNotifState(orgId, next)\n return next\n })\n }, [payload, replies, toastReply, panelOpen, notif.lastSeenAt, notif.toastedReplyIds, orgId])\n\n // Toast click: navigate to the reply's href when it carries one; otherwise\n // open the notifications panel (which also advances the seen watermark).\n const onToastActivate = useCallback(() => {\n const href = toastReply?.href\n setToastReply(null)\n if (href && typeof window !== 'undefined') {\n window.location.assign(href)\n return\n }\n setOpenToken((t) => t + 1)\n }, [toastReply])\n\n // Badge: UNREAD alerts + replies newer than the last-seen watermark. A reply\n // with no timestamp counts before the first open, then is treated as seen.\n const unreadAlertCount = alerts.filter((a) => !notif.readAlertIds.includes(a.id)).length\n const unseenReplyCount = replies.filter((r) => {\n if (!notif.lastSeenAt) return true\n if (!r.createdAt) return false\n return r.createdAt > notif.lastSeenAt\n }).length\n const badgeCount = unreadAlertCount + unseenReplyCount\n\n const isEmpty =\n alerts.length === 0 && replies.length === 0 && imports.length === 0 && quarantined.length === 0\n\n return (\n // Relative wrapper so the new-reply toast anchors to the bell trigger,\n // outside the popover panel (same pattern as the fuel low-fuel nudge).\n <div className=\"relative inline-flex\">\n <TopBarPopover\n label=\"Alerts & Notifications\"\n description=\"System alerts and recent activity for the active organization.\"\n slot=\"notifications\"\n fallbackIcon={BellGlyph}\n badge={loading ? 0 : badgeCount}\n onOpen={onOpen}\n openToken={openToken}\n onOpenChange={setPanelOpen}\n >\n <div className=\"px-4 py-3\">\n <p className=\"mb-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Notifications\n </p>\n {loading ? (\n <div className=\"flex flex-col gap-2 py-1\">\n <ValueSkeleton className=\"h-4 w-full\" />\n <ValueSkeleton className=\"h-4 w-3/4\" />\n </div>\n ) : error ? (\n <p className=\"text-sm text-[color:var(--muted)]\">\n Notifications are unavailable right now.\n </p>\n ) : isEmpty ? (\n <p className=\"py-1 text-sm text-[color:var(--muted)]\">You’re all caught up.</p>\n ) : (\n <div className=\"flex max-h-80 flex-col gap-2 overflow-y-auto\">\n {/* Alerts (with per-item read toggle) + replies — unchanged order. */}\n {alerts.length > 0 || replies.length > 0 ? (\n <ul className=\"flex flex-col gap-1\">\n {alerts.map((a) => {\n const isRead = notif.readAlertIds.includes(a.id)\n return (\n <li key={a.id} className={isRead ? 'opacity-50' : undefined}>\n <div className=\"flex items-start gap-1 rounded-lg px-2 py-2 hover:bg-[color:var(--panel)]\">\n <a\n href={a.href ?? '#'}\n onClick={() => markRead(a.id)}\n className=\"block min-w-0 flex-1\"\n >\n <p className=\"text-sm font-semibold text-[color:var(--foreground)]\">\n {a.title}\n </p>\n <p className=\"text-xs text-[color:var(--muted)]\">{a.description}</p>\n </a>\n <button\n type=\"button\"\n aria-label={isRead ? 'Mark as unread' : 'Mark as read'}\n onClick={() => (isRead ? markUnread(a.id) : markRead(a.id))}\n className=\"mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full text-[color:var(--muted)] transition hover:bg-[color:var(--panel-elevated)] hover:text-[color:var(--foreground)]\"\n >\n <CheckGlyph />\n </button>\n </div>\n </li>\n )\n })}\n {replies.map((r) => (\n <li key={r.id} className=\"rounded-lg px-2 py-2 hover:bg-[color:var(--panel)]\">\n <p className=\"text-sm font-semibold text-[color:var(--foreground)]\">{r.name}</p>\n <p className=\"truncate text-xs text-[color:var(--muted)]\">{r.preview}</p>\n </li>\n ))}\n </ul>\n ) : null}\n\n {/* Imports — running/finished contact imports. */}\n {imports.length > 0 ? (\n <div>\n <p className=\"mb-1 px-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Imports\n </p>\n <ul className=\"flex flex-col gap-1\">\n {imports.map((imp) => (\n <li key={imp.id} className=\"rounded-lg px-2 py-2 hover:bg-[color:var(--panel)]\">\n {imp.href ? (\n <a href={imp.href} className=\"block\">\n <ImportRow imp={imp} />\n </a>\n ) : (\n <ImportRow imp={imp} />\n )}\n </li>\n ))}\n </ul>\n </div>\n ) : null}\n\n {/* Quarantined contact clusters. */}\n {quarantined.length > 0 ? (\n <div>\n <div className=\"mb-1 flex items-center justify-between px-2\">\n <p className=\"text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Quarantined Contacts\n </p>\n <a\n href={withOrgParam(QUARANTINED_CONTACTS_URL, orgId)}\n className=\"text-[11px] font-semibold text-[color:var(--color-race-red)] hover:underline\"\n >\n View all\n </a>\n </div>\n <ul className=\"flex flex-col gap-1\">\n {/* Each row is a REAL link, not a div with a hover class. It\n used to carry a hover highlight on a non-interactive <li>,\n so the row advertised interactivity and then did nothing\n when clicked (reported 2026-08-03). An affordance has to\n lead somewhere: the row opens the quarantined-contacts\n view filtered to that number — the same destination as\n \"View all\", scoped. Being an <a> makes it keyboard\n focusable and Enter-activatable for free. */}\n {quarantined.map((q) => (\n <li key={q.phone}>\n <a\n href={withPhoneParam(withOrgParam(QUARANTINED_CONTACTS_URL, orgId), q.phone)}\n aria-label={`Review ${q.count} quarantined message${q.count === 1 ? '' : 's'} from ${formatPhone(q.phone)}`}\n className=\"block rounded-lg px-2 py-2 transition hover:bg-[color:var(--nav-row-hover)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--color-race-red)]\"\n >\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-sm font-semibold text-[color:var(--foreground)]\">\n {formatPhone(q.phone)}\n </span>\n {/* Same geometry as the shared TopBarCountBadge (16px\n circle, 10px/400, px-1); it sits in flow rather\n than absolutely on a 32px trigger, because this is\n a list row and not a top-bar icon. */}\n <span className=\"flex h-4 min-w-4 items-center justify-center rounded-full bg-[color:var(--panel)] px-1 text-[10px] font-normal leading-none tabular-nums text-[color:var(--muted)]\">\n {q.count > 99 ? '99+' : q.count}\n </span>\n </div>\n {q.latestAt ? (\n <p className=\"text-xs text-[color:var(--muted)]\">\n {new Date(q.latestAt).toLocaleString()}\n </p>\n ) : null}\n </a>\n </li>\n ))}\n </ul>\n </div>\n ) : null}\n </div>\n )}\n </div>\n </TopBarPopover>\n {/* Only ONE surface at this anchor at a time: the toast yields to the panel\n (both hang off the bell trigger, so rendering both means the toast sits\n on the panel's header — Reference/UI-Platform, one surface per trigger). */}\n {toastReply && !panelOpen && !anyPanelOpen ? (\n <NewReplyToast\n reply={toastReply}\n onActivate={onToastActivate}\n onClose={() => setToastReply(null)}\n />\n ) : null}\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// SupportAction — life-buoy trigger + the shared support-request modal\n// (never a mailto:, never an app-local form — Reference/UI-Platform).\n// ---------------------------------------------------------------------------\n\n/**\n * Compose the delivered support message: the user's note, then a context block\n * carrying the page, URL and active org — plus a Reply-to line when the user\n * had to supply contact details the profile was missing. The upstream contract\n * stays `POST support { message }`; this just enriches the text (VRM parity).\n */\nfunction composeSupportMessage(input: {\n note: string\n pageTitle: string\n url: string\n orgName?: string | null\n replyEmail?: string\n replyPhone?: string\n}): string {\n const ctx = [`Page: ${input.pageTitle || 'Unknown'}`, `URL: ${input.url}`]\n if (input.orgName) ctx.push(`Org: ${input.orgName}`)\n const reply = [input.replyEmail?.trim(), input.replyPhone?.trim()].filter(Boolean).join(' / ')\n if (reply) ctx.push(`Reply-to: ${reply}`)\n return `${input.note.trim()}\\n\\n---\\n${ctx.join('\\n')}`\n}\n\nexport function SupportAction({ orgId }: { orgId?: string | null } = {}) {\n const { fetchJson } = useNavChrome('SupportAction')\n const { me, loaded } = useChromeMe()\n const { orgs } = useChromeOrgs()\n const [open, setOpen] = useState(false)\n const [message, setMessage] = useState('')\n const [email, setEmail] = useState('')\n const [phone, setPhone] = useState('')\n const [showEmailError, setShowEmailError] = useState(false)\n const [state, setState] = useState<'idle' | 'sending' | 'sent' | 'error'>('idle')\n\n // The profile knows email/phone unless the chrome `me` loaded without them —\n // then we collect the missing one(s) in the modal (email required, phone not).\n const meEmail = me?.email ?? null\n const mePhone = me?.phone ?? null\n const missingEmail = loaded && !meEmail\n const missingPhone = loaded && !mePhone\n\n const activeOrg =\n (orgId ? orgs?.find((o) => o.id === orgId) : null) ??\n (orgs && orgs.length === 1 ? orgs[0] : null)\n const orgName = activeOrg?.name ?? null\n\n const close = useCallback(() => {\n setOpen(false)\n setState('idle')\n setMessage('')\n setShowEmailError(false)\n }, [])\n\n // Seed the contact inputs from the profile whenever the modal opens.\n useEffect(() => {\n if (!open) return\n setEmail(meEmail ?? '')\n setPhone(mePhone ?? '')\n setShowEmailError(false)\n }, [open, meEmail, mePhone])\n\n useEffect(() => {\n if (!open) return\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') close()\n }\n document.addEventListener('keydown', onKey)\n return () => document.removeEventListener('keydown', onKey)\n }, [open, close])\n\n const submit = async () => {\n if (!message.trim() || state === 'sending') return\n\n const resolvedEmail = (missingEmail ? email : meEmail ?? '').trim()\n const resolvedPhone = (missingPhone ? phone : mePhone ?? '').trim()\n // Email is required when the profile didn't carry one.\n if (missingEmail && !resolvedEmail) {\n setShowEmailError(true)\n return\n }\n setShowEmailError(false)\n\n const collectedContact = missingEmail || missingPhone\n const fullMessage = composeSupportMessage({\n note: message,\n pageTitle: typeof document !== 'undefined' ? document.title : '',\n url: typeof window !== 'undefined' ? window.location.href : '',\n orgName,\n replyEmail: collectedContact ? resolvedEmail : undefined,\n replyPhone: collectedContact ? resolvedPhone : undefined,\n })\n\n setState('sending')\n try {\n await fetchJson('support', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ message: fullMessage }),\n })\n setState('sent')\n } catch {\n setState('error')\n }\n }\n\n return (\n <>\n <button\n type=\"button\"\n aria-label=\"Support\"\n className={topBarIconButtonClass()}\n onClick={() => setOpen(true)}\n >\n <SlotGlyph slot=\"support\" fallback={LifeBuoyGlyph} />\n <TopBarTooltip\n title=\"Support\"\n description=\"Send a support request to the Politogy team.\"\n />\n </button>\n {open && typeof document !== 'undefined'\n ? createPortal(\n <div\n // Portaled to <body>: the top bar's backdrop-blur creates a CSS\n // containing block, so a fixed-position descendant would center on\n // the HEADER (rendering off-screen) instead of the viewport.\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Support request\"\n onMouseDown={(e) => {\n if (e.target === e.currentTarget) close()\n }}\n >\n <div className=\"w-full max-w-md rounded-2xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] p-6 shadow-[var(--shadow-soft)]\">\n <h2 className=\"text-lg font-bold tracking-[-0.01em] text-[color:var(--foreground)]\">\n Contact Support\n </h2>\n {state === 'sent' ? (\n <>\n <p className=\"mt-3 text-sm text-[color:var(--muted)]\">\n Your request was sent. The team will reply by email.\n </p>\n <div className=\"mt-5 flex justify-end\">\n <button\n type=\"button\"\n onClick={close}\n className=\"rounded-full bg-[color:var(--color-race-red)] px-4 py-2 text-sm font-semibold text-white hover:opacity-90\"\n >\n Done\n </button>\n </div>\n </>\n ) : (\n <>\n <p className=\"mt-1 text-sm text-[color:var(--muted)]\">\n Describe the problem or question. Your account details ride along\n automatically.\n </p>\n {missingEmail ? (\n <label className=\"mt-4 block\">\n <span className=\"mb-1 block text-xs font-semibold text-[color:var(--foreground)]\">\n Your email\n </span>\n <input\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n placeholder=\"you@example.com\"\n className=\"w-full rounded-lg border border-[color:var(--line)] bg-[color:var(--panel)] px-3 py-2 text-sm text-[color:var(--foreground)] placeholder:text-[color:var(--muted)] focus:outline-none focus:ring-2 focus:ring-[color:var(--color-race-red)]\"\n />\n {showEmailError ? (\n <span className=\"mt-1 block text-xs text-[color:var(--color-race-red)]\">\n Enter an email so support can reply.\n </span>\n ) : null}\n </label>\n ) : null}\n {missingPhone ? (\n <label className=\"mt-3 block\">\n <span className=\"mb-1 block text-xs font-semibold text-[color:var(--foreground)]\">\n Your phone — optional\n </span>\n <input\n type=\"tel\"\n value={phone}\n onChange={(e) => setPhone(e.target.value)}\n placeholder=\"(503) 555-1212\"\n className=\"w-full rounded-lg border border-[color:var(--line)] bg-[color:var(--panel)] px-3 py-2 text-sm text-[color:var(--foreground)] placeholder:text-[color:var(--muted)] focus:outline-none focus:ring-2 focus:ring-[color:var(--color-race-red)]\"\n />\n </label>\n ) : null}\n <textarea\n value={message}\n onChange={(e) => setMessage(e.target.value)}\n rows={5}\n placeholder=\"How can we help?\"\n className=\"mt-4 w-full resize-y rounded-lg border border-[color:var(--line)] bg-[color:var(--panel)] px-3 py-2 text-sm text-[color:var(--foreground)] placeholder:text-[color:var(--muted)] focus:outline-none focus:ring-2 focus:ring-[color:var(--color-race-red)]\"\n />\n {state === 'error' ? (\n <p className=\"mt-2 text-sm text-[color:var(--color-race-red)]\">\n Sending failed — try again.\n </p>\n ) : null}\n <div className=\"mt-4 flex justify-end gap-2\">\n <button\n type=\"button\"\n onClick={close}\n className=\"rounded-full border border-[color:var(--line)] px-4 py-2 text-sm font-semibold text-[color:var(--foreground)] hover:bg-[color:var(--panel)]\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={submit}\n disabled={!message.trim() || state === 'sending'}\n className=\"rounded-full bg-[color:var(--color-race-red)] px-4 py-2 text-sm font-semibold text-white transition hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {state === 'sending' ? 'Sending…' : 'Send request'}\n </button>\n </div>\n </>\n )}\n </div>\n </div>,\n document.body,\n )\n : null}\n </>\n )\n}\n\n// ---------------------------------------------------------------------------\n// NavDisplayAction — the Menu / Tabs / Both navigation-display switcher.\n// Controlled: the app owns persistence (localStorage/profile) and layout\n// consequences (sub-menu visibility, tab strip visibility).\n// ---------------------------------------------------------------------------\n\nexport type NavDisplayMode = 'menu' | 'tabs' | 'both'\n\nconst NAV_DISPLAY_OPTIONS: { value: NavDisplayMode; label: string }[] = [\n { value: 'menu', label: 'Sub Menu' },\n { value: 'tabs', label: 'Tabs Only' },\n { value: 'both', label: 'Both' },\n]\n\nexport function NavDisplayAction({\n value,\n onChange,\n}: {\n value: NavDisplayMode\n onChange: (next: NavDisplayMode) => void\n}) {\n return (\n <TopBarPopover\n label=\"Navigation Display\"\n description=\"Show navigation as a sub-menu, tabs, or both.\"\n fallbackIcon={LayoutGlyph}\n panelClassName=\"w-44\"\n >\n <div className=\"py-1\" role=\"radiogroup\" aria-label=\"Navigation display\">\n {NAV_DISPLAY_OPTIONS.map((opt) => (\n <button\n key={opt.value}\n type=\"button\"\n role=\"radio\"\n aria-checked={value === opt.value}\n onClick={() => onChange(opt.value)}\n className={[\n 'flex w-full items-center justify-between px-4 py-2 text-left text-sm font-medium',\n value === opt.value\n ? 'text-[color:var(--color-race-red)]'\n : 'text-[color:var(--foreground)] hover:bg-[color:var(--panel)]',\n ].join(' ')}\n >\n {opt.label}\n {value === opt.value ? <span aria-hidden>✓</span> : null}\n </button>\n ))}\n </div>\n </TopBarPopover>\n )\n}\n\n// ---------------------------------------------------------------------------\n// useThemePreference — the cross-app theme state machine (Task: theme derived\n// from the Auth system, live across tabs and apps).\n//\n// boot : cookie → localStorage → \"system\" (the pre-paint script already\n// painted this), then ONCE per session reconcile against the\n// profile value from `GET me` (authoritative) when a fetcher is\n// available.\n// change : apply + localStorage + cross-subdomain cookie + best-effort\n// `PATCH me/preferences { themePreference }`.\n// sync : same-app tabs via the `storage` event; other-app tabs re-read the\n// shared cookie on focus/visibility; `system` follows live OS\n// changes via matchMedia.\n// ---------------------------------------------------------------------------\n\nexport function useThemePreference(): {\n value: ThemePreference\n setValue: (next: ThemePreference) => void\n} {\n const ctx = useContext(NavChromeContext)\n const fetchJson = ctx?.fetchJson ?? null\n const [value, setValueState] = useState<ThemePreference>('system')\n const reconciled = useRef(false)\n\n // Boot: cookie → localStorage → system.\n useEffect(() => {\n const cookie = readThemeCookie()\n let ls: string | null = null\n try {\n ls = localStorage.getItem(THEME_STORAGE_KEY)\n } catch {\n /* unavailable */\n }\n const pref = cookie ?? (isThemePreference(ls) ? ls : null) ?? 'system'\n setValueState(pref)\n applyThemePreference(pref)\n }, [])\n\n // Once per session: converge on the profile's saved choice (authoritative),\n // reusing the provider's single `me` fetch.\n const meCtx = useContext(NavChromeContext)\n useEffect(() => {\n if (reconciled.current) return\n // A choice made where no chrome-API session exists (Politogy ID's login\n // screen) is still only in the cookie. Push it UP rather than pulling the\n // stale profile value DOWN — otherwise the user's fresh pick is silently\n // reverted on the next app they open (HITL 2026-07-23: \"I set System and it\n // keeps switching back to Light\").\n const pending = readPendingThemeChoice()\n if (pending) {\n // Only latch once the profile write has actually been attempted, so a\n // later `me` arrival still gets a chance to persist it.\n if (meCtx?.me) reconciled.current = true\n setValueState(pending)\n applyThemePreference(pending)\n writeThemeCookie(pending)\n try {\n localStorage.setItem(THEME_STORAGE_KEY, pending)\n } catch {\n /* unavailable */\n }\n if (!meCtx?.me) return\n fetchJson?.('me/preferences', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ themePreference: pending }),\n })\n .then(() => clearPendingThemeChoice())\n .catch(() => {})\n return\n }\n const pref = meCtx?.me?.themePreference\n if (isThemePreference(pref)) {\n reconciled.current = true\n setValueState(pref)\n applyThemePreference(pref)\n writeThemeCookie(pref)\n try {\n localStorage.setItem(THEME_STORAGE_KEY, pref)\n } catch {\n /* unavailable */\n }\n }\n }, [meCtx?.me])\n\n // Live sync: storage events (same-app tabs), focus/visibility cookie\n // re-reads (other-app tabs), and OS changes while on \"system\".\n useEffect(() => {\n const onStorage = (e: StorageEvent) => {\n if (e.key === THEME_STORAGE_KEY && isThemePreference(e.newValue)) {\n setValueState(e.newValue)\n applyThemePreference(e.newValue)\n }\n }\n const onWake = () => {\n const cookie = readThemeCookie()\n if (cookie) {\n setValueState((prev) => {\n if (cookie !== prev) applyThemePreference(cookie)\n return cookie\n })\n }\n }\n window.addEventListener('storage', onStorage)\n window.addEventListener('focus', onWake)\n document.addEventListener('visibilitychange', onWake)\n return () => {\n window.removeEventListener('storage', onStorage)\n window.removeEventListener('focus', onWake)\n document.removeEventListener('visibilitychange', onWake)\n }\n }, [])\n\n // Follow the OS while set to \"system\".\n useEffect(() => {\n if (value !== 'system') return\n let mq: MediaQueryList\n try {\n mq = window.matchMedia('(prefers-color-scheme: dark)')\n } catch {\n return\n }\n const onChange = () => applyThemePreference('system')\n mq.addEventListener('change', onChange)\n return () => mq.removeEventListener('change', onChange)\n }, [value])\n\n const setValue = useCallback(\n (next: ThemePreference) => {\n setValueState(next)\n applyThemePreference(next)\n writeThemeCookie(next)\n try {\n localStorage.setItem(THEME_STORAGE_KEY, next)\n } catch {\n /* unavailable */\n }\n // Best-effort profile persistence — a theme toggle never errors. Until it\n // lands, the choice stays marked pending so the next app pushes it up\n // instead of reconciling the stale profile value back down.\n markThemeChoicePending(next)\n fetchJson?.('me/preferences', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ themePreference: next }),\n })\n .then(() => clearPendingThemeChoice())\n .catch(() => {})\n },\n [fetchJson],\n )\n\n return { value, setValue }\n}\n","import type { NavIcon, NavItem } from './index'\n\n// ---------------------------------------------------------------------------\n// standardPolitogyNav — the canonical Politogy VRM menu, per operating Mode.\n//\n// This is the single source of truth for the navigation every politogy app\n// renders. The RELATIONSHIP tree is extracted verbatim from VRM core's\n// relationship-mode sidebar (`getRelationshipLinkItems`); the CAMPAIGN and\n// PETITION trees mirror VRM core's mode-scoped menus. Apps consume the same\n// menu everywhere; an app that owns one of the items (e.g. the standalone\n// Contacts app) nests its own pages as that item's children while every other\n// entry links out to another *.politogyvrm.com app as an absolute URL —\n// full-page navigation with SSO shared across the domain.\n//\n// Which tree an app renders is NOT the user's live mode selection — it is the\n// app's own mode, mapped from the app registry (see `POLITOGY_APPS[app].mode`).\n// A campaign-scoped app (a2p / phonebank / canvass / signs) always renders the\n// Campaign tree; an unscoped app (forms / surveys / polls / contacts) always\n// renders Relationship, exactly as before. Switching modes is a full-page\n// navigation between mode homes (the Mode pill's job), and each destination is\n// itself pinned — so the tree is deterministic from app identity, never a\n// value an app has to pass.\n// ---------------------------------------------------------------------------\n\n/**\n * Icon slots used by the standard menus. The shell stays icon-library-agnostic:\n * callers map each key to their own icon components (lucide, react-icons, …).\n * A missing key simply renders that row without an icon.\n */\nexport type StandardNavIconKey =\n | 'home'\n | 'users'\n | 'mail'\n | 'messageSquare'\n | 'layout'\n | 'activity'\n | 'lifeBuoy'\n | 'grid'\n | 'list'\n | 'upload'\n | 'edit'\n | 'fileText'\n | 'send'\n | 'clock'\n | 'user'\n | 'barChart'\n | 'briefcase'\n | 'settings'\n | 'creditCard'\n | 'dollarSign'\n | 'share'\n // Campaign / Petition mode slots.\n | 'phone'\n | 'map'\n | 'mapPin'\n | 'target'\n | 'flag'\n\n/** The operating Mode whose nav tree to build. Defaults to `relationship`. */\nexport type StandardNavMode = 'relationship' | 'campaign' | 'petition'\n\n/**\n * Per-feature availability for the Campaign tree. Campaign Mode ships its apps\n * incrementally: a disabled feature is omitted from the nav entirely (rather\n * than rendered as a dead/disabled row), and its flag flips to `true` in a\n * later patch release as the app goes live. Dashboard and Voter Contact are\n * core-hosted and always present, so they carry no flag.\n */\nexport interface CampaignFeatureAvailability {\n a2p: boolean\n phonebank: boolean\n canvass: boolean\n signs: boolean\n tribes: boolean\n polling: boolean\n}\n\n/**\n * Launch state at this shell version: every Campaign feature is deployed and\n * live (a2p / phonebank / canvass / signs .politogyvrm.com all serve the app\n * behind SSO as of 2026-07-24), so no row is hidden. The flags remain so a\n * future feature can ship dark, and so a caller can hide one per-deployment.\n */\nexport const CAMPAIGN_FEATURE_AVAILABILITY: CampaignFeatureAvailability = {\n a2p: true,\n phonebank: true,\n canvass: true,\n signs: true,\n tribes: true,\n polling: true,\n}\n\n/** Absolute origins for the standalone Campaign / Petition apps. */\nconst A2P_ORIGIN = 'https://a2p.politogyvrm.com/'\nconst PHONEBANK_ORIGIN = 'https://phonebank.politogyvrm.com/'\nconst CANVASS_ORIGIN = 'https://canvass.politogyvrm.com/'\nconst SIGNS_ORIGIN = 'https://signs.politogyvrm.com/'\nconst POLLS_ORIGIN = 'https://polls.politogyvrm.com/'\n// Tribes is a page inside the standalone Contacts app (Specs/Tribes: Tribes is\n// implemented as an extension of Contacts). Matches app-shell.tsx's `/tribes`.\nconst CONTACTS_TRIBES = 'https://contacts.politogyvrm.com/tribes'\n// Petition Mode is its own standalone app on its own subdomain (the petitions\n// repo deploys production to petition-mode.politogyvrm.com).\nconst PETITION_MODE_ORIGIN = 'https://petition-mode.politogyvrm.com/'\n\nexport interface StandardNavOptions {\n /** VRM core origin, e.g. \"https://app.politogyvrm.com\". Trailing slash OK. */\n coreBaseUrl: string\n /** Icon component per slot; omitted slots render icon-less rows. */\n icons?: Partial<Record<StandardNavIconKey, NavIcon>>\n /**\n * App-local override for the \"Contacts\" item. `children` are used verbatim\n * (NOT absolutized) so the owning app nests its own routes; `href` (also\n * verbatim) feeds active-detection for the group header. When omitted, the\n * item carries VRM core's own contacts sub-pages as absolute links.\n * (Relationship tree only.)\n */\n contactsItem?: { href?: string; children?: NavItem[] }\n /**\n * The trailing \"Support\" row. VRM core opens its SupportRequestModal here;\n * other apps supply their own handler (`onClick`) or a link (`href`).\n * Omitted or `false` → no Support row. Appended to every mode's tree.\n */\n supportItem?: { onClick?: () => void; href?: string } | false\n /**\n * Which mode's tree to build. Default `relationship`, whose output is\n * byte-for-byte what this function produced before modes existed.\n */\n mode?: StandardNavMode\n /**\n * Active organization id (full UUID). EVERY link in EVERY tree carries it as\n * `?org=<uuid>` — the same convention the Mode switcher and My Account menu\n * use — so the destination app opens on the same org instead of the user's\n * default one. Omit it only when the caller genuinely has no active org yet.\n */\n activeOrgId?: string | null\n /**\n * Per-feature Campaign availability overrides, merged over\n * `CAMPAIGN_FEATURE_AVAILABILITY`. Only meaningful for the Campaign tree.\n */\n campaignAvailability?: Partial<CampaignFeatureAvailability>\n}\n\n/** Core-relative route + icon slot for one standard entry. */\ntype CoreLeaf = { label: string; icon: StandardNavIconKey; path: string }\n\n/**\n * One sub-item of a standalone app, as a path RELATIVE to that app's origin\n * (`''` is the app root). Resolved against the origin and given the active-org\n * query param, exactly like the parent row it hangs under.\n */\ntype CrossAppLeaf = { label: string; icon: StandardNavIconKey; path: string }\n\nconst CONTACTS_DEFAULT_CHILDREN: CoreLeaf[] = [\n { label: 'Dashboard', icon: 'grid', path: '/relationship/contacts/dashboard' },\n { label: 'All Contacts', icon: 'list', path: '/relationship/contacts/all' },\n { label: 'Tribes', icon: 'users', path: '/relationship/contacts/groups' },\n { label: 'Import', icon: 'upload', path: '/relationship/contacts/import' },\n { label: 'Import History', icon: 'fileText', path: '/relationship/contacts/import-history' },\n { label: 'Merge Rules', icon: 'layout', path: '/relationship/contacts/merge-rules' },\n]\n\nconst EMAIL_CHILDREN: CoreLeaf[] = [\n { label: 'Dashboard', icon: 'grid', path: '/relationship/email/dashboard' },\n { label: 'Create & Edit', icon: 'edit', path: '/relationship/email/create-and-edit' },\n { label: 'Sender Information', icon: 'mail', path: '/relationship/email/inbox' },\n { label: 'Recipients', icon: 'user', path: '/relationship/email/send-to' },\n { label: 'Send & Automate', icon: 'clock', path: '/relationship/email/send-and-automate' },\n { label: 'Statistics', icon: 'barChart', path: '/relationship/email/statistics' },\n]\n\nconst SMS_CHILDREN: CoreLeaf[] = [\n { label: 'Dashboard', icon: 'grid', path: '/relationship/sms-mms-blast/dashboard' },\n { label: 'Compose & Send', icon: 'send', path: '/relationship/sms-mms-blast/compose-and-send' },\n { label: 'Conversations', icon: 'messageSquare', path: '/relationship/sms-mms-blast/conversations' },\n]\n\nconst CTA_CHILDREN: CoreLeaf[] = [\n { label: 'Dashboard', icon: 'grid', path: '/relationship/cta-database/dashboard' },\n { label: 'Create & Edit', icon: 'edit', path: '/relationship/cta-creator/create-and-edit' },\n { label: 'Submissions', icon: 'fileText', path: '/relationship/cta-submissions/submissions' },\n]\n\n// Organization Settings — promoted from the My Account menu into the left nav\n// (HITL directive 2026-07-23). Mirrors the main app's page IA exactly:\n// /organization-settings/:tab, with Subscription & Billing carrying its own\n// third level (/organization-settings/subscription-billing/:tab). This is the\n// canonical depth-3 example the nav renderers support.\ntype CoreBranch = CoreLeaf & { children?: CoreLeaf[] }\n\nconst ORG_SETTINGS_CHILDREN: CoreBranch[] = [\n { label: 'General', icon: 'settings', path: '/organization-settings' },\n {\n label: 'Subscription & Billing',\n icon: 'creditCard',\n path: '/organization-settings/subscription-billing',\n children: [\n { label: 'Current Plan', icon: 'fileText', path: '/organization-settings/subscription-billing/current-plan' },\n { label: 'SMS, MMS & Email Usage', icon: 'activity', path: '/organization-settings/subscription-billing/text-email' },\n { label: 'Wallet', icon: 'dollarSign', path: '/organization-settings/subscription-billing/wallet' },\n { label: '10DLC', icon: 'messageSquare', path: '/organization-settings/subscription-billing/10dlc' },\n { label: 'Billing History', icon: 'clock', path: '/organization-settings/subscription-billing/billing-history' },\n ],\n },\n { label: 'Email', icon: 'mail', path: '/organization-settings/email-settings' },\n { label: 'Users', icon: 'users', path: '/organization-settings/users' },\n { label: 'Shared Links', icon: 'share', path: '/organization-settings/shared-links' },\n]\n\n// The NEW standalone acquisition apps (forms./surveys./polls.politogyvrm.com)\n// replace the legacy in-core \"Forms & Surveys\" system (HITL directive\n// 2026-07-23; removal plan: politogy/docs/legacy-forms-removal-plan.md).\n// Absolute cross-app links — SSO carries the session.\nconst APP_FORMS_CHILDREN = [\n { label: 'Forms', icon: 'list' as const, href: 'https://forms.politogyvrm.com/?tab=forms' },\n { label: 'Canvas', icon: 'edit' as const, href: 'https://forms.politogyvrm.com/?tab=canvas' },\n { label: 'Submissions', icon: 'fileText' as const, href: 'https://forms.politogyvrm.com/?tab=submissions' },\n]\n// The Surveys sub-menu mirrors the app's tab strip: Surveys / Canvas / Results.\n// Canvas and Results are survey-scoped routes (/surveys/:id/canvas), so with no\n// survey selected the list page carries a ?view= param — distinct hrefs, so\n// active-detection singles out exactly one (identical hrefs were the earlier\n// all-active bug; query params ARE compared, hashes are not).\nconst APP_SURVEYS_CHILDREN = [\n { label: 'Surveys', icon: 'list' as const, href: 'https://surveys.politogyvrm.com/surveys' },\n { label: 'Canvas', icon: 'edit' as const, href: 'https://surveys.politogyvrm.com/surveys?view=canvas' },\n { label: 'Results', icon: 'barChart' as const, href: 'https://surveys.politogyvrm.com/surveys?view=results' },\n]\nconst APP_POLLS_CHILDREN = [\n { label: 'Command Center', icon: 'grid' as const, href: 'https://polls.politogyvrm.com/' },\n { label: 'New Poll', icon: 'edit' as const, href: 'https://polls.politogyvrm.com/polls/new' },\n]\n\n// ---------------------------------------------------------------------------\n// Campaign app sub-navigation.\n//\n// Reference/UI-Platform v13 (Left bar → Navigation): \"The canonical VRM nav\n// tree — PARENT GROUPS WITH SUB-ITEMS. The app's own pages nest under their\n// group.\" The Campaign tree shipped as eight flat rows with no `children`, so\n// the Navigation Display control's \"Both\" and \"Sub Menu\" modes had nothing to\n// expand in the left bar of a2p / phonebank / canvass / signs — the three modes\n// rendered an identical sidebar and the control looked broken.\n//\n// Each list below is the app's OWN section list, taken verbatim from that app's\n// in-app tab strip (its `components/Shell.tsx`), so the sidebar sub-menu and the\n// page tab strip name the same sections in the same order — the sidebar/tab\n// agreement Reference/UI-Platform exists to enforce.\n// ---------------------------------------------------------------------------\n\n/** a2p/components/Shell.tsx `TABS` — the six A2P tabs. */\nconst APP_A2P_CHILDREN: CrossAppLeaf[] = [\n { label: 'Dashboard', icon: 'grid', path: 'dashboard' },\n { label: 'Compose', icon: 'edit', path: 'compose' },\n { label: 'Recipients', icon: 'user', path: 'recipients' },\n { label: 'Tech Check', icon: 'activity', path: 'tech-check' },\n { label: 'Status', icon: 'clock', path: 'status' },\n { label: 'Conversations', icon: 'messageSquare', path: 'conversations' },\n]\n\n/** phonebank/components/Shell.tsx `NAV` — the Manager console's sections. */\nconst APP_PHONEBANK_CHILDREN: CrossAppLeaf[] = [\n { label: 'Dashboard', icon: 'grid', path: '' },\n { label: 'Campaigns', icon: 'phone', path: 'campaigns' },\n { label: 'Inbound', icon: 'messageSquare', path: 'inbound' },\n { label: 'Reports', icon: 'barChart', path: 'reports' },\n]\n\n/** canvass/components/Shell.tsx `SECTIONS` — the manager console's sections. */\nconst APP_CANVASS_CHILDREN: CrossAppLeaf[] = [\n { label: 'Dashboard', icon: 'grid', path: '' },\n { label: 'Campaigns', icon: 'target', path: 'campaigns' },\n { label: 'Canvassers', icon: 'users', path: 'canvassers' },\n]\n\n/**\n * signs/components/Shell.tsx `SECTIONS`. Review Queue is Manager+ in the app's\n * tab strip; the shared tree carries no role input, so the row is listed for\n * everyone and the ROUTE enforces it — /review renders a \"available to Managers\n * and Admins\" notice and loads no queue data for a volunteer (signs\n * app/review/page.tsx). Listing it keeps sidebar and tab strip identical for the\n * managers who use it rather than re-opening per-app nav drift.\n */\nconst APP_SIGNS_CHILDREN: CrossAppLeaf[] = [\n { label: 'Map', icon: 'map', path: '' },\n { label: 'Placements', icon: 'list', path: 'placements' },\n { label: 'Review Queue', icon: 'fileText', path: 'review' },\n { label: 'Recovery', icon: 'flag', path: 'recovery' },\n { label: 'Reports', icon: 'barChart', path: 'reports' },\n]\n\n/**\n * Build the standard Politogy VRM menu for the given `mode` (default\n * `relationship`), in the exact order and wording the main app renders it. See\n * `StandardNavOptions` for the app-specific hooks (`contactsItem`,\n * `supportItem`) and the Campaign inputs (`activeOrgId`, `campaignAvailability`).\n */\nexport function standardPolitogyNav(opts: StandardNavOptions): NavItem[] {\n const base = opts.coreBaseUrl.replace(/\\/+$/, '')\n const abs = (path: string): string => `${base}${path.startsWith('/') ? path : `/${path}`}`\n const icon = (key: StandardNavIconKey): NavIcon | undefined => opts.icons?.[key]\n\n // EVERY link this tree emits leaves the current app (core routes are\n // cross-app for a standalone app, and the app-owned rows are supplied by the\n // caller), so each one carries the active org as `?org=<full-uuid>` — the\n // full id is the only collision-free selector (contacts-api matches exact id\n // first, then a short suffix that can collide across a user's orgs). Without\n // it a multi-org user following a bare cross-app link lands in whatever org\n // the destination defaults to; the cookie is only the fallback for a bare\n // URL, the param is the explicit selector. Active-detection ignores `org`\n // (isNavItemActive's ACTIVE_IGNORED_PARAMS) so stamping it selects nothing\n // differently, and it keeps the org in the address bar for bookmarking.\n const orgParam = opts.activeOrgId ? `org=${opts.activeOrgId}` : ''\n const withOrg = (url: string): string =>\n orgParam ? `${url}${url.includes('?') ? '&' : '?'}${orgParam}` : url\n\n const leaves = (children: CoreLeaf[]): NavItem[] =>\n children.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(abs(c.path)) }))\n const branches = (children: CoreBranch[]): NavItem[] =>\n children.map((c) => ({\n label: c.label,\n icon: icon(c.icon),\n href: withOrg(abs(c.path)),\n children: c.children ? leaves(c.children) : undefined,\n }))\n\n const buildRelationship = (): NavItem[] => {\n const contacts: NavItem = opts.contactsItem\n ? {\n label: 'Contacts',\n icon: icon('users'),\n href: opts.contactsItem.href,\n children: opts.contactsItem.children,\n }\n : {\n label: 'Contacts',\n icon: icon('users'),\n href: withOrg(abs('/relationship/contacts/dashboard')),\n children: leaves(CONTACTS_DEFAULT_CHILDREN),\n }\n\n return [\n { label: 'Dashboard', icon: icon('home'), href: withOrg(abs('/relationship/dashboard')) },\n contacts,\n {\n label: 'Email Broadcast',\n icon: icon('mail'),\n href: withOrg(abs('/relationship/email/dashboard')),\n children: leaves(EMAIL_CHILDREN),\n },\n {\n label: 'SMS/MMS Blast',\n icon: icon('messageSquare'),\n href: withOrg(abs('/relationship/sms-mms-blast/dashboard')),\n children: leaves(SMS_CHILDREN),\n },\n // These two carry no top-level href in VRM core (parent row only toggles).\n { label: 'Calls to Action', icon: icon('layout'), children: leaves(CTA_CHILDREN) },\n {\n label: 'Forms',\n icon: icon('activity'),\n href: withOrg('https://forms.politogyvrm.com/'),\n children: APP_FORMS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) })),\n },\n {\n label: 'Surveys',\n icon: icon('fileText'),\n href: withOrg('https://surveys.politogyvrm.com/surveys'),\n children: APP_SURVEYS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) })),\n },\n {\n label: 'Polls',\n icon: icon('barChart'),\n href: withOrg('https://polls.politogyvrm.com/'),\n children: APP_POLLS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) })),\n },\n {\n label: 'Organization Settings',\n icon: icon('briefcase'),\n href: withOrg(abs('/organization-settings')),\n children: branches(ORG_SETTINGS_CHILDREN),\n },\n ]\n }\n\n // Campaign tree — Dashboard + the 7 Campaign Mode features. Dashboard and\n // Voter Contact are core-hosted (VRM core /campaign/*); the rest link out to\n // standalone apps and are gated by CAMPAIGN_FEATURE_AVAILABILITY.\n const buildCampaign = (): NavItem[] => {\n const avail: CampaignFeatureAvailability = {\n ...CAMPAIGN_FEATURE_AVAILABILITY,\n ...opts.campaignAvailability,\n }\n // Sub-items of a standalone app: `origin` + the app-relative path, carrying\n // the active org the way the parent row does. Trailing slash on the origin\n // is normalized so `''` yields the app root and `x` yields `/x`.\n const appLeaves = (origin: string, children: CrossAppLeaf[]): NavItem[] => {\n const base = origin.replace(/\\/+$/, '')\n return children.map((c) => ({\n label: c.label,\n icon: icon(c.icon),\n href: withOrg(c.path ? `${base}/${c.path}` : `${base}/`),\n }))\n }\n type Gated = NavItem & { flag?: keyof CampaignFeatureAvailability }\n const rows: Gated[] = [\n { label: 'Dashboard', icon: icon('home'), href: withOrg(abs('/campaign/dashboard')) },\n { label: 'Voter Contact', icon: icon('target'), href: withOrg(abs('/campaign/campaigns')) },\n {\n label: 'A2P',\n icon: icon('messageSquare'),\n href: withOrg(A2P_ORIGIN),\n children: appLeaves(A2P_ORIGIN, APP_A2P_CHILDREN),\n flag: 'a2p',\n },\n {\n label: 'Phone Banking',\n icon: icon('phone'),\n href: withOrg(PHONEBANK_ORIGIN),\n children: appLeaves(PHONEBANK_ORIGIN, APP_PHONEBANK_CHILDREN),\n flag: 'phonebank',\n },\n {\n label: 'Field Canvassing',\n icon: icon('map'),\n href: withOrg(CANVASS_ORIGIN),\n children: appLeaves(CANVASS_ORIGIN, APP_CANVASS_CHILDREN),\n flag: 'canvass',\n },\n {\n label: 'Sign Mapping',\n icon: icon('mapPin'),\n href: withOrg(SIGNS_ORIGIN),\n children: appLeaves(SIGNS_ORIGIN, APP_SIGNS_CHILDREN),\n flag: 'signs',\n },\n { label: 'Tribes', icon: icon('users'), href: withOrg(CONTACTS_TRIBES), flag: 'tribes' },\n { label: 'Polling Engine', icon: icon('barChart'), href: withOrg(POLLS_ORIGIN), flag: 'polling' },\n ]\n return rows\n .filter((r) => !r.flag || avail[r.flag])\n .map(({ flag: _flag, ...item }) => item)\n }\n\n // Petition tree — minimal: the Petition Mode home (its own standalone app).\n // Labeled Dashboard so the shared breadcrumb trail anchors correctly.\n const buildPetition = (): NavItem[] => [\n { label: 'Dashboard', icon: icon('home'), href: withOrg(PETITION_MODE_ORIGIN) },\n ]\n\n const mode = opts.mode ?? 'relationship'\n const items =\n mode === 'campaign'\n ? buildCampaign()\n : mode === 'petition'\n ? buildPetition()\n : buildRelationship()\n\n if (opts.supportItem) {\n items.push({\n label: 'Support',\n icon: icon('lifeBuoy'),\n href: opts.supportItem.href,\n onClick: opts.supportItem.onClick,\n })\n }\n\n return items\n}\n","// ---------------------------------------------------------------------------\n// Framework-agnostic chrome (sidebar + top navbar) for @the-portland-company/shell.\n//\n// The other chrome in this package (ShellChrome, Sidebar, Header, …) is built\n// on Chakra UI v2 + react-router and targets Vite SPAs. That stack cannot be\n// imported into a Next.js / React 19 / Tailwind app. This \"native\" module is a\n// dependency-light alternative: pure React (no Chakra, no emotion, no\n// react-router, no icon library) whose styling is driven entirely by the CSS\n// design tokens shipped in `@the-portland-company/shell/chrome.css`.\n//\n// It is a FAITHFUL VISUAL TWIN of the Chakra chrome (Sidebar.tsx / Header.tsx /\n// OrgPill / ModePill / NavItem / UserMenu): same 240px sidebar, brand-logo\n// slot, \"ORGANIZATION\" org pill, mode pill, solid active nav rows, pipe-\n// separated footer links + commit string, and an avatar+name+email+chevron user\n// menu — so an app rendering this looks identical to the main VRM app.\n//\n// Every app concern (nav items, org, mode, user, links, icons, the routing\n// Link component, the theme toggle) is injected via props, so both the Contacts\n// app (Next.js) and the VRM app could consume the same components.\n// ---------------------------------------------------------------------------\n\nimport type { ComponentType, CSSProperties, ReactNode } from 'react'\nimport { useEffect, useMemo, useState } from 'react'\nimport { useTopBarIconSlotGlyph, type TopBarIconSlot } from '../lib/topbarIconSlot'\nimport { resolveBrandGlyph } from '../lib/brandGlyphs'\nimport { topBarIconButtonClass, TopBarTooltip, TopBarPanelArrow, NavThemeControl, resolveOrgLogoUrl, type ThemePreference } from './chromeActions'\n\n// Data-backed top-bar widgets (Fuel, Notifications, Support, Nav-display) +\n// the injected-fetcher provider they hang off. One implementation for every app.\nexport {\n NavChromeProvider,\n CORE_APP_ORIGIN,\n CORE_BILLING_PATH,\n FuelAction,\n NotificationsAction,\n SupportAction,\n NavDisplayAction,\n NavThemeControl,\n TopBarCountBadge,\n TopBarPanelArrow,\n TopBarTooltip,\n TopBarWidgetSlot,\n TopBarPopover,\n topBarIconButtonClass,\n resolveOrgLogoUrl,\n useChromeMe,\n useChromeOrgs,\n useNavChromeFetcher,\n useThemePreference,\n} from './chromeActions'\nexport type {\n ChromeMe,\n NavChromeFetcher,\n NavDisplayMode,\n ThemePreference,\n ChromeOrgSummary,\n ChromeNotificationsPayload,\n ChromeNotificationAlert,\n ChromeNotificationReply,\n ChromeNotificationImport,\n ChromeNotificationQuarantine,\n CommunicationsFuelStatus,\n FuelChannelStatus,\n} from './chromeActions'\n\n// An icon is any component that accepts an optional size + className. This\n// matches both `lucide-react` and `react-icons` icon signatures, so consuming\n// apps pass their own icon set without this package depending on one.\nexport type NavIcon = ComponentType<{ size?: number; className?: string }>\n\nexport type NavItem = {\n /** Route to link to. Optional when `onClick` is supplied (renders a button). */\n href?: string\n label: string\n icon?: NavIcon\n /**\n * When supplied the row renders as a `<button>` (styled identically to the\n * link rows) instead of a routed link — used for actions like \"Support\".\n */\n onClick?: () => void\n /**\n * Disables the row: non-interactive and dimmed, with `disabledTitle` shown as\n * a hover tooltip explaining why. Mirrors `NavTab`'s existing contract so a\n * gated row looks the same whether it renders in the sidebar or a tab strip.\n * Without this, an app that gates a section (VRM dims Email / SMS until setup\n * is complete) had no way to express it and the row rendered fully clickable\n * (shell-nav-handoff §3).\n */\n disabled?: boolean\n /** Tooltip for a disabled row — say why, and how to resolve it. */\n disabledTitle?: string\n /**\n * Nested sub-items. When present, the row becomes an expandable GROUP header.\n * Clicking it always toggles the children open/closed and rotates the\n * right-aligned chevron; if the item ALSO carries an `onClick`, that runs too,\n * so a parent can navigate to its section dashboard while expanding\n * (shell-nav-handoff §2). An `href` alone never navigates from a group header. The sidebar runs a single-open accordion (opening one group closes\n * the others) and auto-expands whichever group contains the active route —\n * mirroring the main VRM app's Chakra sidebar. Children render as smaller nav\n * rows on a lighter panel and support both `href` links and `onClick` actions.\n */\n children?: NavItem[]\n}\n\n// The routing primitive is injected so each app supplies its own (Next.js\n// `<Link>`, react-router `<Link>`, or a plain `<a>`). Defaults to an anchor.\nexport type NavLinkProps = {\n href: string\n className?: string\n 'aria-current'?: 'page' | undefined\n children: ReactNode\n // Optional passthrough attributes so the same injected link can back a\n // routed nav row OR a routed tab (which needs ARIA tab semantics + inline\n // token geometry). Next.js `<Link>`, react-router `<Link>` and a plain <a>\n // all accept these DOM props, and DefaultLink spreads them onto its anchor.\n role?: string\n 'aria-selected'?: boolean\n 'aria-label'?: string\n title?: string\n style?: CSSProperties\n}\nexport type NavLinkComponent = ComponentType<NavLinkProps>\n\n/**\n * URL-scheme allow-list for host-supplied hrefs. React does not neutralize\n * `javascript:`/`data:` schemes on anchor href, so any app-supplied nav/footer/\n * action href must be validated before it reaches the DOM. Permits absolute\n * http(s), mailto/tel, and in-app relative targets; everything else → '#'.\n */\nconst safeHref = (h?: string) =>\n h && /^(https?:|mailto:|tel:|\\/|#|\\.)/i.test(h.trim()) ? h : '#'\n\nconst DefaultLink: NavLinkComponent = ({ href, children, ...rest }) => (\n <a href={safeHref(href)} {...rest}>\n {children}\n </a>\n)\n\n/**\n * Default active-route test. Handles three href shapes so the CURRENT app's\n * item + sub-item select correctly in the cross-app menu (HITL 2026-07-23):\n * - relative path: exact for \"/\", prefix otherwise (legacy behavior);\n * - absolute URL: active only when its host matches window.location.host,\n * then compared by path (and query, when the href carries one — e.g.\n * forms' /?tab=canvas sub-items);\n * - query-only relative hrefs likewise compare location.search.\n *\n * The `org` param is EXCLUDED from the query comparison. Campaign / Petition\n * links carry `?org=<last6>` purely to hand the active organization to the\n * destination app (`standardPolitogyNav`'s `activeOrgId`); it scopes data, it\n * does not identify a page. Comparing it would deselect every campaign row the\n * moment an org is active, because the app's own URL bar carries no `org=`.\n */\nconst ACTIVE_IGNORED_PARAMS = new Set(['org'])\n\nexport function isNavItemActive(pathname: string, href: string): boolean {\n let targetPath = href\n let targetSearch = ''\n if (/^https?:\\/\\//i.test(href)) {\n if (typeof window === 'undefined') return false\n try {\n const u = new URL(href)\n if (u.host !== window.location.host) return false\n targetPath = u.pathname\n targetSearch = u.search\n } catch {\n return false\n }\n } else {\n const qi = href.indexOf('?')\n if (qi >= 0) {\n targetPath = href.slice(0, qi) || '/'\n targetSearch = href.slice(qi)\n }\n }\n // Every IDENTIFYING key=value in the target query must be present in the\n // location. Once the scoping params are dropped a link like\n // \"https://signs.politogyvrm.com/placements?org=abc123\" is a plain path href\n // again and falls through to the path rules below.\n const want = new URLSearchParams(targetSearch)\n for (const k of ACTIVE_IGNORED_PARAMS) want.delete(k)\n if (Array.from(want).length > 0) {\n if (typeof window === 'undefined') return false\n if (pathname !== targetPath) return false\n const have = new URLSearchParams(window.location.search)\n for (const [k, v] of want) if (have.get(k) !== v) return false\n return true\n }\n if (targetPath === '/') return pathname === '/'\n return pathname === targetPath || pathname.startsWith(`${targetPath}/`)\n}\n\n/**\n * Stable identity for an expandable nav group's accordion state. Prefers the\n * item's href; falls back to an index-scoped label so two groups can never\n * collide even when they share a label and have no href.\n */\nfunction groupKeyOf(item: NavItem, index: number): string {\n return item.href ?? `nav-group-${index}-${item.label}`\n}\n\n/** True when any of a group's children links to the active route. */\nfunction hasActiveChild(\n item: NavItem,\n pathname: string,\n activeFn: (pathname: string, href: string) => boolean,\n): boolean {\n return (item.children ?? []).some(\n (child) =>\n (child.href ? activeFn(pathname, child.href) : false) ||\n // Depth-3: a grandchild owning the route also opens the top group.\n (child.children ?? []).some((leaf) =>\n leaf.href ? activeFn(pathname, leaf.href) : false,\n ),\n )\n}\n\n/**\n * Color-coded tone classes for the sidebar environment chip, matching the main\n * VRM app: prod red, staging orange, local/dev green, unknown gray.\n */\nexport function envChipClasses(label: string): string {\n const l = label.toLowerCase()\n if (l === 'production' || l === 'prod')\n return 'bg-[#fee2e2] text-[#ef4444]'\n if (l === 'staging' || l === 'stage')\n return 'bg-[#ffedd5] text-[#f97316]'\n if (l === 'local' || l === 'development' || l === 'dev')\n return 'bg-[#dcfce7] text-[#22c55e]'\n return 'bg-[rgba(107,114,128,0.16)] text-[#6b7280]'\n}\n\n// ---------------------------------------------------------------------------\n\nexport type NavBrand = {\n /** Where the logo links to. Defaults to \"/\". */\n homeHref?: string\n /**\n * Brand logo image src. When supplied this renders as the wordmark logo\n * (matching the main app's BrandLogo), and `badgeLabel`/`title`/`subtitle`\n * are used only as the no-image fallback.\n */\n logoSrc?: string\n logoAlt?: string\n /** Short label shown inside the brand badge fallback (e.g. \"P\"). */\n badgeLabel: string\n title: string\n subtitle?: string\n}\n\nexport type NavOrgOption = {\n id: string\n name: string | null\n logoUrl?: string | null\n brandColor?: string | null\n role?: string | null\n}\n\nexport type NavOrg = {\n name: string | null\n /** Full org id. When present, a copy affordance is shown by the label. */\n id?: string | null\n /** Optional org logo for the pill badge; falls back to initials. */\n logoUrl?: string | null\n /** Solid pill background (the org's brand color). Defaults to race red. */\n brandColor?: string | null\n onClick?: () => void\n /**\n * The user's organizations. When present (even one), the pill renders as a\n * dropdown SWITCHER (Reference/UI-Platform \"Organization selector\": never a\n * static label in a multi-org app); selecting one calls `onSwitch(id)`.\n */\n organizations?: NavOrgOption[]\n onSwitch?: (id: string) => void\n /**\n * The active org is still resolving from the chrome API. Renders a skeleton\n * pill instead of a name. Required because the app's own workspace label is\n * NOT the organization: showing it while the real org loads flashes a wrong\n * value (Global Rules — async values shimmer, they never render a stand-in).\n */\n loading?: boolean\n}\n\nexport type NavModeOption = {\n id: string\n label: string\n icon?: NavIcon\n}\n\nexport type NavMode = {\n label: string\n icon?: NavIcon\n /**\n * Entitled modes for the active organization. With more than one option the\n * pill renders as a SELECTOR (dropdown); with zero/one it stays the classic\n * disabled single-mode pill. Selecting calls onSelect(id).\n */\n options?: NavModeOption[]\n onSelect?: (id: string) => void\n}\n\nexport type NavFooterLink = { label: string; href: string; external?: boolean }\n\nexport type NavFooter = {\n /**\n * Build metadata (env chip / commit / version / date / author). OPTIONAL:\n * omit envLabel/version/commit to render a links-only footer — apps show\n * the meta block to Super Administrators only (Reference/UI-Platform).\n */\n envLabel?: string\n version?: string\n commit?: string\n links?: NavFooterLink[]\n /** ISO date (or any Date-parseable string) of the deployed commit. */\n commitDate?: string\n /** Full name of the commit author (only the first name is shown). */\n commitAuthor?: string\n}\n\nexport type NavSidebarProps = {\n pathname: string\n brand: NavBrand\n nav: {\n groupLabel?: string\n items: NavItem[]\n isActive?: (pathname: string, href: string) => boolean\n }\n org?: NavOrg | null\n mode?: NavMode | null\n footer?: NavFooter | null\n linkComponent?: NavLinkComponent\n}\n\n// Default org-pill background — race red, matching the main app's fallback\n// (mode primary) when an org has no explicit brand color.\nconst ORG_PILL_DEFAULT = 'var(--color-race-red)'\n\nexport function NavSidebar({\n pathname,\n brand,\n nav,\n org,\n mode,\n footer,\n linkComponent,\n}: NavSidebarProps) {\n const Link = linkComponent ?? DefaultLink\n const activeFn = nav.isActive ?? isNavItemActive\n const ModeIcon = mode?.icon\n const orgBg = org?.brandColor || ORG_PILL_DEFAULT\n // Core stores logo_url as a core-relative storage route; resolve it against\n // the core origin so it loads in EVERY app, not just app.politogyvrm.com.\n const orgLogoSrc = resolveOrgLogoUrl(org?.logoUrl)\n\n // Single-open accordion for expandable nav groups, mirroring the main VRM\n // app's Chakra sidebar. `activeGroupKey` is the group (if any) that owns the\n // current route; deriving it as a primitive string keeps the auto-expand\n // effect from firing when `nav.items` is a fresh array reference each render\n // (which would otherwise clobber a manual toggle).\n const activeGroupKey = useMemo(() => {\n for (let i = 0; i < nav.items.length; i++) {\n const item = nav.items[i]\n if (item.children && item.children.length > 0 && hasActiveChild(item, pathname, activeFn)) {\n return groupKeyOf(item, i)\n }\n }\n return null\n }, [nav.items, pathname, activeFn])\n\n // Seed the open group from the active route on first paint (no expand flash),\n // then keep it synced as the route changes. Manual toggles between route\n // changes are preserved because the effect only reruns when the *derived*\n // active group actually changes.\n const [openGroup, setOpenGroup] = useState<string | null>(activeGroupKey)\n useEffect(() => {\n setOpenGroup(activeGroupKey)\n }, [activeGroupKey])\n const toggleGroup = (key: string) =>\n setOpenGroup((prev) => (prev === key ? null : key))\n\n return (\n <aside className=\"fixed inset-y-0 left-0 z-30 hidden w-[240px] flex-col border-r border-[color:var(--line)] bg-[color:var(--nav-surface)] lg:flex\">\n {/* Brand — logo image (preferred) or badge fallback */}\n <Link\n href={brand.homeHref ?? '/'}\n className=\"flex h-[64px] flex-shrink-0 items-center gap-2.5 px-6\"\n >\n {brand.logoSrc ? (\n <img\n src={brand.logoSrc}\n alt={brand.logoAlt ?? brand.title}\n draggable={false}\n className=\"h-10 w-auto object-contain\"\n />\n ) : (\n <>\n <span className=\"flex h-9 w-9 items-center justify-center rounded-xl bg-[color:var(--color-race-red)] text-base font-black text-white shadow-sm\">\n {brand.badgeLabel}\n </span>\n <span className=\"flex flex-col leading-tight\">\n <span className=\"text-base font-extrabold tracking-[-0.01em] text-[color:var(--color-race-red)]\">\n {brand.title}\n </span>\n {brand.subtitle ? (\n <span className=\"text-[11px] font-semibold uppercase tracking-[0.16em] text-[color:var(--muted)]\">\n {brand.subtitle}\n </span>\n ) : null}\n </span>\n </>\n )}\n </Link>\n\n {/* Scroll region: org pill, mode pill, nav */}\n <div className=\"flex flex-1 flex-col overflow-y-auto px-4 pb-2\">\n {/* Organization switcher */}\n {org ? (\n <div className=\"mb-3\">\n <div className=\"mb-2 flex items-center justify-between px-1\">\n <p className=\"text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Organization\n </p>\n {org.id && !org.loading ? <OrgIdCopyButton id={org.id} /> : null}\n </div>\n {org.loading ? (\n <div className=\"flex w-full items-center gap-2.5 rounded-md border border-[color:var(--line)] bg-[color:var(--panel-elevated)] px-2.5 py-2 shadow-sm\">\n <span\n aria-hidden\n className=\"h-7 w-7 shrink-0 animate-pulse rounded-full bg-[color:var(--panel)]\"\n />\n <span\n aria-hidden\n className=\"h-4 flex-1 animate-pulse rounded bg-[color:var(--panel)]\"\n />\n <span className=\"sr-only\">Loading organization</span>\n </div>\n ) : org.organizations && org.organizations.length > 0 && org.onSwitch ? (\n <details data-nav-details className=\"group relative\">\n <summary className=\"flex w-full cursor-pointer list-none items-center justify-between gap-2 rounded-md border border-[color:var(--line)] bg-[color:var(--panel-elevated)] px-2.5 py-2 text-left text-[color:var(--foreground)] shadow-sm transition hover:bg-[color:var(--panel)] [&::-webkit-details-marker]:hidden\">\n <span className=\"flex min-w-0 items-center gap-2.5\">\n {/* Only the circular badge carries the org's brand color. */}\n <span\n style={{ backgroundColor: orgBg }}\n className=\"flex h-7 w-7 shrink-0 items-center justify-center overflow-hidden rounded-full text-[11px] font-bold text-white\"\n >\n {orgLogoSrc ? (\n <img src={orgLogoSrc} alt=\"\" className=\"h-full w-full object-cover\" />\n ) : (\n (org.name ?? 'Org').slice(0, 2).toUpperCase()\n )}\n </span>\n <span\n title={org.name ?? undefined}\n className=\"truncate text-sm font-semibold\"\n >\n {org.name ?? 'No organizations'}\n </span>\n </span>\n <ChevronDown />\n </summary>\n <div className=\"absolute left-0 right-0 z-40 mt-1 max-h-72 overflow-y-auto rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] py-1 shadow-[var(--shadow-soft)]\">\n {org.organizations.map((o) => {\n const selected = o.id === org.id\n return (\n <button\n key={o.id}\n type=\"button\"\n onClick={(e) => {\n // Close the <details> popover, then switch.\n e.currentTarget.closest('details')?.removeAttribute('open')\n if (!selected) org.onSwitch?.(o.id)\n }}\n aria-current={selected ? 'true' : undefined}\n className={[\n 'flex w-full items-center gap-2.5 px-3 py-2 text-left text-sm',\n selected\n ? 'font-semibold text-[color:var(--color-race-red)]'\n : 'font-medium text-[color:var(--foreground)] hover:bg-[color:var(--panel)]',\n ].join(' ')}\n >\n <span\n style={{ backgroundColor: o.brandColor || ORG_PILL_DEFAULT }}\n className=\"flex h-6 w-6 shrink-0 items-center justify-center overflow-hidden rounded-full text-[10px] font-bold text-white\"\n >\n {resolveOrgLogoUrl(o.logoUrl) ? (\n <img\n src={resolveOrgLogoUrl(o.logoUrl)}\n alt=\"\"\n className=\"h-full w-full object-cover\"\n />\n ) : (\n (o.name ?? 'Org').slice(0, 2).toUpperCase()\n )}\n </span>\n <span title={o.name ?? o.id} className=\"truncate\">\n {o.name ?? o.id.slice(0, 8)}\n </span>\n </button>\n )\n })}\n </div>\n </details>\n ) : (\n <button\n type=\"button\"\n onClick={org.onClick}\n className=\"flex w-full items-center justify-between gap-2 rounded-md border border-[color:var(--line)] bg-[color:var(--panel-elevated)] px-2.5 py-2 text-left text-[color:var(--foreground)] shadow-sm transition hover:bg-[color:var(--panel)]\"\n >\n <span className=\"flex min-w-0 items-center gap-2.5\">\n {/* Only the circular badge carries the org's brand color. */}\n <span\n style={{ backgroundColor: orgBg }}\n className=\"flex h-7 w-7 shrink-0 items-center justify-center overflow-hidden rounded-full text-[11px] font-bold text-white\"\n >\n {orgLogoSrc ? (\n <img src={orgLogoSrc} alt=\"\" className=\"h-full w-full object-cover\" />\n ) : (\n (org.name ?? 'Org').slice(0, 2).toUpperCase()\n )}\n </span>\n <span className=\"truncate text-sm font-semibold\">\n {org.name ?? 'No organizations'}\n </span>\n </span>\n <ChevronDown />\n </button>\n )}\n </div>\n ) : null}\n\n {/* Mode pill — a SELECTOR when the org is entitled to >1 mode. */}\n {mode ? (\n <div className=\"mb-4\">\n {mode.options && mode.options.length > 1 && mode.onSelect ? (\n <details data-nav-details className=\"group relative\">\n <summary className=\"flex w-full cursor-pointer list-none items-center justify-between gap-2 rounded-md bg-[color:var(--color-race-red)] px-2.5 py-2 text-white shadow-sm transition hover:opacity-95 [&::-webkit-details-marker]:hidden\">\n <span className=\"flex items-center gap-2.5\">\n {ModeIcon ? <ModeIcon size={16} className=\"shrink-0\" /> : null}\n <span className=\"text-sm font-semibold tracking-[-0.01em]\">{mode.label}</span>\n </span>\n <ChevronDown />\n </summary>\n <div className=\"absolute left-0 right-0 z-40 mt-1 overflow-hidden rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] py-1 shadow-[var(--shadow-soft)]\">\n {mode.options.map((opt) => {\n const selected = opt.label === mode.label\n const OptIcon = opt.icon\n return (\n <button\n key={opt.id}\n type=\"button\"\n onClick={(e) => {\n e.currentTarget.closest('details')?.removeAttribute('open')\n if (!selected) mode.onSelect?.(opt.id)\n }}\n aria-current={selected ? 'true' : undefined}\n className={[\n 'flex w-full items-center gap-2.5 px-3 py-2 text-left text-sm',\n selected\n ? 'font-semibold text-[color:var(--color-race-red)]'\n : 'font-medium text-[color:var(--foreground)] hover:bg-[color:var(--panel)]',\n ].join(' ')}\n >\n {OptIcon ? <OptIcon size={15} className=\"shrink-0 text-current\" /> : null}\n {opt.label}\n </button>\n )\n })}\n </div>\n </details>\n ) : (\n <button\n type=\"button\"\n className=\"flex w-full items-center justify-between gap-2 rounded-md bg-[color:var(--color-race-red)] px-2.5 py-2 text-white shadow-sm\"\n >\n <span className=\"flex items-center gap-2.5\">\n {ModeIcon ? <ModeIcon size={16} className=\"shrink-0\" /> : null}\n <span className=\"text-sm font-semibold tracking-[-0.01em]\">{mode.label}</span>\n </span>\n <ChevronDown />\n </button>\n )}\n </div>\n ) : null}\n\n {/* Nav list */}\n <nav className=\"flex flex-col gap-1\">\n {nav.groupLabel ? (\n <p className=\"px-2 pb-1 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n {nav.groupLabel}\n </p>\n ) : null}\n {nav.items.map((item, idx) => {\n // Expandable group: renders a toggle header + collapsible children.\n if (item.children && item.children.length > 0) {\n const key = groupKeyOf(item, idx)\n const selfActive = item.href ? activeFn(pathname, item.href) : false\n const parentActive = selfActive || hasActiveChild(item, pathname, activeFn)\n return (\n <NavGroup\n key={key}\n item={item}\n active={parentActive}\n open={openGroup === key}\n onToggle={() => toggleGroup(key)}\n pathname={pathname}\n activeFn={activeFn}\n Link={Link}\n />\n )\n }\n const active = item.href ? activeFn(pathname, item.href) : false\n return (\n <NavRow\n key={item.href ?? `nav-${idx}-${item.label}`}\n item={item}\n active={active}\n Link={Link}\n />\n )\n })}\n </nav>\n </div>\n\n {/* Footer — pipe-separated links + commit/version string */}\n {footer ? (\n <div className=\"flex-shrink-0 border-t border-[color:var(--line)] px-4 py-3\">\n {footer.links && footer.links.length > 0 ? (\n <div className=\"flex flex-wrap items-center justify-center gap-1.5 text-xs\">\n {footer.links.map((l, idx) => (\n <span key={l.label} className=\"inline-flex items-center gap-1.5\">\n {idx > 0 ? <span className=\"text-[color:var(--muted)]\">|</span> : null}\n <a\n href={safeHref(l.href)}\n className=\"font-medium text-[color:var(--foreground)] opacity-80 hover:opacity-100 hover:underline\"\n >\n {l.label}\n </a>\n </span>\n ))}\n </div>\n ) : null}\n {footer.envLabel ? (\n <div className=\"mt-1.5 flex flex-col items-center gap-0.5 font-[family-name:var(--font-plex-mono)] text-[10px] text-[color:var(--muted)]\">\n {/* Row 1: env chip | commit | version */}\n <div className=\"flex items-center gap-1.5\">\n <span\n className={[\n 'rounded-md px-1.5 py-0.5 text-[10px] font-semibold',\n envChipClasses(footer.envLabel),\n ].join(' ')}\n >\n {footer.envLabel}\n </span>\n {footer.commit ? (\n <>\n <span className=\"text-[color:var(--muted)]\">|</span>\n <span>{footer.commit.slice(-4)}</span>\n </>\n ) : null}\n {footer.version ? (\n <>\n <span className=\"text-[color:var(--muted)]\">|</span>\n <span>v{footer.version}</span>\n </>\n ) : null}\n </div>\n {/* Row 2: date | author (only when supplied) */}\n {footer.commitDate || footer.commitAuthor ? (\n <div className=\"flex items-center gap-1.5\">\n {footer.commitDate ? (\n <span>\n {new Date(footer.commitDate).toLocaleDateString(undefined, {\n month: 'short',\n day: 'numeric',\n })}\n </span>\n ) : null}\n {footer.commitDate && footer.commitAuthor ? (\n <span className=\"text-[color:var(--muted)]\">|</span>\n ) : null}\n {footer.commitAuthor ? (\n <span>{footer.commitAuthor.split(/\\s+/)[0]}</span>\n ) : null}\n </div>\n ) : null}\n </div>\n ) : null}\n </div>\n ) : null}\n </aside>\n )\n}\n\n// Inline chevron-down (mirrors lucide `ChevronDown`) — no icon dependency.\n// Callers may override `className` to add a rotation (used by expandable groups).\nfunction ChevronDown({ className }: { className?: string } = {}) {\n return (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className ?? 'shrink-0 opacity-80'}\n aria-hidden=\"true\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n )\n}\n\n// A single sidebar nav row. Renders as a routed <Link> (href) or a <button>\n// (onClick), styled identically. Inactive rows animate a left→right gradient\n// sweep on hover (matching the main app); active rows keep solid race-red.\n//\n// `variant=\"sub\"` renders the smaller child rows inside an expanded group: a\n// tighter row whose ACTIVE state is a lighter elevated surface with race-red\n// text (not a solid-red fill — that stays reserved for top-level/parent rows,\n// exactly as the main VRM app's Chakra sidebar treats active sub-items).\n// Specs race-red ramp (hover → active primary).\nconst NAV_HOVER_GRADIENT = 'linear-gradient(90deg,#EA4751 0%,#E63946 100%)'\n\nfunction NavRow({\n item,\n active,\n Link,\n variant = 'top',\n}: {\n item: NavItem\n active: boolean\n Link: NavLinkComponent\n variant?: 'top' | 'sub'\n}) {\n const Icon = item.icon\n const isSub = variant === 'sub'\n const activeClasses = isSub\n ? 'bg-[color:var(--panel-elevated)] text-[color:var(--color-race-red)] shadow-sm'\n : 'bg-[color:var(--color-race-red)] text-white shadow-sm'\n const wrapperClasses = [\n 'group relative block overflow-hidden rounded-md transition',\n active ? activeClasses : 'text-[color:var(--muted)] hover:text-white',\n ].join(' ')\n\n const rowPadding = isSub ? 'px-3 py-1.5 text-[13px]' : 'px-3 py-2 text-sm'\n const iconSize = isSub ? 16 : 18\n // Top-level active rows use white glyphs on the red fill; sub-item active\n // rows inherit the race-red text color via `text-current`.\n const iconClass = active && !isSub ? 'text-white' : 'text-current'\n\n const inner = (\n <>\n {!active ? (\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-y-0 left-0 w-0 transition-[width] duration-300 group-hover:w-full\"\n style={{ background: NAV_HOVER_GRADIENT }}\n />\n ) : null}\n <span className={`relative z-10 flex items-center gap-3 font-semibold ${rowPadding}`}>\n {Icon ? <Icon size={iconSize} className={iconClass} /> : null}\n {item.label}\n </span>\n </>\n )\n\n // A gated row renders as a non-interactive span: dimmed, not focusable, and\n // carrying its reason as a tooltip. Same treatment a disabled NavTab gets, so\n // gating reads identically in the sidebar and in a tab strip.\n if (item.disabled) {\n return (\n <span\n aria-disabled=\"true\"\n title={item.disabledTitle}\n className={`${wrapperClasses} cursor-not-allowed opacity-50`}\n >\n {inner}\n </span>\n )\n }\n\n if (item.onClick && !item.href) {\n return (\n <button type=\"button\" onClick={item.onClick} className={`w-full text-left ${wrapperClasses}`}>\n {inner}\n </button>\n )\n }\n\n return (\n <Link\n href={item.href ?? '#'}\n aria-current={active ? 'page' : undefined}\n className={wrapperClasses}\n >\n {inner}\n </Link>\n )\n}\n\n// An expandable nav GROUP: a toggle header + a collapsible list of child rows.\n// Faithful twin of the main VRM app's Chakra accordion (Sidebar.tsx /\n// NavItem.tsx):\n// - Clicking the header toggles the children — it never navigates, even when\n// the group carries an `href`.\n// - A right-aligned chevron rotates 180° when open.\n// - The header goes solid race-red (white text) when the group owns the active\n// route (its own href OR any child), matching top-level active rows; when\n// merely open it lifts onto the `--panel` surface; otherwise it's a muted row\n// with the same left→right gradient hover sweep as every other nav row.\n// - Children sit on the lighter `--panel` surface, indented and rounded, each\n// rendered through the SAME injected LinkComponent (or as a button for\n// `onClick` children) via <NavRow variant=\"sub\" />.\nfunction NavGroup({\n item,\n active,\n open,\n onToggle,\n pathname,\n activeFn,\n Link,\n}: {\n item: NavItem\n active: boolean\n open: boolean\n onToggle: () => void\n pathname: string\n activeFn: (pathname: string, href: string) => boolean\n Link: NavLinkComponent\n}) {\n const Icon = item.icon\n const headerClasses = [\n 'group relative block w-full overflow-hidden text-left transition',\n open ? 'rounded-t-md' : 'rounded-md',\n active\n ? 'bg-[color:var(--color-race-red)] text-white shadow-sm'\n : open\n ? 'bg-[color:var(--panel)] text-[color:var(--foreground)]'\n : 'text-[color:var(--muted)] hover:text-white',\n ].join(' ')\n\n return (\n <div>\n <button\n type=\"button\"\n // A group header ALWAYS toggles. When the item also carries its own\n // onClick, that runs too — so a parent can navigate to its section\n // dashboard (e.g. Email Broadcast → /relationship/email/dashboard) and\n // expand in one click. Existing apps pass no parent onClick, so their\n // behavior is unchanged (shell-nav-handoff §2).\n onClick={() => {\n onToggle()\n item.onClick?.()\n }}\n aria-expanded={open}\n className={headerClasses}\n >\n {/* Hover sweep only when CLOSED and inactive — an expanded group keeps\n its raised/selected background intact through hover and hover-out. */}\n {!active && !open ? (\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-y-0 left-0 w-0 transition-[width] duration-300 group-hover:w-full\"\n style={{ background: NAV_HOVER_GRADIENT }}\n />\n ) : null}\n <span className=\"relative z-10 flex items-center gap-3 px-3 py-2 text-sm font-semibold\">\n {Icon ? (\n <Icon size={18} className={active ? 'text-white' : 'text-current'} />\n ) : null}\n <span className=\"flex-1\">{item.label}</span>\n <ChevronDown\n className={[\n 'shrink-0 opacity-80 transition-transform duration-200',\n open ? 'rotate-180' : '',\n ].join(' ')}\n />\n </span>\n </button>\n\n {open ? (\n <div className=\"overflow-hidden rounded-b-md bg-[color:var(--nav-submenu-bg)] p-1\">\n <div className=\"flex flex-col gap-0.5\">\n {item.children!.map((child, i) => {\n const childActive = child.href ? activeFn(pathname, child.href) : false\n // Depth-3: a child that carries its own children renders as a\n // NESTED collapsible sub-group (e.g. Organization Settings →\n // Subscription & Billing → Wallet). Deeper levels are not\n // rendered — three is the platform maximum.\n if (child.children && child.children.length > 0) {\n return (\n <NavSubGroup\n key={child.href ?? `subgrp-${i}-${child.label}`}\n item={child}\n pathname={pathname}\n activeFn={activeFn}\n Link={Link}\n />\n )\n }\n return (\n <NavRow\n key={child.href ?? `sub-${i}-${child.label}`}\n item={child}\n active={childActive}\n Link={Link}\n variant=\"sub\"\n />\n )\n })}\n </div>\n </div>\n ) : null}\n </div>\n )\n}\n\n// A second-level group INSIDE an expanded group — the depth-3 renderer\n// (Reference/UI-Platform: sub-sub items). Auto-expands when it owns the active\n// route; otherwise toggles locally. Grandchildren render as further-indented\n// sub rows on the same panel surface.\nfunction NavSubGroup({\n item,\n pathname,\n activeFn,\n Link,\n}: {\n item: NavItem\n pathname: string\n activeFn: (pathname: string, href: string) => boolean\n Link: NavLinkComponent\n}) {\n const ownsActive =\n (item.href ? activeFn(pathname, item.href) : false) ||\n (item.children ?? []).some((c) => (c.href ? activeFn(pathname, c.href) : false))\n const [open, setOpen] = useState(ownsActive)\n useEffect(() => {\n if (ownsActive) setOpen(true)\n }, [ownsActive])\n const Icon = item.icon\n\n return (\n <div>\n <button\n type=\"button\"\n onClick={() => setOpen((v) => !v)}\n aria-expanded={open}\n className={[\n 'flex w-full items-center gap-2.5 rounded px-3 py-1.5 text-left text-[13px] font-medium transition',\n ownsActive\n ? 'text-[color:var(--color-race-red)]'\n : 'text-[color:var(--muted)] hover:bg-[color:var(--nav-row-hover)] hover:text-[color:var(--foreground)]',\n ].join(' ')}\n >\n {Icon ? <Icon size={15} className=\"shrink-0 text-current\" /> : null}\n <span className=\"flex-1\">{item.label}</span>\n <ChevronDown\n className={[\n 'shrink-0 opacity-70 transition-transform duration-200',\n open ? 'rotate-180' : '',\n ].join(' ')}\n />\n </button>\n {open ? (\n <div className=\"ml-4 flex flex-col gap-0.5 border-l border-[color:var(--line)] pl-2\">\n {item.children!.map((leaf, i) => (\n <NavRow\n key={leaf.href ?? `subsub-${i}-${leaf.label}`}\n item={leaf}\n active={leaf.href ? activeFn(pathname, leaf.href) : false}\n Link={Link}\n variant=\"sub\"\n />\n ))}\n </div>\n ) : null}\n </div>\n )\n}\n\n// Right-aligned copy affordance for the org id, shown beside the \"Organization\"\n// label. Copies the full id and briefly swaps its text to \"Copied\".\nfunction OrgIdCopyButton({ id }: { id: string }) {\n const [copied, setCopied] = useState(false)\n return (\n <button\n type=\"button\"\n onClick={() => {\n try {\n void navigator.clipboard?.writeText(id)\n } catch {\n /* clipboard unavailable — ignore */\n }\n setCopied(true)\n setTimeout(() => setCopied(false), 1500)\n }}\n title=\"Copy organization id\"\n className=\"rounded px-1 text-[11px] text-[color:var(--muted)] hover:bg-[color:var(--panel)]\"\n >\n {copied ? 'Copied' : `...${id.slice(-8)}`}\n </button>\n )\n}\n\n// ---------------------------------------------------------------------------\n\nexport type NavUser = {\n name: string | null\n email?: string | null\n /** Profile PHOTO url — highest-precedence avatar source. */\n avatarUrl?: string | null\n /** Memoji url — used when no photo is set; falls back to initials. */\n memojiUrl?: string | null\n tier?: string | null\n role?: string | null\n}\n\nexport type NavTopBarAction = {\n key: string\n /**\n * Canonical top-bar slot. When set, the glyph is sourced by NAME from the\n * Brand API via `--topbar-icon-<slot>`; `icon` becomes the fallback used\n * until the runtime Brand stylesheet lands (or when the token is unset).\n */\n slot?: TopBarIconSlot\n icon: NavIcon\n label: string\n onClick?: () => void\n href?: string\n badge?: number | null\n tone?: 'default' | 'warning' | 'danger'\n /** Tooltip body shown under the icon (label is the tooltip title). */\n description?: string\n}\n\nexport type NavLinkedAccount = {\n id: string\n name: string | null\n email?: string | null\n avatarUrl?: string | null\n active?: boolean\n}\n\nexport type NavRoleBadge = {\n role: string\n orgName?: string | null\n}\n\n/**\n * The My Account menu (avatar dropdown) — mirrors the main VRM app's user\n * menu: My Profile / Organization Settings links, a ROLES & ORGANIZATIONS\n * section, an ACCOUNTS switcher, an optional theme control, then Sign out.\n * Every section renders only when its data is supplied.\n */\nexport type NavUserMenu = {\n myProfileHref?: string\n organizationSettingsHref?: string\n roles?: NavRoleBadge[]\n accounts?: NavLinkedAccount[]\n onSwitchAccount?: (id: string) => void\n onRemoveAccount?: (id: string) => void\n addAccountHref?: string\n onAddAccount?: () => void\n /** Theme preference segmented control (Light / System / Dark). */\n theme?: {\n value: ThemePreference\n onChange: (next: ThemePreference) => void\n }\n}\n\nexport type NavBreadcrumb = {\n label: string\n href?: string\n}\n\nexport type NavTopBarProps = {\n title: string\n subtitle?: string\n /**\n * Breadcrumb trail rendered UNDER the page title (Reference/UI-Platform:\n * every page and sub-page/tab shows its location). Last crumb = current\n * location (non-link); earlier crumbs may carry hrefs.\n */\n breadcrumbs?: NavBreadcrumb[]\n user?: NavUser | null\n userMenu?: NavUserMenu\n onSignOut?: () => void\n /**\n * Structured icon-button action cluster (32×32 circular buttons with optional\n * count badges), rendered before the `actions` slot. Matches the main app's\n * topbar action icons.\n */\n actionsList?: NavTopBarAction[]\n /** App-specific action cluster rendered left of the theme toggle. */\n actions?: ReactNode\n /** Theme toggle slot (injected so this package needs no theme dependency). */\n themeToggle?: ReactNode\n}\n\nexport function NavTopBar({\n title,\n subtitle,\n breadcrumbs,\n user,\n userMenu,\n onSignOut,\n actionsList,\n actions,\n themeToggle,\n}: NavTopBarProps) {\n // Real name = anything that isn't empty and isn't an email address. The\n // trigger shows \"First L.\" — never the email on both lines.\n const rawName = user?.name?.trim() || ''\n const hasRealName = rawName.length > 0 && !rawName.includes('@')\n const displayName = hasRealName ? formatFirstLast(rawName) : (user?.email ?? 'Signed in')\n const initials = (hasRealName ? rawName : (user?.email ?? 'P')).slice(0, 2).toUpperCase()\n const secondary = hasRealName\n ? user?.email || [user?.tier, user?.role].filter(Boolean).join(' · ') || 'member'\n : [user?.tier, user?.role].filter(Boolean).join(' · ') || 'member'\n return (\n <header className=\"sticky top-0 z-20 flex h-20 items-center justify-between gap-4 border-b border-[color:var(--line)] bg-[color:var(--panel)] px-4 backdrop-blur-xl\">\n <div className=\"min-w-0\">\n <h1\n className=\"truncate text-lg font-bold tracking-[-0.01em] text-[color:var(--foreground)]\"\n data-display=\"true\"\n >\n {title}\n </h1>\n {breadcrumbs && breadcrumbs.length > 0 ? (\n <nav aria-label=\"Breadcrumb\" className=\"flex min-w-0 items-center gap-1.5 text-sm text-[color:var(--muted)]\">\n {breadcrumbs.map((b, i) => {\n const last = i === breadcrumbs.length - 1\n return (\n <span key={`${b.label}-${i}`} className=\"flex min-w-0 items-center gap-1.5\">\n {i > 0 ? (\n <span aria-hidden className=\"text-[color:var(--muted)] opacity-60\">\n ›\n </span>\n ) : null}\n {b.href && !last ? (\n <a\n href={safeHref(b.href)}\n className=\"truncate hover:text-[color:var(--foreground)] hover:underline\"\n >\n {b.label}\n </a>\n ) : (\n <span\n aria-current={last ? 'page' : undefined}\n className={['truncate', last ? 'text-[color:var(--foreground)]' : ''].join(' ')}\n >\n {b.label}\n </span>\n )}\n </span>\n )\n })}\n </nav>\n ) : subtitle ? (\n <p className=\"truncate text-sm text-[color:var(--muted)]\">{subtitle}</p>\n ) : null}\n </div>\n\n <div className=\"relative flex shrink-0 items-center gap-[var(--topbar-icon-gap,8px)]\">\n {actionsList && actionsList.length > 0\n ? actionsList.map((action) => (\n <NavTopBarActionButton key={action.key} action={action} />\n ))\n : null}\n {actions}\n {themeToggle}\n\n {/* My Account menu — avatar + name/email + chevron trigger, with the\n full account dropdown (profile/org links, roles, account switcher,\n appearance, sign out). Native <details> popover. */}\n <details data-nav-details className=\"group/acct relative\">\n <summary className=\"group/tbtip relative flex cursor-pointer list-none items-center gap-2.5 rounded-full py-1 pl-1 pr-2 transition hover:bg-[color:var(--panel-elevated)] [&::-webkit-details-marker]:hidden\">\n {/* Same circle size as every top-bar icon button (one shared var).\n Avatar precedence: photo → memoji → initials. */}\n <span className=\"flex h-[var(--topbar-icon-button-size,32px)] w-[var(--topbar-icon-button-size,32px)] items-center justify-center overflow-hidden rounded-full bg-[color:var(--color-race-red)] text-xs font-bold text-white\">\n {user?.avatarUrl || user?.memojiUrl ? (\n <img\n src={(user.avatarUrl || user.memojiUrl) as string}\n alt=\"\"\n className=\"h-full w-full object-cover\"\n />\n ) : (\n initials\n )}\n </span>\n <span className=\"hidden flex-col leading-tight md:flex\">\n <span className=\"text-sm font-semibold text-[color:var(--foreground)]\">\n {displayName}\n </span>\n <span className=\"text-xs text-[color:var(--muted)]\">{secondary}</span>\n </span>\n <ChevronDown />\n <span className=\"group-open/acct:hidden\">\n <TopBarTooltip\n title=\"My Account\"\n description={\n <>\n {hasRealName ? rawName : user?.email ?? 'Signed in'}\n {user?.email ? (\n <>\n <br />\n {user.email}\n </>\n ) : null}\n <br />\n Profile, organizations, appearance and sign out.\n </>\n }\n />\n </span>\n </summary>\n {/*\n The menu grows with the user's data — roles, linked accounts, the\n theme control — and on a short viewport (or a user in many orgs) it\n ran past the bottom of the screen with no way to scroll, putting\n Sign out permanently out of reach. Cap the panel at the viewport,\n scroll the SECTIONS, and keep Sign out outside that scroll area so\n it is always on screen no matter how long the list gets.\n */}\n <div className=\"absolute right-0 z-30 mt-2 flex max-h-[calc(100vh-5rem)] w-72 flex-col overflow-hidden rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] py-1 shadow-[var(--shadow-soft)]\">\n <TopBarPanelArrow />\n <div className=\"min-h-0 flex-1 overflow-y-auto overscroll-contain\">\n {userMenu?.myProfileHref ? (\n <a\n href={safeHref(userMenu.myProfileHref)}\n className=\"flex w-full items-center gap-2.5 px-4 py-2.5 text-left text-sm font-medium text-[color:var(--foreground)] hover:bg-[color:var(--panel)]\"\n >\n <ProfileIcon />\n My Profile\n </a>\n ) : null}\n {userMenu?.organizationSettingsHref ? (\n <a\n href={safeHref(userMenu.organizationSettingsHref)}\n className=\"flex w-full items-center gap-2.5 border-t border-[color:var(--line)] px-4 py-2.5 text-left text-sm font-medium text-[color:var(--foreground)] hover:bg-[color:var(--panel)]\"\n >\n <BriefcaseIcon />\n Organization Settings\n </a>\n ) : null}\n\n {userMenu?.roles && userMenu.roles.length > 0 ? (\n <div className=\"border-t border-[color:var(--line)] px-4 py-3\">\n <p className=\"mb-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Roles & Organizations\n </p>\n <ul className=\"flex flex-col gap-1.5\">\n {userMenu.roles.map((r, i) => (\n <li key={`${r.role}-${i}`} className=\"flex flex-wrap items-center gap-1.5 text-sm\">\n <span className=\"rounded-md bg-[color:var(--panel)] px-2 py-0.5 text-xs font-bold uppercase tracking-wide text-[color:var(--foreground)]\">\n {r.role}\n </span>\n {r.orgName ? (\n <span className=\"text-[color:var(--muted)]\">in {r.orgName}</span>\n ) : null}\n </li>\n ))}\n </ul>\n </div>\n ) : null}\n\n {userMenu?.accounts && userMenu.accounts.length > 0 ? (\n <div className=\"border-t border-[color:var(--line)] px-4 py-3\">\n <p className=\"mb-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Accounts\n </p>\n <ul className=\"flex flex-col gap-1\">\n {userMenu.accounts.map((a) => (\n <li key={a.id} className=\"flex items-center gap-2.5\">\n <button\n type=\"button\"\n onClick={() => {\n if (!a.active) userMenu.onSwitchAccount?.(a.id)\n }}\n className=\"flex min-w-0 flex-1 items-center gap-2.5 rounded-lg px-1 py-1 text-left hover:bg-[color:var(--panel)]\"\n >\n <span className=\"flex h-8 w-8 shrink-0 items-center justify-center overflow-hidden rounded-full bg-[color:var(--color-race-red)] text-[11px] font-bold text-white\">\n {a.avatarUrl ? (\n <img src={a.avatarUrl} alt=\"\" className=\"h-full w-full object-cover\" />\n ) : (\n (a.name ?? a.email ?? '?').slice(0, 2).toUpperCase()\n )}\n </span>\n <span className=\"flex min-w-0 flex-col leading-tight\">\n <span\n className={[\n 'truncate text-sm font-semibold',\n a.active\n ? 'text-[color:var(--color-race-red)]'\n : 'text-[color:var(--foreground)]',\n ].join(' ')}\n >\n {a.name ?? a.email ?? a.id.slice(0, 8)}\n </span>\n <span className=\"truncate text-xs text-[color:var(--muted)]\">\n {a.active ? 'Active' : a.email ?? ''}\n </span>\n </span>\n </button>\n {!a.active && userMenu.onRemoveAccount ? (\n <button\n type=\"button\"\n aria-label={`Remove ${a.name ?? a.email ?? 'account'}`}\n onClick={() => userMenu.onRemoveAccount?.(a.id)}\n className=\"shrink-0 rounded p-1 text-[color:var(--color-race-red)] hover:bg-[color:var(--panel)]\"\n >\n <TrashIcon />\n </button>\n ) : null}\n </li>\n ))}\n </ul>\n {userMenu.addAccountHref || userMenu.onAddAccount ? (\n userMenu.addAccountHref ? (\n <a\n href={safeHref(userMenu.addAccountHref)}\n className=\"mt-1.5 flex items-center gap-2.5 rounded-lg px-1 py-1.5 text-sm font-semibold text-[color:var(--color-race-red)] hover:bg-[color:var(--panel)]\"\n >\n <AddUserIcon />\n Add Account\n </a>\n ) : (\n <button\n type=\"button\"\n onClick={userMenu.onAddAccount}\n className=\"mt-1.5 flex w-full items-center gap-2.5 rounded-lg px-1 py-1.5 text-left text-sm font-semibold text-[color:var(--color-race-red)] hover:bg-[color:var(--panel)]\"\n >\n <AddUserIcon />\n Add Account\n </button>\n )\n ) : null}\n </div>\n ) : null}\n\n {userMenu?.theme ? (\n <div className=\"border-t border-[color:var(--line)]\">\n <NavThemeControl\n value={userMenu.theme.value}\n onChange={userMenu.theme.onChange}\n />\n </div>\n ) : null}\n </div>\n\n {onSignOut ? (\n <button\n type=\"button\"\n onClick={onSignOut}\n className=\"flex w-full shrink-0 items-center gap-2.5 border-t border-[color:var(--line)] px-4 py-2.5 text-left text-sm font-medium text-[color:var(--foreground)] hover:bg-[color:var(--panel)] hover:text-[color:var(--color-race-red)]\"\n >\n <SignOutIcon />\n Sign out\n </button>\n ) : null}\n </div>\n </details>\n {!hasRealName && user ? (\n <NamePromptBubble profileHref={userMenu?.myProfileHref} />\n ) : null}\n </div>\n </header>\n )\n}\n\n/**\n * Floating, per-session-dismissable bubble under the account trigger that\n * prompts a user with no display name to set their first + last name. The\n * arrow points up at the avatar; dismissal is remembered in sessionStorage\n * until they actually set a name.\n */\nfunction NamePromptBubble({ profileHref }: { profileHref?: string }) {\n const KEY = 'politogy_name_prompt_dismissed'\n const [dismissed, setDismissed] = useState(true)\n useEffect(() => {\n try {\n setDismissed(sessionStorage.getItem(KEY) === '1')\n } catch {\n setDismissed(false)\n }\n }, [])\n if (dismissed) return null\n return (\n <div className=\"absolute right-4 top-full z-30 mt-2 w-64 rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] p-3 shadow-[var(--shadow-soft)]\">\n <span\n aria-hidden\n className=\"absolute -top-[5px] right-[11px] h-2.5 w-2.5 rotate-45 border-l border-t border-[color:var(--line)] bg-[color:var(--panel-elevated)]\"\n />\n <p className=\"text-sm font-semibold text-[color:var(--foreground)]\">\n Add your name\n </p>\n <p className=\"mt-0.5 text-xs leading-snug text-[color:var(--muted)]\">\n Set your first and last name so teammates see you — not your email.\n </p>\n <div className=\"mt-2 flex items-center gap-2\">\n {profileHref ? (\n <a\n href={safeHref(profileHref)}\n className=\"rounded-full bg-[color:var(--color-race-red)] px-3 py-1 text-xs font-semibold text-white hover:opacity-90\"\n >\n Set name\n </a>\n ) : null}\n <button\n type=\"button\"\n onClick={() => {\n setDismissed(true)\n try {\n sessionStorage.setItem(KEY, '1')\n } catch {\n /* session-only dismiss */\n }\n }}\n className=\"rounded-full border border-[color:var(--line)] px-3 py-1 text-xs font-semibold text-[color:var(--foreground)] hover:bg-[color:var(--panel)]\"\n >\n Dismiss\n </button>\n </div>\n </div>\n )\n}\n\n/** \"Spencer Hill\" → \"Spencer H.\" — first name + last initial. */\nfunction formatFirstLast(name: string): string {\n const parts = name.split(/\\s+/).filter(Boolean)\n if (parts.length === 1) return parts[0]\n return `${parts[0]} ${parts[parts.length - 1][0].toUpperCase()}.`\n}\n\nfunction ProfileIcon() {\n return (\n <svg width={16} height={16} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <path d=\"M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2\" />\n <circle cx=\"12\" cy=\"7\" r=\"4\" />\n </svg>\n )\n}\n\nfunction BriefcaseIcon() {\n return (\n <svg width={16} height={16} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <rect x=\"2\" y=\"7\" width=\"20\" height=\"14\" rx=\"2\" ry=\"2\" />\n <path d=\"M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16\" />\n </svg>\n )\n}\n\nfunction TrashIcon() {\n return (\n <svg width={14} height={14} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <polyline points=\"3 6 5 6 21 6\" />\n <path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\" />\n </svg>\n )\n}\n\nfunction AddUserIcon() {\n return (\n <svg width={16} height={16} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <path d=\"M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2\" />\n <circle cx=\"8.5\" cy=\"7\" r=\"4\" />\n <line x1=\"20\" y1=\"8\" x2=\"20\" y2=\"14\" />\n <line x1=\"23\" y1=\"11\" x2=\"17\" y2=\"11\" />\n </svg>\n )\n}\n\n// Inline log-out glyph (mirrors lucide `LogOut`) to avoid an icon dependency.\nfunction SignOutIcon() {\n return (\n <svg\n width={15}\n height={15}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\" />\n <polyline points=\"16 17 21 12 16 7\" />\n <line x1=\"21\" x2=\"9\" y1=\"12\" y2=\"12\" />\n </svg>\n )\n}\n\n// A single 32×32 circular icon button for the top bar's structured action list.\n// Renders an <a> when `href` is present (external links open in a new tab),\n// otherwise a <button>. Shows a red count badge when `badge > 0`.\nfunction NavTopBarActionButton({ action }: { action: NavTopBarAction }) {\n const Icon = action.icon\n // Universal treatment (Global Rules v9): size, color and hover are a single\n // shared value across every top-bar slot — only the glyph varies per slot.\n // Tone is a semantic state, not a bespoke per-slot style. The class comes\n // from the ONE shared builder in chromeActions so the data-backed widgets\n // and this structured list can never drift apart.\n const className = topBarIconButtonClass(action.tone ?? 'default')\n\n // Per-slot glyph from Brand; `icon` is the fallback until the token resolves.\n // Brand emits Feather/Lucide glyph NAMES, not asset paths.\n const glyphName = useTopBarIconSlotGlyph(action.slot ?? 'apps')\n const BrandGlyph = action.slot ? resolveBrandGlyph(glyphName) : null\n const Glyph = BrandGlyph ?? Icon\n\n const content = (\n <>\n <Glyph size={20} className=\"text-current\" />\n {typeof action.badge === 'number' && action.badge > 0 ? (\n <span className=\"absolute -top-1 -right-1 flex h-4 min-w-4 items-center justify-center rounded-full bg-[color:var(--color-race-red)] px-1 text-[10px] text-white\">\n {action.badge}\n </span>\n ) : null}\n <TopBarTooltip title={action.label} description={action.description} />\n </>\n )\n\n const isExternal = action.href ? /^https?:\\/\\//.test(action.href) : false\n\n if (action.href) {\n return (\n <a\n href={safeHref(action.href)}\n aria-label={action.label}\n className={className}\n {...(isExternal ? { target: '_blank', rel: 'noreferrer' } : {})}\n >\n {content}\n </a>\n )\n }\n\n return (\n <button\n type=\"button\"\n onClick={action.onClick}\n aria-label={action.label}\n className={className}\n >\n {content}\n </button>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Icon-only tab strip — the standard secondary navigation the three Next.js\n// worker apps (Forms / Surveys / Polls) render below the top bar: a horizontal\n// row of icon-only tabs where the SELECTED tab merges into the content panel\n// below it (top/left/right border, no bottom border, sharing --tab-content-bg).\n//\n// A faithful twin of the hand-rolled `.tabstrip`/`.tab-strip` markup those apps\n// carried, promoted into the shell so every app renders the same accessible,\n// token-driven strip. All geometry is driven by the Brand `--tab-*` CSS vars\n// shipped in chrome.css (with literal fallbacks so the strip still renders in\n// an app that hasn't loaded the runtime tokens link yet):\n// --tab-height (row height) · --tab-icon-size (glyph) · --tab-radius (top\n// corners) · --tab-gap (between tabs) · --tab-content-bg (selected + panel\n// surface) · --tab-unselected-opacity (dimmed inactive tabs, default 0.6).\n// ---------------------------------------------------------------------------\n\nexport type NavTab = {\n /** Stable identity (used as the React key). */\n key: string\n /** Accessible name — becomes both the `title` tooltip and `aria-label`. */\n label: string\n icon: NavIcon\n /** Route to link to (rendered through `linkComponent`). */\n href?: string\n /** Click handler — rendered as a `<button>` when there's no `href`. */\n onSelect?: () => void\n /** Whether this tab is the active one (drives the merged-panel geometry). */\n selected?: boolean\n /**\n * Non-interactive, dimmed tab (e.g. Surveys' Canvas/Results before a survey\n * is chosen). Renders a non-navigating span; `disabledTitle` overrides the\n * tooltip to explain why (falls back to `label`).\n */\n disabled?: boolean\n disabledTitle?: string\n}\n\nexport type NavTabStripProps = {\n tabs: NavTab[]\n /** Accessible name for the tablist. */\n 'aria-label'?: string\n /** Routing primitive for `href` tabs (Next `<Link>`, etc). Defaults to <a>. */\n linkComponent?: NavLinkComponent\n /** Extra classes on the tablist container. */\n className?: string\n /**\n * Optional content panel rendered directly below the strip. When supplied it\n * renders on the shared `--tab-content-bg` surface with a square top-left\n * corner so the selected tab visually merges into it. Omit to render only the\n * strip and compose the panel yourself.\n */\n children?: ReactNode\n}\n\n/** Default icon glyph size — mirrors the `--tab-icon-size` token default. */\nconst TAB_ICON_SIZE = 18\n\nfunction NavTabButton({\n tab,\n Link,\n}: {\n tab: NavTab\n Link: NavLinkComponent\n}) {\n const { label, icon: Icon, href, onSelect, selected, disabled, disabledTitle } = tab\n const title = disabled ? disabledTitle ?? label : label\n\n // Base geometry shared by every state. Selected tabs sit above the content\n // panel (`z-10`) so their missing bottom border merges cleanly into it.\n const base =\n 'inline-flex shrink-0 items-center justify-center border border-b-0 transition-opacity'\n const stateClass = disabled\n ? 'cursor-not-allowed border-transparent opacity-40'\n : selected\n ? 'relative z-10 opacity-100 border-[color:var(--line)]'\n : 'border-transparent opacity-[var(--tab-unselected-opacity,0.6)] hover:opacity-90'\n const className = `${base} ${stateClass}`\n\n const style: CSSProperties = {\n height: 'var(--tab-height, 36px)',\n width: 'var(--tab-width, 40px)',\n color: 'var(--foreground)',\n borderTopLeftRadius: 'var(--tab-radius, 12px)',\n borderTopRightRadius: 'var(--tab-radius, 12px)',\n ...(selected ? { background: 'var(--tab-content-bg)' } : null),\n }\n\n const glyph = <Icon size={TAB_ICON_SIZE} className=\"text-current\" />\n\n // Disabled: non-navigating span, still exposed as a tab for AT.\n if (disabled) {\n return (\n <span\n role=\"tab\"\n aria-selected={false}\n aria-disabled=\"true\"\n aria-label={label}\n title={title}\n className={className}\n style={style}\n >\n {glyph}\n </span>\n )\n }\n\n if (href) {\n return (\n <Link\n href={href}\n role=\"tab\"\n aria-selected={selected ? true : false}\n aria-label={label}\n title={title}\n className={className}\n style={style}\n >\n {glyph}\n </Link>\n )\n }\n\n return (\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={selected ? true : false}\n aria-label={label}\n title={title}\n onClick={onSelect}\n className={className}\n style={style}\n >\n {glyph}\n </button>\n )\n}\n\n/**\n * Icon-only, token-driven tab strip. Render it below `NavTopBar`; pass the\n * app's `Link` as `linkComponent` for `href` tabs. Supply `children` to get the\n * merged content panel, or omit it and compose your own panel on\n * `var(--tab-content-bg)`.\n */\nexport function NavTabStrip({\n tabs,\n 'aria-label': ariaLabel,\n linkComponent,\n className,\n children,\n}: NavTabStripProps) {\n const Link = linkComponent ?? DefaultLink\n return (\n <>\n <div\n role=\"tablist\"\n aria-label={ariaLabel}\n className={['flex items-end gap-[var(--tab-gap,8px)]', className]\n .filter(Boolean)\n .join(' ')}\n >\n {tabs.map((tab) => (\n <NavTabButton key={tab.key} tab={tab} Link={Link} />\n ))}\n </div>\n {children !== undefined ? (\n <div\n className=\"relative -mt-px border border-[color:var(--line)] p-5\"\n style={{\n background: 'var(--tab-content-bg)',\n borderTopLeftRadius: 0,\n borderTopRightRadius: 'var(--tab-radius, 12px)',\n borderBottomLeftRadius: 'var(--tab-radius, 12px)',\n borderBottomRightRadius: 'var(--tab-radius, 12px)',\n }}\n >\n {children}\n </div>\n ) : null}\n </>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Beta banner — a full-width amber NOTICE strip rendered directly below the top\n// bar (a semantic notice, not a chrome surface, so it keeps its amber hue in\n// both themes via the --beta-banner-* tokens in chrome.css). One line, centered,\n// with a bold + underlined link to the Beta Terms & Conditions.\n// ---------------------------------------------------------------------------\n\nconst BETA_BANNER_DEFAULTS = {\n text: 'Our product is in Beta. Thank you for participating in the Pilot Program. ',\n linkLabel: 'You can click here to see the Terms & Conditions for Beta users.',\n href: 'https://app.politogyvrm.com/beta-terms-and-conditions',\n} as const\n\nexport type NavBetaBannerProps = {\n /** Leading sentence(s) before the link. Defaults to the standard Beta copy. */\n text?: string\n /** Bold + underlined link label. Defaults to the standard Terms copy. */\n linkLabel?: string\n /** Terms & Conditions URL (opens in a new tab). Defaults to the app T&C page. */\n href?: string\n}\n\nexport function NavBetaBanner({ text, linkLabel, href }: NavBetaBannerProps) {\n const body = text ?? BETA_BANNER_DEFAULTS.text\n const label = linkLabel ?? BETA_BANNER_DEFAULTS.linkLabel\n const target = href ?? BETA_BANNER_DEFAULTS.href\n return (\n <div\n role=\"note\"\n className=\"w-full px-4 py-2 text-center text-sm\"\n style={{\n // Amber warning fill, matching the \"10DLC Registration Required\" notice\n // (HITL 2026-07-29). This used to fall through to `--color-accent`, the\n // brand RED, so a participation notice read as an error. The\n // --beta-banner-* tokens carry the amber defaults (chrome.css) and a\n // Brand edit still wins over them.\n background: 'var(--beta-banner-bg, #FEEBC8)',\n color: 'var(--beta-banner-text, #1A202C)',\n }}\n >\n <span>{body}</span>\n <a\n href={safeHref(target)}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"font-bold underline\"\n style={{ color: 'var(--beta-banner-text, #1A202C)' }}\n >\n {label}\n </a>\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n\nexport type NavAppShellProps = {\n sidebar: NavSidebarProps\n topBar: NavTopBarProps\n /**\n * When supplied, a full-width Beta notice strip renders directly below the top\n * bar. Presence of the prop enables it; all fields fall back to the standard\n * Beta copy + Terms & Conditions link.\n */\n betaBanner?: NavBetaBannerProps\n /**\n * How the content region wraps `children`.\n *\n * - `'padded'` (default, unchanged): `<main class=\"px-6 py-7\">` around a\n * `mx-auto max-w-7xl` container — what forms / surveys / polls / contacts\n * rely on.\n * - `'bare'`: render `children` directly, with no `<main>`, no gutter and no\n * max-width. For apps that already supply their own page container — VRM\n * wraps every page in the shell's `PageContainer`, which emits its OWN\n * `<main>` + `mx-auto max-w-*` + padding, so the default produced a NESTED\n * `<main>` (invalid HTML) and a doubled gutter on Org Settings, Email\n * Broadcast and SMS/MMS Blast (shell-nav-handoff §1).\n */\n contentWrapper?: 'padded' | 'bare'\n children: ReactNode\n}\n\n/**\n * Full chrome: branded left sidebar + sticky top navbar + scrollable content\n * region. Presentational only — wrap it in app-level auth/gating as needed.\n */\n/**\n * Closes any open chrome <details data-nav-details> (org switcher, mode\n * selector, My Account) when the pointer lands outside it or Escape is\n * pressed — dropdowns must deselect on outside click (HITL 2026-07-23).\n */\nfunction useCloseNavDetailsOnOutsideClick() {\n useEffect(() => {\n const close = (target: Node | null) => {\n document.querySelectorAll('details[data-nav-details][open]').forEach((d) => {\n if (!target || !d.contains(target)) d.removeAttribute('open')\n })\n }\n const onPointerDown = (e: MouseEvent) => close(e.target as Node)\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') close(null)\n }\n document.addEventListener('mousedown', onPointerDown)\n document.addEventListener('keydown', onKey)\n return () => {\n document.removeEventListener('mousedown', onPointerDown)\n document.removeEventListener('keydown', onKey)\n }\n }, [])\n}\n\nexport function NavAppShell({\n sidebar,\n topBar,\n betaBanner,\n contentWrapper = 'padded',\n children,\n}: NavAppShellProps) {\n useCloseNavDetailsOnOutsideClick()\n return (\n <div className=\"min-h-screen bg-[color:var(--background)] text-[color:var(--foreground)]\">\n <NavSidebar {...sidebar} />\n <div className=\"lg:pl-[240px]\">\n <NavTopBar {...topBar} />\n {betaBanner ? <NavBetaBanner {...betaBanner} /> : null}\n {contentWrapper === 'bare' ? (\n children\n ) : (\n <main className=\"px-6 py-7\">\n <div className=\"mx-auto max-w-7xl\">{children}</div>\n </main>\n )}\n </div>\n </div>\n )\n}\n\n// Canonical Politogy VRM menu — the standard nav structure every politogy app\n// renders, per operating Mode, with hooks for the app-owned \"Contacts\" item and\n// Support handler, plus the Campaign feature-availability config.\nexport {\n standardPolitogyNav,\n CAMPAIGN_FEATURE_AVAILABILITY,\n type StandardNavIconKey,\n type StandardNavOptions,\n type StandardNavMode,\n type CampaignFeatureAvailability,\n} from './standardNav'\n","// Universal active-organization selection — the ONE cross-app contract.\n//\n// A user belongs to many orgs; ONE active-org choice must follow them across\n// every Politogy app + subdomain so all apps resolve the SAME org (and campaign\n// apps don't land on a rel-only org and lock themselves). Layers cooperate,\n// mirroring the theme-preference contract:\n// 1. URL `?org=<uuid>` — the authoritative per-request selector. The shared\n// chrome stamps it onto every route so it is bookmarkable + shareable, and\n// each app forwards it to the chrome API as `x-contacts-org`.\n// 2. `.politogyvrm.com` cookie `politogy_active_org` — cross-subdomain vehicle\n// (auth session cookies are host-only) that remembers the LAST USED org so\n// a bare URL in the next app opens on the same org.\n//\n// The stored/most-authoritative value is the FULL org UUID: contacts-api\n// (auth/vrmMembership.selectRequestedMembership) matches the selector by EXACT\n// id first, then falls back to a short suffix that can COLLIDE across a user's\n// orgs — so the full UUID is the only collision-free selector.\n//\n// Server-safe (no 'use client'): constants/resolve helpers are importable from\n// server layouts; the cookie read/write helpers no-op on the server.\n\nexport const ACTIVE_ORG_COOKIE = 'politogy_active_org'\nexport const ACTIVE_ORG_QUERY_PARAM = 'org'\n\n// Loose UUID shape check — we only ever store ids that came from the user's own\n// authoritative membership list, so this just rejects obvious garbage.\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i\n\nexport function isOrgId(v: unknown): v is string {\n return typeof v === 'string' && UUID_RE.test(v.trim())\n}\n\n/** Read the shared active-org cookie (browser only; null on server or unset). */\nexport function readActiveOrgCookie(): string | null {\n if (typeof document === 'undefined') return null\n try {\n const m = document.cookie.match(\n new RegExp(`(?:^|;\\\\s*)${ACTIVE_ORG_COOKIE}=([^;]+)`),\n )\n const v = m ? decodeURIComponent(m[1]) : null\n return isOrgId(v) ? v : null\n } catch {\n return null\n }\n}\n\n// Write the cross-subdomain cookie with the SAME scoping rules as the theme\n// cookie: on a *.politogyvrm.com host scope to the parent domain so every app\n// subdomain reads it; on any other host (localhost, *.pages.dev preview) fall\n// back to a host-only cookie. 1-year, SameSite=Lax, Secure on https.\nexport function writeActiveOrgCookie(orgId: string): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n if (!isOrgId(orgId)) return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n document.cookie = `${ACTIVE_ORG_COOKIE}=${encodeURIComponent(\n orgId,\n )}; Path=/; Max-Age=31536000; SameSite=Lax${domainAttr}${secure}`\n}\n\n/**\n * Read the `?org=` selector from a URL search string (full UUID only). Accepts a\n * `location.search`-style string or a full URL.\n */\nexport function readActiveOrgFromUrl(search: string | null | undefined): string | null {\n if (!search) return null\n try {\n const qs = search.includes('?') ? search.slice(search.indexOf('?') + 1) : search\n const v = new URLSearchParams(qs).get(ACTIVE_ORG_QUERY_PARAM)\n return isOrgId(v) ? v : null\n } catch {\n return null\n }\n}\n\n/**\n * Resolve the active org with the cross-app precedence:\n * 1. `?org=<uuid>` in the current URL (explicit per-request selector)\n * 2. the `.politogyvrm.com` cookie (last used, cross-subdomain)\n * 3. null → let the app fall back to the chrome-API default (earliest-joined)\n * Pass `search` on the server (from the request URL); it defaults to\n * `window.location.search` in the browser.\n */\nexport function resolveActiveOrg(search?: string | null): string | null {\n const fromUrl = readActiveOrgFromUrl(\n search ?? (typeof window !== 'undefined' ? window.location.search : null),\n )\n if (fromUrl) return fromUrl\n return readActiveOrgCookie()\n}\n\n/** The canonical `?org=` query fragment for a full org id (no leading `?`/`&`). */\nexport function activeOrgParam(orgId: string | null | undefined): string {\n return isOrgId(orgId) ? `${ACTIVE_ORG_QUERY_PARAM}=${orgId}` : ''\n}\n\n/**\n * Return `url` with `?org=<uuid>` set/replaced. Used by the shared chrome to\n * stamp the active org onto every route so it is always present in the address\n * bar. Leaves the URL unchanged when `orgId` is not a valid id.\n */\nexport function withActiveOrgParam(url: string, orgId: string | null | undefined): string {\n if (!isOrgId(orgId)) return url\n try {\n // Support both absolute and relative URLs.\n const base = typeof window !== 'undefined' ? window.location.origin : 'https://politogyvrm.com'\n const u = new URL(url, base)\n u.searchParams.set(ACTIVE_ORG_QUERY_PARAM, orgId as string)\n // Preserve relative form when the input was relative.\n return /^https?:\\/\\//i.test(url) ? u.toString() : `${u.pathname}${u.search}${u.hash}`\n } catch {\n return url\n }\n}\n","// Universal navigation-display preference — the same cross-app contract as the\n// theme (see ./theme-preference, which this deliberately mirrors).\n//\n// The user's choice of how navigation renders (Menu / Tabs / Both) follows the\n// authenticated user across every Politogy app + subdomain. Three layers:\n// 1. VRM Core `profiles.nav_display_preference` — source of truth, persisted\n// via the chrome API (`PATCH me/preferences { navDisplay }`) and read back\n// from `GET me` (`navDisplay`).\n// 2. `.politogyvrm.com` cookie `politogy_nav_display` — the cross-subdomain\n// vehicle (app session cookies are host-only, and so is localStorage).\n// 3. localStorage — same-app fast reads and cross-tab `storage` events.\n//\n// Before this existed the preference lived ONLY in localStorage under\n// `vrm.navDisplay`, which is per-ORIGIN: every app subdomain kept its own copy\n// and a freshly opened app booted the default, so the setting appeared not to\n// hold when moving between apps. The legacy key is still read as a fallback so\n// an existing local choice survives the upgrade.\n//\n// Server-safe (no 'use client'): layouts may import NAV_DISPLAY_PREPAINT_SCRIPT.\n\nexport type NavDisplayPreference = 'menu' | 'tabs' | 'both'\n\n// One key for BOTH the localStorage store and the cross-subdomain cookie, so a\n// choice in one app is the same key in the next.\nexport const NAV_DISPLAY_STORAGE_KEY = 'politogy_nav_display'\nexport const NAV_DISPLAY_COOKIE = 'politogy_nav_display'\n\n/** Pre-0.37 host-only key. Read for migration; never written. */\nexport const LEGACY_NAV_DISPLAY_KEY = 'vrm.navDisplay'\n\nexport const NAV_DISPLAY_DEFAULT: NavDisplayPreference = 'both'\n\nconst VALID: readonly NavDisplayPreference[] = ['menu', 'tabs', 'both']\n\nexport function isNavDisplayPreference(v: unknown): v is NavDisplayPreference {\n return typeof v === 'string' && (VALID as readonly string[]).includes(v)\n}\n\n/** Read the shared cookie (browser only; null on the server or when unset). */\nexport function readNavDisplayCookie(): NavDisplayPreference | null {\n if (typeof document === 'undefined') return null\n try {\n const m = document.cookie.match(\n new RegExp(`(?:^|;\\\\s*)${NAV_DISPLAY_COOKIE}=([^;]+)`),\n )\n const v = m ? decodeURIComponent(m[1]) : null\n return isNavDisplayPreference(v) ? v : null\n } catch {\n return null\n }\n}\n\n// Same host-aware scoping as the theme cookie: parent domain on\n// *.politogyvrm.com so every app subdomain reads it, host-only elsewhere\n// (localhost, *.pages.dev preview) because browsers silently drop a mismatched\n// Domain attribute. 1-year, SameSite=Lax, Secure on https.\nexport function writeNavDisplayCookie(pref: NavDisplayPreference): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n document.cookie = `${NAV_DISPLAY_COOKIE}=${encodeURIComponent(\n pref,\n )}; Path=/; Max-Age=31536000; SameSite=Lax${domainAttr}${secure}`\n}\n\n/** Read the local store, falling back to the legacy host-only key. */\nexport function readNavDisplayLocal(): NavDisplayPreference | null {\n if (typeof localStorage === 'undefined') return null\n try {\n const current = localStorage.getItem(NAV_DISPLAY_STORAGE_KEY)\n if (isNavDisplayPreference(current)) return current\n const legacy = localStorage.getItem(LEGACY_NAV_DISPLAY_KEY)\n return isNavDisplayPreference(legacy) ? legacy : null\n } catch {\n return null\n }\n}\n\nexport function writeNavDisplayLocal(pref: NavDisplayPreference): void {\n if (typeof localStorage === 'undefined') return\n try {\n localStorage.setItem(NAV_DISPLAY_STORAGE_KEY, pref)\n } catch {\n /* storage unavailable */\n }\n}\n\n/** Boot precedence: cookie → localStorage (incl. legacy) → default. */\nexport function resolveNavDisplay(): NavDisplayPreference {\n return readNavDisplayCookie() ?? readNavDisplayLocal() ?? NAV_DISPLAY_DEFAULT\n}\n\n// Inline pre-paint script — optional, and the mirror of THEME_PREPAINT_SCRIPT.\n// Nav display has no paint-blocking visual (the frame is client-rendered), but\n// seeding localStorage from the cookie before hydration keeps the first render\n// on the synced value instead of the default. Self-contained and silent.\nexport const NAV_DISPLAY_PREPAINT_SCRIPT = `(function(){try{\nvar KEY=${JSON.stringify(NAV_DISPLAY_STORAGE_KEY)};\nvar VALID=[\"menu\",\"tabs\",\"both\"];\nfunction fromCookie(){try{var m=document.cookie.match(/(?:^|;\\\\s*)${NAV_DISPLAY_COOKIE}=([^;]+)/);return m?decodeURIComponent(m[1]):null;}catch(e){return null;}}\nvar cookie=fromCookie();\nif(cookie&&VALID.indexOf(cookie)!==-1){var ls=null;try{ls=localStorage.getItem(KEY);}catch(e){}\nif(cookie!==ls){try{localStorage.setItem(KEY,cookie);}catch(e){}}}\n}catch(e){}})();`\n","// Breadcrumb derivation — pure, dependency-free logic (no React, no DevNotes),\n// so it is importable from a server module and testable in isolation.\n//\n// The standard is Dashboard > Sub > Item (HITL 2026-07-23), derived from the\n// same nav tree the sidebar renders. Apps previously hand-built their own\n// trails and disagreed: forms rendered \"Forms > Dashboard\" while polls rendered\n// a lone \"Polls\" crumb under a \"Polls\" title (\"Polls / Polls\").\n\nimport type { NavBreadcrumb, NavItem } from '../native/index'\n\nexport function deriveBreadcrumbs(\n items: NavItem[],\n pathname: string,\n opts?: { search?: string; origin?: string },\n): NavBreadcrumb[] {\n const search = opts?.search ?? (typeof window !== 'undefined' ? window.location.search : '')\n const origin = opts?.origin ?? (typeof window !== 'undefined' ? window.location.origin : '')\n\n // Same-origin comparison: cross-app hrefs are absolute, local ones relative.\n const matches = (href?: string): boolean => {\n if (!href) return false\n let path = href\n let query = ''\n if (/^https?:\\/\\//i.test(href)) {\n try {\n const u = new URL(href)\n if (origin && u.origin !== origin) return false\n path = u.pathname\n query = u.search\n } catch {\n return false\n }\n } else {\n const qi = href.indexOf('?')\n if (qi >= 0) {\n path = href.slice(0, qi) || '/'\n query = href.slice(qi)\n }\n }\n if (path !== pathname) return false\n if (!query) return true\n const want = new URLSearchParams(query)\n const have = new URLSearchParams(search)\n for (const [k, v] of want) if (have.get(k) !== v) return false\n return true\n }\n\n // Depth-first walk for the deepest item owning the current route.\n const walk = (nodes: NavItem[], trail: NavItem[]): NavItem[] | null => {\n for (const node of nodes) {\n const here = [...trail, node]\n if (node.children?.length) {\n const deeper = walk(node.children, here)\n if (deeper) return deeper\n }\n if (matches(node.href)) return here\n }\n return null\n }\n\n const trail = walk(items, [])\n // Always anchored at Dashboard; the last crumb is the current location and\n // carries no href (the shell marks it aria-current=\"page\").\n const dashboard = items.find((i) => i.label === 'Dashboard')\n const crumbs: NavBreadcrumb[] = [{ label: 'Dashboard', href: dashboard?.href }]\n if (!trail) return crumbs\n for (const node of trail) {\n if (node.label === 'Dashboard') continue\n crumbs.push({ label: node.label, href: node.href })\n }\n const last = crumbs[crumbs.length - 1]\n if (last) delete (last as { href?: string }).href\n return crumbs\n}\n","// Identity resolution — pure logic, shared by the chrome hook.\n//\n// The chrome API (VRM-core profile) is the AUTHORITY for a user's display name;\n// what an app knows from its own session token is a pre-hydration fallback. An\n// email is never a name: forms passed `user.name ?? user.email`, so a user with\n// no name set had their email rendered as their name in the top bar and the\n// shell's \"add your name\" affordance never fired (HITL 2026-07-23).\n\nexport type ResolvedIdentity = {\n userName: string | null\n email: string | null\n avatarUrl: string | null\n loaded: boolean\n}\n\n/** True when a \"name\" is really just an email address. */\nexport function looksLikeEmail(value: string | null | undefined): boolean {\n return typeof value === 'string' && /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value.trim())\n}\n\nexport function resolveIdentity(input: {\n apiName?: string | null\n fallbackName?: string | null\n email?: string | null\n avatarUrl?: string | null\n loaded?: boolean\n}): ResolvedIdentity {\n const apiName = looksLikeEmail(input.apiName) ? null : input.apiName ?? null\n const fallbackName = looksLikeEmail(input.fallbackName) ? null : input.fallbackName ?? null\n return {\n userName: apiName ?? fallbackName,\n email: input.email ?? null,\n avatarUrl: input.avatarUrl ?? null,\n loaded: input.loaded ?? false,\n }\n}\n","// Universal sign-out propagation — the ONE cross-app logout contract.\n//\n// Every Politogy app holds its OWN host-only session cookie with a long sliding\n// window, so signing out of one app used to leave every other open tab — and\n// every other subdomain — signed in until its cookie happened to expire. A user\n// who signs out in Contacts and switches to the Forms tab they already had open\n// is still fully authenticated there. That is the bug this module closes.\n//\n// The vehicle mirrors the active-org contract: a `.politogyvrm.com` cookie that\n// every subdomain can read. It carries a single monotonic value — the epoch\n// milliseconds at which the user signed out.\n//\n// politogy_logout_at = <epoch ms of the most recent sign-out>\n//\n// Two layers cooperate, and BOTH are required:\n//\n// 1. SERVER (authoritative). Each app's middleware compares this cookie\n// against the session's `auth_time`. A session minted BEFORE the last\n// sign-out is dead, whatever its own expiry says — so a reload, a\n// bookmark, or a restored tab can never resurrect it. See\n// `isSessionRevoked`.\n//\n// 2. CLIENT (immediacy). Open tabs are not making requests, so the server\n// layer alone only takes effect on their next navigation. `watchLogout`\n// notices the cookie change within ~1s and navigates the tab out.\n//\n// The cookie is deliberately NOT HttpOnly: it holds no secret — just a\n// timestamp — and every tab on every subdomain must be able to read it from\n// JavaScript. It grants nothing; it only ever revokes.\n//\n// Server-safe (no 'use client'): the constants and `isSessionRevoked` are\n// importable from middleware and server components; the browser helpers no-op\n// on the server.\n\nexport const LOGOUT_COOKIE = 'politogy_logout_at'\n\n/** Same-origin instant channel; cross-subdomain falls back to the cookie poll. */\nconst LOGOUT_CHANNEL = 'politogy-logout'\n\n/** How often a tab re-reads the cookie. Cheap: a string compare, no I/O. */\nconst POLL_MS = 1000\n\nfunction parseTimestamp(value: string | null | undefined): number | null {\n if (!value) return null\n const n = Number(value)\n return Number.isFinite(n) && n > 0 ? n : null\n}\n\n/**\n * Server-side authority. Given the logout-cookie value and the moment this\n * session was authenticated, is the session revoked?\n *\n * `authTime` is the OIDC `auth_time` (seconds) or an equivalent millisecond\n * timestamp captured when the session was minted. Sessions with no recorded\n * auth time are treated as revoked whenever a logout is on record: we cannot\n * prove they postdate it, and failing closed is the only safe direction for a\n * sign-out.\n */\nexport function isSessionRevoked(\n logoutCookieValue: string | null | undefined,\n authTime: number | null | undefined,\n): boolean {\n const loggedOutAt = parseTimestamp(logoutCookieValue)\n if (loggedOutAt === null) return false\n if (authTime == null || !Number.isFinite(authTime) || authTime <= 0) return true\n // Accept either seconds (OIDC auth_time) or milliseconds.\n const authMs = authTime < 1e12 ? authTime * 1000 : authTime\n return authMs < loggedOutAt\n}\n\n/** Read the shared logout timestamp (browser only; null on server or unset). */\nexport function readLogoutCookie(): number | null {\n if (typeof document === 'undefined') return null\n try {\n const m = document.cookie.match(new RegExp(`(?:^|;\\\\s*)${LOGOUT_COOKIE}=([^;]+)`))\n return parseTimestamp(m ? decodeURIComponent(m[1]) : null)\n } catch {\n return null\n }\n}\n\n/**\n * Record a sign-out for every tab on every Politogy subdomain. Call this\n * BEFORE navigating to the app's sign-out route, so tabs that are already open\n * see it immediately rather than after the round trip.\n *\n * Scoping mirrors the active-org and theme cookies: parent-domain on\n * *.politogyvrm.com so all app subdomains read it, host-only anywhere else\n * (localhost, *.pages.dev previews).\n */\nexport function broadcastLogout(at: number = Date.now()): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n // 30 days: comfortably longer than the longest app session window, so a tab\n // resumed from sleep still sees the revocation. Shorter than that and a stale\n // session could outlive the signal that killed it.\n document.cookie = `${LOGOUT_COOKIE}=${at}; Path=/; Max-Age=2592000; SameSite=Lax${domainAttr}${secure}`\n try {\n new BroadcastChannel(LOGOUT_CHANNEL).postMessage(at)\n } catch {\n // No BroadcastChannel (older Safari) — the cookie poll covers it.\n }\n}\n\n/**\n * Clear the signal. Call after a successful LOGIN: the new session postdates\n * the old sign-out, and leaving the cookie behind would make every future\n * `isSessionRevoked` check depend on clock skew between the two.\n */\nexport function clearLogoutSignal(): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n document.cookie = `${LOGOUT_COOKIE}=; Path=/; Max-Age=0; SameSite=Lax${domainAttr}`\n}\n\nexport type WatchLogoutOptions = {\n /**\n * Sessions minted at or before this moment are revoked by a sign-out. Pass\n * the session's auth time; when omitted, ANY logout signal observed after the\n * watcher starts fires the callback (correct for an already-open tab, which\n * by definition authenticated earlier).\n */\n authTime?: number | null\n /** Poll interval override, for tests. */\n intervalMs?: number\n}\n\n/**\n * Watch for a sign-out that happened in ANY other tab or window, on this or any\n * sibling Politogy subdomain, and invoke `onLogout` once.\n *\n * Returns an unsubscribe function.\n *\n * Three signals, cheapest first:\n * - BroadcastChannel — instant, same-origin only.\n * - visibility/focus/pageshow — the moment a backgrounded tab is looked at.\n * - a ~1s cookie poll — the cross-subdomain path, and the backstop for a\n * visible tab the user is staring at but not interacting with.\n */\nexport function watchLogout(\n onLogout: () => void,\n options: WatchLogoutOptions = {},\n): () => void {\n if (typeof document === 'undefined' || typeof window === 'undefined') {\n return () => {}\n }\n\n const { authTime = null, intervalMs = POLL_MS } = options\n // Anything already on record when this tab started is not news: the server\n // layer decides whether THIS session is revoked, and it has already let the\n // page render. Only a signal newer than our baseline means \"someone just\n // signed out\".\n const baseline = readLogoutCookie() ?? 0\n let done = false\n\n const fire = (at: number) => {\n if (done) return\n if (at <= baseline) return\n if (authTime != null && !isSessionRevoked(String(at), authTime)) return\n done = true\n cleanup()\n onLogout()\n }\n\n const check = () => {\n const at = readLogoutCookie()\n if (at !== null) fire(at)\n }\n\n let channel: BroadcastChannel | null = null\n try {\n channel = new BroadcastChannel(LOGOUT_CHANNEL)\n channel.onmessage = (event) => {\n const at = typeof event.data === 'number' ? event.data : readLogoutCookie()\n if (at !== null) fire(at)\n }\n } catch {\n channel = null\n }\n\n const timer = window.setInterval(check, intervalMs)\n window.addEventListener('visibilitychange', check)\n window.addEventListener('focus', check)\n window.addEventListener('pageshow', check)\n\n function cleanup() {\n window.clearInterval(timer)\n window.removeEventListener('visibilitychange', check)\n window.removeEventListener('focus', check)\n window.removeEventListener('pageshow', check)\n try {\n channel?.close()\n } catch {\n /* already closed */\n }\n }\n\n return cleanup\n}\n","// ---------------------------------------------------------------------------\n// PolitogyAppFrame — ONE component that renders the entire app frame.\n//\n// Why this exists (HITL directive 2026-07-23): shipping the same npm package at\n// the same version is necessary but NOT sufficient. The package exposed\n// PRIMITIVES (NavAppShell + a dozen hooks) and every app hand-assembled them in\n// its own ~150-line Shell.tsx. Identical inputs were never guaranteed, so the\n// outputs diverged — measured on production: forms rendered its user's EMAIL as\n// their name, polls' breadcrumb read \"Polls / Polls\", forms and surveys pinned\n// the mode pill to a hardcoded \"relationship\", and each app declared its own\n// chrome CSS variables (surveys' accent was #C8102E where everyone else was\n// #E63946).\n//\n// The fix is to stop exporting assembly as an app responsibility. An app now\n// renders:\n//\n// <PolitogyAppFrame app=\"forms\" pathname={pathname} linkComponent={Link}\n// session={{ userId, email, role, accountName, accountId }}\n// onSignOut={signOut}>\n// {children}\n// </PolitogyAppFrame>\n//\n// and passes NOTHING about the chrome: no nav, no breadcrumbs, no title, no\n// mode, no user menu, no footer, no theme. Those are derived here, identically,\n// for every app. Anything an app cannot pass is something it cannot drift on.\n// ---------------------------------------------------------------------------\n\n'use client'\n\nimport { useCallback, useEffect, useMemo, useRef, type ReactNode } from 'react'\n\nimport { broadcastLogout, watchLogout } from '../logout-signal'\nimport {\n NavAppShell,\n standardPolitogyNav,\n type NavLinkComponent,\n} from '../native/index'\nimport {\n ChromeTopBarActions,\n PolitogyAppChrome,\n standardNavIcons,\n useChromeFooter,\n useChromeIdentity,\n useChromeMode,\n useChromeState,\n useChromeUserMenu,\n type ChromeDevNotesConfig,\n type ControlledOrgState,\n} from './index'\nimport type {\n NavBreadcrumb,\n NavChromeFetcher,\n NavItem,\n NavMode,\n NavUserMenu,\n} from '../native/index'\nimport type { StandardNavMode } from '../native/standardNav'\nimport { deriveBreadcrumbs } from '../lib/breadcrumbs'\n\n/**\n * The core app — the one that OWNS the canonical nav tree and routes in-app.\n * `PolitogyFrameData.core` is honored for this key and no other.\n */\nconst CORE_APP: PolitogyAppKey = 'vrm'\n\n/**\n * Template A convention: every feature app exposes GET /auth/signout, which\n * clears its session cookie and 302s to the IdP's end_session endpoint. Apps\n * that route sign-out elsewhere (core: /api/auth/logout) pass `signOutUrl`.\n */\nconst DEFAULT_SIGN_OUT_URL = '/auth/signout'\n\n/** Every app that renders the shared chrome. Keyed by its subdomain. */\nexport type PolitogyAppKey =\n | 'vrm'\n | 'contacts'\n | 'forms'\n | 'surveys'\n | 'polls'\n | 'petitions'\n // Campaign Mode standalone apps.\n | 'a2p'\n | 'phonebank'\n | 'canvass'\n | 'signs'\n\n/**\n * The operating Mode an app is scoped to, if any. It drives two things,\n * BOTH derived here from app identity so no app passes chrome config:\n * 1. the standardPolitogyNav tree the sidebar renders, and\n * 2. the static Mode pill the app shows (a campaign app shows a Campaign\n * pill, never Relationship).\n * An UNSCOPED app (no `mode`) keeps its prior behavior exactly: the\n * Relationship tree + an entitlement-driven Mode pill.\n */\nexport type PolitogyAppMode = StandardNavMode\n\n/**\n * The per-app registry — the ONLY place app identity lives. A new app adds a\n * row here and inherits every chrome behavior; it never re-derives one.\n */\nexport const POLITOGY_APPS: Record<\n PolitogyAppKey,\n { title: string; origin: string; storagePrefix: string; mode?: PolitogyAppMode }\n> = {\n vrm: { title: 'Politogy VRM', origin: 'https://app.politogyvrm.com', storagePrefix: 'vrm' },\n contacts: { title: 'Contacts', origin: 'https://contacts.politogyvrm.com', storagePrefix: 'contacts' },\n forms: { title: 'Forms', origin: 'https://forms.politogyvrm.com', storagePrefix: 'forms' },\n surveys: { title: 'Surveys', origin: 'https://surveys.politogyvrm.com', storagePrefix: 'surveys' },\n polls: { title: 'Polls', origin: 'https://polls.politogyvrm.com', storagePrefix: 'polls' },\n petitions: {\n title: 'Petitions',\n origin: 'https://petition-mode.politogyvrm.com',\n storagePrefix: 'petitions',\n mode: 'petition',\n },\n // Campaign Mode apps — each scoped to Campaign, so they render the Campaign\n // tree and a static Campaign pill. Not yet deployed; hidden from the Campaign\n // nav by CAMPAIGN_FEATURE_AVAILABILITY until their launch flips the flag.\n a2p: { title: 'A2P Messaging', origin: 'https://a2p.politogyvrm.com', storagePrefix: 'a2p', mode: 'campaign' },\n phonebank: { title: 'Phone Banking', origin: 'https://phonebank.politogyvrm.com', storagePrefix: 'phonebank', mode: 'campaign' },\n canvass: { title: 'Field Canvassing', origin: 'https://canvass.politogyvrm.com', storagePrefix: 'canvass', mode: 'campaign' },\n signs: { title: 'Sign Mapping', origin: 'https://signs.politogyvrm.com', storagePrefix: 'signs', mode: 'campaign' },\n}\n\nexport type PolitogyAppSession = {\n /** Stable IdP subject (`sub`). */\n userId: string\n email: string | null\n /** The app's own role string — feeds DevNotes admin gating. */\n role: string\n /** The app's own workspace label, used only until core orgs resolve. */\n accountName: string\n accountId: string\n /**\n * Pre-hydration display name ONLY. The chrome API is the authority; an email\n * passed here is discarded rather than rendered as a name.\n */\n userName?: string | null\n}\n\n/**\n * Optional DATA plumbing for apps whose session/auth differs — never styling.\n *\n * Everything here is about WHERE data comes from (which fetcher, which org\n * state, which routes an app owns), not what the chrome looks like. Adding a\n * visual option to this type would re-open the drift this component exists to\n * close.\n */\nexport type PolitogyFrameData = {\n /** Chrome-API fetcher override for apps that authenticate client-side. */\n fetchJson?: NavChromeFetcher\n /** DevNotes wiring override for those same direct-auth apps. */\n devNotes?: ChromeDevNotesConfig\n /** Controlled org state for apps that own active-org + switching. */\n org?: ControlledOrgState\n /** App-owned children for a standard nav entry this app owns (Contacts). */\n contactsItem?: { href?: string; children?: NavItem[] }\n /** Avatar fallback when the profile has no uploaded photo (memoji, default). */\n fallbackAvatarUrl?: string | null\n /**\n * CORE-ONLY frame inputs. **Honored only when `app` is the core app (`vrm`)\n * — silently ignored for every other app**, which is what keeps the\n * no-drift guarantee intact: a feature app cannot re-specify a chrome\n * element even by passing this, so the props are inert for it.\n *\n * Core is genuinely different, and pretending otherwise would have meant\n * REMOVING shipped behavior from app.politogyvrm.com to satisfy packaging —\n * which Reference/UI-Platform forbids (\"migration may not drop a shipped\n * element … extend the shell first, then migrate\"). Specifically, core:\n * - owns the canonical nav tree AND decorates it with live entitlement\n * state a static tree cannot express (10DLC gating, contact/group\n * counts, org-lock),\n * - routes in-app (react-router), so its rows must be app-relative paths,\n * not the absolute cross-app URLs `standardPolitogyNav` emits,\n * - publishes per-page title/breadcrumbs from 66 page components,\n * - switches Mode client-side rather than by full-page navigation,\n * - owns real linked-account switching (with its own modals).\n *\n * Everything here is still DATA or app-owned STATE. There is no styling\n * input, no ordering input, and no way to change the top-bar action cluster\n * — those stay identical for every app, core included.\n */\n core?: PolitogyCoreFrame\n}\n\n/** See `PolitogyFrameData.core` — core app (`vrm`) only. */\nexport type PolitogyCoreFrame = {\n /** The canonical nav tree, decorated with core's live entitlement state. */\n nav?: NavItem[]\n /** Per-page identity published by core's own pages. */\n page?: { title?: string; breadcrumbs?: NavBreadcrumb[]; actions?: ReactNode }\n /** Client-side Mode switching (core navigates in-app, not cross-origin). */\n mode?: NavMode\n /** Real linked-account switching + core's theme persistence. */\n userMenu?: NavUserMenu\n /** Mode-specific brand wordmark (core swaps it per operating Mode). */\n brandLogoSrc?: string\n /** Core wraps every page in PageContainer, which emits its own <main>. */\n contentWrapper?: 'padded' | 'bare'\n}\n\nexport type PolitogyBuildMeta = {\n envLabel?: string\n version?: string\n commit?: string\n commitDate?: string\n commitAuthor?: string\n}\n\nexport function PolitogyAppFrame({\n app,\n pathname,\n search,\n linkComponent,\n session,\n onSignOut,\n signOutUrl = DEFAULT_SIGN_OUT_URL,\n buildMeta,\n data,\n children,\n}: {\n app: PolitogyAppKey\n /** Current path from the app's router (Next: usePathname()). */\n pathname: string\n /** Current query string, when the app routes by query (forms' ?tab=). */\n search?: string\n /** The app's routing primitive (Next: <Link>). */\n linkComponent: NavLinkComponent\n session: PolitogyAppSession\n onSignOut: () => void\n /**\n * The app's sign-out ROUTE — a GET endpoint that clears the session cookie\n * and redirects to RP-initiated logout at the IdP. Defaults to the Template A\n * convention; core overrides it. This, not `onSignOut`, is what actually\n * signs the user out (see handleSignOut).\n */\n signOutUrl?: string\n buildMeta?: PolitogyBuildMeta\n /** Optional DATA plumbing (never styling) — see PolitogyFrameData. */\n data?: PolitogyFrameData\n children: ReactNode\n}) {\n const meta = POLITOGY_APPS[app]\n return (\n <PolitogyAppChrome\n storagePrefix={meta.storagePrefix}\n fetchJson={data?.fetchJson}\n devNotes={data?.devNotes}\n org={data?.org}\n identity={{\n userId: session.userId,\n userName: session.userName ?? null,\n email: session.email,\n role: session.role,\n }}\n >\n <FrameBody\n app={app}\n pathname={pathname}\n search={search}\n linkComponent={linkComponent}\n session={session}\n onSignOut={onSignOut}\n signOutUrl={signOutUrl}\n buildMeta={buildMeta}\n data={data}\n >\n {children}\n </FrameBody>\n </PolitogyAppChrome>\n )\n}\n\nfunction FrameBody({\n app,\n pathname,\n search,\n linkComponent,\n session,\n onSignOut,\n signOutUrl,\n buildMeta,\n data,\n children,\n}: {\n app: PolitogyAppKey\n pathname: string\n search?: string\n linkComponent: NavLinkComponent\n session: PolitogyAppSession\n onSignOut: () => void\n signOutUrl: string\n buildMeta?: PolitogyBuildMeta\n data?: PolitogyFrameData\n children: ReactNode\n}) {\n const meta = POLITOGY_APPS[app]\n const chrome = useChromeState()\n\n // Sign-out is a PLATFORM event, not an app event. Each app holds its own\n // host-only session cookie with a long sliding window, so without this a user\n // who signed out in one tab stayed fully signed in in every other open tab\n // and on every other subdomain. Announce the sign-out to all of them, then\n // run the app's own sign-out.\n //\n // Every app reaches sign-out through this frame, so wiring it here covers the\n // whole estate without an app having to opt in — the same guarantee the rest\n // of the chrome relies on.\n const signOutRef = useRef(onSignOut)\n signOutRef.current = onSignOut\n // This tab started the sign-out, so its own watcher must not also fire and\n // run the app's sign-out a second time concurrently.\n const signingOutRef = useRef(false)\n\n const handleSignOut = useCallback(() => {\n signingOutRef.current = true\n broadcastLogout()\n // Navigate to the app's sign-out ROUTE. Apps also pass an onSignOut\n // handler, but it cannot be relied on: they wire it as\n // `onSignOut={() => { void signOutAction(); }}`, and a server action\n // invoked outside a transition can never have its redirect() applied by\n // the client. Measured against production 2026-07-25: clicking Sign out\n // left the user signed in, and an app they had never opened authenticated\n // with no credentials — the IdP session was still alive because the\n // browser never reached its end-session endpoint.\n //\n // A plain navigation to a GET route cannot fail that way: the route drops\n // the session cookie and 302s to RP-initiated logout at the IdP.\n signOutRef.current()\n window.location.assign(signOutUrl)\n }, [signOutUrl])\n\n useEffect(\n () =>\n // A tab that learns of a sign-out elsewhere ends its own session for\n // real, by navigating to the same sign-out route.\n //\n // Measured against production before this landed: calling the app's\n // handler did nothing at all. Apps wire it as\n // `onSignOut={() => { void signOutAction(); }}` — a server action invoked\n // outside a transition, so the `redirect()` inside it can never be\n // applied by the client and the tab just sits there. Building cross-tab\n // logout on that path made the whole feature a no-op.\n //\n // A hard navigation cannot fail that way, and it hands the decision to\n // the authority rather than guessing: the app's middleware sees a session\n // whose auth_time predates `politogy_logout_at`, treats it as revoked,\n // and redirects to Politogy ID. Server-side truth decides; the client\n // only forces the request. No re-broadcast — the signal that woke us is\n // already on record for every tab.\n watchLogout(() => {\n if (signingOutRef.current) return\n window.location.assign(signOutUrl)\n }),\n [signOutUrl],\n )\n // Core-only inputs are read through this ONE gate. For every other app it is\n // undefined no matter what the app passed, so the \"an app cannot re-specify a\n // chrome element\" guarantee holds by construction, not by convention.\n const core = app === CORE_APP ? data?.core : undefined\n\n // Identity: chrome API wins, app claims are a fallback, an email is never a\n // name (that is what forms was rendering in the top right).\n const identity = useChromeIdentity({ userName: session.userName, email: session.email })\n const derivedUserMenu = useChromeUserMenu({\n userId: session.userId,\n userName: identity.userName,\n email: identity.email,\n })\n const userMenu = core?.userMenu ?? derivedUserMenu\n const footer = useChromeFooter(buildMeta ?? {})\n // A mode-scoped app (Campaign apps, Petitions) pins its pill to its own mode;\n // an unscoped app stays entitlement + user-selection driven. Either way no\n // app passes a mode — it is read from the registry (app identity).\n const appMode = meta.mode\n const derivedMode = useChromeMode(appMode ? { pinnedModeId: appMode } : undefined)\n // Core switches Mode client-side; every other app jumps to the mode's home.\n const mode = core?.mode ?? derivedMode\n\n const coreOrgs = chrome?.orgs ?? []\n const activeCoreOrg = coreOrgs.find((o) => o.id === chrome?.orgId) ?? null\n const navDisplay = chrome?.navDisplay ?? 'both'\n\n // The nav tree follows the app's OWN mode (registry), not the live pill\n // selection — so it is deterministic from app identity. Unscoped apps render\n // Relationship exactly as before. Cross-app links in the Campaign/Petition\n // trees carry the active org the way the switcher/account menu do.\n const navMode: StandardNavMode = appMode ?? 'relationship'\n const activeOrgId = chrome?.orgId ?? null\n const derivedNavItems = useMemo(\n () =>\n standardPolitogyNav({\n coreBaseUrl: POLITOGY_APPS.vrm.origin,\n icons: standardNavIcons,\n // An app that OWNS a standard nav entry (Contacts) nests its own routes\n // under it. This is routing data, not chrome configuration.\n contactsItem: data?.contactsItem,\n mode: navMode,\n activeOrgId,\n }),\n [data?.contactsItem, navMode, activeOrgId],\n )\n // Core supplies the canonical tree already decorated with its live gating\n // state (and with app-relative hrefs so its router handles them in-app).\n const navItems = core?.nav ?? derivedNavItems\n\n // Dashboard › Sub › Item, derived from the same tree the sidebar renders.\n // Core publishes its trail from the page itself, because a core page's\n // location is finer-grained than its nav row (e.g. a contact detail view).\n const derivedBreadcrumbs = useMemo(\n () => deriveBreadcrumbs(navItems, pathname, { search, origin: meta.origin }),\n [navItems, pathname, search, meta.origin],\n )\n const breadcrumbs = core ? core.page?.breadcrumbs : derivedBreadcrumbs\n\n return (\n <NavAppShell\n sidebar={{\n pathname,\n brand: {\n logoSrc: core?.brandLogoSrc ?? '/brand/logos/relationship-mode-logo.png',\n logoAlt: 'Politogy',\n badgeLabel: 'P',\n title: 'Politogy',\n },\n nav: {\n items:\n navDisplay === 'tabs'\n ? navItems.map(({ children: _sub, ...item }) => item)\n : navItems,\n },\n // The app's own workspace is NOT the organization — it is a per-app\n // bootstrap account with a different id in every app. Showing it while\n // the chrome API resolves flashed the wrong org on every load (\"not\n // connected to the account\"). Shimmer while in flight; only fall back\n // to the app label once the chrome lookup has actually failed.\n org: activeCoreOrg\n ? {\n name: activeCoreOrg.name,\n id: activeCoreOrg.id,\n logoUrl: activeCoreOrg.logoUrl,\n brandColor: activeCoreOrg.brandColor,\n organizations: coreOrgs,\n onSwitch: chrome?.setOrgId,\n }\n : chrome?.orgsLoading\n ? { name: null, id: null, loading: true }\n : { name: session.accountName, id: session.accountId },\n mode,\n footer,\n linkComponent,\n }}\n betaBanner={{}}\n contentWrapper={core?.contentWrapper}\n topBar={{\n // Core's pages publish their own identity; every other app is one\n // product surface and takes its registry title.\n title: core?.page?.title ?? meta.title,\n breadcrumbs,\n user: {\n name: identity.userName,\n email: identity.email,\n // The chrome API's avatar wins; the app may supply a fallback chain\n // (e.g. a stored memoji) for users with no uploaded photo.\n avatarUrl: identity.avatarUrl ?? data?.fallbackAvatarUrl ?? null,\n role: session.role,\n },\n userMenu,\n onSignOut: handleSignOut,\n // The action cluster is IDENTICAL everywhere — core included. Page\n // actions sit BEFORE it, never inside it, so the Alerts bell keeps its\n // required position: farthest right, immediately before My Account.\n actions: (\n <>\n {core?.page?.actions}\n <ChromeTopBarActions />\n </>\n ),\n }}\n >\n {children}\n </NavAppShell>\n )\n}\n","// ---------------------------------------------------------------------------\n// App chrome wiring — the ONE shared implementation of the per-app glue that\n// previously lived as a copied ChromeWidgets.tsx in every Next.js feature app\n// (forms / surveys / polls / contacts). Copies drifted (org dropdown, badges);\n// this module makes that class of drift impossible: apps configure, never\n// re-implement (Reference/UI-Platform: consume via npm, never vendored).\n//\n// Provides:\n// <PolitogyAppChrome> — NavChromeProvider (same-origin proxy fetcher) +\n// chrome state (active core org, nav display) +\n// DevNotes provider, in one wrapper.\n// <ChromeTopBarActions> — the canonical top-bar cluster, in canonical order\n// (Fuel · Nav display · DevNotes · Support · Alerts\n// LAST, immediately left of My Account).\n// useChromeState / useChromeUserMenu / useIsSuperAdmin / useChromeFooter.\n//\n// The app still owns: its session (the /api/chrome proxy), page frames, build\n// metadata (env/commit/version), tab strips, and its own icons.\n// ---------------------------------------------------------------------------\n\n'use client'\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react'\nimport {\n NavChromeProvider,\n FuelAction,\n NotificationsAction,\n SupportAction,\n NavDisplayAction,\n TopBarWidgetSlot,\n useChromeOrgs,\n useThemePreference,\n type NavChromeFetcher,\n type NavDisplayMode,\n type NavOrgOption,\n type NavUserMenu,\n type NavFooter,\n type NavFooterLink,\n} from '../native/index'\nimport {\n DevNotesProvider,\n DevNotesMenu,\n DevNotesOverlay,\n DevNotesTaskListModal,\n createDevNotesClient,\n type DevNotesConfig,\n} from '@the-portland-company/devnotes'\nimport {\n FiActivity,\n FiBarChart2,\n FiBriefcase,\n FiClock,\n FiCreditCard,\n FiDollarSign,\n FiEdit3,\n FiFileText,\n FiFlag,\n FiGrid,\n FiHome,\n FiLayout,\n FiLifeBuoy,\n FiList,\n FiMail,\n FiMap,\n FiMapPin,\n FiMessageSquare,\n FiPhone,\n FiSend,\n FiSettings,\n FiShare2,\n FiTarget,\n FiUpload,\n FiUser,\n FiUsers,\n} from 'react-icons/fi'\nimport { useChromeMe, useNavChromeFetcher } from '../native/index'\nimport {\n ACTIVE_ORG_QUERY_PARAM,\n isOrgId,\n resolveActiveOrg,\n writeActiveOrgCookie,\n} from '../active-org'\nimport {\n NAV_DISPLAY_DEFAULT,\n NAV_DISPLAY_STORAGE_KEY,\n isNavDisplayPreference,\n readNavDisplayCookie,\n resolveNavDisplay,\n writeNavDisplayCookie,\n writeNavDisplayLocal,\n} from '../nav-preference'\nimport type { StandardNavIconKey } from '../native/standardNav'\nimport type { NavBreadcrumb, NavIcon, NavItem, NavMode } from '../native/index'\n\n/**\n * The canonical icon map for standardPolitogyNav — ONE definition so every\n * app renders identical glyphs (including the Organization Settings branch:\n * briefcase / settings / creditCard / dollarSign / share).\n */\nexport const standardNavIcons: Record<StandardNavIconKey, NavIcon> = {\n home: FiHome,\n users: FiUsers,\n mail: FiMail,\n messageSquare: FiMessageSquare,\n layout: FiLayout,\n activity: FiActivity,\n lifeBuoy: FiLifeBuoy,\n grid: FiGrid,\n list: FiList,\n upload: FiUpload,\n edit: FiEdit3,\n fileText: FiFileText,\n send: FiSend,\n clock: FiClock,\n user: FiUser,\n barChart: FiBarChart2,\n briefcase: FiBriefcase,\n settings: FiSettings,\n creditCard: FiCreditCard,\n dollarSign: FiDollarSign,\n share: FiShare2,\n // Campaign / Petition mode slots.\n phone: FiPhone,\n map: FiMap,\n mapPin: FiMapPin,\n target: FiTarget,\n flag: FiFlag,\n}\n\nconst ORG_STORAGE_KEY = 'vrm.activeOrg'\n// The user's mode choice, shared by every app on the origin's localStorage.\nconst MODE_STORAGE_KEY = 'vrm.activeMode'\nconst CORE_BASE_URL = 'https://app.politogyvrm.com'\n\nexport type ChromeIdentity = {\n userId: string\n userName: string | null\n email: string | null\n /** The APP's own role string (any casing) — feeds DevNotes admin gating. */\n role: string\n}\n\ntype ChromeState = {\n orgId: string | null\n setOrgId: (id: string) => void\n orgs: (NavOrgOption & { rawRole?: string | null })[]\n /**\n * The org list is still in flight. Consumers must render a skeleton rather\n * than fall back to the app's own workspace label, which is a DIFFERENT\n * account and flashes as the wrong organization.\n */\n orgsLoading: boolean\n navDisplay: NavDisplayMode\n setNavDisplay: (m: NavDisplayMode) => void\n}\n\nconst ChromeStateContext = createContext<ChromeState | null>(null)\n\nexport function useChromeState(): ChromeState | null {\n return useContext(ChromeStateContext)\n}\n\nexport type ControlledOrgState = {\n orgId: string | null\n onSwitch: (id: string) => void\n /** Override the org list (e.g. the app's own session-scoped list). */\n orgs?: (NavOrgOption & { rawRole?: string | null })[]\n}\n\nfunction ChromeStateProvider({\n controlledOrg,\n children,\n}: {\n controlledOrg?: ControlledOrgState\n children: ReactNode\n}) {\n const { orgs, loading: orgsFetching, error: orgsError } = useChromeOrgs()\n const chromeMe = useChromeMe()\n const chromeFetch = useNavChromeFetcher()\n const [orgId, setOrgIdState] = useState<string | null>(null)\n const [navDisplay, setNavDisplayState] = useState<NavDisplayMode>(NAV_DISPLAY_DEFAULT)\n const navReconciled = useRef(false)\n\n // Boot: restore persisted choices. The cross-app active org (URL `?org=` or\n // the `.politogyvrm.com` cookie) wins over host-only localStorage so every\n // app + subdomain resolves the SAME org instead of each defaulting to its own\n // earliest-joined org. Nav display follows the same cross-subdomain contract\n // as theme (cookie → localStorage → default) — it used to be localStorage\n // only, which is per-origin, so it reset on every app the user opened.\n useEffect(() => {\n try {\n const storedOrg = resolveActiveOrg() ?? localStorage.getItem(ORG_STORAGE_KEY)\n if (storedOrg) setOrgIdState(storedOrg)\n } catch {\n /* storage unavailable */\n }\n setNavDisplayState(resolveNavDisplay())\n }, [])\n\n // Once per session: converge on the profile's saved choice (authoritative),\n // reusing the provider's single `me` fetch — the theme reconcile pattern.\n useEffect(() => {\n if (navReconciled.current || !chromeMe.me) return\n const pref = chromeMe.me.navDisplay\n if (!isNavDisplayPreference(pref)) return\n navReconciled.current = true\n setNavDisplayState(pref)\n writeNavDisplayCookie(pref)\n writeNavDisplayLocal(pref)\n }, [chromeMe])\n\n // Live sync: `storage` events for same-app tabs, cookie re-reads on\n // focus/visibility for tabs on OTHER app subdomains.\n useEffect(() => {\n const onStorage = (e: StorageEvent) => {\n if (e.key === NAV_DISPLAY_STORAGE_KEY && isNavDisplayPreference(e.newValue)) {\n setNavDisplayState(e.newValue)\n }\n }\n const onWake = () => {\n const cookie = readNavDisplayCookie()\n if (cookie) setNavDisplayState(cookie)\n }\n window.addEventListener('storage', onStorage)\n window.addEventListener('focus', onWake)\n document.addEventListener('visibilitychange', onWake)\n return () => {\n window.removeEventListener('storage', onStorage)\n window.removeEventListener('focus', onWake)\n document.removeEventListener('visibilitychange', onWake)\n }\n }, [])\n\n // Once orgs resolve: validate the stored org, default to the first.\n useEffect(() => {\n if (!orgs || orgs.length === 0) return\n setOrgIdState((prev) => (prev && orgs.some((o) => o.id === prev) ? prev : orgs[0].id))\n }, [orgs])\n\n const setOrgId = useCallback((id: string) => {\n setOrgIdState(id)\n try {\n localStorage.setItem(ORG_STORAGE_KEY, id)\n } catch {\n /* best effort */\n }\n // Remember the choice cross-subdomain so the next app opens on the same org.\n writeActiveOrgCookie(id)\n }, [])\n\n const setNavDisplay = useCallback(\n (m: NavDisplayMode) => {\n setNavDisplayState(m)\n writeNavDisplayLocal(m)\n // Cross-subdomain, so the next app opens on the same choice.\n writeNavDisplayCookie(m)\n // Best-effort durable persistence on the user's profile — a nav toggle\n // never errors, and the cookie already carries the choice meanwhile.\n chromeFetch?.('me/preferences', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ navDisplay: m }),\n })?.catch(() => {})\n },\n [chromeFetch],\n )\n\n const value = useMemo<ChromeState>(() => {\n // CONTROLLED mode (Contacts): the APP owns the active org + switching —\n // its switch does a full session re-scope. The shared widgets read the\n // app's state so there is exactly one org truth (unification directive).\n if (controlledOrg) {\n return {\n orgId: controlledOrg.orgId,\n setOrgId: controlledOrg.onSwitch,\n orgs:\n controlledOrg.orgs ??\n (orgs ?? []).map((o) => ({\n id: o.id,\n name: o.name,\n logoUrl: o.logoUrl,\n brandColor: o.brandColor,\n role: o.role,\n rawRole: o.rawRole ?? null,\n })),\n orgsLoading: false,\n navDisplay,\n setNavDisplay,\n }\n }\n return {\n orgId,\n setOrgId,\n orgs: (orgs ?? []).map((o) => ({\n id: o.id,\n name: o.name,\n logoUrl: o.logoUrl,\n brandColor: o.brandColor,\n role: o.role,\n rawRole: o.rawRole ?? null,\n })),\n // Loading until the fetch settles. On error we stop loading so the frame\n // falls back to the app label rather than shimmering forever.\n orgsLoading: orgsFetching && !orgsError && !orgs,\n navDisplay,\n setNavDisplay,\n }\n }, [controlledOrg, orgId, setOrgId, orgs, orgsFetching, orgsError, navDisplay, setNavDisplay])\n\n // Keep the shared cookie + address-bar `?org=` in sync with the ACTIVE org —\n // whichever path owns it, controlled (Contacts) or uncontrolled (feature\n // apps) — so every app + tab resolves the same org and every URL is\n // bookmarkable/shareable with its org context. Idempotent; no-op on server.\n const activeOrgId = value.orgId\n useEffect(() => {\n if (!isOrgId(activeOrgId)) return\n writeActiveOrgCookie(activeOrgId as string)\n try {\n const url = new URL(window.location.href)\n if (url.searchParams.get(ACTIVE_ORG_QUERY_PARAM) !== activeOrgId) {\n url.searchParams.set(ACTIVE_ORG_QUERY_PARAM, activeOrgId as string)\n window.history.replaceState(window.history.state, '', url.toString())\n }\n } catch {\n /* SSR / no window */\n }\n }, [activeOrgId])\n\n return <ChromeStateContext.Provider value={value}>{children}</ChromeStateContext.Provider>\n}\n\nexport type ChromeDevNotesConfig = {\n /** Override the DevNotes API base (default: `${proxyBasePath}/devnotes`). */\n basePath?: string\n /** Client-side token supplier (default: empty — same-origin proxy injects). */\n getAuthToken?: () => Promise<string> | string\n /** Custom fetch (e.g. credentials:'include' against a cross-origin API). */\n fetch?: typeof globalThis.fetch\n /**\n * The app already mounts its own `<DevNotesProvider>` ABOVE this chrome, so\n * the chrome must not mount a second one (VRM core, whose provider carries\n * capabilities the generic client has no equivalent for — user stories, its\n * own role gating). The working SURFACE still comes from here, so the\n * launcher, the overlay and the task modal behave identically everywhere;\n * only the data adapter is the app's.\n */\n providedByApp?: boolean\n}\n\nfunction AppDevNotes({\n storagePrefix,\n proxyBasePath,\n devNotes,\n identity,\n children,\n}: {\n storagePrefix: string\n proxyBasePath: string\n devNotes?: ChromeDevNotesConfig\n identity: ChromeIdentity\n children: ReactNode\n}) {\n const adapter = useMemo(\n () =>\n createDevNotesClient({\n basePath: devNotes?.basePath ?? `${proxyBasePath}/devnotes`,\n // Default: the same-origin proxy attaches the session's Bearer.\n getAuthToken: devNotes?.getAuthToken ?? (async () => ''),\n ...(devNotes?.fetch ? { fetch: devNotes.fetch } : {}),\n }),\n [proxyBasePath, devNotes?.basePath, devNotes?.getAuthToken, devNotes?.fetch],\n )\n\n const user = useMemo(\n () => ({\n id: identity.userId,\n email: identity.email ?? '',\n fullName: identity.userName ?? undefined,\n }),\n [identity.userId, identity.email, identity.userName],\n )\n\n const config = useMemo<DevNotesConfig>(\n () => ({\n storagePrefix,\n role: identity.role.toLowerCase() === 'admin' ? 'admin' : 'reporter',\n disableAi: true,\n getPagePath: () => window.location.pathname,\n }),\n [storagePrefix, identity.role],\n )\n\n // The app brought its own provider — mount only the surface, so a second\n // DevNotesProvider never shadows the app's adapter.\n if (devNotes?.providedByApp) return <DevNotesSurface>{children}</DevNotesSurface>\n\n return (\n <DevNotesProvider adapter={adapter} user={user} config={config}>\n <DevNotesSurface>{children}</DevNotesSurface>\n </DevNotesProvider>\n )\n}\n\n// \"View All Tasks\" is triggered from the menu in the top bar but the modal has\n// to render at the chrome ROOT, or it would be trapped inside the top bar's\n// stacking/blur context. The menu publishes the request through this context.\nconst DevNotesTasksContext = createContext<{ ready: boolean; openTasks: () => void }>({\n ready: false,\n openTasks: () => {},\n})\n\n/**\n * The DevNotes working surface, mounted once at the chrome root.\n *\n * `<DevNotesMenu>` only TOGGLES creation mode — `<DevNotesOverlay>` is what\n * renders the click-to-place capture layer, the report dots and the report\n * form. The shell shipped the provider and the menu but never the overlay, so\n * on every app that used this chrome (forms / surveys / polls) \"Create Task\"\n * closed the menu and did nothing at all: the mode flipped on with nothing\n * listening (HITL bug report 2026-07-23). Contacts didn't hit it only because\n * it still had its own hand-rolled surface.\n */\nfunction DevNotesSurface({ children }: { children: ReactNode }) {\n const [tasksOpen, setTasksOpen] = useState(false)\n const openTasks = useCallback(() => setTasksOpen(true), [])\n const tasksCtx = useMemo(() => ({ ready: true, openTasks }), [openTasks])\n\n return (\n <DevNotesTasksContext.Provider value={tasksCtx}>\n {children}\n {/* Mounted only while open: the modal loads data on mount regardless of\n its `open` prop, so keeping it unmounted avoids fetching every user's\n tasks before they ask for them. */}\n {tasksOpen ? <DevNotesTaskListModal open onClose={() => setTasksOpen(false)} /> : null}\n <DevNotesOverlay />\n </DevNotesTasksContext.Provider>\n )\n}\n\n/**\n * The app-chrome root. Wrap the authenticated frame once:\n *\n * <PolitogyAppChrome storagePrefix=\"forms\" identity={{userId, userName, email, role}}>\n * <ShellFrame …/>\n * </PolitogyAppChrome>\n */\nexport function PolitogyAppChrome({\n storagePrefix,\n proxyBasePath = '/api/chrome',\n fetchJson: fetchJsonOverride,\n devNotes,\n org,\n identity,\n children,\n}: {\n storagePrefix: string\n proxyBasePath?: string\n /**\n * Override the same-origin proxy fetcher for apps that talk to the chrome\n * API directly with their own auth (Contacts sends a client-side Bearer).\n * Paths stay relative ('orgs', 'me', …) — the override owns base + auth.\n */\n fetchJson?: NavChromeFetcher\n /** DevNotes wiring override for direct-auth apps (Contacts). */\n devNotes?: ChromeDevNotesConfig\n /** Controlled org state — the app owns active-org + switching (Contacts). */\n org?: ControlledOrgState\n identity: ChromeIdentity\n children: ReactNode\n}) {\n const proxyFetchJson = useMemo<NavChromeFetcher>(\n () =>\n async (path, init) => {\n const res = await fetch(`${proxyBasePath}/${path}`, {\n method: init?.method ?? 'GET',\n headers: init?.headers,\n body: init?.body,\n })\n if (!res.ok) throw new Error(`chrome ${path}: ${res.status}`)\n if (res.status === 204) return null\n const text = await res.text()\n return text ? JSON.parse(text) : null\n },\n [proxyBasePath],\n )\n const fetchJson = fetchJsonOverride ?? proxyFetchJson\n\n return (\n <NavChromeProvider fetchJson={fetchJson}>\n <ChromeStateProvider controlledOrg={org}>\n <AppDevNotes\n storagePrefix={storagePrefix}\n proxyBasePath={proxyBasePath}\n devNotes={devNotes}\n identity={identity}\n >\n {children}\n </AppDevNotes>\n </ChromeStateProvider>\n </NavChromeProvider>\n )\n}\n\n/** The standard top-bar action cluster. The Alerts bell renders LAST so it\n * sits farthest right, immediately left of the My Account badge. */\nexport function ChromeTopBarActions() {\n const state = useChromeState()\n if (!state) return null\n return (\n <>\n <FuelAction orgId={state.orgId} />\n <NavDisplayAction value={state.navDisplay} onChange={state.setNavDisplay} />\n <TopBarWidgetSlot\n title=\"DevNotes\"\n description=\"Capture bugs and notes, filed straight to Forge.\"\n >\n <ChromeDevNotesMenu />\n </TopBarWidgetSlot>\n <SupportAction orgId={state.orgId} />\n <NotificationsAction orgId={state.orgId} />\n </>\n )\n}\n\n/**\n * The DevNotes launcher. Renders nothing until the surface above is mounted, so\n * it never touches DevNotes context before the provider exists, and forwards\n * \"View All Tasks\" to the root-level modal.\n */\nfunction ChromeDevNotesMenu() {\n const { ready, openTasks } = useContext(DevNotesTasksContext)\n if (!ready) return null\n return <DevNotesMenu position=\"top-right\" onViewTasks={openTasks} />\n}\n\n/** True when any core-org membership carries a super-admin tier. */\nexport function useIsSuperAdmin(): boolean {\n const state = useChromeState()\n return (state?.orgs ?? []).some((o) => /super/i.test(o.rawRole ?? ''))\n}\n\nconst FOOTER_LINKS: NavFooterLink[] = [\n { label: 'Privacy', href: `${CORE_BASE_URL}/privacy-policy`, external: true },\n { label: 'Terms', href: `${CORE_BASE_URL}/terms-and-conditions`, external: true },\n {\n label: 'Subscriptions',\n href: 'https://politogyvrm.com/subscription-cancellation-policy',\n external: true,\n },\n]\n\n/**\n * Sidebar footer: legal links for everyone; build metadata (env / commit /\n * version / date / author) ONLY for Super Administrators\n * (Reference/UI-Platform). Pass the app's build-time metadata in.\n */\nexport function useChromeFooter(meta: {\n envLabel?: string\n version?: string\n commit?: string\n commitDate?: string\n commitAuthor?: string\n}): NavFooter {\n const isSuperAdmin = useIsSuperAdmin()\n return useMemo<NavFooter>(\n () => (isSuperAdmin ? { links: FOOTER_LINKS, ...meta } : { links: FOOTER_LINKS }),\n [isSuperAdmin, meta.envLabel, meta.version, meta.commit, meta.commitDate, meta.commitAuthor],\n )\n}\n\n// ---------------------------------------------------------------------------\n// Identity — resolved by the PACKAGE, from the chrome API.\n//\n// Apps used to pass a display name straight from their own session claims, and\n// forms passed `user.name ?? user.email` — so a user with no name set had their\n// EMAIL rendered as their name, and the chrome API's real profile name could\n// never win (HITL 2026-07-23). The chrome API is the authority; what the app\n// passes is a pre-hydration fallback only, and an email is never a name.\n// ---------------------------------------------------------------------------\n\nexport function useChromeIdentity(fallback?: {\n userName?: string | null\n email?: string | null\n}): ResolvedIdentity {\n const { me, loaded } = useChromeMe()\n return resolveIdentity({\n apiName: me?.userName,\n fallbackName: fallback?.userName,\n email: fallback?.email,\n avatarUrl: me?.avatarUrl,\n loaded,\n })\n}\n\n// Breadcrumbs live in ../lib/breadcrumbs (pure, dependency-free) and are\n// re-exported here so apps keep a single import surface.\nexport { deriveBreadcrumbs } from '../lib/breadcrumbs'\nexport { looksLikeEmail, resolveIdentity, type ResolvedIdentity } from '../lib/identity'\nimport { resolveIdentity, type ResolvedIdentity } from '../lib/identity'\n\n// ---------------------------------------------------------------------------\n// Breadcrumbs — derived by the PACKAGE from the nav tree + the current path.\n//\n// Every app hand-built its own trail, so they disagreed: forms rendered\n// \"Forms › Dashboard\" while polls rendered \"Polls\" under a \"Polls\" title\n// (\"Polls / Polls\"). The standard is Dashboard › Sub › Item (HITL 2026-07-23),\n// derived from the same nav tree the sidebar renders, so no app can drift.\n// ---------------------------------------------------------------------------\n\n/**\n * The My Account menu config — profile/org links into VRM core, real roles\n * from the user's core organizations, the signed-in account, and the shared\n * Light/System/Dark theme control (auth-derived, cross-app).\n */\nexport function useChromeUserMenu({\n userId,\n userName,\n email,\n}: {\n userId: string\n userName: string | null\n email: string | null\n}): NavUserMenu {\n const state = useChromeState()\n const theme = useThemePreference()\n const activeOrg = state?.orgs.find((o) => o.id === state.orgId) ?? null\n const orgSuffix = activeOrg ? `?org=${activeOrg.id}` : ''\n return {\n // My Profile is global — NOT org-suffixed (main-app ShellChromeBridge).\n myProfileHref: `${CORE_BASE_URL}/my-profile`,\n organizationSettingsHref: `${CORE_BASE_URL}/organization-settings${orgSuffix}`,\n roles: (state?.orgs ?? [])\n .filter((o) => o.rawRole || o.role)\n .map((o) => ({ role: (o.rawRole ?? o.role) as string, orgName: o.name })),\n accounts: [{ id: userId, name: userName, email, avatarUrl: null, active: true }],\n addAccountHref: `${CORE_BASE_URL}/my-profile#accounts`,\n theme: { value: theme.value, onChange: theme.setValue },\n }\n}\n\n// ---------------------------------------------------------------------------\n// Mode selector — entitlement-driven (HITL 2026-07-23: an org with multiple\n// active modes selects them from the left nav). Entitlements come from the\n// chrome API: GET me with the active org header → modes booleans\n// {relationship, campaign, petition, polling}. Selecting a mode navigates to\n// that mode's VRM-core dashboard carrying the active org.\n// ---------------------------------------------------------------------------\n\nconst MODE_DEFS: {\n id: string\n label: string\n icon: NavIcon\n /** Absolute destination, or a VRM-core path prefixed with CORE_BASE_URL. */\n href: string\n orgQuery: boolean\n}[] = [\n {\n id: 'relationship',\n label: 'Relationship Mode',\n icon: FiUsers,\n href: `${CORE_BASE_URL}/relationship/dashboard`,\n orgQuery: true,\n },\n {\n id: 'campaign',\n label: 'Campaign Mode',\n icon: FiBarChart2,\n href: `${CORE_BASE_URL}/campaign/dashboard`,\n orgQuery: true,\n },\n {\n // Petition Mode lives in its own standalone app on its own subdomain — the\n // petitions repo deploys production to petition-mode.politogyvrm.com.\n id: 'petition',\n label: 'Petition Mode',\n icon: FiFlag,\n href: 'https://petition-mode.politogyvrm.com/',\n orgQuery: true,\n },\n]\n\ntype ModeId = 'relationship' | 'campaign' | 'petition'\n\ntype UseChromeModeArg =\n | ModeId\n | {\n /** Pre-entitlement fallback for first paint (default 'relationship'). */\n fallbackModeId?: ModeId\n /**\n * Registry-pinned mode for a MODE-SCOPED app (e.g. the Campaign apps\n * a2p / phonebank / canvass / signs, from `POLITOGY_APPS[app].mode`). The\n * pill DISPLAYS this mode regardless of the cross-app selection, so a\n * campaign app never shows a Relationship pill. The switcher still appears\n * when the active org is entitled to more than one mode, so the user can\n * jump out to another mode's home.\n */\n pinnedModeId?: ModeId\n }\n\n/**\n * The active mode pill / selector.\n *\n * For an UNSCOPED app the current mode is the USER'S OWN SELECTION (persisted\n * cross-app in localStorage under `vrm.activeMode`), narrowed to what the active\n * org is entitled to — never a literal an app hardcodes. Apps used to call\n * `useChromeMode('relationship')`, which pinned the pill to Relationship even\n * for an org entitled to Campaign or Petition (HITL 2026-07-23); the string\n * argument now only supplies the pre-entitlement fallback for first paint.\n *\n * A MODE-SCOPED app passes `{ pinnedModeId }` so its pill displays that mode\n * (its own mode from the app registry) rather than the cross-app selection —\n * while a multi-mode org still gets the switcher to leave.\n */\nexport function useChromeMode(arg: UseChromeModeArg = {}): NavMode {\n const { fallbackModeId = 'relationship', pinnedModeId } =\n typeof arg === 'string' ? { fallbackModeId: arg, pinnedModeId: undefined } : arg\n const ctx = useContext(ChromeStateContext)\n const nav = useNavChromeFetcher()\n const orgId = ctx?.orgId ?? null\n const [entitled, setEntitled] = useState<Record<string, boolean> | null>(null)\n const [selectedModeId, setSelectedModeId] = useState<string | null>(null)\n\n // Restore the user's last mode choice (shared key across every app).\n useEffect(() => {\n try {\n const stored = localStorage.getItem(MODE_STORAGE_KEY)\n if (stored && MODE_DEFS.some((m) => m.id === stored)) setSelectedModeId(stored)\n } catch {\n /* storage unavailable */\n }\n }, [])\n\n useEffect(() => {\n if (!nav || !orgId) return\n let cancelled = false\n nav('me', { headers: { 'x-contacts-org': orgId } })\n .then((data) => {\n if (cancelled) return\n const modes = (data as { modes?: Record<string, boolean> | null })?.modes ?? null\n setEntitled(modes)\n })\n .catch(() => {\n /* entitlements unavailable — single-mode pill stands */\n })\n return () => {\n cancelled = true\n }\n }, [nav, orgId])\n\n const options = MODE_DEFS.filter((m) => entitled?.[m.id])\n // Resolution order: a registry pin (mode-scoped app) wins outright → then the\n // user's selection (if the org is still entitled to it) → the first entitled\n // mode → the app's fallback. Entitlements are async, so before they land the\n // pin/fallback holds the pill's shape (no layout shift).\n const pinned = pinnedModeId ? MODE_DEFS.find((m) => m.id === pinnedModeId) ?? null : null\n const selected = selectedModeId\n ? options.find((m) => m.id === selectedModeId) ?? null\n : null\n const current =\n pinned ??\n selected ??\n options[0] ??\n MODE_DEFS.find((m) => m.id === fallbackModeId) ??\n MODE_DEFS[0]\n const suffix = orgId ? `?org=${orgId}` : ''\n\n return {\n label: current.label,\n icon: current.icon,\n options:\n options.length > 1\n ? options.map((o) => ({ id: o.id, label: o.label, icon: o.icon }))\n : undefined,\n onSelect:\n options.length > 1\n ? (id: string) => {\n const def = MODE_DEFS.find((m) => m.id === id)\n if (!def) return\n // Remember the choice BEFORE navigating so the destination app —\n // and every app after it — opens in the mode the user picked.\n setSelectedModeId(id)\n try {\n localStorage.setItem(MODE_STORAGE_KEY, id)\n } catch {\n /* storage unavailable */\n }\n const sep = def.href.includes('?') ? '&' : '?'\n window.location.assign(\n def.orgQuery && suffix ? `${def.href}${sep}${suffix.slice(1)}` : def.href,\n )\n }\n : undefined,\n }\n}\n\n// The one-component app frame (see ./frame.tsx). Re-exported here so apps have\n// a single import surface: `@the-portland-company/shell/app-chrome`.\nexport {\n PolitogyAppFrame,\n POLITOGY_APPS,\n type PolitogyAppKey,\n type PolitogyAppMode,\n type PolitogyAppSession,\n type PolitogyBuildMeta,\n type PolitogyFrameData,\n} from './frame'\n"]}
|