@dloizides/ui-access-admin 1.2.2 → 1.4.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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/AccessResultTone.ts","../src/constants.ts","../src/expiry/expiryPolicy.ts","../src/links/capabilityLinkHelpers.ts","../src/links/useCapabilityLinkMint.ts","../src/theme/useAccessAdminPalette.ts","../src/AccessLinkPanel/AccessLinkPanel.tsx","../src/accounts/accountOptions.ts","../src/accounts/useSubjectAccountLink.ts","../src/AccountLinkPanel/AccountLinkPanel.tsx","../src/UserManagementPanel/userManagementFormat.ts","../src/UserManagementPanel/buildUserColumns.tsx","../src/UserManagementPanel/PickerField.tsx","../src/UserManagementPanel/userManagementStyles.ts","../src/UserManagementPanel/CreateUserModal.tsx","../src/UserManagementPanel/EditUserModal.tsx","../src/UserManagementPanel/ResetPasswordModal.tsx","../src/UserManagementPanel/useUserManagement.ts","../src/UserManagementPanel/UserManagementPanel.tsx"],"names":["AccessResultTone","ISO_DATE_LENGTH","useState","useRef","useEffect","useCallback","copyText","useUi","useMemo","Linking","View","jsx","Text","jsxs","Button","StyleSheet","SPACE_XS","SPACE_SM","SPACE_MD","SPACE_LG","FONT_SM","FONT_MD","buildStyles","SelectControl","Field","ModalDropdown","DropdownVariant","ModalShell","FormField","FormSwitch","createToastBus","ToastHost","FilterBar","DataTable"],"mappings":";;;;;;;;;;;;;;AAYO,IAAW,gBAAA,qBAAAA,iBAAAA,KAAX;AACL,EAAAA,kBAAA,SAAA,CAAA,GAAU,SAAA;AACV,EAAAA,kBAAA,OAAA,CAAA,GAAQ,OAAA;AAFQ,EAAA,OAAAA,iBAAAA;AAAA,CAAA,EAAA,gBAAA,IAAA,EAAA;;;ACeX,IAAM,iBAAA,GAAoB;AAAA;AAAA;AAAA,EAG/B,YAAA,EAAc,+BAAA;AAAA;AAAA,EAEd,SAAA,EAAW,4BAAA;AAAA;AAAA,EAEX,iBAAA,EAAmB,oCAAA;AAAA;AAAA,EAEnB,aAAA,EAAe,gCAAA;AAAA;AAAA,EAGf,IAAA,EAAM,uBAAA;AAAA,EACN,QAAA,EAAU,2BAAA;AAAA;AAAA,EAEV,WAAA,EAAa,8BAAA;AAAA;AAAA,EAEb,UAAA,EAAY,6BAAA;AAAA;AAAA,EAEZ,WAAA,EAAa,8BAAA;AAAA;AAAA,EAEb,aAAA,EAAe,gCAAA;AAAA;AAAA,EAEf,UAAA,EAAY,6BAAA;AAAA;AAAA,EAGZ,MAAA,EAAQ,yBAAA;AAAA,EACR,UAAA,EAAY,6BAAA;AAAA,EACZ,MAAA,EAAQ,yBAAA;AAAA,EACR,OAAA,EAAS,0BAAA;AAAA,EACT,WAAA,EAAa,8BAAA;AAAA,EACb,KAAA,EAAO,wBAAA;AAAA,EACP,SAAA,EAAW,4BAAA;AAAA;AAAA,EAEX,SAAA,EAAW,4BAAA;AAAA;AAAA,EAEX,YAAA,EAAc,+BAAA;AAAA;AAAA,EAEd,SAAA,EAAW,4BAAA;AAAA;AAAA;AAAA,EAIX,WAAA,EAAa,8BAAA;AAAA;AAAA,EAEb,QAAA,EAAU,2BAAA;AAAA;AAAA,EAEV,YAAA,EAAc,+BAAA;AAAA,EACd,MAAA,EAAQ,yBAAA;AAAA;AAAA,EAER,aAAA,EAAe,gCAAA;AAAA,EACf,KAAA,EAAO,wBAAA;AAAA,EACP,SAAA,EAAW,4BAAA;AAAA;AAAA;AAAA,EAIX,mBAAA,EAAqB,kCAAA;AAAA,EACrB,gBAAA,EAAkB,+BAAA;AAAA,EAClB,kBAAA,EAAoB,iCAAA;AAAA,EACpB,iBAAA,EAAmB,gCAAA;AAAA,EACnB,wBAAA,EAA0B,uCAAA;AAAA,EAC1B,iBAAA,EAAmB,gCAAA;AAAA;AAAA,EAEnB,cAAA,EAAgB,6BAAA;AAAA;AAAA,EAEhB,WAAA,EAAa,0BAAA;AAAA,EACb,WAAA,EAAa,0BAAA;AAAA,EACb,eAAA,EAAiB,8BAAA;AAAA;AAAA,EAEjB,kBAAA,EAAoB,iCAAA;AAAA,EACpB,aAAA,EAAe,4BAAA;AAAA,EACf,iBAAA,EAAmB,gCAAA;AAAA;AAAA,EAEnB,oBAAA,EAAsB,mCAAA;AAAA,EACtB,YAAA,EAAc,2BAAA;AAAA,EACd,gBAAA,EAAkB,+BAAA;AAAA;AAAA;AAAA,EAIlB,YAAA,EAAc,2BAAA;AAAA;AAAA,EAEd,SAAA,EAAW,wBAAA;AAAA;AAAA,EAEX,sBAAA,EAAwB,qCAAA;AAAA;AAAA,EAExB,gBAAA,EAAkB,+BAAA;AAAA,EAClB,eAAA,EAAiB,8BAAA;AAAA;AAAA,EAEjB,iBAAA,EAAmB,gCAAA;AAAA,EACnB,WAAA,EAAa,0BAAA;AAAA,EACb,eAAA,EAAiB,8BAAA;AAAA;AAAA,EAGjB,aAAA,EAAe,4BAAA;AAAA,EACf,mBAAA,EAAqB,kCAAA;AAAA,EACrB,aAAA,EAAe,4BAAA;AAAA,EACf,cAAA,EAAgB,6BAAA;AAAA,EAChB,cAAA,EAAgB,6BAAA;AAAA,EAChB,eAAA,EAAiB,8BAAA;AAAA,EACjB,eAAA,EAAiB,8BAAA;AAAA;AAAA,EAGjB,cAAA,EAAgB,6BAAA;AAAA,EAChB,aAAA,EAAe,4BAAA;AAAA;AAAA,EAEf,eAAA,EAAiB,8BAAA;AAAA;AAAA,EAEjB,YAAA,EAAc,2BAAA;AAAA;AAAA,EAEd,mBAAA,EAAqB,kCAAA;AAAA;AAAA,EAGrB,SAAA,EAAW,wBAAA;AAAA,EACX,aAAA,EAAe,4BAAA;AAAA,EACf,UAAA,EAAY,yBAAA;AAAA,EACZ,cAAA,EAAgB,6BAAA;AAAA;AAAA,EAGhB,YAAA,EAAc,2BAAA;AAAA,EACd,UAAA,EAAY,yBAAA;AAAA;AAAA,EAEZ,cAAA,EAAgB,6BAAA;AAAA,EAChB,UAAA,EAAY,yBAAA;AAAA,EACZ,cAAA,EAAgB,6BAAA;AAAA;AAAA,EAGhB,gBAAA,EAAkB,+BAAA;AAAA,EAClB,cAAA,EAAgB,6BAAA;AAAA,EAChB,eAAA,EAAiB,8BAAA;AAAA;AAAA,EAGjB,eAAA,EAAiB,8BAAA;AAAA,EACjB,qBAAA,EAAuB,oCAAA;AAAA,EACvB,kBAAA,EAAoB,iCAAA;AAAA,EACpB,wBAAA,EAA0B,uCAAA;AAAA,EAC1B,qBAAA,EAAuB,oCAAA;AAAA,EACvB,2BAAA,EAA6B,0CAAA;AAAA,EAC7B,cAAA,EAAgB,6BAAA;AAAA,EAChB,oBAAA,EAAsB,mCAAA;AAAA,EACtB,mBAAA,EAAqB,kCAAA;AAAA,EACrB,gBAAA,EAAkB,+BAAA;AAAA,EAClB,sBAAA,EAAwB,qCAAA;AAAA,EACxB,qBAAA,EAAuB,oCAAA;AAAA,EACvB,gBAAA,EAAkB,+BAAA;AAAA,EAClB,qBAAA,EAAuB,oCAAA;AAAA,EACvB,qBAAA,EAAuB,oCAAA;AAAA,EACvB,2BAAA,EAA6B,0CAAA;AAAA;AAAA,EAG7B,iBAAA,EAAmB,gCAAA;AAAA,EACnB,qBAAA,EAAuB,oCAAA;AAAA,EACvB,eAAA,EAAiB,8BAAA;AAAA,EACjB,mBAAA,EAAqB,kCAAA;AAAA,EACrB,gBAAA,EAAkB,+BAAA;AAAA,EAClB,oBAAA,EAAsB,mCAAA;AAAA,EACtB,WAAA,EAAa,0BAAA;AAAA,EACb,eAAA,EAAiB,8BAAA;AAAA;AAAA,EAGjB,kBAAA,EAAoB,iCAAA;AAAA,EACpB,iBAAA,EAAmB,gCAAA;AAAA,EACnB,kBAAA,EAAoB,iCAAA;AAAA,EACpB,iBAAA,EAAmB,gCAAA;AAAA,EACnB,iBAAA,EAAmB,gCAAA;AAAA,EACnB,gBAAA,EAAkB;AACpB;AAUO,IAAM,qBAAA,GAAwB;AAAA,EACnC,SAAA,EAAW,mBAAA;AAAA,EACX,YAAA,EAAc,oBAAA;AAAA,EACd,UAAA,EAAY;AACd;;;ACvLA,IAAM,UAAA,GAAa,KAAA;AAGnB,IAAM,eAAA,GAAkB,EAAA;AA8BjB,SAAS,eAAA,CAAgB,YAAuC,GAAA,EAA0B;AAC/F,EAAA,IAAI,OAAO,UAAA,KAAe,QAAA,IAAY,WAAW,IAAA,EAAK,KAAM,IAAI,OAAO,IAAA;AACvE,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,UAAU,CAAA;AACpC,EAAA,IAAI,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,EAAG,OAAO,IAAA;AACjC,EAAA,OAAO,IAAA,CAAK,KAAA,CAAM,MAAA,GAAS,UAAU,CAAA,GAAI,KAAK,KAAA,CAAM,GAAA,CAAI,OAAA,EAAQ,GAAI,UAAU,CAAA;AAChF;AAWO,SAAS,oBAAA,CAAqB,QAAsB,GAAA,EAAmB;AAC5E,EAAA,MAAM,WAAA,GAAc,eAAA,CAAgB,MAAA,CAAO,UAAA,EAAY,GAAG,CAAA;AAC1D,EAAA,MAAM,MAAM,WAAA,KAAgB,IAAA,GAAO,MAAA,CAAO,QAAA,GAAW,cAAc,MAAA,CAAO,QAAA;AAC1E,EAAA,IAAI,GAAA,GAAM,MAAA,CAAO,OAAA,EAAS,OAAO,MAAA,CAAO,OAAA;AACxC,EAAA,IAAI,GAAA,GAAM,MAAA,CAAO,OAAA,EAAS,OAAO,MAAA,CAAO,OAAA;AACxC,EAAA,OAAO,GAAA;AACT;AAGO,SAAS,oBAAA,CAAqB,QAAsB,GAAA,EAAmB;AAC5E,EAAA,MAAM,IAAA,GAAO,oBAAA,CAAqB,MAAA,EAAQ,GAAG,CAAA;AAC7C,EAAA,OAAO,IAAI,IAAA,CAAK,GAAA,CAAI,OAAA,EAAQ,GAAI,IAAA,GAAO,UAAU,CAAA,CAAE,WAAA,EAAY,CAAE,KAAA,CAAM,CAAA,EAAG,eAAe,CAAA;AAC3F;;;ACzEA,IAAMC,gBAAAA,GAAkB,EAAA;AAUjB,SAAS,eAAA,CACd,OACA,SAAA,EACkB;AAClB,EAAA,OAAO,KAAA,CACJ,OAAO,CAAC,IAAA,KAAS,KAAK,SAAA,KAAc,SAAS,CAAA,CAC7C,IAAA,CAAK,CAAC,CAAA,EAAG,MAAM,MAAA,CAAO,CAAA,CAAE,SAAA,IAAa,EAAE,CAAA,CAAE,aAAA,CAAc,OAAO,CAAA,CAAE,SAAA,IAAa,EAAE,CAAC,CAAC,CAAA;AACtF;AAGO,SAAS,qBAAA,CACd,OACA,SAAA,EACkB;AAClB,EAAA,OAAO,eAAA,CAAgB,OAAO,SAAS,CAAA,CAAE,OAAO,CAAC,IAAA,KAAS,KAAK,QAAQ,CAAA;AACzE;AAGO,SAAS,cAAA,CAAe,OAAkC,QAAA,EAA0B;AACzF,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,MAAM,IAAA,EAAK,KAAM,IAAI,OAAO,QAAA;AAC7D,EAAA,OAAO,KAAA,CAAM,KAAA,CAAM,CAAA,EAAGA,gBAAe,CAAA;AACvC;AAYO,SAAS,yBAAA,CACd,OAAA,EACA,IAAA,EACA,GAAA,EACe;AACf,EAAA,IAAI,GAAA,CAAI,IAAA,EAAK,KAAM,EAAA,EAAI,OAAO,IAAA;AAC9B,EAAA,OAAO,mBAAmB,kBAAA,CAAmB,OAAO,CAAC,CAAA,MAAA,EAAS,kBAAA,CAAmB,IAAI,CAAC,CAAA,CAAA;AACxF;ACOO,SAAS,sBACd,OAAA,EACyB;AACzB,EAAA,MAAM,EAAE,SAAS,MAAA,EAAQ,IAAA,EAAM,eAAe,QAAA,EAAU,CAAA,EAAG,GAAA,EAAK,eAAA,EAAgB,GAAI,OAAA;AAEpF,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIC,eAAgC,IAAI,CAAA;AAChE,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIA,eAAkB,KAAK,CAAA;AACnD,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIA,eAAkB,KAAK,CAAA;AAIzD,EAAA,MAAM,UAAA,GAAaC,aAAgB,IAAI,CAAA;AACvC,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,UAAA,CAAW,OAAA,GAAU,IAAA;AACrB,IAAA,OAAO,MAAM;AACX,MAAA,UAAA,CAAW,OAAA,GAAU,KAAA;AAAA,IACvB,CAAA;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,OAAA,GAAUC,iBAAA;AAAA,IACd,OAAO,GAAA,KAAkC;AACvC,MAAA,MAAM,EAAA,GAAK,MAAMC,iBAAA,CAAS,GAAA,EAAK,eAAe,CAAA;AAC9C,MAAA,IAAI,UAAA,CAAW,OAAA,EAAS,SAAA,CAAU,EAAE,CAAA;AACpC,MAAA,OAAO,EAAA;AAAA,IACT,CAAA;AAAA,IACA,CAAC,eAAe;AAAA,GAClB;AAEA,EAAA,MAAM,OAAA,GAAUD,kBAAY,MAAY;AACtC,IAAA,IAAI,SAAA,EAAW;AACf,IAAA,YAAA,CAAa,IAAI,CAAA;AAEjB,IAAA,KAAA,CAAM,YAAY;AAChB,MAAA,IAAI;AACF,QAAA,MAAM,aAAA,GAAgB,qBAAqB,MAAA,EAAQ,GAAA,KAAQ,yBAAY,IAAI,IAAA,EAAK,GAAI,GAAA,EAAK,CAAA;AACzF,QAAA,MAAM,OAAO,MAAM,IAAA,CAAK,EAAE,OAAA,EAAS,eAAe,CAAA;AAClD,QAAA,IAAI,CAAC,WAAW,OAAA,EAAS;AAEzB,QAAA,SAAA,CAAU,IAAI,CAAA;AACd,QAAA,MAAM,EAAA,GAAK,MAAM,OAAA,CAAQ,IAAA,CAAK,OAAO,EAAE,CAAA;AACvC,QAAA,IAAI,CAAC,WAAW,OAAA,EAAS;AAEzB,QAAA,QAAA;AAAA,UACE,CAAA;AAAA,YACE,EAAA,GAAK,iBAAA,CAAkB,WAAA,GAAc,iBAAA,CAAkB,aAAA;AAAA,YACvD,OAAA,CAAQ;AAAA,WACV;AAAA,UACA,EAAA,GAAA,SAAA,iBAAA,OAAA;AAAA,SACF;AAAA,MACF,SAAS,KAAA,EAAO;AACd,QAAA,IAAI,CAAC,WAAW,OAAA,EAAS;AACzB,QAAA,QAAA,CAAS,aAAA,CAAc,KAAc,CAAA,EAAA,OAAA,aAAyB;AAAA,MAChE,CAAA,SAAE;AACA,QAAA,IAAI,UAAA,CAAW,OAAA,EAAS,YAAA,CAAa,KAAK,CAAA;AAAA,MAC5C;AAAA,IACF,CAAA,GAAG;AAAA,EACL,CAAA,EAAG,CAAC,SAAA,EAAW,MAAA,EAAQ,GAAA,EAAK,IAAA,EAAM,OAAA,EAAS,OAAA,EAAS,QAAA,EAAU,CAAA,EAAG,aAAa,CAAC,CAAA;AAE/E,EAAA,MAAM,MAAA,GAASA,kBAAY,MAAY;AACrC,IAAA,MAAM,GAAA,GAAM,QAAQ,GAAA,IAAO,EAAA;AAC3B,IAAA,IAAI,QAAQ,EAAA,EAAI;AAEhB,IAAA,KAAA,CAAM,YAAY;AAChB,MAAA,MAAM,EAAA,GAAK,MAAM,OAAA,CAAQ,GAAG,CAAA;AAC5B,MAAA,IAAI,CAAC,WAAW,OAAA,EAAS;AACzB,MAAA,QAAA;AAAA,QACE,EAAE,EAAA,GAAK,iBAAA,CAAkB,cAAc,iBAAA,CAAkB,UAAA,EAAY,QAAQ,WAAW,CAAA;AAAA,QACxF,EAAA,GAAA,SAAA,iBAAA,OAAA;AAAA,OACF;AAAA,IACF,CAAA,GAAG;AAAA,EACL,CAAA,EAAG,CAAC,MAAA,EAAQ,OAAA,EAAS,UAAU,CAAA,EAAG,OAAA,CAAQ,WAAW,CAAC,CAAA;AAEtD,EAAA,MAAM,OAAA,GAAUA,kBAAY,MAAY;AACtC,IAAA,SAAA,CAAU,IAAI,CAAA;AACd,IAAA,SAAA,CAAU,KAAK,CAAA;AAAA,EACjB,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,OAAO,EAAE,MAAA,EAAQ,SAAA,EAAW,QAAQ,IAAA,EAAM,OAAA,EAAS,QAAQ,OAAA,EAAQ;AACrE;AC7GO,SAAS,qBAAA,GAA4C;AAC1D,EAAA,MAAM,EAAE,KAAA,EAAM,GAAIE,gBAAA,EAAM;AACxB,EAAA,MAAM,EAAE,MAAA,EAAQ,OAAA,EAAS,QAAA,EAAS,GAAI,KAAA;AAEtC,EAAA,OAAOC,cAA4B,MAAM;AACvC,IAAA,MAAM,OAAA,GAAU,QAAA,CAAS,OAAA,IAAW,QAAA,CAAS,KAAA;AAC7C,IAAA,OAAO;AAAA,MACL,cAAc,MAAA,CAAO,OAAA;AAAA,MACrB,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,aAAa,MAAA,CAAO,IAAA;AAAA,MACpB,eAAe,MAAA,CAAO,aAAA;AAAA,MACtB,MAAA,EAAQ,QAAA,CAAS,KAAA,CAAM,KAAK,CAAA;AAAA;AAAA;AAAA,MAG5B,eAAe,OAAA,CAAQ,IAAI,KAAK,OAAA,CAAQ,KAAK,KAAK,MAAA,CAAO,eAAA;AAAA,MACzD,YAAA,EAAc,QAAQ,KAAK,CAAA;AAAA,MAC3B,eAAe,OAAA,CAAQ,OAAA,CAAQ,KAAK,CAAA,IAAK,OAAA,CAAQ,QAAQ,KAAK;AAAA,KAChE;AAAA,EACF,CAAA,EAAG,CAAC,MAAA,EAAQ,OAAA,EAAS,QAAQ,CAAC,CAAA;AAChC;ACTA,IAAM,QAAA,GAAW,CAAA;AACjB,IAAM,QAAA,GAAW,CAAA;AACjB,IAAM,QAAA,GAAW,EAAA;AACjB,IAAM,QAAA,GAAW,EAAA;AAEjB,IAAM,OAAA,GAAU,EAAA;AAChB,IAAM,OAAA,GAAU,EAAA;AAmCT,IAAM,kBAAkB,CAAC;AAAA,EAC9B,OAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,WAAA,GAAc,KAAA;AAAA,EACd,IAAA;AAAA,EACA,aAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,iBAAA;AAAA,EACA,GAAA;AAAA,EACA,eAAA;AAAA,EACA,eAAe,qBAAA,CAAsB;AACvC,CAAA,KAAgD;AAC9C,EAAA,MAAM,EAAE,CAAA,EAAE,GAAID,gBAAAA,EAAM;AACpB,EAAA,MAAM,UAAU,qBAAA,EAAsB;AACtC,EAAA,MAAM,MAAA,GAASC,cAAQ,MAAM,WAAA,CAAY,OAAO,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAE5D,EAAA,MAAM,QAAQ,qBAAA,CAAsB;AAAA,IAClC,OAAA;AAAA,IACA,MAAA;AAAA,IACA,IAAA;AAAA,IACA,aAAA;AAAA,IACA,QAAA;AAAA,IACA,CAAA;AAAA,IACA,GAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,MAAM,UAAA,GAAaA,aAAAA;AAAA,IACjB,MAAM,qBAAqB,MAAA,EAAQ,GAAA,KAAQ,yBAAY,IAAI,IAAA,EAAK,GAAI,GAAA,EAAK,CAAA;AAAA,IACzE,CAAC,QAAQ,GAAG;AAAA,GACd;AACA,EAAA,MAAM,SAAA,GAAYA,aAAAA,CAAQ,MAAM,qBAAA,CAAsB,KAAA,EAAO,OAAA,CAAQ,EAAE,CAAA,EAAG,CAAC,KAAA,EAAO,OAAA,CAAQ,EAAE,CAAC,CAAA;AAC7F,EAAA,MAAM,SAAA,GAAY,KAAA,CAAM,MAAA,EAAQ,GAAA,IAAO,EAAA;AAEvC,EAAA,MAAM,cAAc,MAAY;AAC9B,IAAA,MAAM,MAAA,GAAS,yBAAA;AAAA,MACb,CAAA,CAAE,iBAAA,CAAkB,YAAA,EAAc,OAAA,CAAQ,WAAW,CAAA;AAAA,MACrD,EAAE,iBAAA,CAAkB,SAAA,EAAW,OAAA,CAAQ,WAAA,EAAa,WAAW,UAAU,CAAA;AAAA,MACzE;AAAA,KACF;AACA,IAAA,IAAI,WAAW,IAAA,EAAM;AAKrB,IAAA,KAAKC,mBAAA,CAAQ,OAAA,CAAQ,MAAM,CAAA,CAAE,MAAM,MAAM;AACvC,MAAA,QAAA,CAAS,CAAA,CAAE,iBAAA,CAAkB,UAAA,EAAY,OAAA,CAAQ,WAAW,CAAA,EAAA,OAAA,aAAyB;AAAA,IACvF,CAAC,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,uCACGC,gBAAA,EAAA,EAAK,KAAA,EAAO,MAAA,CAAO,KAAA,EAAO,QAAQ,YAAA,EACjC,QAAA,EAAA;AAAA,oBAAAC,cAAA,CAACC,gBAAA,EAAA,EAAK,OAAO,MAAA,CAAO,OAAA,EAAU,YAAE,iBAAA,CAAkB,YAAA,EAAc,OAAA,CAAQ,WAAW,CAAA,EAAE,CAAA;AAAA,oBACrFD,cAAA,CAACC,oBAAK,KAAA,EAAO,MAAA,CAAO,MAAO,QAAA,EAAA,CAAA,CAAE,iBAAA,CAAkB,SAAS,CAAA,EAAE,CAAA;AAAA,oBAG1DD,cAAA,CAACC,gBAAA,EAAA,EAAK,KAAA,EAAO,MAAA,CAAO,OAAA,EAAS,MAAA,EAAQ,CAAA,EAAG,YAAY,CAAA,mBAAA,CAAA,EACjD,QAAA,EAAA,CAAA,CAAE,iBAAA,CAAkB,iBAAiB,CAAA,EACxC,CAAA;AAAA,oBACAD,cAAA,CAACC,gBAAA,EAAA,EAAK,KAAA,EAAO,MAAA,CAAO,IAAA,EAAM,MAAA,EAAQ,CAAA,EAAG,YAAY,CAAA,eAAA,CAAA,EAC9C,QAAA,EAAA,CAAA,CAAE,iBAAA,CAAkB,aAAA,EAAe,UAAU,CAAA,EAChD,CAAA;AAAA,IAEC,KAAA,CAAM,MAAA,KAAW,IAAA,mBAChBC,eAAA,CAACH,gBAAA,EAAA,EAAK,KAAA,EAAO,MAAA,CAAO,SAAA,EAAW,MAAA,EAAQ,CAAA,EAAG,YAAY,CAAA,OAAA,CAAA,EACpD,QAAA,EAAA;AAAA,sBAAAC,cAAA,CAACC,gBAAA,EAAA,EAAK,OAAO,MAAA,CAAO,WAAA,EACjB,YAAE,iBAAA,CAAkB,WAAA,EAAa,OAAA,CAAQ,WAAW,CAAA,EACvD,CAAA;AAAA,sBACAD,cAAA,CAACC,oBAAK,KAAA,EAAO,MAAA,CAAO,MAAO,QAAA,EAAA,CAAA,CAAE,iBAAA,CAAkB,UAAU,CAAA,EAAE,CAAA;AAAA,sBAC3DD,cAAA,CAACC,gBAAA,EAAA,EAAK,UAAA,EAAU,IAAA,EAAC,KAAA,EAAO,MAAA,CAAO,GAAA,EAAK,MAAA,EAAQ,CAAA,EAAG,YAAY,CAAA,WAAA,CAAA,EACxD,QAAA,EAAA,SAAA,EACH,CAAA;AAAA,sBACAC,eAAA,CAACH,gBAAA,EAAA,EAAK,KAAA,EAAO,MAAA,CAAO,OAAA,EAClB,QAAA,EAAA;AAAA,wBAAAC,cAAA;AAAA,UAACG,gBAAA;AAAA,UAAA;AAAA,YACC,iBAAA,EAAmB,CAAA,CAAE,iBAAA,CAAkB,UAAU,CAAA;AAAA,YACjD,kBAAA,EAAoB,MAAM,MAAA,GAAS,CAAA,CAAE,kBAAkB,MAAM,CAAA,GAAI,CAAA,CAAE,iBAAA,CAAkB,MAAM,CAAA;AAAA,YAC3F,KAAA,EAAO,MAAM,MAAA,GAAS,CAAA,CAAE,kBAAkB,MAAM,CAAA,GAAI,CAAA,CAAE,iBAAA,CAAkB,MAAM,CAAA;AAAA,YAC9E,SAAS,KAAA,CAAM,MAAA;AAAA,YACf,MAAA,EAAQ,GAAG,YAAY,CAAA,OAAA;AAAA;AAAA,SACzB;AAAA,wBACAH,cAAA;AAAA,UAACG,gBAAA;AAAA,UAAA;AAAA,YACC,iBAAA,EAAmB,CAAA,CAAE,iBAAA,CAAkB,SAAS,CAAA;AAAA,YAChD,kBAAA,EAAoB,CAAA,CAAE,iBAAA,CAAkB,KAAK,CAAA;AAAA,YAC7C,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,KAAK,CAAA;AAAA,YAChC,OAAA,EAAS,WAAA;AAAA,YACT,MAAA,EAAQ,GAAG,YAAY,CAAA,MAAA,CAAA;AAAA,YACvB,OAAA,EAAQ;AAAA;AAAA,SACV;AAAA,wBACAH,cAAA;AAAA,UAACG,gBAAA;AAAA,UAAA;AAAA,YACC,iBAAA,EAAmB,CAAA,CAAE,iBAAA,CAAkB,WAAW,CAAA;AAAA,YAClD,kBAAA,EAAoB,CAAA,CAAE,iBAAA,CAAkB,OAAO,CAAA;AAAA,YAC/C,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,OAAO,CAAA;AAAA,YAClC,SAAS,KAAA,CAAM,OAAA;AAAA,YACf,MAAA,EAAQ,GAAG,YAAY,CAAA,QAAA,CAAA;AAAA,YACvB,OAAA,EAAQ;AAAA;AAAA;AACV,OAAA,EACF,CAAA;AAAA,sBACAH,cAAA,CAACC,oBAAK,KAAA,EAAO,MAAA,CAAO,MAAO,QAAA,EAAA,CAAA,CAAE,iBAAA,CAAkB,SAAS,CAAA,EAAE;AAAA,KAAA,EAC5D,CAAA,GACE,IAAA;AAAA,IAEH,WAAA,mBACCD,cAAA,CAACC,gBAAA,EAAA,EAAK,KAAA,EAAO,OAAO,OAAA,EAAS,MAAA,EAAQ,CAAA,EAAG,YAAY,CAAA,WAAA,CAAA,EACjD,QAAA,EAAA,CAAA,CAAE,iBAAA,CAAkB,aAAa,GACpC,CAAA,GACE,IAAA;AAAA,IAEH,CAAC,eAAe,SAAA,CAAU,MAAA,GAAS,oBAClCC,eAAA,CAACH,gBAAA,EAAA,EAAK,KAAA,EAAO,MAAA,CAAO,OAAA,EAClB,QAAA,EAAA;AAAA,sBAAAC,cAAA,CAACC,gBAAA,EAAA,EAAK,KAAA,EAAO,MAAA,CAAO,UAAA,EACjB,QAAA,EAAA,CAAA,CAAE,iBAAA,CAAkB,WAAA,EAAa,MAAA,CAAO,SAAA,CAAU,MAAM,CAAC,CAAA,EAC5D,CAAA;AAAA,MACC,SAAA,CAAU,IAAI,CAAC,IAAA,qCACbF,gBAAA,EAAA,EAAmB,KAAA,EAAO,OAAO,OAAA,EAChC,QAAA,EAAA;AAAA,wBAAAC,cAAA,CAACC,gBAAA,EAAA,EAAK,KAAA,EAAO,MAAA,CAAO,QAAA,EACjB,QAAA,EAAA,CAAA;AAAA,UACC,iBAAA,CAAkB,QAAA;AAAA,UAClB,cAAA,CAAe,IAAA,CAAK,SAAA,EAAW,EAAE,CAAA;AAAA,UACjC,eAAe,IAAA,CAAK,SAAA,EAAW,CAAA,CAAE,iBAAA,CAAkB,YAAY,CAAC;AAAA,SAClE,EACF,CAAA;AAAA,QACC,iBAAA,KAAsB,MAAA,GAAY,IAAA,GAAO,iBAAA,CAAkB,IAAI;AAAA,OAAA,EAAA,EARvD,IAAA,CAAK,EAShB,CACD;AAAA,KAAA,EACH,CAAA,GACE,IAAA;AAAA,IAEH,CAAC,WAAA,IAAe,SAAA,CAAU,WAAW,CAAA,mBACpCD,cAAA,CAACC,oBAAK,KAAA,EAAO,MAAA,CAAO,IAAA,EAAM,MAAA,EAAQ,GAAG,YAAY,CAAA,QAAA,CAAA,EAC9C,YAAE,iBAAA,CAAkB,MAAM,GAC7B,CAAA,GACE,IAAA;AAAA,oBAEJC,eAAA,CAACH,gBAAA,EAAA,EAAK,KAAA,EAAO,MAAA,CAAO,OAAA,EAClB,QAAA,EAAA;AAAA,sBAAAC,cAAA;AAAA,QAACG,gBAAA;AAAA,QAAA;AAAA,UACC,iBAAA,EAAmB,CAAA,CAAE,iBAAA,CAAkB,QAAQ,CAAA;AAAA,UAC/C,kBAAA,EAAoB,CAAA,CAAE,iBAAA,CAAkB,IAAI,CAAA;AAAA,UAC5C,UAAU,KAAA,CAAM,SAAA;AAAA,UAChB,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,IAAI,CAAA;AAAA,UAC/B,SAAS,KAAA,CAAM,SAAA;AAAA,UACf,SAAS,KAAA,CAAM,IAAA;AAAA,UACf,MAAA,EAAQ,GAAG,YAAY,CAAA,KAAA;AAAA;AAAA,OACzB;AAAA,sBACAH,cAAA;AAAA,QAACG,gBAAA;AAAA,QAAA;AAAA,UACC,iBAAA,EAAmB,CAAA,CAAE,iBAAA,CAAkB,SAAS,CAAA;AAAA,UAChD,kBAAA,EAAoB,CAAA,CAAE,iBAAA,CAAkB,KAAK,CAAA;AAAA,UAC7C,UAAU,KAAA,CAAM,SAAA;AAAA,UAChB,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,KAAK,CAAA;AAAA,UAChC,OAAA,EAAS,OAAA;AAAA,UACT,MAAA,EAAQ,GAAG,YAAY,CAAA,MAAA,CAAA;AAAA,UACvB,OAAA,EAAQ;AAAA;AAAA;AACV,KAAA,EACF;AAAA,GAAA,EACF,CAAA;AAEJ;AAGA,IAAM,WAAA,GAAc,CAAC,CAAA,KACnBC,sBAAA,CAAW,MAAA,CAAO;AAAA,EAChB,SAAS,EAAE,aAAA,EAAe,OAAO,QAAA,EAAU,MAAA,EAAQ,KAAK,QAAA,EAAS;AAAA,EACjE,OAAA,EAAS,EAAE,KAAA,EAAO,CAAA,CAAE,aAAa,QAAA,EAAU,OAAA,EAAS,YAAY,KAAA,EAAM;AAAA,EACtE,OAAA,EAAS,EAAE,GAAA,EAAK,QAAA,EAAU,WAAW,QAAA,EAAS;AAAA,EAC9C,UAAU,EAAE,KAAA,EAAO,CAAA,CAAE,aAAA,EAAe,UAAU,OAAA,EAAQ;AAAA,EACtD,OAAA,EAAS;AAAA,IACP,gBAAgB,CAAA,CAAE,MAAA;AAAA,IAClB,cAAA,EAAgB,CAAA;AAAA,IAChB,GAAA,EAAK,QAAA;AAAA,IACL,UAAA,EAAY;AAAA,GACd;AAAA,EACA,MAAM,EAAE,KAAA,EAAO,CAAA,CAAE,aAAA,EAAe,UAAU,OAAA,EAAQ;AAAA,EAClD,KAAA,EAAO;AAAA,IACL,iBAAiB,CAAA,CAAE,YAAA;AAAA,IACnB,aAAa,CAAA,CAAE,MAAA;AAAA,IACf,YAAA,EAAc,QAAA;AAAA,IACd,WAAA,EAAa,CAAA;AAAA,IACb,GAAA,EAAK,QAAA;AAAA,IACL,YAAA,EAAc,QAAA;AAAA,IACd,OAAA,EAAS;AAAA,GACX;AAAA,EACA,SAAA,EAAW;AAAA,IACT,iBAAiB,CAAA,CAAE,aAAA;AAAA,IACnB,aAAa,CAAA,CAAE,YAAA;AAAA,IACf,YAAA,EAAc,QAAA;AAAA,IACd,WAAA,EAAa,CAAA;AAAA,IACb,GAAA,EAAK,QAAA;AAAA,IACL,cAAA,EAAgB,QAAA;AAAA,IAChB,OAAA,EAAS;AAAA,GACX;AAAA,EACA,WAAA,EAAa,EAAE,KAAA,EAAO,CAAA,CAAE,eAAe,QAAA,EAAU,OAAA,EAAS,YAAY,KAAA,EAAM;AAAA,EAC5E,UAAA,EAAY,EAAE,KAAA,EAAO,CAAA,CAAE,aAAa,QAAA,EAAU,OAAA,EAAS,YAAY,KAAA,EAAM;AAAA,EACzE,GAAA,EAAK,EAAE,KAAA,EAAO,CAAA,CAAE,aAAa,QAAA,EAAU,OAAA,EAAS,YAAY,KAAA,EAAM;AAAA,EAClE,OAAA,EAAS,EAAE,KAAA,EAAO,CAAA,CAAE,QAAQ,QAAA,EAAU,OAAA,EAAS,YAAY,KAAA;AAC7D,CAAC,CAAA;;;AC9QH,SAAS,SAAS,KAAA,EAAmD;AACnE,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,CAAM,MAAK,KAAM,EAAA;AACvD;AAUO,SAAS,mBAAA,CAAoB,SAA0B,YAAA,EAA8B;AAC1F,EAAA,IAAI,SAAS,OAAA,CAAQ,WAAW,GAAG,OAAO,OAAA,CAAQ,YAAY,IAAA,EAAK;AACnE,EAAA,IAAI,SAAS,OAAA,CAAQ,KAAK,GAAG,OAAO,OAAA,CAAQ,MAAM,IAAA,EAAK;AACvD,EAAA,OAAO,YAAA;AACT;AAgBO,SAAS,mBAAA,CACd,QAAA,EACA,QAAA,EACA,OAAA,EACA,YAAA,EACiB;AACjB,EAAA,MAAM,aAAA,uBAAoB,GAAA,EAAY;AACtC,EAAA,QAAA,CAAS,OAAA,CAAQ,CAAC,SAAA,EAAW,SAAA,KAAc;AACzC,IAAA,IAAI,SAAA,KAAc,QAAQ,EAAA,IAAM,QAAA,CAAS,SAAS,CAAA,EAAG,aAAA,CAAc,IAAI,SAAS,CAAA;AAAA,EAClF,CAAC,CAAA;AAED,EAAA,OAAO,QAAA,CACJ,MAAA,CAAO,CAAC,OAAA,KAAY,CAAC,aAAA,CAAc,GAAA,CAAI,OAAA,CAAQ,MAAM,CAAC,CAAA,CACtD,GAAA,CAAI,CAAC,OAAA,MAAa;AAAA,IACjB,OAAO,OAAA,CAAQ,MAAA;AAAA,IACf,KAAA,EAAO,mBAAA,CAAoB,OAAA,EAAS,YAAY;AAAA,GAClD,CAAE,CAAA;AACN;ACvBO,SAAS,sBACd,OAAA,EACyB;AACzB,EAAA,MAAM,EAAE,OAAA,EAAS,cAAA,EAAgB,aAAa,aAAA,EAAe,QAAA,EAAU,GAAE,GAAI,OAAA;AAE7E,EAAA,MAAM,CAAC,iBAAA,EAAmB,oBAAoB,CAAA,GAAIb,eAAwB,cAAc,CAAA;AACxF,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIA,eAAkB,KAAK,CAAA;AAEzD,EAAA,MAAM,UAAA,GAAaC,aAAgB,IAAI,CAAA;AACvC,EAAAC,gBAAU,MAAM;AACd,IAAA,UAAA,CAAW,OAAA,GAAU,IAAA;AACrB,IAAA,OAAO,MAAM;AACX,MAAA,UAAA,CAAW,OAAA,GAAU,KAAA;AAAA,IACvB,CAAA;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAKL,EAAAA,gBAAU,MAAM;AACd,IAAA,oBAAA,CAAqB,cAAc,CAAA;AAAA,EACrC,CAAA,EAAG,CAAC,OAAA,CAAQ,EAAA,EAAI,cAAc,CAAC,CAAA;AAE/B,EAAA,MAAM,OAAA,GAAU,CAAC,SAAA,IAAa,iBAAA,KAAsB,QAAQ,iBAAA,KAAsB,cAAA;AAClF,EAAA,MAAM,SAAA,GAAY,CAAC,SAAA,IAAa,cAAA,KAAmB,IAAA;AAEnD,EAAA,MAAM,MAAA,GAASC,iBAAAA;AAAA,IACb,CAAC,WAA0B,UAAA,KAA6B;AACtD,MAAA,YAAA,CAAa,IAAI,CAAA;AACjB,MAAA,KAAA,CAAM,YAAY;AAChB,QAAA,IAAI;AACF,UAAA,MAAM,WAAA,CAAY,SAAS,SAAS,CAAA;AACpC,UAAA,IAAI,CAAC,WAAW,OAAA,EAAS;AACzB,UAAA,QAAA,CAAS,CAAA,CAAE,UAAA,EAAY,OAAA,CAAQ,WAAW,CAAA,EAAA,SAAA,eAA2B;AAAA,QACvE,SAAS,KAAA,EAAO;AACd,UAAA,IAAI,CAAC,WAAW,OAAA,EAAS;AACzB,UAAA,QAAA,CAAS,aAAA,CAAc,KAAc,CAAA,EAAA,OAAA,aAAyB;AAAA,QAChE,CAAA,SAAE;AACA,UAAA,IAAI,UAAA,CAAW,OAAA,EAAS,YAAA,CAAa,KAAK,CAAA;AAAA,QAC5C;AAAA,MACF,CAAA,GAAG;AAAA,IACL,CAAA;AAAA,IACA,CAAC,WAAA,EAAa,OAAA,EAAS,QAAA,EAAU,GAAG,aAAa;AAAA,GACnD;AAEA,EAAA,MAAM,IAAA,GAAOA,kBAAY,MAAY;AACnC,IAAA,IAAI,CAAC,OAAA,IAAW,iBAAA,KAAsB,IAAA,EAAM;AAC5C,IAAA,MAAA,CAAO,iBAAA,EAAmB,kBAAkB,kBAAkB,CAAA;AAAA,EAChE,CAAA,EAAG,CAAC,OAAA,EAAS,iBAAA,EAAmB,MAAM,CAAC,CAAA;AAEvC,EAAA,MAAM,MAAA,GAASA,kBAAY,MAAY;AACrC,IAAA,IAAI,CAAC,SAAA,EAAW;AAChB,IAAA,MAAA,CAAO,IAAA,EAAM,kBAAkB,oBAAoB,CAAA;AAAA,EACrD,CAAA,EAAG,CAAC,SAAA,EAAW,MAAM,CAAC,CAAA;AAEtB,EAAA,OAAO,EAAE,mBAAmB,MAAA,EAAQ,oBAAA,EAAsB,WAAW,OAAA,EAAS,SAAA,EAAW,MAAM,MAAA,EAAO;AACxG;ACpEA,IAAMW,SAAAA,GAAW,CAAA;AACjB,IAAMC,SAAAA,GAAW,CAAA;AACjB,IAAMC,SAAAA,GAAW,EAAA;AACjB,IAAMC,SAAAA,GAAW,EAAA;AACjB,IAAMC,QAAAA,GAAU,EAAA;AAChB,IAAMC,QAAAA,GAAU,EAAA;AAwBT,IAAM,mBAAmB,CAAC;AAAA,EAC/B,OAAA;AAAA,EACA,cAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,eAAe,qBAAA,CAAsB;AACvC,CAAA,KAAiD;AAC/C,EAAA,MAAM,EAAE,CAAA,EAAE,GAAId,gBAAAA,EAAM;AACpB,EAAA,MAAM,UAAU,qBAAA,EAAsB;AACtC,EAAA,MAAM,MAAA,GAASC,cAAQ,MAAMc,YAAAA,CAAY,OAAO,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAE5D,EAAA,MAAM,QAAQ,qBAAA,CAAsB;AAAA,IAClC,OAAA;AAAA,IACA,cAAA;AAAA,IACA,WAAA;AAAA,IACA,aAAA;AAAA,IACA,QAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,MAAM,YAAA,GAAe,CAAA,CAAE,iBAAA,CAAkB,cAAc,CAAA;AACvD,EAAA,MAAM,OAAA,GAAUd,aAAAA;AAAA,IACd,MAAM,mBAAA,CAAoB,QAAA,EAAU,QAAA,EAAU,SAAS,YAAY,CAAA;AAAA,IACnE,CAAC,QAAA,EAAU,QAAA,EAAU,OAAA,EAAS,YAAY;AAAA,GAC5C;AAEA,EAAA,MAAM,aAAA,GACJ,OAAA,CAAQ,IAAA,CAAK,CAAC,MAAA,KAAW,OAAO,KAAA,KAAU,KAAA,CAAM,iBAAiB,CAAA,EAAG,KAAA,IAAS,EAAA;AAE/E,EAAA,uBACEK,gBAACH,gBAAAA,EAAA,EAAK,OAAO,MAAA,CAAO,KAAA,EAAO,QAAQ,YAAA,EACjC,QAAA,EAAA;AAAA,oBAAAC,cAAAA,CAACC,gBAAAA,EAAA,EAAK,KAAA,EAAO,MAAA,CAAO,OAAA,EACjB,QAAA,EAAA,CAAA,CAAE,iBAAA,CAAkB,mBAAA,EAAqB,OAAA,CAAQ,WAAW,CAAA,EAC/D,CAAA;AAAA,oBACAD,cAAAA,CAACC,gBAAAA,EAAA,EAAK,KAAA,EAAO,OAAO,IAAA,EAAO,QAAA,EAAA,CAAA,CAAE,iBAAA,CAAkB,gBAAgB,CAAA,EAAE,CAAA;AAAA,IAEhE,OAAA,CAAQ,MAAA,GAAS,CAAA,mBAChBD,cAAAA;AAAA,MAACY,qBAAA;AAAA,MAAA;AAAA,QAIC,iBAAA,EAAmB,CAAA,CAAE,iBAAA,CAAkB,iBAAiB,CAAA;AAAA,QACxD,kBAAA,EAAoB,CAAA,EAAG,CAAA,CAAE,iBAAA,CAAkB,kBAAkB,CAAC,CAAA,EAAA,EAC5D,aAAA,KAAkB,EAAA,GAAK,CAAA,CAAE,iBAAA,CAAkB,wBAAwB,IAAI,aACzE,CAAA,CAAA;AAAA,QACA,UAAU,KAAA,CAAM,MAAA;AAAA,QAChB,UAAA,EAAY,CAAA,CAAE,iBAAA,CAAkB,iBAAiB,CAAA;AAAA,QACjD,OAAA;AAAA,QACA,WAAA,EAAa,CAAA,CAAE,iBAAA,CAAkB,wBAAwB,CAAA;AAAA,QACzD,MAAA,EAAQ,GAAG,YAAY,CAAA,OAAA,CAAA;AAAA,QACvB,KAAA,EAAO,MAAM,iBAAA,IAAqB;AAAA;AAAA,KACpC,mBAEAZ,cAAAA,CAACC,gBAAAA,EAAA,EAAK,KAAA,EAAO,MAAA,CAAO,IAAA,EAAM,MAAA,EAAQ,GAAG,YAAY,CAAA,YAAA,CAAA,EAC9C,QAAA,EAAA,CAAA,CAAE,iBAAA,CAAkB,WAAW,CAAA,EAClC,CAAA;AAAA,oBAGFC,eAAAA,CAACH,gBAAAA,EAAA,EAAK,KAAA,EAAO,OAAO,OAAA,EAClB,QAAA,EAAA;AAAA,sBAAAC,cAAAA;AAAA,QAACG,gBAAAA;AAAA,QAAA;AAAA,UACC,iBAAA,EAAmB,CAAA,CAAE,iBAAA,CAAkB,eAAe,CAAA;AAAA,UACtD,kBAAA,EAAoB,CAAA,CAAE,iBAAA,CAAkB,WAAW,CAAA;AAAA,UACnD,QAAA,EAAU,CAAC,KAAA,CAAM,OAAA;AAAA,UACjB,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,WAAW,CAAA;AAAA,UACtC,SAAS,KAAA,CAAM,SAAA;AAAA,UACf,SAAS,KAAA,CAAM,IAAA;AAAA,UACf,MAAA,EAAQ,GAAG,YAAY,CAAA,KAAA;AAAA;AAAA,OACzB;AAAA,MACC,KAAA,CAAM,4BACLH,cAAAA;AAAA,QAACG,gBAAAA;AAAA,QAAA;AAAA,UACC,iBAAA,EAAmB,CAAA,CAAE,iBAAA,CAAkB,iBAAiB,CAAA;AAAA,UACxD,kBAAA,EAAoB,CAAA,CAAE,iBAAA,CAAkB,aAAa,CAAA;AAAA,UACrD,UAAU,KAAA,CAAM,SAAA;AAAA,UAChB,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,aAAa,CAAA;AAAA,UACxC,SAAS,KAAA,CAAM,MAAA;AAAA,UACf,MAAA,EAAQ,GAAG,YAAY,CAAA,OAAA,CAAA;AAAA,UACvB,OAAA,EAAQ;AAAA;AAAA,OACV,GACE,IAAA;AAAA,sBACJH,cAAAA;AAAA,QAACG,gBAAAA;AAAA,QAAA;AAAA,UACC,iBAAA,EAAmB,CAAA,CAAE,iBAAA,CAAkB,gBAAgB,CAAA;AAAA,UACvD,kBAAA,EAAoB,CAAA,CAAE,iBAAA,CAAkB,YAAY,CAAA;AAAA,UACpD,UAAU,KAAA,CAAM,SAAA;AAAA,UAChB,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,YAAY,CAAA;AAAA,UACvC,OAAA,EAAS,OAAA;AAAA,UACT,MAAA,EAAQ,GAAG,YAAY,CAAA,MAAA,CAAA;AAAA,UACvB,OAAA,EAAQ;AAAA;AAAA;AACV,KAAA,EACF;AAAA,GAAA,EACF,CAAA;AAEJ;AAGA,IAAMQ,YAAAA,GAAc,CAAC,CAAA,KACnBP,sBAAAA,CAAW,MAAA,CAAO;AAAA,EAChB,SAAS,EAAE,aAAA,EAAe,OAAO,QAAA,EAAU,MAAA,EAAQ,KAAKE,SAAAA,EAAS;AAAA,EACjE,OAAA,EAAS,EAAE,KAAA,EAAO,CAAA,CAAE,aAAa,QAAA,EAAUI,QAAAA,EAAS,YAAY,KAAA,EAAM;AAAA,EACtE,MAAM,EAAE,KAAA,EAAO,CAAA,CAAE,aAAA,EAAe,UAAUD,QAAAA,EAAQ;AAAA,EAClD,KAAA,EAAO;AAAA,IACL,iBAAiB,CAAA,CAAE,YAAA;AAAA,IACnB,aAAa,CAAA,CAAE,MAAA;AAAA,IACf,YAAA,EAAcH,SAAAA;AAAA,IACd,WAAA,EAAa,CAAA;AAAA,IACb,GAAA,EAAKD,SAAAA;AAAA,IACL,YAAA,EAAcG,SAAAA;AAAA,IACd,OAAA,EAASD;AAAA;AAEb,CAAC,CAAA;;;ACzJH,IAAM,cAAA,GAAiB,IAAA;AAEhB,IAAM,eAAA,GAAkB,EAAA;AAGxB,SAAS,UAAA,CAAW,OAA0B,CAAA,EAAoC;AACvF,EAAA,OAAO,KAAA,CAAM,SAAS,CAAA,GAAI,KAAA,CAAM,KAAK,cAAc,CAAA,GAAI,CAAA,CAAE,iBAAA,CAAkB,YAAY,CAAA;AACzF;AAOO,SAAS,WAAA,CACd,QAAA,EACA,OAAA,EACA,CAAA,EACQ;AACR,EAAA,IAAI,QAAA,KAAa,IAAA,EAAM,OAAO,CAAA,CAAE,kBAAkB,eAAe,CAAA;AACjE,EAAA,MAAM,QAAQ,OAAA,CAAQ,IAAA,CAAK,CAAC,MAAA,KAAW,MAAA,CAAO,OAAO,QAAQ,CAAA;AAC7D,EAAA,OAAO,KAAA,KAAU,MAAA,GAAY,KAAA,CAAM,KAAA,GAAQ,QAAA;AAC7C;AAGO,SAAS,WAAA,CAAY,QAAiB,CAAA,EAAoC;AAC/E,EAAA,OAAO,SAAS,CAAA,CAAE,iBAAA,CAAkB,cAAc,CAAA,GAAI,CAAA,CAAE,kBAAkB,aAAa,CAAA;AACzF;AAGO,SAAS,YAAA,CAAa,WAA+B,CAAA,EAAoC;AAC9F,EAAA,IAAI,cAAc,MAAA,IAAa,SAAA,KAAc,IAAI,OAAO,CAAA,CAAE,kBAAkB,mBAAmB,CAAA;AAC/F,EAAA,MAAM,MAAA,GAAS,IAAI,IAAA,CAAK,SAAS,CAAA;AACjC,EAAA,IAAI,MAAA,CAAO,MAAM,MAAA,CAAO,OAAA,EAAS,CAAA,EAAG,OAAO,CAAA,CAAE,iBAAA,CAAkB,mBAAmB,CAAA;AAClF,EAAA,OAAO,OAAO,WAAA,EAAY,CAAE,KAAA,CAAM,CAAA,EAAG,aAAa,MAAM,CAAA;AAC1D;AASO,SAAS,WAAA,CACd,OACA,KAAA,EAC+B;AAC/B,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,IAAA,EAAK,CAAE,WAAA,EAAY;AACxC,EAAA,IAAI,MAAA,KAAW,IAAI,OAAO,KAAA;AAC1B,EAAA,OAAO,KAAA,CAAM,MAAA,CAAO,CAAC,IAAA,KAAS;AAC5B,IAAA,MAAM,QAAA,GAAW,CAAA,EAAG,IAAA,CAAK,KAAK,IAAI,IAAA,CAAK,WAAW,CAAA,CAAA,EAAI,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAG,CAAC,GAAG,WAAA,EAAY;AACzF,IAAA,OAAO,QAAA,CAAS,SAAS,MAAM,CAAA;AAAA,EACjC,CAAC,CAAA;AACH;AAOO,SAAS,aAAA,CACd,SACA,CAAA,EACiD;AACjD,EAAA,MAAM,QAAA,GAAW,EAAE,KAAA,EAAO,CAAA,CAAE,kBAAkB,eAAe,CAAA,EAAG,OAAO,eAAA,EAAgB;AACvF,EAAA,OAAO,CAAC,QAAA,EAAU,GAAG,OAAA,CAAQ,IAAI,CAAC,MAAA,MAAY,EAAE,KAAA,EAAO,OAAO,KAAA,EAAO,KAAA,EAAO,MAAA,CAAO,EAAA,GAAK,CAAC,CAAA;AAC3F;AAGO,SAAS,YACd,eAAA,EACiD;AACjD,EAAA,OAAO,eAAA,CAAgB,IAAI,CAAC,IAAA,MAAU,EAAE,KAAA,EAAO,IAAA,EAAM,KAAA,EAAO,IAAA,EAAK,CAAE,CAAA;AACrE;AAGO,SAAS,gBAAgB,KAAA,EAA8B;AAC5D,EAAA,OAAO,KAAA,KAAU,kBAAkB,IAAA,GAAO,KAAA;AAC5C;ACzEA,IAAM,WAAA,GAAc,CAAA;AAUb,SAAS,gBAAA,CAAiB;AAAA,EAC/B,CAAA;AAAA,EACA,OAAA;AAAA,EACA,YAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,EAAuE;AACrE,EAAA,OAAO;AAAA,IACL;AAAA,MACE,GAAA,EAAK,OAAA;AAAA,MACL,MAAA,EAAQ,CAAA,CAAE,iBAAA,CAAkB,aAAa,CAAA;AAAA,MACzC,MAAA,EAAQ,CAAC,IAAA,KAAS,IAAA,CAAK;AAAA,KACzB;AAAA,IACA;AAAA,MACE,GAAA,EAAK,aAAA;AAAA,MACL,MAAA,EAAQ,CAAA,CAAE,iBAAA,CAAkB,mBAAmB,CAAA;AAAA,MAC/C,MAAA,EAAQ,CAAC,IAAA,KAAS,IAAA,CAAK;AAAA,KACzB;AAAA,IACA;AAAA,MACE,GAAA,EAAK,OAAA;AAAA,MACL,MAAA,EAAQ,CAAA,CAAE,iBAAA,CAAkB,aAAa,CAAA;AAAA,MACzC,QAAQ,CAAC,IAAA,KAAS,UAAA,CAAW,IAAA,CAAK,OAAO,CAAC;AAAA,KAC5C;AAAA,IACA;AAAA,MACE,GAAA,EAAK,QAAA;AAAA,MACL,MAAA,EAAQ,CAAA,CAAE,iBAAA,CAAkB,cAAc,CAAA;AAAA,MAC1C,QAAQ,CAAC,IAAA,KAAS,YAAY,IAAA,CAAK,QAAA,EAAU,SAAS,CAAC;AAAA,KACzD;AAAA,IACA;AAAA,MACE,GAAA,EAAK,QAAA;AAAA,MACL,MAAA,EAAQ,CAAA,CAAE,iBAAA,CAAkB,cAAc,CAAA;AAAA,MAC1C,QAAQ,CAAC,IAAA,KAAS,WAAA,CAAY,IAAA,CAAK,QAAQ,CAAC;AAAA,KAC9C;AAAA,IACA;AAAA,MACE,GAAA,EAAK,SAAA;AAAA,MACL,MAAA,EAAQ,CAAA,CAAE,iBAAA,CAAkB,eAAe,CAAA;AAAA,MAC3C,QAAQ,CAAC,IAAA,KAAS,YAAA,CAAa,IAAA,CAAK,WAAW,CAAC;AAAA,KAClD;AAAA,IACA;AAAA,MACE,GAAA,EAAK,SAAA;AAAA,MACL,MAAA,EAAQ,CAAA,CAAE,iBAAA,CAAkB,eAAe,CAAA;AAAA,MAC3C,MAAA,EAAQ,CAAC,IAAA,qBACPL,gBAACH,gBAAAA,EAAA,EAAK,KAAA,EAAO,EAAE,eAAe,KAAA,EAAO,QAAA,EAAU,MAAA,EAAQ,GAAA,EAAK,aAAY,EACtE,QAAA,EAAA;AAAA,wBAAAC,cAAAA;AAAA,UAACG,gBAAAA;AAAA,UAAA;AAAA,YACC,iBAAA,EAAmB,CAAA,CAAE,iBAAA,CAAkB,aAAa,CAAA;AAAA,YACpD,kBAAA,EAAoB,CAAA,CAAE,iBAAA,CAAkB,SAAS,CAAA;AAAA,YACjD,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,SAAS,CAAA;AAAA,YACpC,OAAA,EAAS,MAAM,MAAA,CAAO,IAAI,CAAA;AAAA,YAC1B,IAAA,EAAK,IAAA;AAAA,YACL,MAAA,EAAQ,CAAA,EAAG,YAAY,CAAA,MAAA,EAAS,KAAK,EAAE,CAAA,CAAA;AAAA,YACvC,OAAA,EAAQ;AAAA;AAAA,SACV;AAAA,wBACAH,cAAAA;AAAA,UAACG,gBAAAA;AAAA,UAAA;AAAA,YACC,iBAAA,EAAmB,CAAA,CAAE,iBAAA,CAAkB,cAAc,CAAA;AAAA,YACrD,kBAAA,EAAoB,CAAA,CAAE,iBAAA,CAAkB,UAAU,CAAA;AAAA,YAClD,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,UAAU,CAAA;AAAA,YACrC,OAAA,EAAS,MAAM,OAAA,CAAQ,IAAI,CAAA;AAAA,YAC3B,IAAA,EAAK,IAAA;AAAA,YACL,MAAA,EAAQ,CAAA,EAAG,YAAY,CAAA,OAAA,EAAU,KAAK,EAAE,CAAA,CAAA;AAAA,YACxC,OAAA,EAAQ;AAAA;AAAA;AACV,OAAA,EACF;AAAA;AAEJ,GACF;AACF;ACzDO,IAAM,cAAc,CAAC;AAAA,EAC1B,MAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,WAAA;AAAA,EACA,KAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA,KAA4C;AAC1C,EAAA,MAAM,WAAW,OAAA,CAAQ,IAAA,CAAK,CAAC,MAAA,KAAW,MAAA,CAAO,UAAU,KAAK,CAAA;AAChE,EAAA,MAAM,cAAA,GAAiB,QAAA,KAAa,MAAA,GAAY,QAAA,CAAS,KAAA,GAAQ,WAAA;AAEjE,EAAA,uBACEH,cAAAA,CAACa,aAAA,EAAA,EAAM,KAAA,EACL,QAAA,kBAAAb,cAAAA;AAAA,IAACc,sBAAA;AAAA,IAAA;AAAA,MACC,iBAAA,EAAmB,IAAA;AAAA,MACnB,kBAAA,EAAoB,CAAA,EAAG,KAAK,CAAA,EAAA,EAAK,cAAc,CAAA,CAAA;AAAA,MAC/C,QAAA;AAAA,MACA,OAAA;AAAA,MACA,MAAA;AAAA,MACA,KAAA;AAAA,MACA,SAASC,wBAAA,CAAgB;AAAA;AAAA,GAC3B,EACF,CAAA;AAEJ,CAAA;ACxDA,IAAMT,SAAAA,GAAW,CAAA;AACjB,IAAMC,SAAAA,GAAW,EAAA;AAEV,IAAM,eAAA,GAAkBH,uBAAW,MAAA,CAAO;AAAA,EAC/C,OAAA,EAAS,EAAE,aAAA,EAAe,KAAA,EAAO,UAAU,MAAA,EAAQ,GAAA,EAAKE,SAAAA,EAAU,SAAA,EAAWA,SAAAA,EAAS;AAAA,EACtF,IAAA,EAAM,EAAE,GAAA,EAAKC,SAAAA,EAAU,SAASA,SAAAA;AAClC,CAAC,CAAA;ACkCM,IAAM,kBAAkB,CAAC;AAAA,EAC9B,OAAA;AAAA,EACA,eAAA;AAAA,EACA,eAAA;AAAA,EACA,OAAA;AAAA,EACA,CAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,KAAgD;AAC9C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIhB,eAAS,EAAE,CAAA;AACrC,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIA,eAAS,EAAE,CAAA;AAC3C,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAIA,eAAS,EAAE,CAAA;AACjD,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIA,eAAS,EAAE,CAAA;AACnC,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAIA,eAAS,eAAe,CAAA;AAC9D,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAIA,eAAS,KAAK,CAAA;AAIlD,EAAAE,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAA,QAAA,CAAS,EAAE,CAAA;AACX,IAAA,WAAA,CAAY,EAAE,CAAA;AACd,IAAA,cAAA,CAAe,EAAE,CAAA;AACjB,IAAA,OAAA,CAAQ,EAAE,CAAA;AACV,IAAA,cAAA,CAAe,eAAe,CAAA;AAC9B,IAAA,aAAA,CAAc,KAAK,CAAA;AAAA,EACrB,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAEZ,EAAA,MAAM,SAAA,GACJ,CAAC,UAAA,IACD,KAAA,CAAM,IAAA,EAAK,KAAM,EAAA,IACjB,QAAA,KAAa,EAAA,IACb,WAAA,CAAY,IAAA,EAAK,KAAM,MACvB,IAAA,KAAS,EAAA;AAEX,EAAA,MAAM,eAAe,YAA2B;AAC9C,IAAA,aAAA,CAAc,IAAI,CAAA;AAClB,IAAA,MAAM,QAAA,GAAW,eAAA,GAAkB,eAAA,CAAgB,WAAW,CAAA,GAAI,IAAA;AAClE,IAAA,MAAM,EAAA,GAAK,MAAM,QAAA,CAAS,EAAE,OAAO,KAAA,CAAM,IAAA,EAAK,EAAG,QAAA,EAAU,aAAa,WAAA,CAAY,IAAA,EAAK,EAAG,IAAA,EAAM,UAAU,CAAA;AAC5G,IAAA,aAAA,CAAc,KAAK,CAAA;AACnB,IAAA,IAAI,IAAI,QAAA,EAAS;AAAA,EACnB,CAAA;AAEA,EAAA,uBACEO,cAAAA,CAACgB,mBAAA,EAAA,EAAW,UAAoB,KAAA,EAAO,CAAA,CAAE,kBAAkB,gBAAgB,CAAA,EAAG,OAAA,EAC5E,QAAA,kBAAAd,gBAACH,gBAAAA,EAAA,EAAK,OAAO,eAAA,CAAgB,IAAA,EAAM,QAAQ,YAAA,EACzC,QAAA,EAAA;AAAA,oBAAAC,cAAAA;AAAA,MAACiB,iBAAA;AAAA,MAAA;AAAA,QACC,cAAA,EAAe,MAAA;AAAA,QACf,YAAA,EAAa,eAAA;AAAA,QACb,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,eAAe,CAAA;AAAA,QAC1C,YAAA,EAAc,QAAA;AAAA,QACd,WAAA,EAAa,CAAA,CAAE,iBAAA,CAAkB,qBAAqB,CAAA;AAAA,QACtD,QAAA,EAAQ,IAAA;AAAA,QACR,MAAA,EAAQ,GAAG,YAAY,CAAA,MAAA,CAAA;AAAA,QACvB,KAAA,EAAO;AAAA;AAAA,KACT;AAAA,oBACAjB,cAAAA;AAAA,MAACiB,iBAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,kBAAkB,CAAA;AAAA,QAC7C,YAAA,EAAc,WAAA;AAAA,QACd,WAAA,EAAa,CAAA,CAAE,iBAAA,CAAkB,wBAAwB,CAAA;AAAA,QACzD,QAAA,EAAQ,IAAA;AAAA,QACR,eAAA,EAAe,IAAA;AAAA,QACf,MAAA,EAAQ,GAAG,YAAY,CAAA,SAAA,CAAA;AAAA,QACvB,KAAA,EAAO;AAAA;AAAA,KACT;AAAA,oBACAjB,cAAAA;AAAA,MAACiB,iBAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,qBAAqB,CAAA;AAAA,QAChD,YAAA,EAAc,cAAA;AAAA,QACd,WAAA,EAAa,CAAA,CAAE,iBAAA,CAAkB,2BAA2B,CAAA;AAAA,QAC5D,QAAA,EAAQ,IAAA;AAAA,QACR,MAAA,EAAQ,GAAG,YAAY,CAAA,aAAA,CAAA;AAAA,QACvB,KAAA,EAAO;AAAA;AAAA,KACT;AAAA,oBACAjB,cAAAA;AAAA,MAAC,WAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,CAAA,CAAE,iBAAA,CAAkB,mBAAmB,CAAA;AAAA,QAC7C,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,cAAc,CAAA;AAAA,QACzC,QAAA,EAAU,OAAA;AAAA,QACV,OAAA,EAAS,YAAY,eAAe,CAAA;AAAA,QACpC,WAAA,EAAa,CAAA,CAAE,iBAAA,CAAkB,oBAAoB,CAAA;AAAA,QACrD,MAAA,EAAQ,GAAG,YAAY,CAAA,KAAA,CAAA;AAAA,QACvB,KAAA,EAAO;AAAA;AAAA,KACT;AAAA,IACC,kCACCA,cAAAA;AAAA,MAAC,WAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,CAAA,CAAE,iBAAA,CAAkB,qBAAqB,CAAA;AAAA,QAC/C,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,gBAAgB,CAAA;AAAA,QAC3C,QAAA,EAAU,cAAA;AAAA,QACV,OAAA,EAAS,aAAA,CAAc,OAAA,EAAS,CAAC,CAAA;AAAA,QACjC,WAAA,EAAa,CAAA,CAAE,iBAAA,CAAkB,sBAAsB,CAAA;AAAA,QACvD,MAAA,EAAQ,GAAG,YAAY,CAAA,OAAA,CAAA;AAAA,QACvB,KAAA,EAAO;AAAA;AAAA,KACT,GACE,IAAA;AAAA,oBACJE,eAAAA,CAACH,gBAAAA,EAAA,EAAK,KAAA,EAAO,gBAAgB,OAAA,EAC3B,QAAA,EAAA;AAAA,sBAAAC,cAAAA;AAAA,QAACG,gBAAAA;AAAA,QAAA;AAAA,UACC,iBAAA,EAAmB,CAAA,CAAE,iBAAA,CAAkB,qBAAqB,CAAA;AAAA,UAC5D,kBAAA,EAAoB,CAAA,CAAE,iBAAA,CAAkB,iBAAiB,CAAA;AAAA,UACzD,UAAU,CAAC,SAAA;AAAA,UACX,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,iBAAiB,CAAA;AAAA,UAC5C,OAAA,EAAS,UAAA;AAAA,UACT,OAAA,EAAS,YAAA;AAAA,UACT,MAAA,EAAQ,GAAG,YAAY,CAAA,OAAA;AAAA;AAAA,OACzB;AAAA,sBACAH,cAAAA;AAAA,QAACG,gBAAAA;AAAA,QAAA;AAAA,UACC,iBAAA,EAAmB,CAAA,CAAE,iBAAA,CAAkB,eAAe,CAAA;AAAA,UACtD,kBAAA,EAAoB,CAAA,CAAE,iBAAA,CAAkB,WAAW,CAAA;AAAA,UACnD,QAAA,EAAU,UAAA;AAAA,UACV,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,WAAW,CAAA;AAAA,UACtC,OAAA,EAAS,QAAA;AAAA,UACT,MAAA,EAAQ,GAAG,YAAY,CAAA,OAAA,CAAA;AAAA,UACvB,OAAA,EAAQ;AAAA;AAAA;AACV,KAAA,EACF;AAAA,GAAA,EACF,CAAA,EACF,CAAA;AAEJ,CAAA;AC3HO,IAAM,gBAAgB,CAAC;AAAA,EAC5B,OAAA;AAAA,EACA,IAAA;AAAA,EACA,eAAA;AAAA,EACA,eAAA;AAAA,EACA,OAAA;AAAA,EACA,CAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,KAA8C;AAC5C,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAIZ,eAAS,EAAE,CAAA;AACjD,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIA,eAAS,EAAE,CAAA;AACnC,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAIA,eAAS,eAAe,CAAA;AAC9D,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIA,eAAS,IAAI,CAAA;AACzC,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAIA,eAAS,KAAK,CAAA;AAElD,EAAA,MAAM,SAAS,IAAA,EAAM,EAAA;AACrB,EAAAE,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,IAAW,IAAA,KAAS,IAAA,EAAM;AAC/B,IAAA,cAAA,CAAe,KAAK,WAAW,CAAA;AAC/B,IAAA,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,IAAK,EAAE,CAAA;AAC3B,IAAA,cAAA,CAAe,IAAA,CAAK,YAAY,eAAe,CAAA;AAC/C,IAAA,SAAA,CAAU,KAAK,MAAM,CAAA;AACrB,IAAA,aAAA,CAAc,KAAK,CAAA;AAAA,EAGrB,CAAA,EAAG,CAAC,OAAA,EAAS,MAAA,EAAQ,IAAI,CAAC,CAAA;AAE1B,EAAA,MAAM,YAAY,CAAC,UAAA,IAAc,YAAY,IAAA,EAAK,KAAM,MAAM,IAAA,KAAS,EAAA;AAEvE,EAAA,MAAM,eAAe,YAA2B;AAC9C,IAAA,IAAI,SAAS,IAAA,EAAM;AACnB,IAAA,aAAA,CAAc,IAAI,CAAA;AAClB,IAAA,MAAM,KAAA,GAA6F;AAAA,MACjG,WAAA,EAAa,YAAY,IAAA,EAAK;AAAA,MAC9B,IAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,IAAI,eAAA,EAAiB,KAAA,CAAM,QAAA,GAAW,eAAA,CAAgB,WAAW,CAAA;AACjE,IAAA,MAAM,EAAA,GAAK,MAAM,QAAA,CAAS,IAAA,CAAK,IAAI,KAAK,CAAA;AACxC,IAAA,aAAA,CAAc,KAAK,CAAA;AACnB,IAAA,IAAI,IAAI,QAAA,EAAS;AAAA,EACnB,CAAA;AAEA,EAAA,uBACEO,cAAAA,CAACgB,mBAAAA,EAAA,EAAW,QAAA,EAAoB,KAAA,EAAO,EAAE,iBAAA,CAAkB,cAAc,GAAG,OAAA,EAC1E,QAAA,kBAAAd,gBAACH,gBAAAA,EAAA,EAAK,OAAO,eAAA,CAAgB,IAAA,EAAM,QAAQ,YAAA,EACzC,QAAA,EAAA;AAAA,oBAAAC,cAAAA;AAAA,MAACiB,iBAAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,qBAAqB,CAAA;AAAA,QAChD,YAAA,EAAc,cAAA;AAAA,QACd,WAAA,EAAa,CAAA,CAAE,iBAAA,CAAkB,2BAA2B,CAAA;AAAA,QAC5D,QAAA,EAAQ,IAAA;AAAA,QACR,MAAA,EAAQ,GAAG,YAAY,CAAA,aAAA,CAAA;AAAA,QACvB,KAAA,EAAO;AAAA;AAAA,KACT;AAAA,oBACAjB,cAAAA;AAAA,MAAC,WAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,CAAA,CAAE,iBAAA,CAAkB,mBAAmB,CAAA;AAAA,QAC7C,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,cAAc,CAAA;AAAA,QACzC,QAAA,EAAU,OAAA;AAAA,QACV,OAAA,EAAS,YAAY,eAAe,CAAA;AAAA,QACpC,WAAA,EAAa,CAAA,CAAE,iBAAA,CAAkB,oBAAoB,CAAA;AAAA,QACrD,MAAA,EAAQ,GAAG,YAAY,CAAA,KAAA,CAAA;AAAA,QACvB,KAAA,EAAO;AAAA;AAAA,KACT;AAAA,IACC,kCACCA,cAAAA;AAAA,MAAC,WAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,CAAA,CAAE,iBAAA,CAAkB,qBAAqB,CAAA;AAAA,QAC/C,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,gBAAgB,CAAA;AAAA,QAC3C,QAAA,EAAU,cAAA;AAAA,QACV,OAAA,EAAS,aAAA,CAAc,OAAA,EAAS,CAAC,CAAA;AAAA,QACjC,WAAA,EAAa,CAAA,CAAE,iBAAA,CAAkB,sBAAsB,CAAA;AAAA,QACvD,MAAA,EAAQ,GAAG,YAAY,CAAA,OAAA,CAAA;AAAA,QACvB,KAAA,EAAO;AAAA;AAAA,KACT,GACE,IAAA;AAAA,oBACJA,cAAAA;AAAA,MAACkB,kBAAA;AAAA,MAAA;AAAA,QACC,iBAAA,EAAmB,CAAA,CAAE,iBAAA,CAAkB,qBAAqB,CAAA;AAAA,QAC5D,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,gBAAgB,CAAA;AAAA,QAC3C,aAAA,EAAe,SAAA;AAAA,QACf,MAAA,EAAQ,GAAG,YAAY,CAAA,OAAA,CAAA;AAAA,QACvB,KAAA,EAAO;AAAA;AAAA,KACT;AAAA,oBACAhB,eAAAA,CAACH,gBAAAA,EAAA,EAAK,KAAA,EAAO,gBAAgB,OAAA,EAC3B,QAAA,EAAA;AAAA,sBAAAC,cAAAA;AAAA,QAACG,gBAAAA;AAAA,QAAA;AAAA,UACC,iBAAA,EAAmB,CAAA,CAAE,iBAAA,CAAkB,mBAAmB,CAAA;AAAA,UAC1D,kBAAA,EAAoB,CAAA,CAAE,iBAAA,CAAkB,eAAe,CAAA;AAAA,UACvD,UAAU,CAAC,SAAA;AAAA,UACX,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,eAAe,CAAA;AAAA,UAC1C,OAAA,EAAS,UAAA;AAAA,UACT,OAAA,EAAS,YAAA;AAAA,UACT,MAAA,EAAQ,GAAG,YAAY,CAAA,OAAA;AAAA;AAAA,OACzB;AAAA,sBACAH,cAAAA;AAAA,QAACG,gBAAAA;AAAA,QAAA;AAAA,UACC,iBAAA,EAAmB,CAAA,CAAE,iBAAA,CAAkB,eAAe,CAAA;AAAA,UACtD,kBAAA,EAAoB,CAAA,CAAE,iBAAA,CAAkB,WAAW,CAAA;AAAA,UACnD,QAAA,EAAU,UAAA;AAAA,UACV,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,WAAW,CAAA;AAAA,UACtC,OAAA,EAAS,QAAA;AAAA,UACT,MAAA,EAAQ,GAAG,YAAY,CAAA,OAAA,CAAA;AAAA,UACvB,OAAA,EAAQ;AAAA;AAAA;AACV,KAAA,EACF;AAAA,GAAA,EACF,CAAA,EACF,CAAA;AAEJ,CAAA;ACvHO,IAAM,qBAAqB,CAAC;AAAA,EACjC,OAAA;AAAA,EACA,IAAA;AAAA,EACA,CAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,KAAmD;AACjD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIZ,eAAS,EAAE,CAAA;AAC3C,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAIA,eAAS,KAAK,CAAA;AAElD,EAAAE,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAA,WAAA,CAAY,EAAE,CAAA;AACd,IAAA,aAAA,CAAc,KAAK,CAAA;AAAA,EACrB,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAEZ,EAAA,MAAM,SAAA,GAAY,CAAC,UAAA,IAAc,QAAA,KAAa,EAAA;AAE9C,EAAA,MAAM,eAAe,YAA2B;AAC9C,IAAA,IAAI,SAAS,IAAA,EAAM;AACnB,IAAA,aAAA,CAAc,IAAI,CAAA;AAClB,IAAA,MAAM,EAAA,GAAK,MAAM,QAAA,CAAS,IAAA,CAAK,IAAI,QAAQ,CAAA;AAC3C,IAAA,aAAA,CAAc,KAAK,CAAA;AACnB,IAAA,IAAI,IAAI,QAAA,EAAS;AAAA,EACnB,CAAA;AAEA,EAAA,uBACEO,cAAAA,CAACgB,mBAAAA,EAAA,EAAW,QAAA,EAAoB,KAAA,EAAO,EAAE,iBAAA,CAAkB,eAAe,GAAG,OAAA,EAC3E,QAAA,kBAAAd,gBAACH,gBAAAA,EAAA,EAAK,OAAO,eAAA,CAAgB,IAAA,EAAM,QAAQ,YAAA,EACzC,QAAA,EAAA;AAAA,oBAAAC,cAAAA;AAAA,MAACiB,iBAAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,qBAAqB,CAAA;AAAA,QAChD,YAAA,EAAc,WAAA;AAAA,QACd,WAAA,EAAa,CAAA,CAAE,iBAAA,CAAkB,2BAA2B,CAAA;AAAA,QAC5D,QAAA,EAAQ,IAAA;AAAA,QACR,eAAA,EAAe,IAAA;AAAA,QACf,MAAA,EAAQ,GAAG,YAAY,CAAA,SAAA,CAAA;AAAA,QACvB,KAAA,EAAO;AAAA;AAAA,KACT;AAAA,oBACAf,eAAAA,CAACH,gBAAAA,EAAA,EAAK,KAAA,EAAO,gBAAgB,OAAA,EAC3B,QAAA,EAAA;AAAA,sBAAAC,cAAAA;AAAA,QAACG,gBAAAA;AAAA,QAAA;AAAA,UACC,iBAAA,EAAmB,CAAA,CAAE,iBAAA,CAAkB,oBAAoB,CAAA;AAAA,UAC3D,kBAAA,EAAoB,CAAA,CAAE,iBAAA,CAAkB,gBAAgB,CAAA;AAAA,UACxD,UAAU,CAAC,SAAA;AAAA,UACX,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,gBAAgB,CAAA;AAAA,UAC3C,OAAA,EAAS,UAAA;AAAA,UACT,OAAA,EAAS,YAAA;AAAA,UACT,MAAA,EAAQ,GAAG,YAAY,CAAA,OAAA;AAAA;AAAA,OACzB;AAAA,sBACAH,cAAAA;AAAA,QAACG,gBAAAA;AAAA,QAAA;AAAA,UACC,iBAAA,EAAmB,CAAA,CAAE,iBAAA,CAAkB,eAAe,CAAA;AAAA,UACtD,kBAAA,EAAoB,CAAA,CAAE,iBAAA,CAAkB,WAAW,CAAA;AAAA,UACnD,QAAA,EAAU,UAAA;AAAA,UACV,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,WAAW,CAAA;AAAA,UACtC,OAAA,EAAS,QAAA;AAAA,UACT,MAAA,EAAQ,GAAG,YAAY,CAAA,OAAA,CAAA;AAAA,UACvB,OAAA,EAAQ;AAAA;AAAA;AACV,KAAA,EACF;AAAA,GAAA,EACF,CAAA,EACF,CAAA;AAEJ,CAAA;AC/CO,SAAS,iBAAA,CACd,KACA,CAAA,EAC0B;AAC1B,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIZ,cAAAA,CAAwC,EAAE,CAAA;AACpE,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIA,eAAS,IAAI,CAAA;AAC3C,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAIA,eAAS,KAAK,CAAA;AAElD,EAAA,MAAM,MAAMM,aAAAA,CAAQ,MAAMsB,yBAAA,EAAe,EAAG,EAAE,CAAA;AAG9C,EAAA,MAAM,UAAA,GAAa3B,aAAO,IAAI,CAAA;AAC9B,EAAAC,gBAAU,MAAM;AACd,IAAA,OAAO,MAAM;AACX,MAAA,UAAA,CAAW,OAAA,GAAU,KAAA;AAAA,IACvB,CAAA;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,MAAA,GAASC,kBAAY,MAAY;AACrC,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,aAAA,CAAc,KAAK,CAAA;AACnB,IAAA,KAAK,GAAA,CACF,SAAA,EAAU,CACV,IAAA,CAAK,CAAC,IAAA,KAAS;AACd,MAAA,IAAI,CAAC,WAAW,OAAA,EAAS;AACzB,MAAA,QAAA,CAAS,IAAI,CAAA;AACb,MAAA,UAAA,CAAW,KAAK,CAAA;AAAA,IAClB,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AACX,MAAA,IAAI,CAAC,WAAW,OAAA,EAAS;AACzB,MAAA,aAAA,CAAc,IAAI,CAAA;AAClB,MAAA,UAAA,CAAW,KAAK,CAAA;AAAA,IAClB,CAAC,CAAA;AAAA,EACL,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAER,EAAAD,gBAAU,MAAM,MAAA,EAAO,EAAG,CAAC,MAAM,CAAC,CAAA;AAElC,EAAA,MAAM,QAAA,GAAWC,iBAAAA;AAAA,IACf,OAAO,KAAA,EAA4B,UAAA,EAAoB,UAAA,KAAyC;AAC9F,MAAA,IAAI;AACF,QAAA,MAAM,KAAA,EAAM;AACZ,QAAA,GAAA,CAAI,OAAA,CAAQ,CAAA,CAAE,UAAU,CAAC,CAAA;AACzB,QAAA,MAAA,EAAO;AACP,QAAA,OAAO,IAAA;AAAA,MACT,CAAA,CAAA,MAAQ;AACN,QAAA,GAAA,CAAI,KAAA,CAAM,CAAA,CAAE,UAAU,CAAC,CAAA;AACvB,QAAA,OAAO,KAAA;AAAA,MACT;AAAA,IACF,CAAA;AAAA,IACA,CAAC,GAAA,EAAK,MAAA,EAAQ,CAAC;AAAA,GACjB;AAEA,EAAA,MAAM,MAAA,GAASA,iBAAAA;AAAA,IACb,CAAC,KAAA,KACC,QAAA;AAAA,MACE,MAAM,GAAA,CAAI,UAAA,CAAW,KAAK,CAAA;AAAA,MAC1B,iBAAA,CAAkB,kBAAA;AAAA,MAClB,iBAAA,CAAkB;AAAA,KACpB;AAAA,IACF,CAAC,KAAK,QAAQ;AAAA,GAChB;AAEA,EAAA,MAAM,MAAA,GAASA,iBAAAA;AAAA,IACb,CAAC,IAAI,KAAA,KACH,QAAA;AAAA,MACE,MAAM,GAAA,CAAI,UAAA,CAAW,EAAA,EAAI,KAAK,CAAA;AAAA,MAC9B,iBAAA,CAAkB,kBAAA;AAAA,MAClB,iBAAA,CAAkB;AAAA,KACpB;AAAA,IACF,CAAC,KAAK,QAAQ;AAAA,GAChB;AAEA,EAAA,MAAM,aAAA,GAAgBA,iBAAAA;AAAA,IACpB,CAAC,IAAI,QAAA,KACH,QAAA;AAAA,MACE,MAAM,GAAA,CAAI,aAAA,CAAc,EAAA,EAAI,QAAQ,CAAA;AAAA,MACpC,iBAAA,CAAkB,iBAAA;AAAA,MAClB,iBAAA,CAAkB;AAAA,KACpB;AAAA,IACF,CAAC,KAAK,QAAQ;AAAA,GAChB;AAEA,EAAA,OAAO;AAAA,IACL,KAAA;AAAA,IACA,OAAA;AAAA,IACA,UAAA;AAAA,IACA,MAAA;AAAA,IACA,MAAA;AAAA,IACA,MAAA;AAAA,IACA,aAAA;AAAA,IACA,gBAAgB,GAAA,CAAI;AAAA,GACtB;AACF;ACnGA,IAAMW,SAAAA,GAAW,CAAA;AACjB,IAAMC,SAAAA,GAAW,CAAA;AACjB,IAAMC,SAAAA,GAAW,EAAA;AACjB,IAAME,QAAAA,GAAU,EAAA;AAChB,IAAMC,QAAAA,GAAU,EAAA;AAChB,IAAM,gBAAA,GAAmB,GAAA;AASlB,IAAM,sBAAsB,CAAC;AAAA,EAClC,GAAA;AAAA,EACA,eAAA;AAAA,EACA,eAAA;AAAA,EACA,UAAU,EAAC;AAAA,EACX,CAAA;AAAA,EACA,SAAS,qBAAA,CAAsB;AACjC,CAAA,KAAoD;AAClD,EAAA,MAAM,UAAU,qBAAA,EAAsB;AACtC,EAAA,MAAM,MAAA,GAASb,cAAQ,MAAMc,YAAAA,CAAY,OAAO,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAE5D,EAAA,MAAM,UAAA,GAAa,iBAAA,CAAkB,GAAA,EAAK,CAAC,CAAA;AAC3C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIpB,eAAS,EAAE,CAAA;AACrC,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIA,eAAoB,MAAA,YAAc;AACpE,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAIA,eAAoC,IAAI,CAAA;AAE5E,EAAA,MAAM,YAAA,GAAeM,aAAAA;AAAA,IACnB,MAAM,WAAA,CAAY,UAAA,CAAW,KAAA,EAAO,KAAK,CAAA;AAAA,IACzC,CAAC,UAAA,CAAW,KAAA,EAAO,KAAK;AAAA,GAC1B;AAEA,EAAA,MAAM,QAAA,GAAW,CAAC,IAAA,KAAmC;AACnD,IAAA,aAAA,CAAc,IAAI,CAAA;AAClB,IAAA,YAAA,CAAa,MAAA,YAAc;AAAA,EAC7B,CAAA;AACA,EAAA,MAAM,SAAA,GAAY,CAAC,IAAA,KAAmC;AACpD,IAAA,aAAA,CAAc,IAAI,CAAA;AAClB,IAAA,YAAA,CAAa,OAAA,aAAe;AAAA,EAC9B,CAAA;AACA,EAAA,MAAM,UAAA,GAAa,MAAY,YAAA,CAAa,MAAA,YAAc;AAE1D,EAAA,MAAM,OAAA,GAAUA,aAAAA;AAAA,IACd,MAAM,gBAAA,CAAiB,EAAE,CAAA,EAAG,OAAA,EAAS,YAAA,EAAc,MAAA,EAAQ,MAAA,EAAQ,QAAA,EAAU,OAAA,EAAS,SAAA,EAAW,CAAA;AAAA,IACjG,CAAC,CAAA,EAAG,OAAA,EAAS,MAAM;AAAA,GACrB;AAEA,EAAA,uBACEK,eAAAA,CAACH,gBAAAA,EAAA,EAAK,KAAA,EAAO,MAAA,CAAO,OAAO,MAAA,EACzB,QAAA,EAAA;AAAA,oBAAAC,cAAAA,CAACoB,wBAAU,SAAA,EAAW,UAAA,CAAW,gBAAgB,WAAA,EAAa,CAAA,EAAG,MAAM,CAAA,MAAA,CAAA,EAAU,CAAA;AAAA,oBAEjFpB,cAAAA,CAACC,gBAAAA,EAAA,EAAK,KAAA,EAAO,OAAO,OAAA,EAAU,QAAA,EAAA,CAAA,CAAE,iBAAA,CAAkB,YAAY,CAAA,EAAE,CAAA;AAAA,oBAChED,cAAAA,CAACC,gBAAAA,EAAA,EAAK,KAAA,EAAO,OAAO,IAAA,EAAO,QAAA,EAAA,CAAA,CAAE,iBAAA,CAAkB,SAAS,CAAA,EAAE,CAAA;AAAA,oBAE1DD,cAAAA;AAAA,MAACqB,kBAAA;AAAA,MAAA;AAAA,QACC,yBACErB,cAAAA;AAAA,UAACG,gBAAAA;AAAA,UAAA;AAAA,YACC,iBAAA,EAAmB,CAAA,CAAE,iBAAA,CAAkB,eAAe,CAAA;AAAA,YACtD,kBAAA,EAAoB,CAAA,CAAE,iBAAA,CAAkB,WAAW,CAAA;AAAA,YACnD,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,WAAW,CAAA;AAAA,YACtC,OAAA,EAAS,MAAM,YAAA,CAAa,QAAA,cAAgB;AAAA,YAC5C,MAAA,EAAQ,GAAG,MAAM,CAAA,OAAA;AAAA;AAAA,SACnB;AAAA,QAEF,cAAc,YAAA,CAAa,MAAA;AAAA,QAC3B,YAAA,EAAc,CAAA,CAAE,iBAAA,CAAkB,iBAAiB,CAAA;AAAA,QACnD,MAAA,EAAQ,GAAG,MAAM,CAAA,WAAA,CAAA;AAAA,QAEjB,0BAAAH,cAAAA,CAACD,gBAAAA,EAAA,EAAK,KAAA,EAAO,MAAA,CAAO,QAClB,QAAA,kBAAAC,cAAAA;AAAA,UAACiB,iBAAAA;AAAA,UAAA;AAAA,YACC,kBAAA,EAAoB,CAAA,CAAE,iBAAA,CAAkB,gBAAgB,CAAA;AAAA,YACxD,iBAAA,EAAmB,CAAA,CAAE,iBAAA,CAAkB,eAAe,CAAA;AAAA,YACtD,cAAA,EAAe,MAAA;AAAA,YACf,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,gBAAgB,CAAA;AAAA,YAC3C,YAAA,EAAc,QAAA;AAAA,YACd,WAAA,EAAa,CAAA,CAAE,iBAAA,CAAkB,sBAAsB,CAAA;AAAA,YACvD,MAAA,EAAQ,GAAG,MAAM,CAAA,OAAA,CAAA;AAAA,YACjB,KAAA,EAAO;AAAA;AAAA,SACT,EACF;AAAA;AAAA,KACF;AAAA,IAEC,UAAA,CAAW,UAAA,mBACVf,eAAAA,CAACH,gBAAAA,EAAA,EAAK,KAAA,EAAO,MAAA,CAAO,QAAA,EAAU,MAAA,EAAQ,CAAA,EAAG,MAAM,CAAA,WAAA,CAAA,EAC7C,QAAA,EAAA;AAAA,sBAAAC,cAAAA,CAACC,kBAAA,EAAK,KAAA,EAAO,OAAO,OAAA,EAAU,QAAA,EAAA,CAAA,CAAE,iBAAA,CAAkB,cAAc,CAAA,EAAE,CAAA;AAAA,sBAClED,cAAAA;AAAA,QAACG,gBAAAA;AAAA,QAAA;AAAA,UACC,iBAAA,EAAmB,CAAA,CAAE,iBAAA,CAAkB,cAAc,CAAA;AAAA,UACrD,kBAAA,EAAoB,CAAA,CAAE,iBAAA,CAAkB,UAAU,CAAA;AAAA,UAClD,KAAA,EAAO,CAAA,CAAE,iBAAA,CAAkB,UAAU,CAAA;AAAA,UACrC,SAAS,UAAA,CAAW,MAAA;AAAA,UACpB,MAAA,EAAQ,GAAG,MAAM,CAAA,MAAA,CAAA;AAAA,UACjB,OAAA,EAAQ;AAAA;AAAA;AACV,KAAA,EACF,oBAEAH,cAAAA;AAAA,MAACsB,kBAAA;AAAA,MAAA;AAAA,QACC,OAAA;AAAA,QACA,UAAA,EAAY,CAAA,CAAE,iBAAA,CAAkB,UAAU,CAAA;AAAA,QAC1C,YAAA,EAAc,CAAC,IAAA,KAAS,IAAA,CAAK,EAAA;AAAA,QAC7B,SAAS,UAAA,CAAW,OAAA;AAAA,QACpB,YAAA,EAAc,CAAA,CAAE,iBAAA,CAAkB,YAAY,CAAA;AAAA,QAC9C,IAAA,EAAM,YAAA;AAAA,QACN,MAAA,EAAQ,GAAG,MAAM,CAAA,MAAA,CAAA;AAAA,QACjB,KAAA,EAAK;AAAA;AAAA,KACP;AAAA,oBAGFtB,cAAAA;AAAA,MAAC,eAAA;AAAA,MAAA;AAAA,QACC,eAAA;AAAA,QACA,eAAA;AAAA,QACA,QAAA,EAAU,UAAA;AAAA,QACV,UAAU,UAAA,CAAW,MAAA;AAAA,QACrB,CAAA;AAAA,QACA,OAAA;AAAA,QACA,YAAA,EAAc,GAAG,MAAM,CAAA,aAAA,CAAA;AAAA,QACvB,SAAS,SAAA,KAAc,QAAA;AAAA;AAAA,KACzB;AAAA,oBACAA,cAAAA;AAAA,MAAC,aAAA;AAAA,MAAA;AAAA,QACC,eAAA;AAAA,QACA,eAAA;AAAA,QACA,QAAA,EAAU,UAAA;AAAA,QACV,UAAU,UAAA,CAAW,MAAA;AAAA,QACrB,CAAA;AAAA,QACA,OAAA;AAAA,QACA,YAAA,EAAc,GAAG,MAAM,CAAA,WAAA,CAAA;AAAA,QACvB,IAAA,EAAM,UAAA;AAAA,QACN,SAAS,SAAA,KAAc,MAAA;AAAA;AAAA,KACzB;AAAA,oBACAA,cAAAA;AAAA,MAAC,kBAAA;AAAA,MAAA;AAAA,QACC,QAAA,EAAU,UAAA;AAAA,QACV,UAAU,UAAA,CAAW,aAAA;AAAA,QACrB,CAAA;AAAA,QACA,YAAA,EAAc,GAAG,MAAM,CAAA,YAAA,CAAA;AAAA,QACvB,IAAA,EAAM,UAAA;AAAA,QACN,SAAS,SAAA,KAAc,OAAA;AAAA;AAAA;AACzB,GAAA,EACF,CAAA;AAEJ;AAGA,IAAMW,YAAAA,GAAc,CAAC,CAAA,KACnBP,sBAAAA,CAAW,MAAA,CAAO;AAAA,EAChB,QAAA,EAAU;AAAA,IACR,iBAAiB,CAAA,CAAE,YAAA;AAAA,IACnB,aAAa,CAAA,CAAE,MAAA;AAAA,IACf,YAAA,EAAcE,SAAAA;AAAA,IACd,WAAA,EAAa,CAAA;AAAA,IACb,GAAA,EAAKA,SAAAA;AAAA,IACL,SAAA,EAAWA,SAAAA;AAAA,IACX,OAAA,EAASC;AAAA,GACX;AAAA,EACA,OAAA,EAAS,EAAE,KAAA,EAAO,CAAA,CAAE,aAAa,QAAA,EAAUG,QAAAA,EAAS,YAAY,KAAA,EAAM;AAAA,EACtE,MAAM,EAAE,KAAA,EAAO,CAAA,CAAE,aAAA,EAAe,UAAUD,QAAAA,EAAQ;AAAA,EAClD,KAAA,EAAO,EAAE,GAAA,EAAKJ,SAAAA,EAAS;AAAA,EACvB,MAAA,EAAQ,EAAE,QAAA,EAAU,gBAAA,EAAiB;AAAA,EACrC,OAAA,EAAS,EAAE,KAAA,EAAO,CAAA,CAAE,QAAQ,QAAA,EAAUI,QAAAA,EAAS,YAAY,KAAA;AAC7D,CAAC,CAAA","file":"index.js","sourcesContent":["/**\n * How a settled write should be reported. Its own file per the repo's\n * \"one exported enum per file\" rule.\n *\n * Two values, not three. There is no \"warning\" because every branch this package\n * reports is either a thing that worked or a thing the user has to act on — and\n * the one case that tempts a warning is the most important error in the package:\n * a mint that SUCCEEDED but whose URL never reached the clipboard. That is\n * reported as `Error`, loudly, because the URL is readable exactly once and a\n * user who dismisses it without copying by hand has to revoke and re-mint. An\n * amber \"heads up\" would let that slide past.\n */\nexport const enum AccessResultTone {\n Success = 'success',\n Error = 'error',\n}\n\n/** Reports a settled outcome with an ALREADY-LOCALIZED message. */\nexport type AccessResultReporter = (message: string, tone: AccessResultTone) => void;\n","/**\n * The package's two host contracts: the translation keys it resolves, and the\n * testIDs it renders.\n */\n\n/**\n * Every translation key this package resolves through `t(...)` — the host's i18n contract.\n *\n * ── WHY A MACHINE-READABLE MAP AND NOT A README TABLE ─────────────────────────\n * The kit is deliberately fallback-free: `t` is the host's own resolver (kefi passes\n * `FM`), and a missing key renders the RAW DOTTED NAME to the user — a panel warning\n * `accessAdmin.capabilityWarning` instead of explaining that anyone holding the URL\n * has the access. Because every `t(...)` call site in this package lives inside\n * `node_modules` once published, a host grepping its own source for untranslated\n * strings cannot see them. Hand-maintained key lists rot on exactly this path: one\n * portal in this fleet was found missing 26 kit keys, rendering raw names to users.\n *\n * So: bind a missing-key guard to this map, the way kefi-web's\n * `kitTranslationKeys.ts` already binds `LAYOUT_I18N` / `TABLE_I18N`. Then a kit\n * upgrade that adds a string FAILS the host's test suite instead of shipping raw\n * key text. `accessAdminI18n.test.ts` asserts this map stays complete and unused-free,\n * so the map cannot drift from the call sites either.\n *\n * The KEY NAMES are the package's; the WORDING is entirely the host's. That split is\n * what lets kefi keep its warm, specific copy (\"This link lets them see their own\n * guests and what they are owed\") under a key a survey tool can reuse with its own.\n */\nexport const ACCESS_ADMIN_I18N = {\n // ── AccessLinkPanel: framing ────────────────────────────────────────────────\n /** Panel heading. `{{p1}}` = subject display name. */\n panelHeading: 'accessAdmin.link.panelHeading',\n /** Supporting line explaining what the link grants. */\n panelNote: 'accessAdmin.link.panelNote',\n /** The security warning. Shown always, not only after a mint — see AccessLinkPanel. */\n capabilityWarning: 'accessAdmin.link.capabilityWarning',\n /** \"A link created now stops working on {{p1}}.\" `{{p1}}` = yyyy-mm-dd. */\n expiryPreview: 'accessAdmin.link.expiryPreview',\n\n // ── AccessLinkPanel: minting ────────────────────────────────────────────────\n mint: 'accessAdmin.link.mint',\n mintHint: 'accessAdmin.link.mintHint',\n /** Heading over the revealed URL. `{{p1}}` = subject display name. */\n mintedTitle: 'accessAdmin.link.mintedTitle',\n /** \"Shown once — copy it now.\" The honesty that makes the one-shot reveal safe. */\n mintedHint: 'accessAdmin.link.mintedHint',\n /** Reported when the mint landed AND the clipboard write succeeded. `{{p1}}` = name. */\n copySuccess: 'accessAdmin.link.copySuccess',\n /** Reported when the mint landed but the clipboard REFUSED. `{{p1}}` = name. */\n mintNotCopied: 'accessAdmin.link.mintNotCopied',\n /** Reported when a re-copy of an already-revealed URL failed. `{{p1}}` = name. */\n copyFailed: 'accessAdmin.link.copyFailed',\n\n // ── AccessLinkPanel: acting on a revealed URL ───────────────────────────────\n recopy: 'accessAdmin.link.recopy',\n recopyHint: 'accessAdmin.link.recopyHint',\n copied: 'accessAdmin.link.copied',\n dismiss: 'accessAdmin.link.dismiss',\n dismissHint: 'accessAdmin.link.dismissHint',\n email: 'accessAdmin.link.email',\n emailHint: 'accessAdmin.link.emailHint',\n /** \"This opens YOUR mail app — we do not send it for you.\" */\n emailNote: 'accessAdmin.link.emailNote',\n /** Mail subject. `{{p1}}` = subject display name. */\n emailSubject: 'accessAdmin.link.emailSubject',\n /** Mail body. `{{p1}}` = name, `{{p2}}` = url, `{{p3}}` = expiry date. */\n emailBody: 'accessAdmin.link.emailBody',\n\n // ── AccessLinkPanel: the live list ──────────────────────────────────────────\n /** \"Live links ({{p1}})\". `{{p1}}` = count. */\n liveHeading: 'accessAdmin.link.liveHeading',\n /** \"Created {{p1}} · stops working {{p2}}\". */\n liveMeta: 'accessAdmin.link.liveMeta',\n /** Shown in `liveMeta`'s `{{p2}}` slot when a link has no expiry at all. */\n expiresNever: 'accessAdmin.link.expiresNever',\n noLive: 'accessAdmin.link.noLive',\n /** Shown when the link list FAILED to load — never conflated with \"there are none\". */\n liveLoadError: 'accessAdmin.link.liveLoadError',\n close: 'accessAdmin.link.close',\n closeHint: 'accessAdmin.link.closeHint',\n\n // ── AccountLinkPanel ────────────────────────────────────────────────────────\n /** Panel heading. `{{p1}}` = subject display name. */\n accountPanelHeading: 'accessAdmin.account.panelHeading',\n accountPanelNote: 'accessAdmin.account.panelNote',\n accountPickerLabel: 'accessAdmin.account.pickerLabel',\n accountPickerHint: 'accessAdmin.account.pickerHint',\n accountPickerPlaceholder: 'accessAdmin.account.pickerPlaceholder',\n accountOptionHint: 'accessAdmin.account.optionHint',\n /** Label for a directory entry carrying neither a display name nor an email. */\n accountUnnamed: 'accessAdmin.account.unnamed',\n /** Shown when the directory is empty (or every entry is taken by another subject). */\n accountNone: 'accessAdmin.account.none',\n accountLink: 'accessAdmin.account.link',\n accountLinkHint: 'accessAdmin.account.linkHint',\n /** `{{p1}}` = subject display name. */\n accountLinkSuccess: 'accessAdmin.account.linkSuccess',\n accountUnlink: 'accessAdmin.account.unlink',\n accountUnlinkHint: 'accessAdmin.account.unlinkHint',\n /** `{{p1}}` = subject display name. */\n accountUnlinkSuccess: 'accessAdmin.account.unlinkSuccess',\n accountClose: 'accessAdmin.account.close',\n accountCloseHint: 'accessAdmin.account.closeHint',\n\n // ── UserManagementPanel: framing + toolbar ──────────────────────────────────\n /** Panel heading. */\n usersHeading: 'accessAdmin.users.heading',\n /** Supporting line under the heading. */\n usersNote: 'accessAdmin.users.note',\n /** Placeholder in the search box. */\n usersSearchPlaceholder: 'accessAdmin.users.searchPlaceholder',\n /** Accessible name of the search box. */\n usersSearchLabel: 'accessAdmin.users.searchLabel',\n usersSearchHint: 'accessAdmin.users.searchHint',\n /** Word shown next to the live result count in the FilterBar. */\n usersResultsLabel: 'accessAdmin.users.resultsLabel',\n usersCreate: 'accessAdmin.users.create',\n usersCreateHint: 'accessAdmin.users.createHint',\n\n // ── UserManagementPanel: table columns ──────────────────────────────────────\n usersColEmail: 'accessAdmin.users.colEmail',\n usersColDisplayName: 'accessAdmin.users.colDisplayName',\n usersColRoles: 'accessAdmin.users.colRoles',\n usersColTenant: 'accessAdmin.users.colTenant',\n usersColActive: 'accessAdmin.users.colActive',\n usersColCreated: 'accessAdmin.users.colCreated',\n usersColActions: 'accessAdmin.users.colActions',\n\n // ── UserManagementPanel: cell values ────────────────────────────────────────\n usersActiveYes: 'accessAdmin.users.activeYes',\n usersActiveNo: 'accessAdmin.users.activeNo',\n /** Tenant cell for a user bound to no tenant (a platform-level account). */\n usersTenantNone: 'accessAdmin.users.tenantNone',\n /** Roles cell for a user with no roles yet. */\n usersNoRoles: 'accessAdmin.users.noRoles',\n /** Created cell when the API did not return a timestamp. */\n usersCreatedUnknown: 'accessAdmin.users.createdUnknown',\n\n // ── UserManagementPanel: per-row actions ────────────────────────────────────\n usersEdit: 'accessAdmin.users.edit',\n usersEditHint: 'accessAdmin.users.editHint',\n usersReset: 'accessAdmin.users.reset',\n usersResetHint: 'accessAdmin.users.resetHint',\n\n // ── UserManagementPanel: load states ────────────────────────────────────────\n usersLoading: 'accessAdmin.users.loading',\n usersEmpty: 'accessAdmin.users.empty',\n /** Shown when the user list FAILED to load — never conflated with \"there are none\". */\n usersLoadError: 'accessAdmin.users.loadError',\n usersRetry: 'accessAdmin.users.retry',\n usersRetryHint: 'accessAdmin.users.retryHint',\n\n // ── UserManagementPanel: modals — titles ────────────────────────────────────\n usersCreateTitle: 'accessAdmin.users.createTitle',\n usersEditTitle: 'accessAdmin.users.editTitle',\n usersResetTitle: 'accessAdmin.users.resetTitle',\n\n // ── UserManagementPanel: modals — fields (shared across modals) ──────────────\n usersFieldEmail: 'accessAdmin.users.fieldEmail',\n usersEmailPlaceholder: 'accessAdmin.users.emailPlaceholder',\n usersFieldPassword: 'accessAdmin.users.fieldPassword',\n usersPasswordPlaceholder: 'accessAdmin.users.passwordPlaceholder',\n usersFieldDisplayName: 'accessAdmin.users.fieldDisplayName',\n usersDisplayNamePlaceholder: 'accessAdmin.users.displayNamePlaceholder',\n usersFieldRole: 'accessAdmin.users.fieldRole',\n usersRolePlaceholder: 'accessAdmin.users.rolePlaceholder',\n usersRolePickerHint: 'accessAdmin.users.rolePickerHint',\n usersFieldTenant: 'accessAdmin.users.fieldTenant',\n usersTenantPlaceholder: 'accessAdmin.users.tenantPlaceholder',\n usersTenantPickerHint: 'accessAdmin.users.tenantPickerHint',\n usersFieldActive: 'accessAdmin.users.fieldActive',\n usersActiveToggleHint: 'accessAdmin.users.activeToggleHint',\n usersFieldNewPassword: 'accessAdmin.users.fieldNewPassword',\n usersNewPasswordPlaceholder: 'accessAdmin.users.newPasswordPlaceholder',\n\n // ── UserManagementPanel: modals — actions ───────────────────────────────────\n usersSubmitCreate: 'accessAdmin.users.submitCreate',\n usersSubmitCreateHint: 'accessAdmin.users.submitCreateHint',\n usersSubmitSave: 'accessAdmin.users.submitSave',\n usersSubmitSaveHint: 'accessAdmin.users.submitSaveHint',\n usersSubmitReset: 'accessAdmin.users.submitReset',\n usersSubmitResetHint: 'accessAdmin.users.submitResetHint',\n usersCancel: 'accessAdmin.users.cancel',\n usersCancelHint: 'accessAdmin.users.cancelHint',\n\n // ── UserManagementPanel: outcome toasts ─────────────────────────────────────\n usersCreateSuccess: 'accessAdmin.users.createSuccess',\n usersCreateFailed: 'accessAdmin.users.createFailed',\n usersUpdateSuccess: 'accessAdmin.users.updateSuccess',\n usersUpdateFailed: 'accessAdmin.users.updateFailed',\n usersResetSuccess: 'accessAdmin.users.resetSuccess',\n usersResetFailed: 'accessAdmin.users.resetFailed',\n} as const;\n\n/** The shape of {@link ACCESS_ADMIN_I18N} — useful for typing an override map. */\nexport type AccessAdminI18n = typeof ACCESS_ADMIN_I18N;\n\n/**\n * Default testIDs. Every one is overridable via each panel's `testIDPrefix`, because\n * Playwright selectors in an adopting app already exist and a shared component is not\n * a good enough reason to rewrite someone's E2E suite.\n */\nexport const ACCESS_ADMIN_TEST_IDS = {\n linkPanel: 'access-link-panel',\n accountPanel: 'account-link-panel',\n usersPanel: 'user-management-panel',\n} as const;\n","/**\n * How long a freshly minted capability link should live.\n *\n * ── THE GENERALIZATION ────────────────────────────────────────────────────────\n * kefi computed this as \"the event date, plus a two-week payout-reconciliation\n * tail, clamped to what the API accepts\". Every noun there is kefi's, but the\n * SHAPE is not: a capability is nearly always anchored to some real-world moment\n * (an event, a deadline, a booking, a review window) and needs to outlive that\n * moment by however long the follow-up work takes. So the policy is expressed as\n * an anchor plus a tail, and the host names them.\n *\n * ── THE ONE RULE THAT DOES NOT BEND ───────────────────────────────────────────\n * There is NO code path here that returns \"never\". Not for a missing anchor, not\n * for an unparseable one, not for an anchor in the past. A capability link is a\n * bearer token pasted into a chat app; the expiry is the only thing that limits\n * the blast radius of it being forwarded. A fallback to \"never\" would turn the\n * least-informed case — we could not read the date — into the most dangerous\n * outcome, which is exactly backwards. A missing anchor yields the bare tail: a\n * link that still dies on a clock.\n */\n\n/** Milliseconds in one day. */\nconst MS_PER_DAY = 86_400_000;\n\n/** Number of leading ISO characters that make up `yyyy-mm-dd`. */\nconst ISO_DATE_LENGTH = 10;\n\n/**\n * The host's expiry rule.\n *\n * `minDays`/`maxDays` are REQUIRED rather than defaulted, because they encode\n * what a specific API will accept. A default here would be a guess that fails\n * server-side at mint time, which is the worst place to find out.\n */\nexport interface ExpiryPolicy {\n /**\n * ISO date/timestamp the capability is anchored to, or null/undefined when\n * there is no anchor. Unparseable values are treated as absent.\n */\n readonly anchorDate?: string | null;\n /** Whole days the link survives PAST the anchor (or from now, when unanchored). */\n readonly tailDays: number;\n /** Smallest expiry the host's API accepts. */\n readonly minDays: number;\n /** Largest expiry the host's API accepts. Anchors beyond this clamp, never unbound. */\n readonly maxDays: number;\n}\n\n/**\n * Whole days from `now` until `anchorDate`, or null when the date is unusable.\n *\n * Both sides are floored to UTC midnight before subtracting, so the answer does\n * not flip by one depending on what time of day the button happens to be pressed.\n * Negative when the anchor is in the past — the caller decides what that means.\n */\nexport function daysUntilAnchor(anchorDate: string | null | undefined, now: Date): number | null {\n if (typeof anchorDate !== 'string' || anchorDate.trim() === '') return null;\n const anchor = Date.parse(anchorDate);\n if (Number.isNaN(anchor)) return null;\n return Math.floor(anchor / MS_PER_DAY) - Math.floor(now.getTime() / MS_PER_DAY);\n}\n\n/**\n * The expiry, in whole days from now, for a link minted under this policy.\n *\n * Three cases, all of which still expire:\n * - no usable anchor → the bare tail;\n * - anchor in the past → tail minus however long ago it was, floored at `minDays`,\n * so a link minted while settling up afterwards still dies soon;\n * - anchor beyond the ceiling → clamped to `maxDays`.\n */\nexport function capabilityExpiryDays(policy: ExpiryPolicy, now: Date): number {\n const untilAnchor = daysUntilAnchor(policy.anchorDate, now);\n const raw = untilAnchor === null ? policy.tailDays : untilAnchor + policy.tailDays;\n if (raw < policy.minDays) return policy.minDays;\n if (raw > policy.maxDays) return policy.maxDays;\n return raw;\n}\n\n/** The `yyyy-mm-dd` date a link minted now under this policy would stop working on. */\nexport function capabilityExpiryDate(policy: ExpiryPolicy, now: Date): string {\n const days = capabilityExpiryDays(policy, now);\n return new Date(now.getTime() + days * MS_PER_DAY).toISOString().slice(0, ISO_DATE_LENGTH);\n}\n","/**\n * Pure rules for presenting a subject's capability links.\n *\n * Logic-only (no JSX) so the parts that are quietly easy to get wrong — which\n * links belong to whom, which are still worth revoking, and what goes into a\n * mail compose window — are unit-tested without a renderer.\n */\nimport type { CapabilityLink } from '../types';\n\n/** Number of leading ISO characters that make up `yyyy-mm-dd`. */\nconst ISO_DATE_LENGTH = 10;\n\n/**\n * A subject's links, newest first.\n *\n * Matching is on `subjectId` and nothing else. The messy part — working out\n * WHICH subject an API's link row belongs to when the wire format does not say —\n * is the host's job, done once when it normalizes its DTOs. That keeps a\n * product's data-model compromise out of the shared filter.\n */\nexport function linksForSubject(\n links: readonly CapabilityLink[],\n subjectId: string,\n): CapabilityLink[] {\n return links\n .filter((link) => link.subjectId === subjectId)\n .sort((a, b) => String(b.createdAt ?? '').localeCompare(String(a.createdAt ?? '')));\n}\n\n/** The still-usable links belonging to a subject — the ones worth revoking. */\nexport function activeLinksForSubject(\n links: readonly CapabilityLink[],\n subjectId: string,\n): CapabilityLink[] {\n return linksForSubject(links, subjectId).filter((link) => link.isActive);\n}\n\n/** An ISO timestamp as a bare `yyyy-mm-dd`, or the supplied fallback when absent. */\nexport function formatLinkDate(value: string | null | undefined, fallback: string): string {\n if (typeof value !== 'string' || value.trim() === '') return fallback;\n return value.slice(0, ISO_DATE_LENGTH);\n}\n\n/**\n * A `mailto:` compose URL carrying the link, or null when there is nothing to send.\n *\n * NO recipient address is filled in, and that is deliberate rather than an\n * omission: an `AccessSubject` has no email field (see `types.ts` for why it\n * stays that small), so the sender picks the address in their own mail client.\n * It is also why the panel calls this \"open in email\" and warns that nothing is\n * sent on the user's behalf — a compose window they abandon looks identical to\n * one they send.\n */\nexport function buildCapabilityLinkMailto(\n subject: string,\n body: string,\n url: string,\n): string | null {\n if (url.trim() === '') return null;\n return `mailto:?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;\n}\n","/**\n * Mint-and-copy state for ONE subject's capability link.\n *\n * ── WHY THE COPY RESULT IS THREADED THROUGH INSTEAD OF IGNORED ────────────────\n * The clipboard write happens AFTER the network round-trip, in the mint's\n * continuation — not synchronously inside the press. Chrome accepts that from a\n * focused document with recent user activation; WebKit is stricter about tying\n * the write to the gesture task, and these panels get used from phones. So the\n * write is treated as one that MAY be refused rather than one that is assumed to\n * land.\n *\n * That matters more here than it would anywhere else, because the URL is\n * revealed exactly ONCE. If the copy silently failed and the user dismissed the\n * panel, the link would be unrecoverable — they would have to revoke and\n * re-mint, having already told someone it was on the way. So a refused copy is\n * reported as an ERROR even though the mint itself succeeded, and the URL stays\n * on screen to be copied by hand.\n *\n * ── NO REACT-QUERY ────────────────────────────────────────────────────────────\n * The mint is an injected promise, so this hook owns its own in-flight flag. A\n * host wires its mutation (and its cache invalidation) inside the callback.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { copyText } from '@dloizides/ui-layout';\n\nimport { AccessResultTone, type AccessResultReporter } from '../AccessResultTone';\nimport { ACCESS_ADMIN_I18N } from '../constants';\nimport { capabilityExpiryDays, type ExpiryPolicy } from '../expiry/expiryPolicy';\nimport type {\n AccessSubject,\n CapabilityLink,\n DescribeError,\n MintCapabilityLink,\n} from '../types';\n\n/** Translate function — mirrors the fleet's `FM(key, p1?, p2?, p3?)` shape. */\nexport type AccessTranslate = (key: string, p1?: string, p2?: string, p3?: string) => string;\n\nexport interface UseCapabilityLinkMintOptions {\n readonly subject: AccessSubject;\n readonly policy: ExpiryPolicy;\n readonly mint: MintCapabilityLink;\n readonly describeError: DescribeError;\n readonly onResult: AccessResultReporter;\n readonly t: AccessTranslate;\n /** Injectable clock, so the expiry maths is testable. Defaults to the real one. */\n readonly now?: () => Date;\n /** Optional platform clipboard writer (React Native's `Clipboard.setString`, say). */\n readonly clipboardWriter?: (text: string) => void | Promise<void>;\n}\n\nexport interface CapabilityLinkMintState {\n /** The just-minted link, revealed once, or null before any mint. */\n readonly minted: CapabilityLink | null;\n /** True while a mint is in flight. */\n readonly isPending: boolean;\n /** True when the last mint's URL actually reached the clipboard. */\n readonly copied: boolean;\n /** Mint a fresh link for this subject and copy it. */\n readonly mint: () => void;\n /** Re-copy the revealed URL, after a refused write. */\n readonly recopy: () => void;\n /** Forget the revealed URL — it cannot be read again afterwards. */\n readonly dismiss: () => void;\n}\n\nexport function useCapabilityLinkMint(\n options: UseCapabilityLinkMintOptions,\n): CapabilityLinkMintState {\n const { subject, policy, mint, describeError, onResult, t, now, clipboardWriter } = options;\n\n const [minted, setMinted] = useState<CapabilityLink | null>(null);\n const [copied, setCopied] = useState<boolean>(false);\n const [isPending, setIsPending] = useState<boolean>(false);\n\n // The mint is async and these panels close (a row collapses, a drawer dismisses)\n // while it is in flight, so every post-await setState is guarded.\n const mountedRef = useRef<boolean>(true);\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n const copyUrl = useCallback(\n async (url: string): Promise<boolean> => {\n const ok = await copyText(url, clipboardWriter);\n if (mountedRef.current) setCopied(ok);\n return ok;\n },\n [clipboardWriter],\n );\n\n const runMint = useCallback((): void => {\n if (isPending) return;\n setIsPending(true);\n\n void (async () => {\n try {\n const expiresInDays = capabilityExpiryDays(policy, now === undefined ? new Date() : now());\n const link = await mint({ subject, expiresInDays });\n if (!mountedRef.current) return;\n\n setMinted(link);\n const ok = await copyUrl(link.url ?? '');\n if (!mountedRef.current) return;\n\n onResult(\n t(\n ok ? ACCESS_ADMIN_I18N.copySuccess : ACCESS_ADMIN_I18N.mintNotCopied,\n subject.displayName,\n ),\n ok ? AccessResultTone.Success : AccessResultTone.Error,\n );\n } catch (error) {\n if (!mountedRef.current) return;\n onResult(describeError(error as Error), AccessResultTone.Error);\n } finally {\n if (mountedRef.current) setIsPending(false);\n }\n })();\n }, [isPending, policy, now, mint, subject, copyUrl, onResult, t, describeError]);\n\n const recopy = useCallback((): void => {\n const url = minted?.url ?? '';\n if (url === '') return;\n\n void (async () => {\n const ok = await copyUrl(url);\n if (!mountedRef.current) return;\n onResult(\n t(ok ? ACCESS_ADMIN_I18N.copySuccess : ACCESS_ADMIN_I18N.copyFailed, subject.displayName),\n ok ? AccessResultTone.Success : AccessResultTone.Error,\n );\n })();\n }, [minted, copyUrl, onResult, t, subject.displayName]);\n\n const dismiss = useCallback((): void => {\n setMinted(null);\n setCopied(false);\n }, []);\n\n return { minted, isPending, copied, mint: runMint, recopy, dismiss };\n}\n","/**\n * The handful of colour roles these panels need, resolved from the host's\n * `UiProvider` theme.\n *\n * ── WHY A MAPPING LAYER AT ALL ────────────────────────────────────────────────\n * The kefi original read a `KefiColors` object with slots named for kefi's brand\n * (`brandDeep`, `positiveBg`, `surfaceMuted`). Carrying those names into a shared\n * package would have made every other portal invent a kefi palette to use it. So\n * the panels ask for ROLES — \"the surface a panel sits on\", \"the colour of a\n * security warning\" — and this module answers them from the theme every portal\n * already broadcasts.\n *\n * Not a single literal colour is defined here. Every value traces back to the\n * host's `@dloizides/design-tokens` theme, so a rebrand reaches these panels for\n * free and the `no-raw-color-literal` gate has nothing to catch.\n */\nimport { useMemo } from 'react';\n\nimport { useUi } from '@dloizides/ui-feedback';\n\nexport interface AccessAdminPalette {\n /** Background of the panel itself — a recessed surface inside a section. */\n readonly panelSurface: string;\n /** Hairline borders. */\n readonly border: string;\n readonly textPrimary: string;\n readonly textSecondary: string;\n /** The security warning, and the destructive action. */\n readonly danger: string;\n /** Fill and edge of the \"here is your new link\" box. */\n readonly revealSurface: string;\n readonly revealBorder: string;\n /** Heading inside the reveal box — the strongest brand tone available. */\n readonly revealHeading: string;\n}\n\nexport function useAccessAdminPalette(): AccessAdminPalette {\n const { theme } = useUi();\n const { colors, palette, semantic } = theme;\n\n return useMemo<AccessAdminPalette>(() => {\n const success = semantic.success ?? semantic.error;\n return {\n panelSurface: colors.surface,\n border: colors.border,\n textPrimary: colors.text,\n textSecondary: colors.textSecondary,\n danger: semantic.error['500'],\n // A tinted step when the host's scale has one, else the elevated surface —\n // never a hardcoded pastel, which would be wrong in dark mode.\n revealSurface: success['50'] ?? success['100'] ?? colors.surfaceElevated,\n revealBorder: success['500'],\n revealHeading: palette.primary['700'] ?? palette.primary['500'],\n };\n }, [colors, palette, semantic]);\n}\n","/**\n * The capability-link panel for ONE subject.\n *\n * ── SCOPED TO ONE SUBJECT ON PURPOSE ──────────────────────────────────────────\n * These links are CAPABILITIES: whoever holds the URL has the access, with no\n * sign-in in the way. A screen listing every subject's live link would itself be\n * a high-value secret. So this panel shows one subject's links, and only while\n * the user is looking at that subject.\n *\n * The primary action mints AND copies in a single press, because the real\n * workflow is pasting the link into a chat app. Email is a secondary COMPOSE\n * action (see `buildCapabilityLinkMailto`). Revoking any of this subject's live\n * links is reachable here, so a leaked link can be killed without disturbing\n * anyone else's.\n *\n * ── WHAT THE HOST OWNS ────────────────────────────────────────────────────────\n * The mint call, the error wording, and the per-link revoke control (via\n * `renderLinkActions`) — revocation usually needs a confirm step wired to the\n * host's own dialog and mutation, so the package renders the row and lets the\n * host fill the action slot rather than shipping half a revoke flow.\n */\nimport React, { useMemo } from 'react';\n\nimport { Linking, StyleSheet, Text, View } from 'react-native';\n\nimport { Button } from '@dloizides/ui-buttons';\nimport { useUi } from '@dloizides/ui-feedback';\n\nimport { AccessResultTone, type AccessResultReporter } from '../AccessResultTone';\nimport { ACCESS_ADMIN_I18N, ACCESS_ADMIN_TEST_IDS } from '../constants';\nimport { capabilityExpiryDate, type ExpiryPolicy } from '../expiry/expiryPolicy';\nimport {\n activeLinksForSubject,\n buildCapabilityLinkMailto,\n formatLinkDate,\n} from '../links/capabilityLinkHelpers';\nimport { useCapabilityLinkMint } from '../links/useCapabilityLinkMint';\nimport { useAccessAdminPalette, type AccessAdminPalette } from '../theme/useAccessAdminPalette';\nimport type {\n AccessSubject,\n CapabilityLink,\n DescribeError,\n MintCapabilityLink,\n} from '../types';\n\n/** Spacing scale — kept local so the package needs no spacing dependency. */\nconst SPACE_XS = 4;\nconst SPACE_SM = 8;\nconst SPACE_MD = 12;\nconst SPACE_LG = 16;\n\nconst FONT_SM = 12;\nconst FONT_MD = 13;\n\nexport interface AccessLinkPanelProps {\n /** The subject whose links are being managed. */\n readonly subject: AccessSubject;\n /** How long a link minted now should live. */\n readonly policy: ExpiryPolicy;\n /**\n * Every capability link the host knows about, normalized. Filtered to this\n * subject here — the host does not need to pre-filter.\n */\n readonly links: readonly CapabilityLink[];\n /**\n * True when the link list FAILED to load.\n *\n * Distinguished from \"loaded, and there are none\" deliberately: an empty list\n * caused by a failed fetch reads as \"this subject has no live link\", which\n * invites minting a SECOND live capability for someone who already has one —\n * and leaves the user believing there is nothing to revoke.\n */\n readonly linksFailed?: boolean;\n readonly mint: MintCapabilityLink;\n readonly describeError: DescribeError;\n readonly onClose: () => void;\n readonly onResult: AccessResultReporter;\n /** Renders the host's revoke control for one live link. */\n readonly renderLinkActions?: (link: CapabilityLink) => React.ReactNode;\n /** Injectable clock, for tests. */\n readonly now?: () => Date;\n /** Optional platform clipboard writer. */\n readonly clipboardWriter?: (text: string) => void | Promise<void>;\n /** Root testID; children derive from it. Defaults to `access-link-panel`. */\n readonly testIDPrefix?: string;\n}\n\nexport const AccessLinkPanel = ({\n subject,\n policy,\n links,\n linksFailed = false,\n mint,\n describeError,\n onClose,\n onResult,\n renderLinkActions,\n now,\n clipboardWriter,\n testIDPrefix = ACCESS_ADMIN_TEST_IDS.linkPanel,\n}: AccessLinkPanelProps): React.ReactElement => {\n const { t } = useUi();\n const palette = useAccessAdminPalette();\n const styles = useMemo(() => buildStyles(palette), [palette]);\n\n const state = useCapabilityLinkMint({\n subject,\n policy,\n mint,\n describeError,\n onResult,\n t,\n now,\n clipboardWriter,\n });\n\n const expiryDate = useMemo(\n () => capabilityExpiryDate(policy, now === undefined ? new Date() : now()),\n [policy, now],\n );\n const liveLinks = useMemo(() => activeLinksForSubject(links, subject.id), [links, subject.id]);\n const mintedUrl = state.minted?.url ?? '';\n\n const handleEmail = (): void => {\n const mailto = buildCapabilityLinkMailto(\n t(ACCESS_ADMIN_I18N.emailSubject, subject.displayName),\n t(ACCESS_ADMIN_I18N.emailBody, subject.displayName, mintedUrl, expiryDate),\n mintedUrl,\n );\n if (mailto === null) return;\n // Single-arg `openURL` is the RN API contract and behaves on native as well as\n // web. react-native-web routes everything but `tel:` through\n // `window.open(url, '_blank')`, so on web this hands off to the mail client in a\n // new tab; some browsers leave an about:blank tab behind. Cosmetic.\n void Linking.openURL(mailto).catch(() => {\n onResult(t(ACCESS_ADMIN_I18N.copyFailed, subject.displayName), AccessResultTone.Error);\n });\n };\n\n return (\n <View style={styles.panel} testID={testIDPrefix}>\n <Text style={styles.heading}>{t(ACCESS_ADMIN_I18N.panelHeading, subject.displayName)}</Text>\n <Text style={styles.note}>{t(ACCESS_ADMIN_I18N.panelNote)}</Text>\n {/* Shown ALWAYS, not only after a mint: the decision to create a bearer token\n is made before the press, so the warning has to be readable before it. */}\n <Text style={styles.warning} testID={`${testIDPrefix}-capability-warning`}>\n {t(ACCESS_ADMIN_I18N.capabilityWarning)}\n </Text>\n <Text style={styles.note} testID={`${testIDPrefix}-expiry-preview`}>\n {t(ACCESS_ADMIN_I18N.expiryPreview, expiryDate)}\n </Text>\n\n {state.minted !== null ? (\n <View style={styles.revealBox} testID={`${testIDPrefix}-minted`}>\n <Text style={styles.revealTitle}>\n {t(ACCESS_ADMIN_I18N.mintedTitle, subject.displayName)}\n </Text>\n <Text style={styles.note}>{t(ACCESS_ADMIN_I18N.mintedHint)}</Text>\n <Text selectable style={styles.url} testID={`${testIDPrefix}-minted-url`}>\n {mintedUrl}\n </Text>\n <View style={styles.actions}>\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.recopyHint)}\n accessibilityLabel={state.copied ? t(ACCESS_ADMIN_I18N.copied) : t(ACCESS_ADMIN_I18N.recopy)}\n label={state.copied ? t(ACCESS_ADMIN_I18N.copied) : t(ACCESS_ADMIN_I18N.recopy)}\n onPress={state.recopy}\n testID={`${testIDPrefix}-recopy`}\n />\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.emailHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.email)}\n label={t(ACCESS_ADMIN_I18N.email)}\n onPress={handleEmail}\n testID={`${testIDPrefix}-email`}\n variant=\"secondary\"\n />\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.dismissHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.dismiss)}\n label={t(ACCESS_ADMIN_I18N.dismiss)}\n onPress={state.dismiss}\n testID={`${testIDPrefix}-dismiss`}\n variant=\"secondary\"\n />\n </View>\n <Text style={styles.note}>{t(ACCESS_ADMIN_I18N.emailNote)}</Text>\n </View>\n ) : null}\n\n {linksFailed ? (\n <Text style={styles.warning} testID={`${testIDPrefix}-load-error`}>\n {t(ACCESS_ADMIN_I18N.liveLoadError)}\n </Text>\n ) : null}\n\n {!linksFailed && liveLinks.length > 0 ? (\n <View style={styles.liveBox}>\n <Text style={styles.subheading}>\n {t(ACCESS_ADMIN_I18N.liveHeading, String(liveLinks.length))}\n </Text>\n {liveLinks.map((link) => (\n <View key={link.id} style={styles.liveRow}>\n <Text style={styles.liveMeta}>\n {t(\n ACCESS_ADMIN_I18N.liveMeta,\n formatLinkDate(link.createdAt, ''),\n formatLinkDate(link.expiresAt, t(ACCESS_ADMIN_I18N.expiresNever)),\n )}\n </Text>\n {renderLinkActions === undefined ? null : renderLinkActions(link)}\n </View>\n ))}\n </View>\n ) : null}\n\n {!linksFailed && liveLinks.length === 0 ? (\n <Text style={styles.note} testID={`${testIDPrefix}-no-live`}>\n {t(ACCESS_ADMIN_I18N.noLive)}\n </Text>\n ) : null}\n\n <View style={styles.actions}>\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.mintHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.mint)}\n disabled={state.isPending}\n label={t(ACCESS_ADMIN_I18N.mint)}\n loading={state.isPending}\n onPress={state.mint}\n testID={`${testIDPrefix}-mint`}\n />\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.closeHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.close)}\n disabled={state.isPending}\n label={t(ACCESS_ADMIN_I18N.close)}\n onPress={onClose}\n testID={`${testIDPrefix}-close`}\n variant=\"secondary\"\n />\n </View>\n </View>\n );\n};\n\n/** Builds the panel styles from the live palette (re-run when the theme changes). */\nconst buildStyles = (c: AccessAdminPalette) =>\n StyleSheet.create({\n actions: { flexDirection: 'row', flexWrap: 'wrap', gap: SPACE_SM },\n heading: { color: c.textPrimary, fontSize: FONT_MD, fontWeight: '700' },\n liveBox: { gap: SPACE_SM, marginTop: SPACE_XS },\n liveMeta: { color: c.textSecondary, fontSize: FONT_SM },\n liveRow: {\n borderTopColor: c.border,\n borderTopWidth: 1,\n gap: SPACE_XS,\n paddingTop: SPACE_SM,\n },\n note: { color: c.textSecondary, fontSize: FONT_SM },\n panel: {\n backgroundColor: c.panelSurface,\n borderColor: c.border,\n borderRadius: SPACE_SM,\n borderWidth: 1,\n gap: SPACE_XS,\n marginBottom: SPACE_LG,\n padding: SPACE_MD,\n },\n revealBox: {\n backgroundColor: c.revealSurface,\n borderColor: c.revealBorder,\n borderRadius: SPACE_SM,\n borderWidth: 1,\n gap: SPACE_XS,\n marginVertical: SPACE_SM,\n padding: SPACE_MD,\n },\n revealTitle: { color: c.revealHeading, fontSize: FONT_MD, fontWeight: '800' },\n subheading: { color: c.textPrimary, fontSize: FONT_SM, fontWeight: '700' },\n url: { color: c.textPrimary, fontSize: FONT_MD, fontWeight: '600' },\n warning: { color: c.danger, fontSize: FONT_SM, fontWeight: '600' },\n });\n","/**\n * Pure rules for the account picker.\n *\n * Logic-only so the two decisions that actually matter — what an account is\n * CALLED when the directory gives you almost nothing, and which accounts must\n * not be offered at all — are tested without a renderer.\n */\nimport type { ControlOption } from '@dloizides/ui-forms';\n\nimport type { AccessSubject, LinkableAccount } from '../types';\n\n/** True when a value is a non-blank string. */\nfunction isFilled(value: string | null | undefined): value is string {\n return typeof value === 'string' && value.trim() !== '';\n}\n\n/**\n * What to call an account: its display name, else its email, else the caller's\n * already-localized fallback.\n *\n * Directories genuinely return entries with neither — a freshly invited user who\n * has not completed a profile is the common one. Rendering those as a blank row\n * gives an unpickable option that looks like a rendering fault.\n */\nexport function accountDisplayLabel(account: LinkableAccount, unnamedLabel: string): string {\n if (isFilled(account.displayName)) return account.displayName.trim();\n if (isFilled(account.email)) return account.email.trim();\n return unnamedLabel;\n}\n\n/**\n * Build the picker's options for one subject.\n *\n * Accounts already bound to a DIFFERENT subject are dropped. That is not tidying:\n * every host that has built this backs it with a uniqueness constraint and\n * answers a duplicate binding with a 409, so offering such an account can only\n * ever produce an error the user cannot act on.\n *\n * The subject's OWN currently-bound account is KEPT, so the picker can show it as\n * the current selection instead of looking empty on a subject that is in fact\n * linked — which would read as \"not linked\" and invite a pointless re-link.\n *\n * Directory order is preserved; hosts return these sorted.\n */\nexport function buildAccountOptions(\n accounts: readonly LinkableAccount[],\n bindings: ReadonlyMap<string, string | null>,\n subject: AccessSubject,\n unnamedLabel: string,\n): ControlOption[] {\n const takenByOthers = new Set<string>();\n bindings.forEach((accountId, subjectId) => {\n if (subjectId !== subject.id && isFilled(accountId)) takenByOthers.add(accountId);\n });\n\n return accounts\n .filter((account) => !takenByOthers.has(account.userId))\n .map((account) => ({\n value: account.userId,\n label: accountDisplayLabel(account, unnamedLabel),\n }));\n}\n","/**\n * Selection state and submit orchestration for the account picker.\n *\n * Holds no JSX so the selection transitions — and, more importantly, the rules\n * about WHEN a link or unlink is allowed — are testable without a renderer.\n * Those rules are the guard rails around a destructive action: unlinking is what\n * stops a real person's work being attributed to them.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { AccessResultTone, type AccessResultReporter } from '../AccessResultTone';\nimport { ACCESS_ADMIN_I18N } from '../constants';\nimport type { AccessTranslate } from '../links/useCapabilityLinkMint';\nimport type { AccessSubject, DescribeError, LinkSubjectAccount } from '../types';\n\nexport interface UseSubjectAccountLinkOptions {\n readonly subject: AccessSubject;\n /** The account currently bound to this subject, or null when it has none. */\n readonly boundAccountId: string | null;\n readonly linkAccount: LinkSubjectAccount;\n readonly describeError: DescribeError;\n readonly onResult: AccessResultReporter;\n readonly t: AccessTranslate;\n}\n\nexport interface SubjectAccountLinkState {\n /** The account chosen in the picker, or null when none is. */\n readonly selectedAccountId: string | null;\n readonly select: (accountId: string) => void;\n readonly isPending: boolean;\n /** True when the chosen account differs from the one already bound. */\n readonly canLink: boolean;\n /** True when there is a binding to remove. */\n readonly canUnlink: boolean;\n readonly link: () => void;\n readonly unlink: () => void;\n}\n\nexport function useSubjectAccountLink(\n options: UseSubjectAccountLinkOptions,\n): SubjectAccountLinkState {\n const { subject, boundAccountId, linkAccount, describeError, onResult, t } = options;\n\n const [selectedAccountId, setSelectedAccountId] = useState<string | null>(boundAccountId);\n const [isPending, setIsPending] = useState<boolean>(false);\n\n const mountedRef = useRef<boolean>(true);\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n // Re-seed when the user switches to another subject, and after a write lands (the\n // host re-renders with a refreshed binding). Without this the picker would keep\n // showing the PREVIOUS subject's selection against the new subject's name.\n useEffect(() => {\n setSelectedAccountId(boundAccountId);\n }, [subject.id, boundAccountId]);\n\n const canLink = !isPending && selectedAccountId !== null && selectedAccountId !== boundAccountId;\n const canUnlink = !isPending && boundAccountId !== null;\n\n const submit = useCallback(\n (accountId: string | null, successKey: string): void => {\n setIsPending(true);\n void (async () => {\n try {\n await linkAccount(subject, accountId);\n if (!mountedRef.current) return;\n onResult(t(successKey, subject.displayName), AccessResultTone.Success);\n } catch (error) {\n if (!mountedRef.current) return;\n onResult(describeError(error as Error), AccessResultTone.Error);\n } finally {\n if (mountedRef.current) setIsPending(false);\n }\n })();\n },\n [linkAccount, subject, onResult, t, describeError],\n );\n\n const link = useCallback((): void => {\n if (!canLink || selectedAccountId === null) return;\n submit(selectedAccountId, ACCESS_ADMIN_I18N.accountLinkSuccess);\n }, [canLink, selectedAccountId, submit]);\n\n const unlink = useCallback((): void => {\n if (!canUnlink) return;\n submit(null, ACCESS_ADMIN_I18N.accountUnlinkSuccess);\n }, [canUnlink, submit]);\n\n return { selectedAccountId, select: setSelectedAccountId, isPending, canLink, canUnlink, link, unlink };\n}\n","/**\n * The account picker for ONE subject.\n *\n * Binds a subject to the account it signs in with, or removes that binding.\n * Unlinking sits behind its own press rather than being a value in the picker,\n * because a mis-tap in a list must not be able to detach someone from their work.\n *\n * The picker is the shared `SelectControl` from `@dloizides/ui-forms` rather than\n * a local one — the fleet already grew six independent select implementations\n * before that was promoted, and this is not going to be the seventh.\n */\nimport React, { useMemo } from 'react';\n\nimport { StyleSheet, Text, View } from 'react-native';\n\nimport { Button } from '@dloizides/ui-buttons';\nimport { useUi } from '@dloizides/ui-feedback';\nimport { SelectControl } from '@dloizides/ui-forms';\n\nimport type { AccessResultReporter } from '../AccessResultTone';\nimport { buildAccountOptions } from '../accounts/accountOptions';\nimport { useSubjectAccountLink } from '../accounts/useSubjectAccountLink';\nimport { ACCESS_ADMIN_I18N, ACCESS_ADMIN_TEST_IDS } from '../constants';\nimport { useAccessAdminPalette, type AccessAdminPalette } from '../theme/useAccessAdminPalette';\nimport type { AccessSubject, DescribeError, LinkableAccount, LinkSubjectAccount } from '../types';\n\nconst SPACE_XS = 4;\nconst SPACE_SM = 8;\nconst SPACE_MD = 12;\nconst SPACE_LG = 16;\nconst FONT_SM = 12;\nconst FONT_MD = 13;\n\nexport interface AccountLinkPanelProps {\n readonly subject: AccessSubject;\n /** The account currently bound to this subject, or null. */\n readonly boundAccountId: string | null;\n /** The directory of accounts that could be bound. */\n readonly accounts: readonly LinkableAccount[];\n /**\n * Which account each subject currently holds, keyed by subject id.\n *\n * The whole map, not just this subject's: accounts already taken by ANOTHER\n * subject are hidden from the picker, because offering them can only produce a\n * uniqueness error the user cannot act on.\n */\n readonly bindings: ReadonlyMap<string, string | null>;\n readonly linkAccount: LinkSubjectAccount;\n readonly describeError: DescribeError;\n readonly onClose: () => void;\n readonly onResult: AccessResultReporter;\n /** Root testID; children derive from it. Defaults to `account-link-panel`. */\n readonly testIDPrefix?: string;\n}\n\nexport const AccountLinkPanel = ({\n subject,\n boundAccountId,\n accounts,\n bindings,\n linkAccount,\n describeError,\n onClose,\n onResult,\n testIDPrefix = ACCESS_ADMIN_TEST_IDS.accountPanel,\n}: AccountLinkPanelProps): React.ReactElement => {\n const { t } = useUi();\n const palette = useAccessAdminPalette();\n const styles = useMemo(() => buildStyles(palette), [palette]);\n\n const state = useSubjectAccountLink({\n subject,\n boundAccountId,\n linkAccount,\n describeError,\n onResult,\n t,\n });\n\n const unnamedLabel = t(ACCESS_ADMIN_I18N.accountUnnamed);\n const options = useMemo(\n () => buildAccountOptions(accounts, bindings, subject, unnamedLabel),\n [accounts, bindings, subject, unnamedLabel],\n );\n\n const selectedLabel =\n options.find((option) => option.value === state.selectedAccountId)?.label ?? '';\n\n return (\n <View style={styles.panel} testID={testIDPrefix}>\n <Text style={styles.heading}>\n {t(ACCESS_ADMIN_I18N.accountPanelHeading, subject.displayName)}\n </Text>\n <Text style={styles.note}>{t(ACCESS_ADMIN_I18N.accountPanelNote)}</Text>\n\n {options.length > 0 ? (\n <SelectControl\n // The accessible name carries the SELECTION, not just the field name —\n // \"Sign-in account: Maria K\" — because the trigger's visible text is\n // replaced by this string for a screen reader.\n accessibilityHint={t(ACCESS_ADMIN_I18N.accountPickerHint)}\n accessibilityLabel={`${t(ACCESS_ADMIN_I18N.accountPickerLabel)}: ${\n selectedLabel === '' ? t(ACCESS_ADMIN_I18N.accountPickerPlaceholder) : selectedLabel\n }`}\n onChange={state.select}\n optionHint={t(ACCESS_ADMIN_I18N.accountOptionHint)}\n options={options}\n placeholder={t(ACCESS_ADMIN_I18N.accountPickerPlaceholder)}\n testID={`${testIDPrefix}-picker`}\n value={state.selectedAccountId ?? ''}\n />\n ) : (\n <Text style={styles.note} testID={`${testIDPrefix}-no-accounts`}>\n {t(ACCESS_ADMIN_I18N.accountNone)}\n </Text>\n )}\n\n <View style={styles.actions}>\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.accountLinkHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.accountLink)}\n disabled={!state.canLink}\n label={t(ACCESS_ADMIN_I18N.accountLink)}\n loading={state.isPending}\n onPress={state.link}\n testID={`${testIDPrefix}-link`}\n />\n {state.canUnlink ? (\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.accountUnlinkHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.accountUnlink)}\n disabled={state.isPending}\n label={t(ACCESS_ADMIN_I18N.accountUnlink)}\n onPress={state.unlink}\n testID={`${testIDPrefix}-unlink`}\n variant=\"danger\"\n />\n ) : null}\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.accountCloseHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.accountClose)}\n disabled={state.isPending}\n label={t(ACCESS_ADMIN_I18N.accountClose)}\n onPress={onClose}\n testID={`${testIDPrefix}-close`}\n variant=\"secondary\"\n />\n </View>\n </View>\n );\n};\n\n/** Builds the panel styles from the live palette (re-run when the theme changes). */\nconst buildStyles = (c: AccessAdminPalette) =>\n StyleSheet.create({\n actions: { flexDirection: 'row', flexWrap: 'wrap', gap: SPACE_SM },\n heading: { color: c.textPrimary, fontSize: FONT_MD, fontWeight: '700' },\n note: { color: c.textSecondary, fontSize: FONT_SM },\n panel: {\n backgroundColor: c.panelSurface,\n borderColor: c.border,\n borderRadius: SPACE_SM,\n borderWidth: 1,\n gap: SPACE_XS,\n marginBottom: SPACE_LG,\n padding: SPACE_MD,\n },\n });\n","/**\n * Pure presentation + selection helpers for {@link UserManagementPanel}.\n *\n * Kept out of the component so the \"what does an empty tenant read as\", \"which\n * users match this search\" decisions are unit-testable without a DOM, the way the\n * package already isolates `capabilityLinkHelpers` and `accountOptions`.\n */\nimport { ACCESS_ADMIN_I18N } from '../constants';\nimport type {\n UserManagementTenant,\n UserManagementTranslate,\n UserManagementUser,\n} from './userManagementTypes';\n\nconst ROLE_SEPARATOR = ', ';\n/** Sentinel value the tenant picker uses for \"no tenant / platform-level\". */\nexport const NO_TENANT_VALUE = '';\n\n/** Roles joined for the cell, or the host's \"no roles\" string when empty. */\nexport function rolesLabel(roles: readonly string[], t: UserManagementTranslate): string {\n return roles.length > 0 ? roles.join(ROLE_SEPARATOR) : t(ACCESS_ADMIN_I18N.usersNoRoles);\n}\n\n/**\n * The tenant cell: the tenant's own label when it can be resolved, the host's\n * \"no tenant\" string when the user is platform-level, and the raw id as a last\n * resort so an unknown tenant is never rendered as blank.\n */\nexport function tenantLabel(\n tenantId: string | null,\n tenants: readonly UserManagementTenant[],\n t: UserManagementTranslate,\n): string {\n if (tenantId === null) return t(ACCESS_ADMIN_I18N.usersTenantNone);\n const match = tenants.find((tenant) => tenant.id === tenantId);\n return match !== undefined ? match.label : tenantId;\n}\n\n/** Active flag as a word. */\nexport function activeLabel(active: boolean, t: UserManagementTranslate): string {\n return active ? t(ACCESS_ADMIN_I18N.usersActiveYes) : t(ACCESS_ADMIN_I18N.usersActiveNo);\n}\n\n/** Created timestamp as `YYYY-MM-DD`, or the host's \"unknown\" string. */\nexport function createdLabel(createdAt: string | undefined, t: UserManagementTranslate): string {\n if (createdAt === undefined || createdAt === '') return t(ACCESS_ADMIN_I18N.usersCreatedUnknown);\n const parsed = new Date(createdAt);\n if (Number.isNaN(parsed.getTime())) return t(ACCESS_ADMIN_I18N.usersCreatedUnknown);\n return parsed.toISOString().slice(0, 'YYYY-MM-DD'.length);\n}\n\n/**\n * Filter users by a free-text query across email, display name and roles.\n *\n * Case-insensitive; an empty/whitespace query returns every user. Matching in the\n * package (not just the host's endpoint) keeps the search responsive on an\n * already-loaded page without a round trip.\n */\nexport function filterUsers(\n users: readonly UserManagementUser[],\n query: string,\n): readonly UserManagementUser[] {\n const needle = query.trim().toLowerCase();\n if (needle === '') return users;\n return users.filter((user) => {\n const haystack = `${user.email} ${user.displayName} ${user.roles.join(' ')}`.toLowerCase();\n return haystack.includes(needle);\n });\n}\n\n/**\n * Tenant picker options for a platform admin: a leading \"no tenant\" option (value\n * {@link NO_TENANT_VALUE}) followed by every tenant. The empty-string sentinel maps\n * back to a `null` tenantId at submit time.\n */\nexport function tenantOptions(\n tenants: readonly UserManagementTenant[],\n t: UserManagementTranslate,\n): ReadonlyArray<{ label: string; value: string }> {\n const platform = { label: t(ACCESS_ADMIN_I18N.usersTenantNone), value: NO_TENANT_VALUE };\n return [platform, ...tenants.map((tenant) => ({ label: tenant.label, value: tenant.id }))];\n}\n\n/** Role picker options — only the caller-allowed roles, never anything else. */\nexport function roleOptions(\n assignableRoles: readonly string[],\n): ReadonlyArray<{ label: string; value: string }> {\n return assignableRoles.map((role) => ({ label: role, value: role }));\n}\n\n/** Turn a picker's string tenant value back into the API's `string | null`. */\nexport function tenantValueToId(value: string): string | null {\n return value === NO_TENANT_VALUE ? null : value;\n}\n","/**\n * The user table's columns, including the per-row Edit / Reset-password actions.\n *\n * A builder (not a constant) because the cells close over the host's `t`, the\n * tenant labels, and the row callbacks. Kept beside the panel so the component body\n * stays about wiring, not cell rendering.\n */\nimport { View } from 'react-native';\n\nimport { Button } from '@dloizides/ui-buttons';\nimport type { DataTableColumn } from '@dloizides/ui-tables';\n\nimport { ACCESS_ADMIN_I18N } from '../constants';\nimport { activeLabel, createdLabel, rolesLabel, tenantLabel } from './userManagementFormat';\nimport type {\n UserManagementTenant,\n UserManagementTranslate,\n UserManagementUser,\n} from './userManagementTypes';\n\nconst ACTIONS_GAP = 8;\n\nexport interface UserColumnDeps {\n readonly t: UserManagementTranslate;\n readonly tenants: readonly UserManagementTenant[];\n readonly testIDPrefix: string;\n readonly onEdit: (user: UserManagementUser) => void;\n readonly onReset: (user: UserManagementUser) => void;\n}\n\nexport function buildUserColumns({\n t,\n tenants,\n testIDPrefix,\n onEdit,\n onReset,\n}: UserColumnDeps): ReadonlyArray<DataTableColumn<UserManagementUser>> {\n return [\n {\n key: 'email',\n header: t(ACCESS_ADMIN_I18N.usersColEmail),\n render: (user) => user.email,\n },\n {\n key: 'displayName',\n header: t(ACCESS_ADMIN_I18N.usersColDisplayName),\n render: (user) => user.displayName,\n },\n {\n key: 'roles',\n header: t(ACCESS_ADMIN_I18N.usersColRoles),\n render: (user) => rolesLabel(user.roles, t),\n },\n {\n key: 'tenant',\n header: t(ACCESS_ADMIN_I18N.usersColTenant),\n render: (user) => tenantLabel(user.tenantId, tenants, t),\n },\n {\n key: 'active',\n header: t(ACCESS_ADMIN_I18N.usersColActive),\n render: (user) => activeLabel(user.active, t),\n },\n {\n key: 'created',\n header: t(ACCESS_ADMIN_I18N.usersColCreated),\n render: (user) => createdLabel(user.createdAt, t),\n },\n {\n key: 'actions',\n header: t(ACCESS_ADMIN_I18N.usersColActions),\n render: (user) => (\n <View style={{ flexDirection: 'row', flexWrap: 'wrap', gap: ACTIONS_GAP }}>\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.usersEditHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.usersEdit)}\n label={t(ACCESS_ADMIN_I18N.usersEdit)}\n onPress={() => onEdit(user)}\n size=\"sm\"\n testID={`${testIDPrefix}-edit-${user.id}`}\n variant=\"secondary\"\n />\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.usersResetHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.usersReset)}\n label={t(ACCESS_ADMIN_I18N.usersReset)}\n onPress={() => onReset(user)}\n size=\"sm\"\n testID={`${testIDPrefix}-reset-${user.id}`}\n variant=\"secondary\"\n />\n </View>\n ),\n },\n ];\n}\n","/**\n * A labelled dropdown field — the role picker and the tenant picker are the same\n * shape, so they share this rather than each re-wiring `Field` + `ModalDropdown`.\n *\n * The dropdown is `@dloizides/ui-layout`'s `ModalDropdown`, forced to the `Modal`\n * variant. This picker ALWAYS lives inside a `ModalShell` (the create / edit user\n * modals), and the responsive default would pick the INLINE menu on desktop web —\n * which `createPortal`s to `document.body`, OUTSIDE the ModalShell's RN-`Modal`\n * layer. Inside a focus-trapping modal that popover renders behind the shell and is\n * dismissed the instant it opens, so the trigger appears to \"do nothing\" (its\n * `aria-expanded` flips straight back to false). The `Modal` variant instead renders\n * the options in their OWN RN-`Modal` layer, which stacks ABOVE the ModalShell and\n * is fully visible + tappable. Its accessible name carries the SELECTION, not just\n * the field name (\"Role: editor\"), because the trigger's visible text is replaced by\n * that string for a screen reader.\n */\nimport React from 'react';\n\nimport { DropdownVariant, ModalDropdown } from '@dloizides/ui-layout';\nimport { Field } from '@dloizides/ui-forms';\n\nexport interface PickerOption {\n readonly label: string;\n readonly value: string;\n}\n\nexport interface PickerFieldProps {\n readonly testID: string;\n /** Visible + accessible field label (e.g. \"Role\"). */\n readonly label: string;\n readonly hint: string;\n /** Shown in the accessible name while nothing is selected. */\n readonly placeholder: string;\n readonly value: string;\n readonly options: readonly PickerOption[];\n readonly onChange: (value: string) => void;\n}\n\nexport const PickerField = ({\n testID,\n label,\n hint,\n placeholder,\n value,\n options,\n onChange,\n}: PickerFieldProps): React.ReactElement => {\n const selected = options.find((option) => option.value === value);\n const selectionLabel = selected !== undefined ? selected.label : placeholder;\n\n return (\n <Field label={label}>\n <ModalDropdown\n accessibilityHint={hint}\n accessibilityLabel={`${label}: ${selectionLabel}`}\n onChange={onChange}\n options={options}\n testID={testID}\n value={value}\n variant={DropdownVariant.Modal}\n />\n </Field>\n );\n};\n","/**\n * Layout-only styles shared by the panel's modals. No colours here on purpose —\n * every field/button the modals render carries its own themed colours from the kit,\n * so these hold nothing the `no-raw-color-literal` gate could catch.\n */\nimport { StyleSheet } from 'react-native';\n\nconst SPACE_SM = 8;\nconst SPACE_MD = 12;\n\nexport const modalFormStyles = StyleSheet.create({\n actions: { flexDirection: 'row', flexWrap: 'wrap', gap: SPACE_SM, marginTop: SPACE_SM },\n body: { gap: SPACE_MD, padding: SPACE_MD },\n});\n","/**\n * Create-user modal.\n *\n * The tenant picker is shown ONLY to a platform admin. A tenant admin creates into\n * their own tenant, so they are never offered a tenant control — the panel submits\n * `tenantId: null` and the backend resolves it. The role picker offers only the\n * caller-allowed `assignableRoles`, never anything else.\n */\nimport React, { useEffect, useState } from 'react';\n\nimport { View } from 'react-native';\n\nimport { Button } from '@dloizides/ui-buttons';\nimport { FormField } from '@dloizides/ui-forms';\nimport { ModalShell } from '@dloizides/ui-layout';\n\nimport { ACCESS_ADMIN_I18N } from '../constants';\nimport { PickerField } from './PickerField';\nimport { modalFormStyles } from './userManagementStyles';\nimport {\n NO_TENANT_VALUE,\n roleOptions,\n tenantOptions,\n tenantValueToId,\n} from './userManagementFormat';\nimport type {\n UserManagementTenant,\n UserManagementTranslate,\n} from './userManagementTypes';\n\nexport interface CreateUserModalProps {\n readonly visible: boolean;\n readonly isPlatformAdmin: boolean;\n readonly assignableRoles: readonly string[];\n readonly tenants: readonly UserManagementTenant[];\n readonly t: UserManagementTranslate;\n readonly testIDPrefix: string;\n readonly onSubmit: (input: {\n email: string;\n password: string;\n displayName: string;\n role: string;\n tenantId: string | null;\n }) => Promise<boolean>;\n readonly onCancel: () => void;\n}\n\nexport const CreateUserModal = ({\n visible,\n isPlatformAdmin,\n assignableRoles,\n tenants,\n t,\n testIDPrefix,\n onSubmit,\n onCancel,\n}: CreateUserModalProps): React.ReactElement => {\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [displayName, setDisplayName] = useState('');\n const [role, setRole] = useState('');\n const [tenantValue, setTenantValue] = useState(NO_TENANT_VALUE);\n const [submitting, setSubmitting] = useState(false);\n\n // Reset the form each time the modal is opened, so a cancelled draft never\n // reappears in the next create.\n useEffect(() => {\n if (!visible) return;\n setEmail('');\n setPassword('');\n setDisplayName('');\n setRole('');\n setTenantValue(NO_TENANT_VALUE);\n setSubmitting(false);\n }, [visible]);\n\n const canSubmit =\n !submitting &&\n email.trim() !== '' &&\n password !== '' &&\n displayName.trim() !== '' &&\n role !== '';\n\n const handleSubmit = async (): Promise<void> => {\n setSubmitting(true);\n const tenantId = isPlatformAdmin ? tenantValueToId(tenantValue) : null;\n const ok = await onSubmit({ email: email.trim(), password, displayName: displayName.trim(), role, tenantId });\n setSubmitting(false);\n if (ok) onCancel();\n };\n\n return (\n <ModalShell onCancel={onCancel} title={t(ACCESS_ADMIN_I18N.usersCreateTitle)} visible={visible}>\n <View style={modalFormStyles.body} testID={testIDPrefix}>\n <FormField\n autoCapitalize=\"none\"\n keyboardType=\"email-address\"\n label={t(ACCESS_ADMIN_I18N.usersFieldEmail)}\n onChangeText={setEmail}\n placeholder={t(ACCESS_ADMIN_I18N.usersEmailPlaceholder)}\n required\n testID={`${testIDPrefix}-email`}\n value={email}\n />\n <FormField\n label={t(ACCESS_ADMIN_I18N.usersFieldPassword)}\n onChangeText={setPassword}\n placeholder={t(ACCESS_ADMIN_I18N.usersPasswordPlaceholder)}\n required\n secureTextEntry\n testID={`${testIDPrefix}-password`}\n value={password}\n />\n <FormField\n label={t(ACCESS_ADMIN_I18N.usersFieldDisplayName)}\n onChangeText={setDisplayName}\n placeholder={t(ACCESS_ADMIN_I18N.usersDisplayNamePlaceholder)}\n required\n testID={`${testIDPrefix}-display-name`}\n value={displayName}\n />\n <PickerField\n hint={t(ACCESS_ADMIN_I18N.usersRolePickerHint)}\n label={t(ACCESS_ADMIN_I18N.usersFieldRole)}\n onChange={setRole}\n options={roleOptions(assignableRoles)}\n placeholder={t(ACCESS_ADMIN_I18N.usersRolePlaceholder)}\n testID={`${testIDPrefix}-role`}\n value={role}\n />\n {isPlatformAdmin ? (\n <PickerField\n hint={t(ACCESS_ADMIN_I18N.usersTenantPickerHint)}\n label={t(ACCESS_ADMIN_I18N.usersFieldTenant)}\n onChange={setTenantValue}\n options={tenantOptions(tenants, t)}\n placeholder={t(ACCESS_ADMIN_I18N.usersTenantPlaceholder)}\n testID={`${testIDPrefix}-tenant`}\n value={tenantValue}\n />\n ) : null}\n <View style={modalFormStyles.actions}>\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.usersSubmitCreateHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.usersSubmitCreate)}\n disabled={!canSubmit}\n label={t(ACCESS_ADMIN_I18N.usersSubmitCreate)}\n loading={submitting}\n onPress={handleSubmit}\n testID={`${testIDPrefix}-submit`}\n />\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.usersCancelHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.usersCancel)}\n disabled={submitting}\n label={t(ACCESS_ADMIN_I18N.usersCancel)}\n onPress={onCancel}\n testID={`${testIDPrefix}-cancel`}\n variant=\"secondary\"\n />\n </View>\n </View>\n </ModalShell>\n );\n};\n","/**\n * Edit-user modal — role, tenant (platform admin only), active toggle, display name.\n *\n * Seeded from the row being edited and reset whenever a different row opens it, so\n * one user's values never bleed into the next. Like create, the tenant control is\n * withheld from a tenant admin, and the role picker offers only `assignableRoles`.\n */\nimport React, { useEffect, useState } from 'react';\n\nimport { View } from 'react-native';\n\nimport { Button } from '@dloizides/ui-buttons';\nimport { FormField, FormSwitch } from '@dloizides/ui-forms';\nimport { ModalShell } from '@dloizides/ui-layout';\n\nimport { ACCESS_ADMIN_I18N } from '../constants';\nimport { PickerField } from './PickerField';\nimport { modalFormStyles } from './userManagementStyles';\nimport { NO_TENANT_VALUE, roleOptions, tenantOptions, tenantValueToId } from './userManagementFormat';\nimport type {\n UserManagementTenant,\n UserManagementTranslate,\n UserManagementUser,\n} from './userManagementTypes';\n\nexport interface EditUserModalProps {\n readonly visible: boolean;\n /** The row being edited, or null while the modal is closed. */\n readonly user: UserManagementUser | null;\n readonly isPlatformAdmin: boolean;\n readonly assignableRoles: readonly string[];\n readonly tenants: readonly UserManagementTenant[];\n readonly t: UserManagementTranslate;\n readonly testIDPrefix: string;\n readonly onSubmit: (\n id: string,\n patch: { displayName?: string; role?: string; tenantId?: string | null; active?: boolean },\n ) => Promise<boolean>;\n readonly onCancel: () => void;\n}\n\nexport const EditUserModal = ({\n visible,\n user,\n isPlatformAdmin,\n assignableRoles,\n tenants,\n t,\n testIDPrefix,\n onSubmit,\n onCancel,\n}: EditUserModalProps): React.ReactElement => {\n const [displayName, setDisplayName] = useState('');\n const [role, setRole] = useState('');\n const [tenantValue, setTenantValue] = useState(NO_TENANT_VALUE);\n const [active, setActive] = useState(true);\n const [submitting, setSubmitting] = useState(false);\n\n const userId = user?.id;\n useEffect(() => {\n if (!visible || user === null) return;\n setDisplayName(user.displayName);\n setRole(user.roles[0] ?? '');\n setTenantValue(user.tenantId ?? NO_TENANT_VALUE);\n setActive(user.active);\n setSubmitting(false);\n // Keyed on the row id, not the object, so a re-fetch that returns an equal user\n // does not stomp an in-progress edit.\n }, [visible, userId, user]);\n\n const canSubmit = !submitting && displayName.trim() !== '' && role !== '';\n\n const handleSubmit = async (): Promise<void> => {\n if (user === null) return;\n setSubmitting(true);\n const patch: { displayName?: string; role?: string; tenantId?: string | null; active?: boolean } = {\n displayName: displayName.trim(),\n role,\n active,\n };\n if (isPlatformAdmin) patch.tenantId = tenantValueToId(tenantValue);\n const ok = await onSubmit(user.id, patch);\n setSubmitting(false);\n if (ok) onCancel();\n };\n\n return (\n <ModalShell onCancel={onCancel} title={t(ACCESS_ADMIN_I18N.usersEditTitle)} visible={visible}>\n <View style={modalFormStyles.body} testID={testIDPrefix}>\n <FormField\n label={t(ACCESS_ADMIN_I18N.usersFieldDisplayName)}\n onChangeText={setDisplayName}\n placeholder={t(ACCESS_ADMIN_I18N.usersDisplayNamePlaceholder)}\n required\n testID={`${testIDPrefix}-display-name`}\n value={displayName}\n />\n <PickerField\n hint={t(ACCESS_ADMIN_I18N.usersRolePickerHint)}\n label={t(ACCESS_ADMIN_I18N.usersFieldRole)}\n onChange={setRole}\n options={roleOptions(assignableRoles)}\n placeholder={t(ACCESS_ADMIN_I18N.usersRolePlaceholder)}\n testID={`${testIDPrefix}-role`}\n value={role}\n />\n {isPlatformAdmin ? (\n <PickerField\n hint={t(ACCESS_ADMIN_I18N.usersTenantPickerHint)}\n label={t(ACCESS_ADMIN_I18N.usersFieldTenant)}\n onChange={setTenantValue}\n options={tenantOptions(tenants, t)}\n placeholder={t(ACCESS_ADMIN_I18N.usersTenantPlaceholder)}\n testID={`${testIDPrefix}-tenant`}\n value={tenantValue}\n />\n ) : null}\n <FormSwitch\n accessibilityHint={t(ACCESS_ADMIN_I18N.usersActiveToggleHint)}\n label={t(ACCESS_ADMIN_I18N.usersFieldActive)}\n onValueChange={setActive}\n testID={`${testIDPrefix}-active`}\n value={active}\n />\n <View style={modalFormStyles.actions}>\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.usersSubmitSaveHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.usersSubmitSave)}\n disabled={!canSubmit}\n label={t(ACCESS_ADMIN_I18N.usersSubmitSave)}\n loading={submitting}\n onPress={handleSubmit}\n testID={`${testIDPrefix}-submit`}\n />\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.usersCancelHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.usersCancel)}\n disabled={submitting}\n label={t(ACCESS_ADMIN_I18N.usersCancel)}\n onPress={onCancel}\n testID={`${testIDPrefix}-cancel`}\n variant=\"secondary\"\n />\n </View>\n </View>\n </ModalShell>\n );\n};\n","/**\n * Reset-password modal — a single new-password field for one user.\n *\n * Scoped to the row it was opened from; the panel owns which user that is. The\n * field is cleared on every open so a password never lingers in component state\n * across two different users.\n */\nimport React, { useEffect, useState } from 'react';\n\nimport { View } from 'react-native';\n\nimport { Button } from '@dloizides/ui-buttons';\nimport { FormField } from '@dloizides/ui-forms';\nimport { ModalShell } from '@dloizides/ui-layout';\n\nimport { ACCESS_ADMIN_I18N } from '../constants';\nimport { modalFormStyles } from './userManagementStyles';\nimport type { UserManagementTranslate, UserManagementUser } from './userManagementTypes';\n\nexport interface ResetPasswordModalProps {\n readonly visible: boolean;\n readonly user: UserManagementUser | null;\n readonly t: UserManagementTranslate;\n readonly testIDPrefix: string;\n readonly onSubmit: (id: string, password: string) => Promise<boolean>;\n readonly onCancel: () => void;\n}\n\nexport const ResetPasswordModal = ({\n visible,\n user,\n t,\n testIDPrefix,\n onSubmit,\n onCancel,\n}: ResetPasswordModalProps): React.ReactElement => {\n const [password, setPassword] = useState('');\n const [submitting, setSubmitting] = useState(false);\n\n useEffect(() => {\n if (!visible) return;\n setPassword('');\n setSubmitting(false);\n }, [visible]);\n\n const canSubmit = !submitting && password !== '';\n\n const handleSubmit = async (): Promise<void> => {\n if (user === null) return;\n setSubmitting(true);\n const ok = await onSubmit(user.id, password);\n setSubmitting(false);\n if (ok) onCancel();\n };\n\n return (\n <ModalShell onCancel={onCancel} title={t(ACCESS_ADMIN_I18N.usersResetTitle)} visible={visible}>\n <View style={modalFormStyles.body} testID={testIDPrefix}>\n <FormField\n label={t(ACCESS_ADMIN_I18N.usersFieldNewPassword)}\n onChangeText={setPassword}\n placeholder={t(ACCESS_ADMIN_I18N.usersNewPasswordPlaceholder)}\n required\n secureTextEntry\n testID={`${testIDPrefix}-password`}\n value={password}\n />\n <View style={modalFormStyles.actions}>\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.usersSubmitResetHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.usersSubmitReset)}\n disabled={!canSubmit}\n label={t(ACCESS_ADMIN_I18N.usersSubmitReset)}\n loading={submitting}\n onPress={handleSubmit}\n testID={`${testIDPrefix}-submit`}\n />\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.usersCancelHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.usersCancel)}\n disabled={submitting}\n label={t(ACCESS_ADMIN_I18N.usersCancel)}\n onPress={onCancel}\n testID={`${testIDPrefix}-cancel`}\n variant=\"secondary\"\n />\n </View>\n </View>\n </ModalShell>\n );\n};\n","/**\n * The state + write orchestration behind {@link UserManagementPanel}.\n *\n * Owns the list (load / reload / loading / failed), and turns each injected write\n * into a settled outcome: on success it reloads the list and emits a success\n * toast; on rejection it emits a failure toast and reports the write did NOT land,\n * so the modal stays open with the operator's input intact. The toast pipeline is\n * `@dloizides/ui-feedback`'s own bus — the panel renders its `<ToastHost>`.\n */\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { createToastBus, type ToastBus } from '@dloizides/ui-feedback';\n\nimport { ACCESS_ADMIN_I18N } from '../constants';\nimport type {\n UserManagementApi,\n UserManagementTranslate,\n UserManagementUser,\n} from './userManagementTypes';\n\nexport interface UserManagementController {\n users: readonly UserManagementUser[];\n loading: boolean;\n /** True when the LOAD failed — kept distinct from \"loaded, and there are none\". */\n loadFailed: boolean;\n reload: () => void;\n /** Each resolves `true` when the write landed, `false` when it was rejected. */\n create: (input: {\n email: string;\n password: string;\n displayName: string;\n role: string;\n tenantId: string | null;\n }) => Promise<boolean>;\n update: (\n id: string,\n patch: { displayName?: string; role?: string; tenantId?: string | null; active?: boolean },\n ) => Promise<boolean>;\n resetPassword: (id: string, password: string) => Promise<boolean>;\n /** The `<ToastHost>` `subscribe` port for this panel's toasts. */\n toastSubscribe: ToastBus['subscribe'];\n}\n\nexport function useUserManagement(\n api: UserManagementApi,\n t: UserManagementTranslate,\n): UserManagementController {\n const [users, setUsers] = useState<readonly UserManagementUser[]>([]);\n const [loading, setLoading] = useState(true);\n const [loadFailed, setLoadFailed] = useState(false);\n\n const bus = useMemo(() => createToastBus(), []);\n\n // Guards a resolved fetch from setting state after unmount (React 18 dev warning).\n const mountedRef = useRef(true);\n useEffect(() => {\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n const reload = useCallback((): void => {\n setLoading(true);\n setLoadFailed(false);\n void api\n .listUsers()\n .then((next) => {\n if (!mountedRef.current) return;\n setUsers(next);\n setLoading(false);\n })\n .catch(() => {\n if (!mountedRef.current) return;\n setLoadFailed(true);\n setLoading(false);\n });\n }, [api]);\n\n useEffect(() => reload(), [reload]);\n\n const runWrite = useCallback(\n async (write: () => Promise<void>, successKey: string, failureKey: string): Promise<boolean> => {\n try {\n await write();\n bus.success(t(successKey));\n reload();\n return true;\n } catch {\n bus.error(t(failureKey));\n return false;\n }\n },\n [bus, reload, t],\n );\n\n const create = useCallback<UserManagementController['create']>(\n (input) =>\n runWrite(\n () => api.createUser(input),\n ACCESS_ADMIN_I18N.usersCreateSuccess,\n ACCESS_ADMIN_I18N.usersCreateFailed,\n ),\n [api, runWrite],\n );\n\n const update = useCallback<UserManagementController['update']>(\n (id, patch) =>\n runWrite(\n () => api.updateUser(id, patch),\n ACCESS_ADMIN_I18N.usersUpdateSuccess,\n ACCESS_ADMIN_I18N.usersUpdateFailed,\n ),\n [api, runWrite],\n );\n\n const resetPassword = useCallback<UserManagementController['resetPassword']>(\n (id, password) =>\n runWrite(\n () => api.resetPassword(id, password),\n ACCESS_ADMIN_I18N.usersResetSuccess,\n ACCESS_ADMIN_I18N.usersResetFailed,\n ),\n [api, runWrite],\n );\n\n return {\n users,\n loading,\n loadFailed,\n reload,\n create,\n update,\n resetPassword,\n toastSubscribe: bus.subscribe,\n };\n}\n","/**\n * UserManagementPanel — the brand-agnostic, cross-portal in-app user administration\n * surface: a users table plus create / edit / reset-password flows, wired to the\n * host's API by injection.\n *\n * ── WHAT THE HOST OWNS ────────────────────────────────────────────────────────\n * The four writes (`api`), the scope (`isPlatformAdmin`, `assignableRoles`,\n * `tenants`) and the words (`t`). Everything else — the table, the modals, the\n * search, the loading / empty / error states and the success / failure toasts — is\n * the package's. Colours come from the host's `UiProvider` theme.\n *\n * ── SCOPE IS ENFORCED IN TWO PLACES ───────────────────────────────────────────\n * This panel is the UI half. It never OFFERS a role outside `assignableRoles` and\n * never shows a tenant control to a non-platform admin, so a tenant admin is not\n * handed a lever they cannot pull. The backend still authorizes every write — the\n * hidden control is a guardrail, not the gate.\n */\nimport React, { useMemo, useState } from 'react';\n\nimport { StyleSheet, Text, View } from 'react-native';\n\nimport { Button } from '@dloizides/ui-buttons';\nimport { ToastHost } from '@dloizides/ui-feedback';\nimport { DataTable, FilterBar } from '@dloizides/ui-tables';\nimport { FormField } from '@dloizides/ui-forms';\n\nimport { ACCESS_ADMIN_I18N, ACCESS_ADMIN_TEST_IDS } from '../constants';\nimport { useAccessAdminPalette, type AccessAdminPalette } from '../theme/useAccessAdminPalette';\nimport { buildUserColumns } from './buildUserColumns';\nimport { CreateUserModal } from './CreateUserModal';\nimport { EditUserModal } from './EditUserModal';\nimport { ResetPasswordModal } from './ResetPasswordModal';\nimport { filterUsers } from './userManagementFormat';\nimport { useUserManagement } from './useUserManagement';\nimport type { UserManagementPanelProps, UserManagementUser } from './userManagementTypes';\n\nconst SPACE_XS = 4;\nconst SPACE_SM = 8;\nconst SPACE_MD = 12;\nconst FONT_SM = 12;\nconst FONT_MD = 13;\nconst SEARCH_MIN_WIDTH = 220;\n\nconst enum OpenModal {\n None = 'none',\n Create = 'create',\n Edit = 'edit',\n Reset = 'reset',\n}\n\nexport const UserManagementPanel = ({\n api,\n isPlatformAdmin,\n assignableRoles,\n tenants = [],\n t,\n testID = ACCESS_ADMIN_TEST_IDS.usersPanel,\n}: UserManagementPanelProps): React.ReactElement => {\n const palette = useAccessAdminPalette();\n const styles = useMemo(() => buildStyles(palette), [palette]);\n\n const controller = useUserManagement(api, t);\n const [query, setQuery] = useState('');\n const [openModal, setOpenModal] = useState<OpenModal>(OpenModal.None);\n const [activeUser, setActiveUser] = useState<UserManagementUser | null>(null);\n\n const visibleUsers = useMemo(\n () => filterUsers(controller.users, query),\n [controller.users, query],\n );\n\n const openEdit = (user: UserManagementUser): void => {\n setActiveUser(user);\n setOpenModal(OpenModal.Edit);\n };\n const openReset = (user: UserManagementUser): void => {\n setActiveUser(user);\n setOpenModal(OpenModal.Reset);\n };\n const closeModal = (): void => setOpenModal(OpenModal.None);\n\n const columns = useMemo(\n () => buildUserColumns({ t, tenants, testIDPrefix: testID, onEdit: openEdit, onReset: openReset }),\n [t, tenants, testID],\n );\n\n return (\n <View style={styles.panel} testID={testID}>\n <ToastHost subscribe={controller.toastSubscribe} toastTestID={`${testID}-toast`} />\n\n <Text style={styles.heading}>{t(ACCESS_ADMIN_I18N.usersHeading)}</Text>\n <Text style={styles.note}>{t(ACCESS_ADMIN_I18N.usersNote)}</Text>\n\n <FilterBar\n actions={\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.usersCreateHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.usersCreate)}\n label={t(ACCESS_ADMIN_I18N.usersCreate)}\n onPress={() => setOpenModal(OpenModal.Create)}\n testID={`${testID}-create`}\n />\n }\n resultsCount={visibleUsers.length}\n resultsLabel={t(ACCESS_ADMIN_I18N.usersResultsLabel)}\n testID={`${testID}-filter-bar`}\n >\n <View style={styles.search}>\n <FormField\n accessibilityLabel={t(ACCESS_ADMIN_I18N.usersSearchLabel)}\n accessibilityHint={t(ACCESS_ADMIN_I18N.usersSearchHint)}\n autoCapitalize=\"none\"\n label={t(ACCESS_ADMIN_I18N.usersSearchLabel)}\n onChangeText={setQuery}\n placeholder={t(ACCESS_ADMIN_I18N.usersSearchPlaceholder)}\n testID={`${testID}-search`}\n value={query}\n />\n </View>\n </FilterBar>\n\n {controller.loadFailed ? (\n <View style={styles.errorBox} testID={`${testID}-load-error`}>\n <Text style={styles.warning}>{t(ACCESS_ADMIN_I18N.usersLoadError)}</Text>\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.usersRetryHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.usersRetry)}\n label={t(ACCESS_ADMIN_I18N.usersRetry)}\n onPress={controller.reload}\n testID={`${testID}-retry`}\n variant=\"secondary\"\n />\n </View>\n ) : (\n <DataTable\n columns={columns}\n emptyLabel={t(ACCESS_ADMIN_I18N.usersEmpty)}\n keyExtractor={(user) => user.id}\n loading={controller.loading}\n loadingLabel={t(ACCESS_ADMIN_I18N.usersLoading)}\n rows={visibleUsers}\n testID={`${testID}-table`}\n zebra\n />\n )}\n\n <CreateUserModal\n assignableRoles={assignableRoles}\n isPlatformAdmin={isPlatformAdmin}\n onCancel={closeModal}\n onSubmit={controller.create}\n t={t}\n tenants={tenants}\n testIDPrefix={`${testID}-create-modal`}\n visible={openModal === OpenModal.Create}\n />\n <EditUserModal\n assignableRoles={assignableRoles}\n isPlatformAdmin={isPlatformAdmin}\n onCancel={closeModal}\n onSubmit={controller.update}\n t={t}\n tenants={tenants}\n testIDPrefix={`${testID}-edit-modal`}\n user={activeUser}\n visible={openModal === OpenModal.Edit}\n />\n <ResetPasswordModal\n onCancel={closeModal}\n onSubmit={controller.resetPassword}\n t={t}\n testIDPrefix={`${testID}-reset-modal`}\n user={activeUser}\n visible={openModal === OpenModal.Reset}\n />\n </View>\n );\n};\n\n/** Builds the panel styles from the live palette (re-run when the theme changes). */\nconst buildStyles = (c: AccessAdminPalette) =>\n StyleSheet.create({\n errorBox: {\n backgroundColor: c.panelSurface,\n borderColor: c.border,\n borderRadius: SPACE_SM,\n borderWidth: 1,\n gap: SPACE_SM,\n marginTop: SPACE_SM,\n padding: SPACE_MD,\n },\n heading: { color: c.textPrimary, fontSize: FONT_MD, fontWeight: '700' },\n note: { color: c.textSecondary, fontSize: FONT_SM },\n panel: { gap: SPACE_XS },\n search: { minWidth: SEARCH_MIN_WIDTH },\n warning: { color: c.danger, fontSize: FONT_SM, fontWeight: '600' },\n });\n"]}
1
+ {"version":3,"sources":["../src/AccessResultTone.ts","../src/constants.ts","../src/expiry/expiryPolicy.ts","../src/links/capabilityLinkHelpers.ts","../src/links/useCapabilityLinkMint.ts","../src/theme/useAccessAdminPalette.ts","../src/AccessLinkPanel/AccessLinkPanel.tsx","../src/accounts/accountOptions.ts","../src/accounts/useSubjectAccountLink.ts","../src/AccountLinkPanel/AccountLinkPanel.tsx","../src/UserManagementPanel/userManagementFormat.ts","../src/UserManagementPanel/buildUserColumns.tsx","../src/UserManagementPanel/PickerField.tsx","../src/UserManagementPanel/userManagementStyles.ts","../src/UserManagementPanel/CreateUserModal.tsx","../src/UserManagementPanel/EditUserModal.tsx","../src/UserManagementPanel/ResetPasswordModal.tsx","../src/UserManagementPanel/useUserManagement.ts","../src/UserManagementPanel/UserManagementPanel.tsx","../src/PermissionMatrix/permissionMatrixModel.ts","../src/PermissionMatrix/PermissionMatrix.tsx"],"names":["AccessResultTone","ISO_DATE_LENGTH","useState","useRef","useEffect","useCallback","copyText","useUi","useMemo","styles","Linking","View","jsx","Text","jsxs","Button","StyleSheet","SPACE_XS","SPACE_SM","SPACE_MD","SPACE_LG","FONT_SM","FONT_MD","buildStyles","SelectControl","Field","ModalDropdown","DropdownVariant","ModalShell","FormField","FormSwitch","createToastBus","ToastHost","FilterBar","DataTable","ScrollView","useWindowDimensions","LAYOUT_COLLAPSE_BREAKPOINT"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * How a settled write should be reported. Its own file per the repo's\n * \"one exported enum per file\" rule.\n *\n * Two values, not three. There is no \"warning\" because every branch this package\n * reports is either a thing that worked or a thing the user has to act on — and\n * the one case that tempts a warning is the most important error in the package:\n * a mint that SUCCEEDED but whose URL never reached the clipboard. That is\n * reported as `Error`, loudly, because the URL is readable exactly once and a\n * user who dismisses it without copying by hand has to revoke and re-mint. An\n * amber \"heads up\" would let that slide past.\n */\nexport const enum AccessResultTone {\n Success = 'success',\n Error = 'error',\n}\n\n/** Reports a settled outcome with an ALREADY-LOCALIZED message. */\nexport type AccessResultReporter = (message: string, tone: AccessResultTone) => void;\n","/**\n * The package's two host contracts: the translation keys it resolves, and the\n * testIDs it renders.\n */\n\n/**\n * Every translation key this package resolves through `t(...)` — the host's i18n contract.\n *\n * ── WHY A MACHINE-READABLE MAP AND NOT A README TABLE ─────────────────────────\n * The kit is deliberately fallback-free: `t` is the host's own resolver (kefi passes\n * `FM`), and a missing key renders the RAW DOTTED NAME to the user — a panel warning\n * `accessAdmin.capabilityWarning` instead of explaining that anyone holding the URL\n * has the access. Because every `t(...)` call site in this package lives inside\n * `node_modules` once published, a host grepping its own source for untranslated\n * strings cannot see them. Hand-maintained key lists rot on exactly this path: one\n * portal in this fleet was found missing 26 kit keys, rendering raw names to users.\n *\n * So: bind a missing-key guard to this map, the way kefi-web's\n * `kitTranslationKeys.ts` already binds `LAYOUT_I18N` / `TABLE_I18N`. Then a kit\n * upgrade that adds a string FAILS the host's test suite instead of shipping raw\n * key text. `accessAdminI18n.test.ts` asserts this map stays complete and unused-free,\n * so the map cannot drift from the call sites either.\n *\n * The KEY NAMES are the package's; the WORDING is entirely the host's. That split is\n * what lets kefi keep its warm, specific copy (\"This link lets them see their own\n * guests and what they are owed\") under a key a survey tool can reuse with its own.\n */\nexport const ACCESS_ADMIN_I18N = {\n // ── AccessLinkPanel: framing ────────────────────────────────────────────────\n /** Panel heading. `{{p1}}` = subject display name. */\n panelHeading: 'accessAdmin.link.panelHeading',\n /** Supporting line explaining what the link grants. */\n panelNote: 'accessAdmin.link.panelNote',\n /** The security warning. Shown always, not only after a mint — see AccessLinkPanel. */\n capabilityWarning: 'accessAdmin.link.capabilityWarning',\n /** \"A link created now stops working on {{p1}}.\" `{{p1}}` = yyyy-mm-dd. */\n expiryPreview: 'accessAdmin.link.expiryPreview',\n\n // ── AccessLinkPanel: minting ────────────────────────────────────────────────\n mint: 'accessAdmin.link.mint',\n mintHint: 'accessAdmin.link.mintHint',\n /** Heading over the revealed URL. `{{p1}}` = subject display name. */\n mintedTitle: 'accessAdmin.link.mintedTitle',\n /** \"Shown once — copy it now.\" The honesty that makes the one-shot reveal safe. */\n mintedHint: 'accessAdmin.link.mintedHint',\n /** Reported when the mint landed AND the clipboard write succeeded. `{{p1}}` = name. */\n copySuccess: 'accessAdmin.link.copySuccess',\n /** Reported when the mint landed but the clipboard REFUSED. `{{p1}}` = name. */\n mintNotCopied: 'accessAdmin.link.mintNotCopied',\n /** Reported when a re-copy of an already-revealed URL failed. `{{p1}}` = name. */\n copyFailed: 'accessAdmin.link.copyFailed',\n\n // ── AccessLinkPanel: acting on a revealed URL ───────────────────────────────\n recopy: 'accessAdmin.link.recopy',\n recopyHint: 'accessAdmin.link.recopyHint',\n copied: 'accessAdmin.link.copied',\n dismiss: 'accessAdmin.link.dismiss',\n dismissHint: 'accessAdmin.link.dismissHint',\n email: 'accessAdmin.link.email',\n emailHint: 'accessAdmin.link.emailHint',\n /** \"This opens YOUR mail app — we do not send it for you.\" */\n emailNote: 'accessAdmin.link.emailNote',\n /** Mail subject. `{{p1}}` = subject display name. */\n emailSubject: 'accessAdmin.link.emailSubject',\n /** Mail body. `{{p1}}` = name, `{{p2}}` = url, `{{p3}}` = expiry date. */\n emailBody: 'accessAdmin.link.emailBody',\n\n // ── AccessLinkPanel: the live list ──────────────────────────────────────────\n /** \"Live links ({{p1}})\". `{{p1}}` = count. */\n liveHeading: 'accessAdmin.link.liveHeading',\n /** \"Created {{p1}} · stops working {{p2}}\". */\n liveMeta: 'accessAdmin.link.liveMeta',\n /** Shown in `liveMeta`'s `{{p2}}` slot when a link has no expiry at all. */\n expiresNever: 'accessAdmin.link.expiresNever',\n noLive: 'accessAdmin.link.noLive',\n /** Shown when the link list FAILED to load — never conflated with \"there are none\". */\n liveLoadError: 'accessAdmin.link.liveLoadError',\n close: 'accessAdmin.link.close',\n closeHint: 'accessAdmin.link.closeHint',\n\n // ── AccountLinkPanel ────────────────────────────────────────────────────────\n /** Panel heading. `{{p1}}` = subject display name. */\n accountPanelHeading: 'accessAdmin.account.panelHeading',\n accountPanelNote: 'accessAdmin.account.panelNote',\n accountPickerLabel: 'accessAdmin.account.pickerLabel',\n accountPickerHint: 'accessAdmin.account.pickerHint',\n accountPickerPlaceholder: 'accessAdmin.account.pickerPlaceholder',\n accountOptionHint: 'accessAdmin.account.optionHint',\n /** Label for a directory entry carrying neither a display name nor an email. */\n accountUnnamed: 'accessAdmin.account.unnamed',\n /** Shown when the directory is empty (or every entry is taken by another subject). */\n accountNone: 'accessAdmin.account.none',\n accountLink: 'accessAdmin.account.link',\n accountLinkHint: 'accessAdmin.account.linkHint',\n /** `{{p1}}` = subject display name. */\n accountLinkSuccess: 'accessAdmin.account.linkSuccess',\n accountUnlink: 'accessAdmin.account.unlink',\n accountUnlinkHint: 'accessAdmin.account.unlinkHint',\n /** `{{p1}}` = subject display name. */\n accountUnlinkSuccess: 'accessAdmin.account.unlinkSuccess',\n accountClose: 'accessAdmin.account.close',\n accountCloseHint: 'accessAdmin.account.closeHint',\n\n // ── UserManagementPanel: framing + toolbar ──────────────────────────────────\n /** Panel heading. */\n usersHeading: 'accessAdmin.users.heading',\n /** Supporting line under the heading. */\n usersNote: 'accessAdmin.users.note',\n /** Placeholder in the search box. */\n usersSearchPlaceholder: 'accessAdmin.users.searchPlaceholder',\n /** Accessible name of the search box. */\n usersSearchLabel: 'accessAdmin.users.searchLabel',\n usersSearchHint: 'accessAdmin.users.searchHint',\n /** Word shown next to the live result count in the FilterBar. */\n usersResultsLabel: 'accessAdmin.users.resultsLabel',\n usersCreate: 'accessAdmin.users.create',\n usersCreateHint: 'accessAdmin.users.createHint',\n\n // ── UserManagementPanel: table columns ──────────────────────────────────────\n usersColEmail: 'accessAdmin.users.colEmail',\n usersColDisplayName: 'accessAdmin.users.colDisplayName',\n usersColRoles: 'accessAdmin.users.colRoles',\n usersColTenant: 'accessAdmin.users.colTenant',\n usersColActive: 'accessAdmin.users.colActive',\n usersColCreated: 'accessAdmin.users.colCreated',\n usersColActions: 'accessAdmin.users.colActions',\n\n // ── UserManagementPanel: cell values ────────────────────────────────────────\n usersActiveYes: 'accessAdmin.users.activeYes',\n usersActiveNo: 'accessAdmin.users.activeNo',\n /** Tenant cell for a user bound to no tenant (a platform-level account). */\n usersTenantNone: 'accessAdmin.users.tenantNone',\n /** Roles cell for a user with no roles yet. */\n usersNoRoles: 'accessAdmin.users.noRoles',\n /** Created cell when the API did not return a timestamp. */\n usersCreatedUnknown: 'accessAdmin.users.createdUnknown',\n\n // ── UserManagementPanel: per-row actions ────────────────────────────────────\n usersEdit: 'accessAdmin.users.edit',\n usersEditHint: 'accessAdmin.users.editHint',\n usersReset: 'accessAdmin.users.reset',\n usersResetHint: 'accessAdmin.users.resetHint',\n\n // ── UserManagementPanel: load states ────────────────────────────────────────\n usersLoading: 'accessAdmin.users.loading',\n usersEmpty: 'accessAdmin.users.empty',\n /** Shown when the user list FAILED to load — never conflated with \"there are none\". */\n usersLoadError: 'accessAdmin.users.loadError',\n usersRetry: 'accessAdmin.users.retry',\n usersRetryHint: 'accessAdmin.users.retryHint',\n\n // ── UserManagementPanel: modals — titles ────────────────────────────────────\n usersCreateTitle: 'accessAdmin.users.createTitle',\n usersEditTitle: 'accessAdmin.users.editTitle',\n usersResetTitle: 'accessAdmin.users.resetTitle',\n\n // ── UserManagementPanel: modals — fields (shared across modals) ──────────────\n usersFieldEmail: 'accessAdmin.users.fieldEmail',\n usersEmailPlaceholder: 'accessAdmin.users.emailPlaceholder',\n usersFieldPassword: 'accessAdmin.users.fieldPassword',\n usersPasswordPlaceholder: 'accessAdmin.users.passwordPlaceholder',\n usersFieldDisplayName: 'accessAdmin.users.fieldDisplayName',\n usersDisplayNamePlaceholder: 'accessAdmin.users.displayNamePlaceholder',\n usersFieldRole: 'accessAdmin.users.fieldRole',\n usersRolePlaceholder: 'accessAdmin.users.rolePlaceholder',\n usersRolePickerHint: 'accessAdmin.users.rolePickerHint',\n usersFieldTenant: 'accessAdmin.users.fieldTenant',\n usersTenantPlaceholder: 'accessAdmin.users.tenantPlaceholder',\n usersTenantPickerHint: 'accessAdmin.users.tenantPickerHint',\n usersFieldActive: 'accessAdmin.users.fieldActive',\n usersActiveToggleHint: 'accessAdmin.users.activeToggleHint',\n usersFieldNewPassword: 'accessAdmin.users.fieldNewPassword',\n usersNewPasswordPlaceholder: 'accessAdmin.users.newPasswordPlaceholder',\n\n // ── UserManagementPanel: modals — actions ───────────────────────────────────\n usersSubmitCreate: 'accessAdmin.users.submitCreate',\n usersSubmitCreateHint: 'accessAdmin.users.submitCreateHint',\n usersSubmitSave: 'accessAdmin.users.submitSave',\n usersSubmitSaveHint: 'accessAdmin.users.submitSaveHint',\n usersSubmitReset: 'accessAdmin.users.submitReset',\n usersSubmitResetHint: 'accessAdmin.users.submitResetHint',\n usersCancel: 'accessAdmin.users.cancel',\n usersCancelHint: 'accessAdmin.users.cancelHint',\n\n // ── UserManagementPanel: outcome toasts ─────────────────────────────────────\n usersCreateSuccess: 'accessAdmin.users.createSuccess',\n usersCreateFailed: 'accessAdmin.users.createFailed',\n usersUpdateSuccess: 'accessAdmin.users.updateSuccess',\n usersUpdateFailed: 'accessAdmin.users.updateFailed',\n usersResetSuccess: 'accessAdmin.users.resetSuccess',\n usersResetFailed: 'accessAdmin.users.resetFailed',\n usersFieldBlockedReason: 'accessAdmin.users.fieldBlockedReason',\n usersBlockedReasonPlaceholder: 'accessAdmin.users.blockedReasonPlaceholder',\n usersBlockedReasonHint: 'accessAdmin.users.blockedReasonHint',\n permissionsHeading: 'accessAdmin.permissions.heading',\n permissionsNote: 'accessAdmin.permissions.note',\n permissionsColPermission: 'accessAdmin.permissions.colPermission',\n permissionsGranted: 'accessAdmin.permissions.granted',\n permissionsNotGranted: 'accessAdmin.permissions.notGranted',\n permissionsCellLabel: 'accessAdmin.permissions.cellLabel',\n permissionsReadOnlyHint: 'accessAdmin.permissions.readOnlyHint',\n permissionsRoleCount: 'accessAdmin.permissions.roleCount',\n permissionsEmpty: 'accessAdmin.permissions.empty',\n} as const;\n\n/** The shape of {@link ACCESS_ADMIN_I18N} — useful for typing an override map. */\nexport type AccessAdminI18n = typeof ACCESS_ADMIN_I18N;\n\n/**\n * Default testIDs. Every one is overridable via each panel's `testIDPrefix`, because\n * Playwright selectors in an adopting app already exist and a shared component is not\n * a good enough reason to rewrite someone's E2E suite.\n */\nexport const ACCESS_ADMIN_TEST_IDS = {\n linkPanel: 'access-link-panel',\n accountPanel: 'account-link-panel',\n usersPanel: 'user-management-panel',\n permissionMatrix: 'permission-matrix',\n} as const;\n","/**\n * How long a freshly minted capability link should live.\n *\n * ── THE GENERALIZATION ────────────────────────────────────────────────────────\n * kefi computed this as \"the event date, plus a two-week payout-reconciliation\n * tail, clamped to what the API accepts\". Every noun there is kefi's, but the\n * SHAPE is not: a capability is nearly always anchored to some real-world moment\n * (an event, a deadline, a booking, a review window) and needs to outlive that\n * moment by however long the follow-up work takes. So the policy is expressed as\n * an anchor plus a tail, and the host names them.\n *\n * ── THE ONE RULE THAT DOES NOT BEND ───────────────────────────────────────────\n * There is NO code path here that returns \"never\". Not for a missing anchor, not\n * for an unparseable one, not for an anchor in the past. A capability link is a\n * bearer token pasted into a chat app; the expiry is the only thing that limits\n * the blast radius of it being forwarded. A fallback to \"never\" would turn the\n * least-informed case — we could not read the date — into the most dangerous\n * outcome, which is exactly backwards. A missing anchor yields the bare tail: a\n * link that still dies on a clock.\n */\n\n/** Milliseconds in one day. */\nconst MS_PER_DAY = 86_400_000;\n\n/** Number of leading ISO characters that make up `yyyy-mm-dd`. */\nconst ISO_DATE_LENGTH = 10;\n\n/**\n * The host's expiry rule.\n *\n * `minDays`/`maxDays` are REQUIRED rather than defaulted, because they encode\n * what a specific API will accept. A default here would be a guess that fails\n * server-side at mint time, which is the worst place to find out.\n */\nexport interface ExpiryPolicy {\n /**\n * ISO date/timestamp the capability is anchored to, or null/undefined when\n * there is no anchor. Unparseable values are treated as absent.\n */\n readonly anchorDate?: string | null;\n /** Whole days the link survives PAST the anchor (or from now, when unanchored). */\n readonly tailDays: number;\n /** Smallest expiry the host's API accepts. */\n readonly minDays: number;\n /** Largest expiry the host's API accepts. Anchors beyond this clamp, never unbound. */\n readonly maxDays: number;\n}\n\n/**\n * Whole days from `now` until `anchorDate`, or null when the date is unusable.\n *\n * Both sides are floored to UTC midnight before subtracting, so the answer does\n * not flip by one depending on what time of day the button happens to be pressed.\n * Negative when the anchor is in the past — the caller decides what that means.\n */\nexport function daysUntilAnchor(anchorDate: string | null | undefined, now: Date): number | null {\n if (typeof anchorDate !== 'string' || anchorDate.trim() === '') return null;\n const anchor = Date.parse(anchorDate);\n if (Number.isNaN(anchor)) return null;\n return Math.floor(anchor / MS_PER_DAY) - Math.floor(now.getTime() / MS_PER_DAY);\n}\n\n/**\n * The expiry, in whole days from now, for a link minted under this policy.\n *\n * Three cases, all of which still expire:\n * - no usable anchor → the bare tail;\n * - anchor in the past → tail minus however long ago it was, floored at `minDays`,\n * so a link minted while settling up afterwards still dies soon;\n * - anchor beyond the ceiling → clamped to `maxDays`.\n */\nexport function capabilityExpiryDays(policy: ExpiryPolicy, now: Date): number {\n const untilAnchor = daysUntilAnchor(policy.anchorDate, now);\n const raw = untilAnchor === null ? policy.tailDays : untilAnchor + policy.tailDays;\n if (raw < policy.minDays) return policy.minDays;\n if (raw > policy.maxDays) return policy.maxDays;\n return raw;\n}\n\n/** The `yyyy-mm-dd` date a link minted now under this policy would stop working on. */\nexport function capabilityExpiryDate(policy: ExpiryPolicy, now: Date): string {\n const days = capabilityExpiryDays(policy, now);\n return new Date(now.getTime() + days * MS_PER_DAY).toISOString().slice(0, ISO_DATE_LENGTH);\n}\n","/**\n * Pure rules for presenting a subject's capability links.\n *\n * Logic-only (no JSX) so the parts that are quietly easy to get wrong — which\n * links belong to whom, which are still worth revoking, and what goes into a\n * mail compose window — are unit-tested without a renderer.\n */\nimport type { CapabilityLink } from '../types';\n\n/** Number of leading ISO characters that make up `yyyy-mm-dd`. */\nconst ISO_DATE_LENGTH = 10;\n\n/**\n * A subject's links, newest first.\n *\n * Matching is on `subjectId` and nothing else. The messy part — working out\n * WHICH subject an API's link row belongs to when the wire format does not say —\n * is the host's job, done once when it normalizes its DTOs. That keeps a\n * product's data-model compromise out of the shared filter.\n */\nexport function linksForSubject(\n links: readonly CapabilityLink[],\n subjectId: string,\n): CapabilityLink[] {\n return links\n .filter((link) => link.subjectId === subjectId)\n .sort((a, b) => String(b.createdAt ?? '').localeCompare(String(a.createdAt ?? '')));\n}\n\n/** The still-usable links belonging to a subject — the ones worth revoking. */\nexport function activeLinksForSubject(\n links: readonly CapabilityLink[],\n subjectId: string,\n): CapabilityLink[] {\n return linksForSubject(links, subjectId).filter((link) => link.isActive);\n}\n\n/** An ISO timestamp as a bare `yyyy-mm-dd`, or the supplied fallback when absent. */\nexport function formatLinkDate(value: string | null | undefined, fallback: string): string {\n if (typeof value !== 'string' || value.trim() === '') return fallback;\n return value.slice(0, ISO_DATE_LENGTH);\n}\n\n/**\n * A `mailto:` compose URL carrying the link, or null when there is nothing to send.\n *\n * NO recipient address is filled in, and that is deliberate rather than an\n * omission: an `AccessSubject` has no email field (see `types.ts` for why it\n * stays that small), so the sender picks the address in their own mail client.\n * It is also why the panel calls this \"open in email\" and warns that nothing is\n * sent on the user's behalf — a compose window they abandon looks identical to\n * one they send.\n */\nexport function buildCapabilityLinkMailto(\n subject: string,\n body: string,\n url: string,\n): string | null {\n if (url.trim() === '') return null;\n return `mailto:?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;\n}\n","/**\n * Mint-and-copy state for ONE subject's capability link.\n *\n * ── WHY THE COPY RESULT IS THREADED THROUGH INSTEAD OF IGNORED ────────────────\n * The clipboard write happens AFTER the network round-trip, in the mint's\n * continuation — not synchronously inside the press. Chrome accepts that from a\n * focused document with recent user activation; WebKit is stricter about tying\n * the write to the gesture task, and these panels get used from phones. So the\n * write is treated as one that MAY be refused rather than one that is assumed to\n * land.\n *\n * That matters more here than it would anywhere else, because the URL is\n * revealed exactly ONCE. If the copy silently failed and the user dismissed the\n * panel, the link would be unrecoverable — they would have to revoke and\n * re-mint, having already told someone it was on the way. So a refused copy is\n * reported as an ERROR even though the mint itself succeeded, and the URL stays\n * on screen to be copied by hand.\n *\n * ── NO REACT-QUERY ────────────────────────────────────────────────────────────\n * The mint is an injected promise, so this hook owns its own in-flight flag. A\n * host wires its mutation (and its cache invalidation) inside the callback.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { copyText } from '@dloizides/ui-layout';\n\nimport { AccessResultTone, type AccessResultReporter } from '../AccessResultTone';\nimport { ACCESS_ADMIN_I18N } from '../constants';\nimport { capabilityExpiryDays, type ExpiryPolicy } from '../expiry/expiryPolicy';\nimport type {\n AccessSubject,\n CapabilityLink,\n DescribeError,\n MintCapabilityLink,\n} from '../types';\n\n/** Translate function — mirrors the fleet's `FM(key, p1?, p2?, p3?)` shape. */\nexport type AccessTranslate = (key: string, p1?: string, p2?: string, p3?: string) => string;\n\nexport interface UseCapabilityLinkMintOptions {\n readonly subject: AccessSubject;\n readonly policy: ExpiryPolicy;\n readonly mint: MintCapabilityLink;\n readonly describeError: DescribeError;\n readonly onResult: AccessResultReporter;\n readonly t: AccessTranslate;\n /** Injectable clock, so the expiry maths is testable. Defaults to the real one. */\n readonly now?: () => Date;\n /** Optional platform clipboard writer (React Native's `Clipboard.setString`, say). */\n readonly clipboardWriter?: (text: string) => void | Promise<void>;\n}\n\nexport interface CapabilityLinkMintState {\n /** The just-minted link, revealed once, or null before any mint. */\n readonly minted: CapabilityLink | null;\n /** True while a mint is in flight. */\n readonly isPending: boolean;\n /** True when the last mint's URL actually reached the clipboard. */\n readonly copied: boolean;\n /** Mint a fresh link for this subject and copy it. */\n readonly mint: () => void;\n /** Re-copy the revealed URL, after a refused write. */\n readonly recopy: () => void;\n /** Forget the revealed URL — it cannot be read again afterwards. */\n readonly dismiss: () => void;\n}\n\nexport function useCapabilityLinkMint(\n options: UseCapabilityLinkMintOptions,\n): CapabilityLinkMintState {\n const { subject, policy, mint, describeError, onResult, t, now, clipboardWriter } = options;\n\n const [minted, setMinted] = useState<CapabilityLink | null>(null);\n const [copied, setCopied] = useState<boolean>(false);\n const [isPending, setIsPending] = useState<boolean>(false);\n\n // The mint is async and these panels close (a row collapses, a drawer dismisses)\n // while it is in flight, so every post-await setState is guarded.\n const mountedRef = useRef<boolean>(true);\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n const copyUrl = useCallback(\n async (url: string): Promise<boolean> => {\n const ok = await copyText(url, clipboardWriter);\n if (mountedRef.current) setCopied(ok);\n return ok;\n },\n [clipboardWriter],\n );\n\n const runMint = useCallback((): void => {\n if (isPending) return;\n setIsPending(true);\n\n void (async () => {\n try {\n const expiresInDays = capabilityExpiryDays(policy, now === undefined ? new Date() : now());\n const link = await mint({ subject, expiresInDays });\n if (!mountedRef.current) return;\n\n setMinted(link);\n const ok = await copyUrl(link.url ?? '');\n if (!mountedRef.current) return;\n\n onResult(\n t(\n ok ? ACCESS_ADMIN_I18N.copySuccess : ACCESS_ADMIN_I18N.mintNotCopied,\n subject.displayName,\n ),\n ok ? AccessResultTone.Success : AccessResultTone.Error,\n );\n } catch (error) {\n if (!mountedRef.current) return;\n onResult(describeError(error as Error), AccessResultTone.Error);\n } finally {\n if (mountedRef.current) setIsPending(false);\n }\n })();\n }, [isPending, policy, now, mint, subject, copyUrl, onResult, t, describeError]);\n\n const recopy = useCallback((): void => {\n const url = minted?.url ?? '';\n if (url === '') return;\n\n void (async () => {\n const ok = await copyUrl(url);\n if (!mountedRef.current) return;\n onResult(\n t(ok ? ACCESS_ADMIN_I18N.copySuccess : ACCESS_ADMIN_I18N.copyFailed, subject.displayName),\n ok ? AccessResultTone.Success : AccessResultTone.Error,\n );\n })();\n }, [minted, copyUrl, onResult, t, subject.displayName]);\n\n const dismiss = useCallback((): void => {\n setMinted(null);\n setCopied(false);\n }, []);\n\n return { minted, isPending, copied, mint: runMint, recopy, dismiss };\n}\n","/**\n * The handful of colour roles these panels need, resolved from the host's\n * `UiProvider` theme.\n *\n * ── WHY A MAPPING LAYER AT ALL ────────────────────────────────────────────────\n * The kefi original read a `KefiColors` object with slots named for kefi's brand\n * (`brandDeep`, `positiveBg`, `surfaceMuted`). Carrying those names into a shared\n * package would have made every other portal invent a kefi palette to use it. So\n * the panels ask for ROLES — \"the surface a panel sits on\", \"the colour of a\n * security warning\" — and this module answers them from the theme every portal\n * already broadcasts.\n *\n * Not a single literal colour is defined here. Every value traces back to the\n * host's `@dloizides/design-tokens` theme, so a rebrand reaches these panels for\n * free and the `no-raw-color-literal` gate has nothing to catch.\n */\nimport { useMemo } from 'react';\n\nimport { useUi } from '@dloizides/ui-feedback';\n\nexport interface AccessAdminPalette {\n /** Background of the panel itself — a recessed surface inside a section. */\n readonly panelSurface: string;\n /** Hairline borders. */\n readonly border: string;\n readonly textPrimary: string;\n readonly textSecondary: string;\n /** The security warning, and the destructive action. */\n readonly danger: string;\n /** Fill and edge of the \"here is your new link\" box. */\n readonly revealSurface: string;\n readonly revealBorder: string;\n /** Heading inside the reveal box — the strongest brand tone available. */\n readonly revealHeading: string;\n}\n\nexport function useAccessAdminPalette(): AccessAdminPalette {\n const { theme } = useUi();\n const { colors, palette, semantic } = theme;\n\n return useMemo<AccessAdminPalette>(() => {\n const success = semantic.success ?? semantic.error;\n return {\n panelSurface: colors.surface,\n border: colors.border,\n textPrimary: colors.text,\n textSecondary: colors.textSecondary,\n danger: semantic.error['500'],\n // A tinted step when the host's scale has one, else the elevated surface —\n // never a hardcoded pastel, which would be wrong in dark mode.\n revealSurface: success['50'] ?? success['100'] ?? colors.surfaceElevated,\n revealBorder: success['500'],\n revealHeading: palette.primary['700'] ?? palette.primary['500'],\n };\n }, [colors, palette, semantic]);\n}\n","/**\n * The capability-link panel for ONE subject.\n *\n * ── SCOPED TO ONE SUBJECT ON PURPOSE ──────────────────────────────────────────\n * These links are CAPABILITIES: whoever holds the URL has the access, with no\n * sign-in in the way. A screen listing every subject's live link would itself be\n * a high-value secret. So this panel shows one subject's links, and only while\n * the user is looking at that subject.\n *\n * The primary action mints AND copies in a single press, because the real\n * workflow is pasting the link into a chat app. Email is a secondary COMPOSE\n * action (see `buildCapabilityLinkMailto`). Revoking any of this subject's live\n * links is reachable here, so a leaked link can be killed without disturbing\n * anyone else's.\n *\n * ── WHAT THE HOST OWNS ────────────────────────────────────────────────────────\n * The mint call, the error wording, and the per-link revoke control (via\n * `renderLinkActions`) — revocation usually needs a confirm step wired to the\n * host's own dialog and mutation, so the package renders the row and lets the\n * host fill the action slot rather than shipping half a revoke flow.\n */\nimport React, { useMemo } from 'react';\n\nimport { Linking, StyleSheet, Text, View } from 'react-native';\n\nimport { Button } from '@dloizides/ui-buttons';\nimport { useUi } from '@dloizides/ui-feedback';\n\nimport { AccessResultTone, type AccessResultReporter } from '../AccessResultTone';\nimport { ACCESS_ADMIN_I18N, ACCESS_ADMIN_TEST_IDS } from '../constants';\nimport { capabilityExpiryDate, type ExpiryPolicy } from '../expiry/expiryPolicy';\nimport {\n activeLinksForSubject,\n buildCapabilityLinkMailto,\n formatLinkDate,\n} from '../links/capabilityLinkHelpers';\nimport { useCapabilityLinkMint } from '../links/useCapabilityLinkMint';\nimport { useAccessAdminPalette, type AccessAdminPalette } from '../theme/useAccessAdminPalette';\nimport type {\n AccessSubject,\n CapabilityLink,\n DescribeError,\n MintCapabilityLink,\n} from '../types';\n\n/** Spacing scale — kept local so the package needs no spacing dependency. */\nconst SPACE_XS = 4;\nconst SPACE_SM = 8;\nconst SPACE_MD = 12;\nconst SPACE_LG = 16;\n\nconst FONT_SM = 12;\nconst FONT_MD = 13;\n\nexport interface AccessLinkPanelProps {\n /** The subject whose links are being managed. */\n readonly subject: AccessSubject;\n /** How long a link minted now should live. */\n readonly policy: ExpiryPolicy;\n /**\n * Every capability link the host knows about, normalized. Filtered to this\n * subject here — the host does not need to pre-filter.\n */\n readonly links: readonly CapabilityLink[];\n /**\n * True when the link list FAILED to load.\n *\n * Distinguished from \"loaded, and there are none\" deliberately: an empty list\n * caused by a failed fetch reads as \"this subject has no live link\", which\n * invites minting a SECOND live capability for someone who already has one —\n * and leaves the user believing there is nothing to revoke.\n */\n readonly linksFailed?: boolean;\n readonly mint: MintCapabilityLink;\n readonly describeError: DescribeError;\n readonly onClose: () => void;\n readonly onResult: AccessResultReporter;\n /** Renders the host's revoke control for one live link. */\n readonly renderLinkActions?: (link: CapabilityLink) => React.ReactNode;\n /** Injectable clock, for tests. */\n readonly now?: () => Date;\n /** Optional platform clipboard writer. */\n readonly clipboardWriter?: (text: string) => void | Promise<void>;\n /** Root testID; children derive from it. Defaults to `access-link-panel`. */\n readonly testIDPrefix?: string;\n}\n\nexport const AccessLinkPanel = ({\n subject,\n policy,\n links,\n linksFailed = false,\n mint,\n describeError,\n onClose,\n onResult,\n renderLinkActions,\n now,\n clipboardWriter,\n testIDPrefix = ACCESS_ADMIN_TEST_IDS.linkPanel,\n}: AccessLinkPanelProps): React.ReactElement => {\n const { t } = useUi();\n const palette = useAccessAdminPalette();\n const styles = useMemo(() => buildStyles(palette), [palette]);\n\n const state = useCapabilityLinkMint({\n subject,\n policy,\n mint,\n describeError,\n onResult,\n t,\n now,\n clipboardWriter,\n });\n\n const expiryDate = useMemo(\n () => capabilityExpiryDate(policy, now === undefined ? new Date() : now()),\n [policy, now],\n );\n const liveLinks = useMemo(() => activeLinksForSubject(links, subject.id), [links, subject.id]);\n const mintedUrl = state.minted?.url ?? '';\n\n const handleEmail = (): void => {\n const mailto = buildCapabilityLinkMailto(\n t(ACCESS_ADMIN_I18N.emailSubject, subject.displayName),\n t(ACCESS_ADMIN_I18N.emailBody, subject.displayName, mintedUrl, expiryDate),\n mintedUrl,\n );\n if (mailto === null) return;\n // Single-arg `openURL` is the RN API contract and behaves on native as well as\n // web. react-native-web routes everything but `tel:` through\n // `window.open(url, '_blank')`, so on web this hands off to the mail client in a\n // new tab; some browsers leave an about:blank tab behind. Cosmetic.\n void Linking.openURL(mailto).catch(() => {\n onResult(t(ACCESS_ADMIN_I18N.copyFailed, subject.displayName), AccessResultTone.Error);\n });\n };\n\n return (\n <View style={styles.panel} testID={testIDPrefix}>\n <Text style={styles.heading}>{t(ACCESS_ADMIN_I18N.panelHeading, subject.displayName)}</Text>\n <Text style={styles.note}>{t(ACCESS_ADMIN_I18N.panelNote)}</Text>\n {/* Shown ALWAYS, not only after a mint: the decision to create a bearer token\n is made before the press, so the warning has to be readable before it. */}\n <Text style={styles.warning} testID={`${testIDPrefix}-capability-warning`}>\n {t(ACCESS_ADMIN_I18N.capabilityWarning)}\n </Text>\n <Text style={styles.note} testID={`${testIDPrefix}-expiry-preview`}>\n {t(ACCESS_ADMIN_I18N.expiryPreview, expiryDate)}\n </Text>\n\n {state.minted !== null ? (\n <View style={styles.revealBox} testID={`${testIDPrefix}-minted`}>\n <Text style={styles.revealTitle}>\n {t(ACCESS_ADMIN_I18N.mintedTitle, subject.displayName)}\n </Text>\n <Text style={styles.note}>{t(ACCESS_ADMIN_I18N.mintedHint)}</Text>\n <Text selectable style={styles.url} testID={`${testIDPrefix}-minted-url`}>\n {mintedUrl}\n </Text>\n <View style={styles.actions}>\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.recopyHint)}\n accessibilityLabel={state.copied ? t(ACCESS_ADMIN_I18N.copied) : t(ACCESS_ADMIN_I18N.recopy)}\n label={state.copied ? t(ACCESS_ADMIN_I18N.copied) : t(ACCESS_ADMIN_I18N.recopy)}\n onPress={state.recopy}\n testID={`${testIDPrefix}-recopy`}\n />\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.emailHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.email)}\n label={t(ACCESS_ADMIN_I18N.email)}\n onPress={handleEmail}\n testID={`${testIDPrefix}-email`}\n variant=\"secondary\"\n />\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.dismissHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.dismiss)}\n label={t(ACCESS_ADMIN_I18N.dismiss)}\n onPress={state.dismiss}\n testID={`${testIDPrefix}-dismiss`}\n variant=\"secondary\"\n />\n </View>\n <Text style={styles.note}>{t(ACCESS_ADMIN_I18N.emailNote)}</Text>\n </View>\n ) : null}\n\n {linksFailed ? (\n <Text style={styles.warning} testID={`${testIDPrefix}-load-error`}>\n {t(ACCESS_ADMIN_I18N.liveLoadError)}\n </Text>\n ) : null}\n\n {!linksFailed && liveLinks.length > 0 ? (\n <View style={styles.liveBox}>\n <Text style={styles.subheading}>\n {t(ACCESS_ADMIN_I18N.liveHeading, String(liveLinks.length))}\n </Text>\n {liveLinks.map((link) => (\n <View key={link.id} style={styles.liveRow}>\n <Text style={styles.liveMeta}>\n {t(\n ACCESS_ADMIN_I18N.liveMeta,\n formatLinkDate(link.createdAt, ''),\n formatLinkDate(link.expiresAt, t(ACCESS_ADMIN_I18N.expiresNever)),\n )}\n </Text>\n {renderLinkActions === undefined ? null : renderLinkActions(link)}\n </View>\n ))}\n </View>\n ) : null}\n\n {!linksFailed && liveLinks.length === 0 ? (\n <Text style={styles.note} testID={`${testIDPrefix}-no-live`}>\n {t(ACCESS_ADMIN_I18N.noLive)}\n </Text>\n ) : null}\n\n <View style={styles.actions}>\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.mintHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.mint)}\n disabled={state.isPending}\n label={t(ACCESS_ADMIN_I18N.mint)}\n loading={state.isPending}\n onPress={state.mint}\n testID={`${testIDPrefix}-mint`}\n />\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.closeHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.close)}\n disabled={state.isPending}\n label={t(ACCESS_ADMIN_I18N.close)}\n onPress={onClose}\n testID={`${testIDPrefix}-close`}\n variant=\"secondary\"\n />\n </View>\n </View>\n );\n};\n\n/** Builds the panel styles from the live palette (re-run when the theme changes). */\nconst buildStyles = (c: AccessAdminPalette) =>\n StyleSheet.create({\n actions: { flexDirection: 'row', flexWrap: 'wrap', gap: SPACE_SM },\n heading: { color: c.textPrimary, fontSize: FONT_MD, fontWeight: '700' },\n liveBox: { gap: SPACE_SM, marginTop: SPACE_XS },\n liveMeta: { color: c.textSecondary, fontSize: FONT_SM },\n liveRow: {\n borderTopColor: c.border,\n borderTopWidth: 1,\n gap: SPACE_XS,\n paddingTop: SPACE_SM,\n },\n note: { color: c.textSecondary, fontSize: FONT_SM },\n panel: {\n backgroundColor: c.panelSurface,\n borderColor: c.border,\n borderRadius: SPACE_SM,\n borderWidth: 1,\n gap: SPACE_XS,\n marginBottom: SPACE_LG,\n padding: SPACE_MD,\n },\n revealBox: {\n backgroundColor: c.revealSurface,\n borderColor: c.revealBorder,\n borderRadius: SPACE_SM,\n borderWidth: 1,\n gap: SPACE_XS,\n marginVertical: SPACE_SM,\n padding: SPACE_MD,\n },\n revealTitle: { color: c.revealHeading, fontSize: FONT_MD, fontWeight: '800' },\n subheading: { color: c.textPrimary, fontSize: FONT_SM, fontWeight: '700' },\n url: { color: c.textPrimary, fontSize: FONT_MD, fontWeight: '600' },\n warning: { color: c.danger, fontSize: FONT_SM, fontWeight: '600' },\n });\n","/**\n * Pure rules for the account picker.\n *\n * Logic-only so the two decisions that actually matter — what an account is\n * CALLED when the directory gives you almost nothing, and which accounts must\n * not be offered at all — are tested without a renderer.\n */\nimport type { ControlOption } from '@dloizides/ui-forms';\n\nimport type { AccessSubject, LinkableAccount } from '../types';\n\n/** True when a value is a non-blank string. */\nfunction isFilled(value: string | null | undefined): value is string {\n return typeof value === 'string' && value.trim() !== '';\n}\n\n/**\n * What to call an account: its display name, else its email, else the caller's\n * already-localized fallback.\n *\n * Directories genuinely return entries with neither — a freshly invited user who\n * has not completed a profile is the common one. Rendering those as a blank row\n * gives an unpickable option that looks like a rendering fault.\n */\nexport function accountDisplayLabel(account: LinkableAccount, unnamedLabel: string): string {\n if (isFilled(account.displayName)) return account.displayName.trim();\n if (isFilled(account.email)) return account.email.trim();\n return unnamedLabel;\n}\n\n/**\n * Build the picker's options for one subject.\n *\n * Accounts already bound to a DIFFERENT subject are dropped. That is not tidying:\n * every host that has built this backs it with a uniqueness constraint and\n * answers a duplicate binding with a 409, so offering such an account can only\n * ever produce an error the user cannot act on.\n *\n * The subject's OWN currently-bound account is KEPT, so the picker can show it as\n * the current selection instead of looking empty on a subject that is in fact\n * linked — which would read as \"not linked\" and invite a pointless re-link.\n *\n * Directory order is preserved; hosts return these sorted.\n */\nexport function buildAccountOptions(\n accounts: readonly LinkableAccount[],\n bindings: ReadonlyMap<string, string | null>,\n subject: AccessSubject,\n unnamedLabel: string,\n): ControlOption[] {\n const takenByOthers = new Set<string>();\n bindings.forEach((accountId, subjectId) => {\n if (subjectId !== subject.id && isFilled(accountId)) takenByOthers.add(accountId);\n });\n\n return accounts\n .filter((account) => !takenByOthers.has(account.userId))\n .map((account) => ({\n value: account.userId,\n label: accountDisplayLabel(account, unnamedLabel),\n }));\n}\n","/**\n * Selection state and submit orchestration for the account picker.\n *\n * Holds no JSX so the selection transitions — and, more importantly, the rules\n * about WHEN a link or unlink is allowed — are testable without a renderer.\n * Those rules are the guard rails around a destructive action: unlinking is what\n * stops a real person's work being attributed to them.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { AccessResultTone, type AccessResultReporter } from '../AccessResultTone';\nimport { ACCESS_ADMIN_I18N } from '../constants';\nimport type { AccessTranslate } from '../links/useCapabilityLinkMint';\nimport type { AccessSubject, DescribeError, LinkSubjectAccount } from '../types';\n\nexport interface UseSubjectAccountLinkOptions {\n readonly subject: AccessSubject;\n /** The account currently bound to this subject, or null when it has none. */\n readonly boundAccountId: string | null;\n readonly linkAccount: LinkSubjectAccount;\n readonly describeError: DescribeError;\n readonly onResult: AccessResultReporter;\n readonly t: AccessTranslate;\n}\n\nexport interface SubjectAccountLinkState {\n /** The account chosen in the picker, or null when none is. */\n readonly selectedAccountId: string | null;\n readonly select: (accountId: string) => void;\n readonly isPending: boolean;\n /** True when the chosen account differs from the one already bound. */\n readonly canLink: boolean;\n /** True when there is a binding to remove. */\n readonly canUnlink: boolean;\n readonly link: () => void;\n readonly unlink: () => void;\n}\n\nexport function useSubjectAccountLink(\n options: UseSubjectAccountLinkOptions,\n): SubjectAccountLinkState {\n const { subject, boundAccountId, linkAccount, describeError, onResult, t } = options;\n\n const [selectedAccountId, setSelectedAccountId] = useState<string | null>(boundAccountId);\n const [isPending, setIsPending] = useState<boolean>(false);\n\n const mountedRef = useRef<boolean>(true);\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n // Re-seed when the user switches to another subject, and after a write lands (the\n // host re-renders with a refreshed binding). Without this the picker would keep\n // showing the PREVIOUS subject's selection against the new subject's name.\n useEffect(() => {\n setSelectedAccountId(boundAccountId);\n }, [subject.id, boundAccountId]);\n\n const canLink = !isPending && selectedAccountId !== null && selectedAccountId !== boundAccountId;\n const canUnlink = !isPending && boundAccountId !== null;\n\n const submit = useCallback(\n (accountId: string | null, successKey: string): void => {\n setIsPending(true);\n void (async () => {\n try {\n await linkAccount(subject, accountId);\n if (!mountedRef.current) return;\n onResult(t(successKey, subject.displayName), AccessResultTone.Success);\n } catch (error) {\n if (!mountedRef.current) return;\n onResult(describeError(error as Error), AccessResultTone.Error);\n } finally {\n if (mountedRef.current) setIsPending(false);\n }\n })();\n },\n [linkAccount, subject, onResult, t, describeError],\n );\n\n const link = useCallback((): void => {\n if (!canLink || selectedAccountId === null) return;\n submit(selectedAccountId, ACCESS_ADMIN_I18N.accountLinkSuccess);\n }, [canLink, selectedAccountId, submit]);\n\n const unlink = useCallback((): void => {\n if (!canUnlink) return;\n submit(null, ACCESS_ADMIN_I18N.accountUnlinkSuccess);\n }, [canUnlink, submit]);\n\n return { selectedAccountId, select: setSelectedAccountId, isPending, canLink, canUnlink, link, unlink };\n}\n","/**\n * The account picker for ONE subject.\n *\n * Binds a subject to the account it signs in with, or removes that binding.\n * Unlinking sits behind its own press rather than being a value in the picker,\n * because a mis-tap in a list must not be able to detach someone from their work.\n *\n * The picker is the shared `SelectControl` from `@dloizides/ui-forms` rather than\n * a local one — the fleet already grew six independent select implementations\n * before that was promoted, and this is not going to be the seventh.\n */\nimport React, { useMemo } from 'react';\n\nimport { StyleSheet, Text, View } from 'react-native';\n\nimport { Button } from '@dloizides/ui-buttons';\nimport { useUi } from '@dloizides/ui-feedback';\nimport { SelectControl } from '@dloizides/ui-forms';\n\nimport type { AccessResultReporter } from '../AccessResultTone';\nimport { buildAccountOptions } from '../accounts/accountOptions';\nimport { useSubjectAccountLink } from '../accounts/useSubjectAccountLink';\nimport { ACCESS_ADMIN_I18N, ACCESS_ADMIN_TEST_IDS } from '../constants';\nimport { useAccessAdminPalette, type AccessAdminPalette } from '../theme/useAccessAdminPalette';\nimport type { AccessSubject, DescribeError, LinkableAccount, LinkSubjectAccount } from '../types';\n\nconst SPACE_XS = 4;\nconst SPACE_SM = 8;\nconst SPACE_MD = 12;\nconst SPACE_LG = 16;\nconst FONT_SM = 12;\nconst FONT_MD = 13;\n\nexport interface AccountLinkPanelProps {\n readonly subject: AccessSubject;\n /** The account currently bound to this subject, or null. */\n readonly boundAccountId: string | null;\n /** The directory of accounts that could be bound. */\n readonly accounts: readonly LinkableAccount[];\n /**\n * Which account each subject currently holds, keyed by subject id.\n *\n * The whole map, not just this subject's: accounts already taken by ANOTHER\n * subject are hidden from the picker, because offering them can only produce a\n * uniqueness error the user cannot act on.\n */\n readonly bindings: ReadonlyMap<string, string | null>;\n readonly linkAccount: LinkSubjectAccount;\n readonly describeError: DescribeError;\n readonly onClose: () => void;\n readonly onResult: AccessResultReporter;\n /** Root testID; children derive from it. Defaults to `account-link-panel`. */\n readonly testIDPrefix?: string;\n}\n\nexport const AccountLinkPanel = ({\n subject,\n boundAccountId,\n accounts,\n bindings,\n linkAccount,\n describeError,\n onClose,\n onResult,\n testIDPrefix = ACCESS_ADMIN_TEST_IDS.accountPanel,\n}: AccountLinkPanelProps): React.ReactElement => {\n const { t } = useUi();\n const palette = useAccessAdminPalette();\n const styles = useMemo(() => buildStyles(palette), [palette]);\n\n const state = useSubjectAccountLink({\n subject,\n boundAccountId,\n linkAccount,\n describeError,\n onResult,\n t,\n });\n\n const unnamedLabel = t(ACCESS_ADMIN_I18N.accountUnnamed);\n const options = useMemo(\n () => buildAccountOptions(accounts, bindings, subject, unnamedLabel),\n [accounts, bindings, subject, unnamedLabel],\n );\n\n const selectedLabel =\n options.find((option) => option.value === state.selectedAccountId)?.label ?? '';\n\n return (\n <View style={styles.panel} testID={testIDPrefix}>\n <Text style={styles.heading}>\n {t(ACCESS_ADMIN_I18N.accountPanelHeading, subject.displayName)}\n </Text>\n <Text style={styles.note}>{t(ACCESS_ADMIN_I18N.accountPanelNote)}</Text>\n\n {options.length > 0 ? (\n <SelectControl\n // The accessible name carries the SELECTION, not just the field name —\n // \"Sign-in account: Maria K\" — because the trigger's visible text is\n // replaced by this string for a screen reader.\n accessibilityHint={t(ACCESS_ADMIN_I18N.accountPickerHint)}\n accessibilityLabel={`${t(ACCESS_ADMIN_I18N.accountPickerLabel)}: ${\n selectedLabel === '' ? t(ACCESS_ADMIN_I18N.accountPickerPlaceholder) : selectedLabel\n }`}\n onChange={state.select}\n optionHint={t(ACCESS_ADMIN_I18N.accountOptionHint)}\n options={options}\n placeholder={t(ACCESS_ADMIN_I18N.accountPickerPlaceholder)}\n testID={`${testIDPrefix}-picker`}\n value={state.selectedAccountId ?? ''}\n />\n ) : (\n <Text style={styles.note} testID={`${testIDPrefix}-no-accounts`}>\n {t(ACCESS_ADMIN_I18N.accountNone)}\n </Text>\n )}\n\n <View style={styles.actions}>\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.accountLinkHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.accountLink)}\n disabled={!state.canLink}\n label={t(ACCESS_ADMIN_I18N.accountLink)}\n loading={state.isPending}\n onPress={state.link}\n testID={`${testIDPrefix}-link`}\n />\n {state.canUnlink ? (\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.accountUnlinkHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.accountUnlink)}\n disabled={state.isPending}\n label={t(ACCESS_ADMIN_I18N.accountUnlink)}\n onPress={state.unlink}\n testID={`${testIDPrefix}-unlink`}\n variant=\"danger\"\n />\n ) : null}\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.accountCloseHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.accountClose)}\n disabled={state.isPending}\n label={t(ACCESS_ADMIN_I18N.accountClose)}\n onPress={onClose}\n testID={`${testIDPrefix}-close`}\n variant=\"secondary\"\n />\n </View>\n </View>\n );\n};\n\n/** Builds the panel styles from the live palette (re-run when the theme changes). */\nconst buildStyles = (c: AccessAdminPalette) =>\n StyleSheet.create({\n actions: { flexDirection: 'row', flexWrap: 'wrap', gap: SPACE_SM },\n heading: { color: c.textPrimary, fontSize: FONT_MD, fontWeight: '700' },\n note: { color: c.textSecondary, fontSize: FONT_SM },\n panel: {\n backgroundColor: c.panelSurface,\n borderColor: c.border,\n borderRadius: SPACE_SM,\n borderWidth: 1,\n gap: SPACE_XS,\n marginBottom: SPACE_LG,\n padding: SPACE_MD,\n },\n });\n","/**\n * Pure presentation + selection helpers for {@link UserManagementPanel}.\n *\n * Kept out of the component so the \"what does an empty tenant read as\", \"which\n * users match this search\" decisions are unit-testable without a DOM, the way the\n * package already isolates `capabilityLinkHelpers` and `accountOptions`.\n */\nimport { ACCESS_ADMIN_I18N } from '../constants';\nimport type {\n UserManagementPatch,\n UserManagementTenant,\n UserManagementTranslate,\n UserManagementUser,\n} from './userManagementTypes';\n\nconst ROLE_SEPARATOR = ', ';\n/** Sentinel value the tenant picker uses for \"no tenant / platform-level\". */\nexport const NO_TENANT_VALUE = '';\n\n/** Roles joined for the cell, or the host's \"no roles\" string when empty. */\nexport function rolesLabel(roles: readonly string[], t: UserManagementTranslate): string {\n return roles.length > 0 ? roles.join(ROLE_SEPARATOR) : t(ACCESS_ADMIN_I18N.usersNoRoles);\n}\n\n/**\n * The tenant cell: the tenant's own label when it can be resolved, the host's\n * \"no tenant\" string when the user is platform-level, and the raw id as a last\n * resort so an unknown tenant is never rendered as blank.\n */\nexport function tenantLabel(\n tenantId: string | null,\n tenants: readonly UserManagementTenant[],\n t: UserManagementTranslate,\n): string {\n if (tenantId === null) return t(ACCESS_ADMIN_I18N.usersTenantNone);\n const match = tenants.find((tenant) => tenant.id === tenantId);\n return match !== undefined ? match.label : tenantId;\n}\n\n/** Active flag as a word. */\nexport function activeLabel(active: boolean, t: UserManagementTranslate): string {\n return active ? t(ACCESS_ADMIN_I18N.usersActiveYes) : t(ACCESS_ADMIN_I18N.usersActiveNo);\n}\n\n/** Created timestamp as `YYYY-MM-DD`, or the host's \"unknown\" string. */\nexport function createdLabel(createdAt: string | undefined, t: UserManagementTranslate): string {\n if (createdAt === undefined || createdAt === '') return t(ACCESS_ADMIN_I18N.usersCreatedUnknown);\n const parsed = new Date(createdAt);\n if (Number.isNaN(parsed.getTime())) return t(ACCESS_ADMIN_I18N.usersCreatedUnknown);\n return parsed.toISOString().slice(0, 'YYYY-MM-DD'.length);\n}\n\n/**\n * Filter users by a free-text query across email, display name and roles.\n *\n * Case-insensitive; an empty/whitespace query returns every user. Matching in the\n * package (not just the host's endpoint) keeps the search responsive on an\n * already-loaded page without a round trip.\n */\nexport function filterUsers(\n users: readonly UserManagementUser[],\n query: string,\n): readonly UserManagementUser[] {\n const needle = query.trim().toLowerCase();\n if (needle === '') return users;\n return users.filter((user) => {\n const haystack = `${user.email} ${user.displayName} ${user.roles.join(' ')}`.toLowerCase();\n return haystack.includes(needle);\n });\n}\n\n/**\n * Tenant picker options for a platform admin: a leading \"no tenant\" option (value\n * {@link NO_TENANT_VALUE}) followed by every tenant. The empty-string sentinel maps\n * back to a `null` tenantId at submit time.\n */\nexport function tenantOptions(\n tenants: readonly UserManagementTenant[],\n t: UserManagementTranslate,\n): ReadonlyArray<{ label: string; value: string }> {\n const platform = { label: t(ACCESS_ADMIN_I18N.usersTenantNone), value: NO_TENANT_VALUE };\n return [platform, ...tenants.map((tenant) => ({ label: tenant.label, value: tenant.id }))];\n}\n\n/** Role picker options — only the caller-allowed roles, never anything else. */\nexport function roleOptions(\n assignableRoles: readonly string[],\n): ReadonlyArray<{ label: string; value: string }> {\n return assignableRoles.map((role) => ({ label: role, value: role }));\n}\n\n/** Turn a picker's string tenant value back into the API's `string | null`. */\nexport function tenantValueToId(value: string): string | null {\n return value === NO_TENANT_VALUE ? null : value;\n}\n\nexport interface EditPatchInput {\n readonly displayName: string;\n readonly role: string;\n readonly wasActive: boolean;\n readonly active: boolean;\n readonly blockedReason: string;\n readonly tenantId: string | null | undefined;\n}\n\nexport function isBlocking(wasActive: boolean, active: boolean): boolean {\n return wasActive && !active;\n}\n\nexport function isBlockReasonMissing(wasActive: boolean, active: boolean, blockedReason: string): boolean {\n return isBlocking(wasActive, active) && blockedReason.trim() === '';\n}\n\nexport function buildEditPatch(input: EditPatchInput): UserManagementPatch {\n const patch: UserManagementPatch = { displayName: input.displayName.trim(), role: input.role, active: input.active };\n if (isBlocking(input.wasActive, input.active)) patch.blockedReason = input.blockedReason.trim();\n if (input.tenantId !== undefined) patch.tenantId = input.tenantId;\n return patch;\n}\n","/**\n * The user table's columns, including the per-row Edit / Reset-password actions.\n *\n * A builder (not a constant) because the cells close over the host's `t`, the\n * tenant labels, and the row callbacks. Kept beside the panel so the component body\n * stays about wiring, not cell rendering.\n */\nimport { View } from 'react-native';\n\nimport { Button } from '@dloizides/ui-buttons';\nimport type { DataTableColumn } from '@dloizides/ui-tables';\n\nimport { ACCESS_ADMIN_I18N } from '../constants';\nimport { activeLabel, createdLabel, rolesLabel, tenantLabel } from './userManagementFormat';\nimport type {\n UserManagementTenant,\n UserManagementTranslate,\n UserManagementUser,\n} from './userManagementTypes';\n\nconst ACTIONS_GAP = 8;\n\nexport interface UserColumnDeps {\n readonly t: UserManagementTranslate;\n readonly tenants: readonly UserManagementTenant[];\n readonly testIDPrefix: string;\n readonly onEdit: (user: UserManagementUser) => void;\n readonly onReset?: (user: UserManagementUser) => void;\n}\n\nexport function buildUserColumns({\n t,\n tenants,\n testIDPrefix,\n onEdit,\n onReset,\n}: UserColumnDeps): ReadonlyArray<DataTableColumn<UserManagementUser>> {\n return [\n {\n key: 'email',\n header: t(ACCESS_ADMIN_I18N.usersColEmail),\n render: (user) => user.email,\n },\n {\n key: 'displayName',\n header: t(ACCESS_ADMIN_I18N.usersColDisplayName),\n render: (user) => user.displayName,\n },\n {\n key: 'roles',\n header: t(ACCESS_ADMIN_I18N.usersColRoles),\n render: (user) => rolesLabel(user.roles, t),\n },\n {\n key: 'tenant',\n header: t(ACCESS_ADMIN_I18N.usersColTenant),\n render: (user) => tenantLabel(user.tenantId, tenants, t),\n },\n {\n key: 'active',\n header: t(ACCESS_ADMIN_I18N.usersColActive),\n render: (user) => activeLabel(user.active, t),\n },\n {\n key: 'created',\n header: t(ACCESS_ADMIN_I18N.usersColCreated),\n render: (user) => createdLabel(user.createdAt, t),\n },\n {\n key: 'actions',\n header: t(ACCESS_ADMIN_I18N.usersColActions),\n render: (user) => (\n <View style={{ flexDirection: 'row', flexWrap: 'wrap', gap: ACTIONS_GAP }}>\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.usersEditHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.usersEdit)}\n label={t(ACCESS_ADMIN_I18N.usersEdit)}\n onPress={() => onEdit(user)}\n size=\"sm\"\n testID={`${testIDPrefix}-edit-${user.id}`}\n variant=\"secondary\"\n />\n {onReset !== undefined ? (\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.usersResetHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.usersReset)}\n label={t(ACCESS_ADMIN_I18N.usersReset)}\n onPress={() => onReset(user)}\n size=\"sm\"\n testID={`${testIDPrefix}-reset-${user.id}`}\n variant=\"secondary\"\n />\n ) : null}\n </View>\n ),\n },\n ];\n}\n","/**\n * A labelled dropdown field — the role picker and the tenant picker are the same\n * shape, so they share this rather than each re-wiring `Field` + `ModalDropdown`.\n *\n * The dropdown is `@dloizides/ui-layout`'s `ModalDropdown`, forced to the `Modal`\n * variant. This picker ALWAYS lives inside a `ModalShell` (the create / edit user\n * modals), and the responsive default would pick the INLINE menu on desktop web —\n * which `createPortal`s to `document.body`, OUTSIDE the ModalShell's RN-`Modal`\n * layer. Inside a focus-trapping modal that popover renders behind the shell and is\n * dismissed the instant it opens, so the trigger appears to \"do nothing\" (its\n * `aria-expanded` flips straight back to false). The `Modal` variant instead renders\n * the options in their OWN RN-`Modal` layer, which stacks ABOVE the ModalShell and\n * is fully visible + tappable. Its accessible name carries the SELECTION, not just\n * the field name (\"Role: editor\"), because the trigger's visible text is replaced by\n * that string for a screen reader.\n */\nimport React from 'react';\n\nimport { DropdownVariant, ModalDropdown } from '@dloizides/ui-layout';\nimport { Field } from '@dloizides/ui-forms';\n\nexport interface PickerOption {\n readonly label: string;\n readonly value: string;\n}\n\nexport interface PickerFieldProps {\n readonly testID: string;\n /** Visible + accessible field label (e.g. \"Role\"). */\n readonly label: string;\n readonly hint: string;\n /** Shown in the accessible name while nothing is selected. */\n readonly placeholder: string;\n readonly value: string;\n readonly options: readonly PickerOption[];\n readonly onChange: (value: string) => void;\n}\n\nexport const PickerField = ({\n testID,\n label,\n hint,\n placeholder,\n value,\n options,\n onChange,\n}: PickerFieldProps): React.ReactElement => {\n const selected = options.find((option) => option.value === value);\n const selectionLabel = selected !== undefined ? selected.label : placeholder;\n\n return (\n <Field label={label}>\n <ModalDropdown\n accessibilityHint={hint}\n accessibilityLabel={`${label}: ${selectionLabel}`}\n onChange={onChange}\n options={options}\n testID={testID}\n value={value}\n variant={DropdownVariant.Modal}\n />\n </Field>\n );\n};\n","/**\n * Layout-only styles shared by the panel's modals. No colours here on purpose —\n * every field/button the modals render carries its own themed colours from the kit,\n * so these hold nothing the `no-raw-color-literal` gate could catch.\n */\nimport { StyleSheet } from 'react-native';\n\nconst SPACE_SM = 8;\nconst SPACE_MD = 12;\n\nexport const modalFormStyles = StyleSheet.create({\n actions: { flexDirection: 'row', flexWrap: 'wrap', gap: SPACE_SM, marginTop: SPACE_SM },\n body: { gap: SPACE_MD, padding: SPACE_MD },\n});\n","/**\n * Create-user modal.\n *\n * The tenant picker is shown ONLY to a platform admin. A tenant admin creates into\n * their own tenant, so they are never offered a tenant control — the panel submits\n * `tenantId: null` and the backend resolves it. The role picker offers only the\n * caller-allowed `assignableRoles`, never anything else.\n */\nimport React, { useEffect, useState } from 'react';\n\nimport { View } from 'react-native';\n\nimport { Button } from '@dloizides/ui-buttons';\nimport { FormField } from '@dloizides/ui-forms';\nimport { ModalShell } from '@dloizides/ui-layout';\n\nimport { ACCESS_ADMIN_I18N } from '../constants';\nimport { PickerField } from './PickerField';\nimport { modalFormStyles } from './userManagementStyles';\nimport {\n NO_TENANT_VALUE,\n roleOptions,\n tenantOptions,\n tenantValueToId,\n} from './userManagementFormat';\nimport type {\n UserManagementTenant,\n UserManagementTranslate,\n} from './userManagementTypes';\n\nexport interface CreateUserModalProps {\n readonly visible: boolean;\n readonly isPlatformAdmin: boolean;\n readonly assignableRoles: readonly string[];\n readonly tenants: readonly UserManagementTenant[];\n readonly t: UserManagementTranslate;\n readonly testIDPrefix: string;\n readonly onSubmit: (input: {\n email: string;\n password: string;\n displayName: string;\n role: string;\n tenantId: string | null;\n }) => Promise<boolean>;\n readonly onCancel: () => void;\n}\n\nexport const CreateUserModal = ({\n visible,\n isPlatformAdmin,\n assignableRoles,\n tenants,\n t,\n testIDPrefix,\n onSubmit,\n onCancel,\n}: CreateUserModalProps): React.ReactElement => {\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [displayName, setDisplayName] = useState('');\n const [role, setRole] = useState('');\n const [tenantValue, setTenantValue] = useState(NO_TENANT_VALUE);\n const [submitting, setSubmitting] = useState(false);\n\n // Reset the form each time the modal is opened, so a cancelled draft never\n // reappears in the next create.\n useEffect(() => {\n if (!visible) return;\n setEmail('');\n setPassword('');\n setDisplayName('');\n setRole('');\n setTenantValue(NO_TENANT_VALUE);\n setSubmitting(false);\n }, [visible]);\n\n const canSubmit =\n !submitting &&\n email.trim() !== '' &&\n password !== '' &&\n displayName.trim() !== '' &&\n role !== '';\n\n const handleSubmit = async (): Promise<void> => {\n setSubmitting(true);\n const tenantId = isPlatformAdmin ? tenantValueToId(tenantValue) : null;\n const ok = await onSubmit({ email: email.trim(), password, displayName: displayName.trim(), role, tenantId });\n setSubmitting(false);\n if (ok) onCancel();\n };\n\n return (\n <ModalShell onCancel={onCancel} title={t(ACCESS_ADMIN_I18N.usersCreateTitle)} visible={visible}>\n <View style={modalFormStyles.body} testID={testIDPrefix}>\n <FormField\n autoCapitalize=\"none\"\n keyboardType=\"email-address\"\n label={t(ACCESS_ADMIN_I18N.usersFieldEmail)}\n onChangeText={setEmail}\n placeholder={t(ACCESS_ADMIN_I18N.usersEmailPlaceholder)}\n required\n testID={`${testIDPrefix}-email`}\n value={email}\n />\n <FormField\n label={t(ACCESS_ADMIN_I18N.usersFieldPassword)}\n onChangeText={setPassword}\n placeholder={t(ACCESS_ADMIN_I18N.usersPasswordPlaceholder)}\n required\n secureTextEntry\n testID={`${testIDPrefix}-password`}\n value={password}\n />\n <FormField\n label={t(ACCESS_ADMIN_I18N.usersFieldDisplayName)}\n onChangeText={setDisplayName}\n placeholder={t(ACCESS_ADMIN_I18N.usersDisplayNamePlaceholder)}\n required\n testID={`${testIDPrefix}-display-name`}\n value={displayName}\n />\n <PickerField\n hint={t(ACCESS_ADMIN_I18N.usersRolePickerHint)}\n label={t(ACCESS_ADMIN_I18N.usersFieldRole)}\n onChange={setRole}\n options={roleOptions(assignableRoles)}\n placeholder={t(ACCESS_ADMIN_I18N.usersRolePlaceholder)}\n testID={`${testIDPrefix}-role`}\n value={role}\n />\n {isPlatformAdmin ? (\n <PickerField\n hint={t(ACCESS_ADMIN_I18N.usersTenantPickerHint)}\n label={t(ACCESS_ADMIN_I18N.usersFieldTenant)}\n onChange={setTenantValue}\n options={tenantOptions(tenants, t)}\n placeholder={t(ACCESS_ADMIN_I18N.usersTenantPlaceholder)}\n testID={`${testIDPrefix}-tenant`}\n value={tenantValue}\n />\n ) : null}\n <View style={modalFormStyles.actions}>\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.usersSubmitCreateHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.usersSubmitCreate)}\n disabled={!canSubmit}\n label={t(ACCESS_ADMIN_I18N.usersSubmitCreate)}\n loading={submitting}\n onPress={handleSubmit}\n testID={`${testIDPrefix}-submit`}\n />\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.usersCancelHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.usersCancel)}\n disabled={submitting}\n label={t(ACCESS_ADMIN_I18N.usersCancel)}\n onPress={onCancel}\n testID={`${testIDPrefix}-cancel`}\n variant=\"secondary\"\n />\n </View>\n </View>\n </ModalShell>\n );\n};\n","/**\n * Edit-user modal — role, tenant (platform admin only), active toggle, display name.\n *\n * Seeded from the row being edited and reset whenever a different row opens it, so\n * one user's values never bleed into the next. Like create, the tenant control is\n * withheld from a tenant admin, and the role picker offers only `assignableRoles`.\n */\nimport React, { useEffect, useState } from 'react';\n\nimport { View } from 'react-native';\n\nimport { Button } from '@dloizides/ui-buttons';\nimport { FormField, FormSwitch } from '@dloizides/ui-forms';\nimport { ModalShell } from '@dloizides/ui-layout';\n\nimport { ACCESS_ADMIN_I18N } from '../constants';\nimport { PickerField } from './PickerField';\nimport { modalFormStyles } from './userManagementStyles';\nimport {\n buildEditPatch,\n isBlockReasonMissing,\n NO_TENANT_VALUE,\n roleOptions,\n tenantOptions,\n tenantValueToId,\n} from './userManagementFormat';\nimport type {\n UserManagementPatch,\n UserManagementTenant,\n UserManagementTranslate,\n UserManagementUser,\n} from './userManagementTypes';\n\nexport interface EditUserModalProps {\n readonly visible: boolean;\n /** The row being edited, or null while the modal is closed. */\n readonly user: UserManagementUser | null;\n readonly isPlatformAdmin: boolean;\n readonly assignableRoles: readonly string[];\n readonly tenants: readonly UserManagementTenant[];\n readonly t: UserManagementTranslate;\n readonly testIDPrefix: string;\n readonly onSubmit: (\n id: string,\n patch: UserManagementPatch,\n ) => Promise<boolean>;\n readonly onCancel: () => void;\n}\n\nexport const EditUserModal = ({\n visible,\n user,\n isPlatformAdmin,\n assignableRoles,\n tenants,\n t,\n testIDPrefix,\n onSubmit,\n onCancel,\n}: EditUserModalProps): React.ReactElement => {\n const [displayName, setDisplayName] = useState('');\n const [role, setRole] = useState('');\n const [tenantValue, setTenantValue] = useState(NO_TENANT_VALUE);\n const [active, setActive] = useState(true);\n const [blockedReason, setBlockedReason] = useState('');\n const [submitting, setSubmitting] = useState(false);\n\n const userId = user?.id;\n useEffect(() => {\n if (!visible || user === null) return;\n setDisplayName(user.displayName);\n setRole(user.roles[0] ?? '');\n setTenantValue(user.tenantId ?? NO_TENANT_VALUE);\n setActive(user.active);\n setBlockedReason(user.blockedReason ?? '');\n setSubmitting(false);\n // Keyed on the row id, not the object, so a re-fetch that returns an equal user\n // does not stomp an in-progress edit.\n }, [visible, userId, user]);\n\n const wasActive = user?.active ?? true;\n const canSubmit =\n !submitting &&\n displayName.trim() !== '' &&\n role !== '' &&\n !isBlockReasonMissing(wasActive, active, blockedReason);\n\n const handleSubmit = async (): Promise<void> => {\n if (user === null) return;\n setSubmitting(true);\n const patch = buildEditPatch({\n displayName,\n role,\n wasActive,\n active,\n blockedReason,\n tenantId: isPlatformAdmin ? tenantValueToId(tenantValue) : undefined,\n });\n const ok = await onSubmit(user.id, patch);\n setSubmitting(false);\n if (ok) onCancel();\n };\n\n const submitIfReady = (): void => {\n if (canSubmit) void handleSubmit();\n };\n\n return (\n <ModalShell onCancel={onCancel} title={t(ACCESS_ADMIN_I18N.usersEditTitle)} visible={visible}>\n <View style={modalFormStyles.body} testID={testIDPrefix}>\n <FormField\n label={t(ACCESS_ADMIN_I18N.usersFieldDisplayName)}\n onChangeText={setDisplayName}\n onSubmitEditing={submitIfReady}\n placeholder={t(ACCESS_ADMIN_I18N.usersDisplayNamePlaceholder)}\n required\n testID={`${testIDPrefix}-display-name`}\n value={displayName}\n />\n <PickerField\n hint={t(ACCESS_ADMIN_I18N.usersRolePickerHint)}\n label={t(ACCESS_ADMIN_I18N.usersFieldRole)}\n onChange={setRole}\n options={roleOptions(assignableRoles)}\n placeholder={t(ACCESS_ADMIN_I18N.usersRolePlaceholder)}\n testID={`${testIDPrefix}-role`}\n value={role}\n />\n {isPlatformAdmin ? (\n <PickerField\n hint={t(ACCESS_ADMIN_I18N.usersTenantPickerHint)}\n label={t(ACCESS_ADMIN_I18N.usersFieldTenant)}\n onChange={setTenantValue}\n options={tenantOptions(tenants, t)}\n placeholder={t(ACCESS_ADMIN_I18N.usersTenantPlaceholder)}\n testID={`${testIDPrefix}-tenant`}\n value={tenantValue}\n />\n ) : null}\n <FormSwitch\n accessibilityHint={t(ACCESS_ADMIN_I18N.usersActiveToggleHint)}\n label={t(ACCESS_ADMIN_I18N.usersFieldActive)}\n onValueChange={setActive}\n testID={`${testIDPrefix}-active`}\n value={active}\n />\n {active ? null : (\n <FormField\n accessibilityHint={t(ACCESS_ADMIN_I18N.usersBlockedReasonHint)}\n label={t(ACCESS_ADMIN_I18N.usersFieldBlockedReason)}\n onChangeText={setBlockedReason}\n onSubmitEditing={submitIfReady}\n placeholder={t(ACCESS_ADMIN_I18N.usersBlockedReasonPlaceholder)}\n required={wasActive}\n testID={`${testIDPrefix}-blocked-reason`}\n value={blockedReason}\n />\n )}\n <View style={modalFormStyles.actions}>\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.usersSubmitSaveHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.usersSubmitSave)}\n disabled={!canSubmit}\n label={t(ACCESS_ADMIN_I18N.usersSubmitSave)}\n loading={submitting}\n onPress={handleSubmit}\n testID={`${testIDPrefix}-submit`}\n />\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.usersCancelHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.usersCancel)}\n disabled={submitting}\n label={t(ACCESS_ADMIN_I18N.usersCancel)}\n onPress={onCancel}\n testID={`${testIDPrefix}-cancel`}\n variant=\"secondary\"\n />\n </View>\n </View>\n </ModalShell>\n );\n};\n","/**\n * Reset-password modal — a single new-password field for one user.\n *\n * Scoped to the row it was opened from; the panel owns which user that is. The\n * field is cleared on every open so a password never lingers in component state\n * across two different users.\n */\nimport React, { useEffect, useState } from 'react';\n\nimport { View } from 'react-native';\n\nimport { Button } from '@dloizides/ui-buttons';\nimport { FormField } from '@dloizides/ui-forms';\nimport { ModalShell } from '@dloizides/ui-layout';\n\nimport { ACCESS_ADMIN_I18N } from '../constants';\nimport { modalFormStyles } from './userManagementStyles';\nimport type { UserManagementTranslate, UserManagementUser } from './userManagementTypes';\n\nexport interface ResetPasswordModalProps {\n readonly visible: boolean;\n readonly user: UserManagementUser | null;\n readonly t: UserManagementTranslate;\n readonly testIDPrefix: string;\n readonly onSubmit: (id: string, password: string) => Promise<boolean>;\n readonly onCancel: () => void;\n}\n\nexport const ResetPasswordModal = ({\n visible,\n user,\n t,\n testIDPrefix,\n onSubmit,\n onCancel,\n}: ResetPasswordModalProps): React.ReactElement => {\n const [password, setPassword] = useState('');\n const [submitting, setSubmitting] = useState(false);\n\n useEffect(() => {\n if (!visible) return;\n setPassword('');\n setSubmitting(false);\n }, [visible]);\n\n const canSubmit = !submitting && password !== '';\n\n const handleSubmit = async (): Promise<void> => {\n if (user === null) return;\n setSubmitting(true);\n const ok = await onSubmit(user.id, password);\n setSubmitting(false);\n if (ok) onCancel();\n };\n\n return (\n <ModalShell onCancel={onCancel} title={t(ACCESS_ADMIN_I18N.usersResetTitle)} visible={visible}>\n <View style={modalFormStyles.body} testID={testIDPrefix}>\n <FormField\n label={t(ACCESS_ADMIN_I18N.usersFieldNewPassword)}\n onChangeText={setPassword}\n placeholder={t(ACCESS_ADMIN_I18N.usersNewPasswordPlaceholder)}\n required\n secureTextEntry\n testID={`${testIDPrefix}-password`}\n value={password}\n />\n <View style={modalFormStyles.actions}>\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.usersSubmitResetHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.usersSubmitReset)}\n disabled={!canSubmit}\n label={t(ACCESS_ADMIN_I18N.usersSubmitReset)}\n loading={submitting}\n onPress={handleSubmit}\n testID={`${testIDPrefix}-submit`}\n />\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.usersCancelHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.usersCancel)}\n disabled={submitting}\n label={t(ACCESS_ADMIN_I18N.usersCancel)}\n onPress={onCancel}\n testID={`${testIDPrefix}-cancel`}\n variant=\"secondary\"\n />\n </View>\n </View>\n </ModalShell>\n );\n};\n","/**\n * The state + write orchestration behind {@link UserManagementPanel}.\n *\n * Owns the list (load / reload / loading / failed), and turns each injected write\n * into a settled outcome: on success it reloads the list and emits a success\n * toast; on rejection it emits a failure toast and reports the write did NOT land,\n * so the modal stays open with the operator's input intact. The toast pipeline is\n * `@dloizides/ui-feedback`'s own bus — the panel renders its `<ToastHost>`.\n */\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { createToastBus, type ToastBus } from '@dloizides/ui-feedback';\n\nimport { ACCESS_ADMIN_I18N } from '../constants';\nimport type {\n UserManagementApi,\n UserManagementPatch,\n UserManagementTranslate,\n UserManagementUser,\n} from './userManagementTypes';\n\nexport interface UserManagementController {\n users: readonly UserManagementUser[];\n loading: boolean;\n /** True when the LOAD failed — kept distinct from \"loaded, and there are none\". */\n loadFailed: boolean;\n reload: () => void;\n /** Each resolves `true` when the write landed, `false` when it was rejected. */\n create: (input: {\n email: string;\n password: string;\n displayName: string;\n role: string;\n tenantId: string | null;\n }) => Promise<boolean>;\n update: (\n id: string,\n patch: UserManagementPatch,\n ) => Promise<boolean>;\n resetPassword: (id: string, password: string) => Promise<boolean>;\n /** The `<ToastHost>` `subscribe` port for this panel's toasts. */\n toastSubscribe: ToastBus['subscribe'];\n}\n\nconst MISSING_CREATE = 'createUser is not provided';\nconst MISSING_RESET = 'resetPassword is not provided';\n\nexport function useUserManagement(\n api: UserManagementApi,\n t: UserManagementTranslate,\n): UserManagementController {\n const [users, setUsers] = useState<readonly UserManagementUser[]>([]);\n const [loading, setLoading] = useState(true);\n const [loadFailed, setLoadFailed] = useState(false);\n\n const bus = useMemo(() => createToastBus(), []);\n\n // Guards a resolved fetch from setting state after unmount (React 18 dev warning).\n const mountedRef = useRef(true);\n useEffect(() => {\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n const reload = useCallback((): void => {\n setLoading(true);\n setLoadFailed(false);\n void api\n .listUsers()\n .then((next) => {\n if (!mountedRef.current) return;\n setUsers(next);\n setLoading(false);\n })\n .catch(() => {\n if (!mountedRef.current) return;\n setLoadFailed(true);\n setLoading(false);\n });\n }, [api]);\n\n useEffect(() => reload(), [reload]);\n\n const runWrite = useCallback(\n async (write: () => Promise<void>, successKey: string, failureKey: string): Promise<boolean> => {\n try {\n await write();\n bus.success(t(successKey));\n reload();\n return true;\n } catch {\n bus.error(t(failureKey));\n return false;\n }\n },\n [bus, reload, t],\n );\n\n const create = useCallback<UserManagementController['create']>(\n (input) =>\n runWrite(\n () => (api.createUser ? api.createUser(input) : Promise.reject(new Error(MISSING_CREATE))),\n ACCESS_ADMIN_I18N.usersCreateSuccess,\n ACCESS_ADMIN_I18N.usersCreateFailed,\n ),\n [api, runWrite],\n );\n\n const update = useCallback<UserManagementController['update']>(\n (id, patch) =>\n runWrite(\n () => api.updateUser(id, patch),\n ACCESS_ADMIN_I18N.usersUpdateSuccess,\n ACCESS_ADMIN_I18N.usersUpdateFailed,\n ),\n [api, runWrite],\n );\n\n const resetPassword = useCallback<UserManagementController['resetPassword']>(\n (id, password) =>\n runWrite(\n () =>\n api.resetPassword ? api.resetPassword(id, password) : Promise.reject(new Error(MISSING_RESET)),\n ACCESS_ADMIN_I18N.usersResetSuccess,\n ACCESS_ADMIN_I18N.usersResetFailed,\n ),\n [api, runWrite],\n );\n\n return {\n users,\n loading,\n loadFailed,\n reload,\n create,\n update,\n resetPassword,\n toastSubscribe: bus.subscribe,\n };\n}\n","/**\n * UserManagementPanel — the brand-agnostic, cross-portal in-app user administration\n * surface: a users table plus create / edit / reset-password flows, wired to the\n * host's API by injection.\n *\n * ── WHAT THE HOST OWNS ────────────────────────────────────────────────────────\n * The four writes (`api`), the scope (`isPlatformAdmin`, `assignableRoles`,\n * `tenants`) and the words (`t`). Everything else — the table, the modals, the\n * search, the loading / empty / error states and the success / failure toasts — is\n * the package's. Colours come from the host's `UiProvider` theme.\n *\n * ── SCOPE IS ENFORCED IN TWO PLACES ───────────────────────────────────────────\n * This panel is the UI half. It never OFFERS a role outside `assignableRoles` and\n * never shows a tenant control to a non-platform admin, so a tenant admin is not\n * handed a lever they cannot pull. The backend still authorizes every write — the\n * hidden control is a guardrail, not the gate.\n */\nimport React, { useMemo, useState } from 'react';\n\nimport { StyleSheet, Text, View } from 'react-native';\n\nimport { Button } from '@dloizides/ui-buttons';\nimport { ToastHost } from '@dloizides/ui-feedback';\nimport { DataTable, FilterBar } from '@dloizides/ui-tables';\nimport { FormField } from '@dloizides/ui-forms';\n\nimport { ACCESS_ADMIN_I18N, ACCESS_ADMIN_TEST_IDS } from '../constants';\nimport { useAccessAdminPalette, type AccessAdminPalette } from '../theme/useAccessAdminPalette';\nimport { buildUserColumns } from './buildUserColumns';\nimport { CreateUserModal } from './CreateUserModal';\nimport { EditUserModal } from './EditUserModal';\nimport { ResetPasswordModal } from './ResetPasswordModal';\nimport { filterUsers } from './userManagementFormat';\nimport { useUserManagement } from './useUserManagement';\nimport type { UserManagementPanelProps, UserManagementUser } from './userManagementTypes';\n\nconst SPACE_XS = 4;\nconst SPACE_SM = 8;\nconst SPACE_MD = 12;\nconst FONT_SM = 12;\nconst FONT_MD = 13;\nconst SEARCH_MIN_WIDTH = 220;\n\nconst enum OpenModal {\n None = 'none',\n Create = 'create',\n Edit = 'edit',\n Reset = 'reset',\n}\n\nexport const UserManagementPanel = ({\n api,\n isPlatformAdmin,\n assignableRoles,\n tenants = [],\n t,\n testID = ACCESS_ADMIN_TEST_IDS.usersPanel,\n}: UserManagementPanelProps): React.ReactElement => {\n const palette = useAccessAdminPalette();\n const styles = useMemo(() => buildStyles(palette), [palette]);\n\n const controller = useUserManagement(api, t);\n const [query, setQuery] = useState('');\n const [openModal, setOpenModal] = useState<OpenModal>(OpenModal.None);\n const [activeUser, setActiveUser] = useState<UserManagementUser | null>(null);\n\n const visibleUsers = useMemo(\n () => filterUsers(controller.users, query),\n [controller.users, query],\n );\n\n const openEdit = (user: UserManagementUser): void => {\n setActiveUser(user);\n setOpenModal(OpenModal.Edit);\n };\n const openReset = (user: UserManagementUser): void => {\n setActiveUser(user);\n setOpenModal(OpenModal.Reset);\n };\n const closeModal = (): void => setOpenModal(OpenModal.None);\n const canCreate = api.createUser !== undefined;\n const canReset = api.resetPassword !== undefined;\n\n const columns = useMemo(\n () =>\n buildUserColumns({\n t,\n tenants,\n testIDPrefix: testID,\n onEdit: openEdit,\n onReset: canReset ? openReset : undefined,\n }),\n [t, tenants, testID, canReset],\n );\n\n return (\n <View style={styles.panel} testID={testID}>\n <ToastHost subscribe={controller.toastSubscribe} toastTestID={`${testID}-toast`} />\n\n <Text style={styles.heading}>{t(ACCESS_ADMIN_I18N.usersHeading)}</Text>\n <Text style={styles.note}>{t(ACCESS_ADMIN_I18N.usersNote)}</Text>\n\n <FilterBar\n actions={\n canCreate ? (\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.usersCreateHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.usersCreate)}\n label={t(ACCESS_ADMIN_I18N.usersCreate)}\n onPress={() => setOpenModal(OpenModal.Create)}\n testID={`${testID}-create`}\n />\n ) : undefined\n }\n resultsCount={visibleUsers.length}\n resultsLabel={t(ACCESS_ADMIN_I18N.usersResultsLabel)}\n testID={`${testID}-filter-bar`}\n >\n <View style={styles.search}>\n <FormField\n accessibilityLabel={t(ACCESS_ADMIN_I18N.usersSearchLabel)}\n accessibilityHint={t(ACCESS_ADMIN_I18N.usersSearchHint)}\n autoCapitalize=\"none\"\n label={t(ACCESS_ADMIN_I18N.usersSearchLabel)}\n onChangeText={setQuery}\n placeholder={t(ACCESS_ADMIN_I18N.usersSearchPlaceholder)}\n testID={`${testID}-search`}\n value={query}\n />\n </View>\n </FilterBar>\n\n {controller.loadFailed ? (\n <View style={styles.errorBox} testID={`${testID}-load-error`}>\n <Text style={styles.warning}>{t(ACCESS_ADMIN_I18N.usersLoadError)}</Text>\n <Button\n accessibilityHint={t(ACCESS_ADMIN_I18N.usersRetryHint)}\n accessibilityLabel={t(ACCESS_ADMIN_I18N.usersRetry)}\n label={t(ACCESS_ADMIN_I18N.usersRetry)}\n onPress={controller.reload}\n testID={`${testID}-retry`}\n variant=\"secondary\"\n />\n </View>\n ) : (\n <DataTable\n columns={columns}\n emptyLabel={t(ACCESS_ADMIN_I18N.usersEmpty)}\n keyExtractor={(user) => user.id}\n loading={controller.loading}\n loadingLabel={t(ACCESS_ADMIN_I18N.usersLoading)}\n rows={visibleUsers}\n testID={`${testID}-table`}\n zebra\n />\n )}\n\n {canCreate ? (\n <CreateUserModal\n assignableRoles={assignableRoles}\n isPlatformAdmin={isPlatformAdmin}\n onCancel={closeModal}\n onSubmit={controller.create}\n t={t}\n tenants={tenants}\n testIDPrefix={`${testID}-create-modal`}\n visible={openModal === OpenModal.Create}\n />\n ) : null}\n <EditUserModal\n assignableRoles={assignableRoles}\n isPlatformAdmin={isPlatformAdmin}\n onCancel={closeModal}\n onSubmit={controller.update}\n t={t}\n tenants={tenants}\n testIDPrefix={`${testID}-edit-modal`}\n user={activeUser}\n visible={openModal === OpenModal.Edit}\n />\n {canReset ? (\n <ResetPasswordModal\n onCancel={closeModal}\n onSubmit={controller.resetPassword}\n t={t}\n testIDPrefix={`${testID}-reset-modal`}\n user={activeUser}\n visible={openModal === OpenModal.Reset}\n />\n ) : null}\n </View>\n );\n};\n\n/** Builds the panel styles from the live palette (re-run when the theme changes). */\nconst buildStyles = (c: AccessAdminPalette) =>\n StyleSheet.create({\n errorBox: {\n backgroundColor: c.panelSurface,\n borderColor: c.border,\n borderRadius: SPACE_SM,\n borderWidth: 1,\n gap: SPACE_SM,\n marginTop: SPACE_SM,\n padding: SPACE_MD,\n },\n heading: { color: c.textPrimary, fontSize: FONT_MD, fontWeight: '700' },\n note: { color: c.textSecondary, fontSize: FONT_SM },\n panel: { gap: SPACE_XS },\n search: { minWidth: SEARCH_MIN_WIDTH },\n warning: { color: c.danger, fontSize: FONT_SM, fontWeight: '600' },\n });\n","import { ACCESS_ADMIN_I18N } from '../constants';\nimport type {\n PermissionMatrixColumn,\n PermissionMatrixGrants,\n PermissionMatrixPermission,\n PermissionMatrixRole,\n PermissionMatrixTranslate,\n} from './permissionMatrixTypes';\n\nexport function buildPermissionMatrix(\n roles: readonly PermissionMatrixRole[],\n permissions: readonly PermissionMatrixPermission[],\n grants: PermissionMatrixGrants,\n): PermissionMatrixColumn[] {\n return roles.map((role) => {\n const held = new Set(grants[role.id] ?? []);\n const cells = permissions.map((permission) => ({ permission, granted: held.has(permission.id) }));\n return { role, cells, grantedCount: cells.filter((cell) => cell.granted).length };\n });\n}\n\nexport function grantStatusLabel(granted: boolean, t: PermissionMatrixTranslate): string {\n return granted ? t(ACCESS_ADMIN_I18N.permissionsGranted) : t(ACCESS_ADMIN_I18N.permissionsNotGranted);\n}\n\nexport function cellAccessibilityLabel(\n role: PermissionMatrixRole,\n permission: PermissionMatrixPermission,\n granted: boolean,\n t: PermissionMatrixTranslate,\n): string {\n return t(ACCESS_ADMIN_I18N.permissionsCellLabel, role.label, permission.label, grantStatusLabel(granted, t));\n}\n","import React, { useMemo } from 'react';\n\nimport { ScrollView, StyleSheet, Text, useWindowDimensions, View } from 'react-native';\n\nimport { LAYOUT_COLLAPSE_BREAKPOINT } from '@dloizides/ui-layout';\n\nimport { ACCESS_ADMIN_I18N, ACCESS_ADMIN_TEST_IDS } from '../constants';\nimport { useAccessAdminPalette, type AccessAdminPalette } from '../theme/useAccessAdminPalette';\nimport { buildPermissionMatrix, cellAccessibilityLabel, grantStatusLabel } from './permissionMatrixModel';\nimport type {\n PermissionMatrixColumn,\n PermissionMatrixPermission,\n PermissionMatrixProps,\n PermissionMatrixTranslate,\n} from './permissionMatrixTypes';\n\nconst SPACE_XS = 4;\nconst SPACE_SM = 8;\nconst SPACE_MD = 12;\nconst RADIUS = 8;\nconst MAX_WIDTH = 1200;\nconst LABEL_COLUMN_WIDTH = 280;\nconst ROLE_COLUMN_WIDTH = 140;\nconst HEADING_SIZE = 18;\nconst BODY_SIZE = 14;\nconst LINE_HEIGHT = 20;\n\nconst styles = StyleSheet.create({\n root: { alignSelf: 'center', gap: SPACE_MD, maxWidth: MAX_WIDTH, width: '100%' },\n heading: { fontSize: HEADING_SIZE, fontWeight: '600', lineHeight: LINE_HEIGHT + SPACE_XS },\n body: { fontSize: BODY_SIZE, lineHeight: LINE_HEIGHT },\n strong: { fontSize: BODY_SIZE, fontWeight: '600', lineHeight: LINE_HEIGHT },\n list: { gap: SPACE_MD },\n card: { borderRadius: RADIUS, borderWidth: StyleSheet.hairlineWidth, gap: SPACE_SM, padding: SPACE_MD },\n stackRow: { flexDirection: 'row', flexWrap: 'wrap', gap: SPACE_SM, justifyContent: 'space-between' },\n stackLabel: { flexBasis: 0, flexGrow: 1, minWidth: 0 },\n tableRow: { borderBottomWidth: StyleSheet.hairlineWidth, flexDirection: 'row' },\n labelCell: { padding: SPACE_SM, width: LABEL_COLUMN_WIDTH },\n roleCell: { padding: SPACE_SM, width: ROLE_COLUMN_WIDTH },\n});\n\ninterface PartProps {\n readonly columns: readonly PermissionMatrixColumn[];\n readonly permissions: readonly PermissionMatrixPermission[];\n readonly palette: AccessAdminPalette;\n readonly t: PermissionMatrixTranslate;\n readonly testID: string;\n}\n\nconst statusColor = (granted: boolean, palette: AccessAdminPalette): string =>\n granted ? palette.textPrimary : palette.textSecondary;\n\nconst StackedMatrix = ({ columns, palette, t, testID }: PartProps): React.ReactElement => (\n <View style={styles.list}>\n {columns.map(({ role, cells, grantedCount }) => (\n <View\n key={role.id}\n style={[styles.card, { backgroundColor: palette.panelSurface, borderColor: palette.border }]}\n testID={`${testID}-role-${role.id}`}\n >\n <Text style={[styles.strong, { color: palette.textPrimary }]}>{role.label}</Text>\n <Text style={[styles.body, { color: palette.textSecondary }]}>\n {t(ACCESS_ADMIN_I18N.permissionsRoleCount, String(grantedCount), String(cells.length))}\n </Text>\n {cells.map(({ permission, granted }) => (\n <View\n accessibilityHint={t(ACCESS_ADMIN_I18N.permissionsReadOnlyHint)}\n accessibilityLabel={cellAccessibilityLabel(role, permission, granted, t)}\n accessible\n key={permission.id}\n style={styles.stackRow}\n testID={`${testID}-cell-${role.id}-${permission.id}`}\n >\n <Text style={[styles.body, styles.stackLabel, { color: palette.textPrimary }]}>{permission.label}</Text>\n <Text style={[granted ? styles.strong : styles.body, { color: statusColor(granted, palette) }]}>\n {grantStatusLabel(granted, t)}\n </Text>\n </View>\n ))}\n </View>\n ))}\n </View>\n);\n\nconst TableMatrix = ({ columns, permissions, palette, t, testID }: PartProps): React.ReactElement => (\n <ScrollView horizontal testID={`${testID}-table`}>\n <View style={[styles.card, { backgroundColor: palette.panelSurface, borderColor: palette.border }]}>\n <View style={[styles.tableRow, { borderColor: palette.border }]}>\n <Text style={[styles.strong, styles.labelCell, { color: palette.textPrimary }]}>\n {t(ACCESS_ADMIN_I18N.permissionsColPermission)}\n </Text>\n {columns.map(({ role }) => (\n <Text key={role.id} style={[styles.strong, styles.roleCell, { color: palette.textPrimary }]}>\n {role.label}\n </Text>\n ))}\n </View>\n {permissions.map((permission, index) => (\n <View key={permission.id} style={[styles.tableRow, { borderColor: palette.border }]}>\n <Text style={[styles.body, styles.labelCell, { color: palette.textPrimary }]}>{permission.label}</Text>\n {columns.map(({ role, cells }) => {\n const granted = cells[index]?.granted === true;\n return (\n <Text\n accessibilityHint={t(ACCESS_ADMIN_I18N.permissionsReadOnlyHint)}\n accessibilityLabel={cellAccessibilityLabel(role, permission, granted, t)}\n key={role.id}\n style={[granted ? styles.strong : styles.body, styles.roleCell, { color: statusColor(granted, palette) }]}\n testID={`${testID}-cell-${role.id}-${permission.id}`}\n >\n {grantStatusLabel(granted, t)}\n </Text>\n );\n })}\n </View>\n ))}\n </View>\n </ScrollView>\n);\n\nexport const PermissionMatrix = ({\n roles,\n permissions,\n grants,\n t,\n testID = ACCESS_ADMIN_TEST_IDS.permissionMatrix,\n}: PermissionMatrixProps): React.ReactElement => {\n const palette = useAccessAdminPalette();\n const { width } = useWindowDimensions();\n const columns = useMemo(() => buildPermissionMatrix(roles, permissions, grants), [roles, permissions, grants]);\n const isWide = width >= LAYOUT_COLLAPSE_BREAKPOINT;\n const isEmpty = roles.length === 0 || permissions.length === 0;\n const partProps: PartProps = { columns, permissions, palette, t, testID };\n\n return (\n <View style={styles.root} testID={testID}>\n <Text accessibilityRole=\"header\" style={[styles.heading, { color: palette.textPrimary }]}>\n {t(ACCESS_ADMIN_I18N.permissionsHeading)}\n </Text>\n <Text style={[styles.body, { color: palette.textSecondary }]}>{t(ACCESS_ADMIN_I18N.permissionsNote)}</Text>\n {isEmpty ? (\n <Text style={[styles.body, { color: palette.textSecondary }]} testID={`${testID}-empty`}>\n {t(ACCESS_ADMIN_I18N.permissionsEmpty)}\n </Text>\n ) : null}\n {!isEmpty && isWide ? <TableMatrix {...partProps} /> : null}\n {!isEmpty && !isWide ? <StackedMatrix {...partProps} /> : null}\n </View>\n );\n};\n"]}