@wssto2/vue-core 0.1.0 → 0.3.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/README.md +53 -9
- package/dist/AccessGate.vue_vue_type_script_setup_true_lang-DKX3PH2n.js +22 -0
- package/dist/AccountMenuItem.vue_vue_type_script_setup_true_lang-DIGqTLwd.js +76 -0
- package/dist/ActionRow.vue_vue_type_script_setup_true_lang-B7Lpfkf6.js +45 -0
- package/dist/Activity-DviO0VQ8.js +156 -0
- package/dist/{AdaptivePageShell.vue_vue_type_script_setup_true_lang-CKghARkW.js → AdaptivePageShell.vue_vue_type_script_setup_true_lang-CvAnzdc1.js} +48 -47
- package/dist/{AlertDialog.vue_vue_type_script_setup_true_lang-BZb4qKXo.js → AlertDialog.vue_vue_type_script_setup_true_lang-CJsMUIUg.js} +2 -2
- package/dist/{AsyncSection.vue_vue_type_script_setup_true_lang-B82bl36A.js → AsyncSection.vue_vue_type_script_setup_true_lang-CCtthMRd.js} +4 -4
- package/dist/Badge.vue_vue_type_script_setup_true_lang-DJyZc0C7.js +51 -0
- package/dist/{Banner.vue_vue_type_script_setup_true_lang-n_wGPIIu.js → Banner.vue_vue_type_script_setup_true_lang-Cib_YYpr.js} +1 -1
- package/dist/{BottomDock.vue_vue_type_script_setup_true_lang-DhlMnPC2.js → BottomDock.vue_vue_type_script_setup_true_lang-CjN7xYEr.js} +1 -1
- package/dist/Button.vue_vue_type_script_setup_true_lang-CYil8h9z.js +182 -0
- package/dist/Changes-DlT5mN9G.js +129 -0
- package/dist/CollectionPage.vue_vue_type_script_setup_true_lang-CXILftEc.js +1481 -0
- package/dist/CountryFlag.vue_vue_type_script_setup_true_lang-Kry_vPPZ.js +299 -0
- package/dist/DataTable.vue_vue_type_script_setup_true_lang-DSYgS9lC.js +52 -0
- package/dist/DateField.vue_vue_type_script_setup_true_lang-DMVjNsaM.js +1099 -0
- package/dist/{DiscardChangesModal.vue_vue_type_script_setup_true_lang-Bx5O1RZJ.js → DiscardChangesModal.vue_vue_type_script_setup_true_lang-Cb3xJI1x.js} +1 -1
- package/dist/{EmptyState.vue_vue_type_script_setup_true_lang-BeGpHMUP.js → EmptyState.vue_vue_type_script_setup_true_lang-C2ZYIT9F.js} +1 -1
- package/dist/FormErrors.vue_vue_type_script_setup_true_lang-DVgNBQ8p.js +276 -0
- package/dist/FormGroup.vue_vue_type_script_setup_true_lang-0mfG8TkU.js +136 -0
- package/dist/FormView.vue_vue_type_script_setup_true_lang-Bz2m3AtF.js +38 -0
- package/dist/General-BD-Hcz0a.js +145 -0
- package/dist/{Icon.vue_vue_type_script_lang-DtC4_mkz.js → Icon.vue_vue_type_script_lang-VvcV2Bzo.js} +46 -33
- package/dist/{IconTile.vue_vue_type_script_setup_true_lang-Csfv6Sel.js → IconTile.vue_vue_type_script_setup_true_lang-D7QgnUyN.js} +1 -1
- package/dist/KeyValue.vue_vue_type_script_setup_true_lang-wcZcvnow.js +35 -0
- package/dist/{LeaveGuardRoot.vue_vue_type_script_setup_true_lang-DH6EB8br.js → LeaveGuardRoot.vue_vue_type_script_setup_true_lang-C2udmeEA.js} +2 -2
- package/dist/{Menu.vue_vue_type_script_setup_true_lang-D44EHXQZ.js → Menu.vue_vue_type_script_setup_true_lang-BNAjx9tj.js} +61 -57
- package/dist/{Modal.vue_vue_type_script_setup_true_lang-DYQgaUtj.js → Modal.vue_vue_type_script_setup_true_lang-D7SwVPpL.js} +139 -129
- package/dist/NewRolePage-Dla4YnMs.js +42 -0
- package/dist/NoAccess.vue_vue_type_script_setup_true_lang-8m9cNptR.js +31 -0
- package/dist/NumberField.vue_vue_type_script_setup_true_lang-CYRg7Kfg.js +113 -0
- package/dist/OtpInput.vue_vue_type_script_setup_true_lang-gp4FfWAH.js +95 -0
- package/dist/PageBar.vue_vue_type_script_setup_true_lang-Cfr5xsJx.js +47 -0
- package/dist/{Panel.vue_vue_type_script_setup_true_lang-BQmv3cLb.js → Panel.vue_vue_type_script_setup_true_lang-BCRxRK4D.js} +1 -1
- package/dist/{PhotoViewer.vue_vue_type_script_setup_true_lang-DDVQXJRB.js → PhotoViewer.vue_vue_type_script_setup_true_lang-B3Q4dhqJ.js} +2 -2
- package/dist/Popover.vue_vue_type_script_setup_true_lang-Dx-tDhNE.js +125 -0
- package/dist/ProfilePage-OJMQ8cr8.js +691 -0
- package/dist/{ProgressTrack.vue_vue_type_script_setup_true_lang-1DDaNs2W.js → ProgressTrack.vue_vue_type_script_setup_true_lang-B6Prw9hi.js} +2 -2
- package/dist/RecordHeader.vue_vue_type_script_setup_true_lang-DKsaKlAq.js +64 -0
- package/dist/ResourcePage.vue_vue_type_script_setup_true_lang-CJcKa9SW.js +173 -0
- package/dist/RoleEditor.vue_vue_type_script_setup_true_lang-DuEPOmjI.js +299 -0
- package/dist/RolePage-bZzv_E4l.js +315 -0
- package/dist/RolesPage-BniZv0nB.js +115 -0
- package/dist/SectionIntro.vue_vue_type_script_setup_true_lang-CZtPrmXD.js +23 -0
- package/dist/SectionList.vue_vue_type_script_setup_true_lang-BKP_bge8.js +148 -0
- package/dist/SectionNavigator.vue_vue_type_script_setup_true_lang-BgGEGxSI.js +314 -0
- package/dist/SegmentedField.vue_vue_type_script_setup_true_lang-BZ9UdgA1.js +58 -0
- package/dist/SelectField.vue_vue_type_script_setup_true_lang-BiGaEKBQ.js +422 -0
- package/dist/SessionList.vue_vue_type_script_setup_true_lang-DUQpr7gb.js +111 -0
- package/dist/Sessions-Co5-xdeb.js +96 -0
- package/dist/Sheet.vue_vue_type_script_setup_true_lang-bHYzx7-J.js +142 -0
- package/dist/SignIn-BWwFbxki.js +140 -0
- package/dist/SignInPage-FnLtoi2q.js +60 -0
- package/dist/SignInTable.vue_vue_type_script_setup_true_lang-Dnx3T_42.js +79 -0
- package/dist/SignIns-3UcI64_h.js +66 -0
- package/dist/SwipeActions.vue_vue_type_script_setup_true_lang-4I8m27ol.js +93 -0
- package/dist/Tabs.vue_vue_type_script_setup_true_lang-BeGaydRr.js +155 -0
- package/dist/TextField.vue_vue_type_script_setup_true_lang-C_FMf3Vc.js +269 -0
- package/dist/TextareaField.vue_vue_type_script_setup_true_lang-CU3KTKIJ.js +127 -0
- package/dist/{Timestamp.vue_vue_type_script_setup_true_lang-CSY_mMm1.js → Timestamp.vue_vue_type_script_setup_true_lang-1RJGKxbD.js} +1 -1
- package/dist/{Tooltip.vue_vue_type_script_setup_true_lang-BJWPVyfT.js → Tooltip.vue_vue_type_script_setup_true_lang-OOD_XNWx.js} +1 -1
- package/dist/UserRecord-Ci8HfwbX.js +267 -0
- package/dist/UsersList-vEJ-cgkT.js +155 -0
- package/dist/ViewTabs.vue_vue_type_script_setup_true_lang-ByqTU2JT.js +28 -0
- package/dist/access/AddRoleDialog.vue.d.ts +19 -0
- package/dist/access/BindingRow.vue.d.ts +19 -0
- package/dist/access/EffectiveAccess.vue.d.ts +12 -0
- package/dist/access/NewRolePage.vue.d.ts +2 -0
- package/dist/access/PermissionTree.vue.d.ts +13 -0
- package/dist/access/PersonAccess.vue.d.ts +21 -0
- package/dist/access/ReplaceRoleDialog.vue.d.ts +17 -0
- package/dist/access/RoleCompareDialog.vue.d.ts +14 -0
- package/dist/access/RoleEditor.vue.d.ts +28 -0
- package/dist/access/RolePage.vue.d.ts +2 -0
- package/dist/access/RolesPage.vue.d.ts +2 -0
- package/dist/access/api.d.ts +26 -0
- package/dist/access/catalogue.d.ts +64 -0
- package/dist/access/context.d.ts +20 -0
- package/dist/access/effective.d.ts +42 -0
- package/dist/access/feature.d.ts +27 -0
- package/dist/access/index.d.ts +13 -0
- package/dist/access/index.js +15 -0
- package/dist/access/labels.d.ts +35 -0
- package/dist/access/refusals.d.ts +6 -0
- package/dist/access/routes.d.ts +45 -0
- package/dist/access/scopes.d.ts +20 -0
- package/dist/app/application.d.ts +5 -0
- package/dist/app/contributions.d.ts +1 -1
- package/dist/app/environment.d.ts +2 -0
- package/dist/app/feature.d.ts +8 -0
- package/dist/app/index.js +260 -294
- package/dist/bottomDock-BZEiOPYZ.js +12 -0
- package/dist/button/Button.vue.d.ts +3 -3
- package/dist/button/index.d.ts +1 -1
- package/dist/button/index.js +5 -3
- package/dist/button/shortcut.d.ts +28 -2
- package/dist/chrome-BS3xJcad.js +93 -0
- package/dist/client/client.d.ts +13 -0
- package/dist/client/index.d.ts +3 -1
- package/dist/client/index.js +19 -138
- package/dist/client/route.d.ts +59 -0
- package/dist/client-Bw0aM5Gu.js +147 -0
- package/dist/closeOverlays-CjVsIrpL.js +8 -0
- package/dist/collection/CollectionPage.vue.d.ts +1 -0
- package/dist/collection/CollectionRows.vue.d.ts +59 -0
- package/dist/collection/CollectionTable.vue.d.ts +1 -1
- package/dist/collection/DataTable.vue.d.ts +47 -0
- package/dist/collection/RowActions.vue.d.ts +19 -0
- package/dist/collection/columns.d.ts +2 -0
- package/dist/collection/http.d.ts +4 -2
- package/dist/collection/index.d.ts +4 -2
- package/dist/collection/index.js +87 -2299
- package/dist/collection/rowLayout.d.ts +10 -0
- package/dist/collection/slots.d.ts +6 -3
- package/dist/content/index.js +37 -66
- package/dist/contributions-CDDg3fKp.js +26 -0
- package/dist/controls/DateButton.vue.d.ts +1 -1
- package/dist/controls/PopupButton.vue.d.ts +1 -1
- package/dist/controls/index.js +11 -10
- package/dist/defineRoutes-BGAdiIrt.js +19 -0
- package/dist/describeError-Ctga6GcS.js +41 -0
- package/dist/dialogStack-DZZg55w0.js +31 -0
- package/dist/environment-Dva-SG8D.js +6 -0
- package/dist/{error-Bb_dr_Ay.js → error-CD7x0Jrz.js} +2 -2
- package/dist/feature-DdUAfyi4.js +25 -0
- package/dist/fieldMessages-C3Rpbktw.js +25 -0
- package/dist/form/CheckboxField.vue.d.ts +1 -1
- package/dist/form/CommandDialog.vue.d.ts +13 -2
- package/dist/form/DateField.vue.d.ts +1 -1
- package/dist/form/DateTimeField.vue.d.ts +1 -1
- package/dist/form/EditorPage.vue.d.ts +1 -1
- package/dist/form/Field.vue.d.ts +1 -1
- package/dist/form/FileField.vue.d.ts +1 -1
- package/dist/form/FormGroup.vue.d.ts +1 -1
- package/dist/form/FormGroupButton.vue.d.ts +1 -1
- package/dist/form/FormRow.vue.d.ts +1 -1
- package/dist/form/I18nField.vue.d.ts +3 -3
- package/dist/form/MoneyField.vue.d.ts +1 -1
- package/dist/form/MonthYearField.vue.d.ts +1 -1
- package/dist/form/MultiSelectField.vue.d.ts +4 -1
- package/dist/form/NumberCell.vue.d.ts +1 -1
- package/dist/form/NumberField.vue.d.ts +8 -2
- package/dist/form/OptionList.vue.d.ts +6 -2
- package/dist/form/OtpInput.vue.d.ts +2 -2
- package/dist/form/PhotoField.vue.d.ts +1 -1
- package/dist/form/SelectField.vue.d.ts +4 -1
- package/dist/form/SwitchField.vue.d.ts +1 -1
- package/dist/form/TextField.vue.d.ts +3 -3
- package/dist/form/TextareaField.vue.d.ts +3 -3
- package/dist/form/TimeField.vue.d.ts +1 -1
- package/dist/form/date/DatePickerSheet.vue.d.ts +1 -1
- package/dist/form/date/MonthYearPanel.vue.d.ts +1 -1
- package/dist/form/index.d.ts +2 -0
- package/dist/form/index.js +1273 -3509
- package/dist/form/suggestions.d.ts +11 -0
- package/dist/form/useOptions.d.ts +60 -0
- package/dist/guards-Cd1V28oG.js +51 -0
- package/dist/http-DGGSKWvU.js +193 -0
- package/dist/i18n/describeError.d.ts +31 -0
- package/dist/i18n/index.d.ts +307 -0
- package/dist/i18n/index.js +54 -52
- package/dist/icon/core.d.ts +13 -0
- package/dist/icon/index.js +1 -1
- package/dist/identity/ImpersonationBanner.vue.d.ts +2 -0
- package/dist/identity/LocaleSync.vue.d.ts +2 -0
- package/dist/identity/SessionExpiry.vue.d.ts +2 -0
- package/dist/identity/SignInAsButton.vue.d.ts +15 -0
- package/dist/identity/SignInPage.vue.d.ts +2 -0
- package/dist/identity/context.d.ts +7 -0
- package/dist/identity/feature.d.ts +16 -0
- package/dist/identity/fieldMessages.d.ts +15 -0
- package/dist/identity/index.d.ts +16 -0
- package/dist/identity/index.js +18 -0
- package/dist/identity/profile/DetailsPanel.vue.d.ts +11 -0
- package/dist/identity/profile/EmailChangeDialog.vue.d.ts +14 -0
- package/dist/identity/profile/EmailPanel.vue.d.ts +11 -0
- package/dist/identity/profile/PanelActions.vue.d.ts +17 -0
- package/dist/identity/profile/PasswordPanel.vue.d.ts +2 -0
- package/dist/identity/profile/ProfileMenuItem.vue.d.ts +2 -0
- package/dist/identity/profile/ProfilePage.vue.d.ts +2 -0
- package/dist/identity/profile/SessionsPanel.vue.d.ts +2 -0
- package/dist/identity/profile/SignInsPanel.vue.d.ts +2 -0
- package/dist/identity/profile/VerifyCode.vue.d.ts +49 -0
- package/dist/identity/profile/routes.d.ts +13 -0
- package/dist/identity/session.d.ts +30 -0
- package/dist/identity/shared/ActionRow.vue.d.ts +20 -0
- package/dist/identity/shared/ChangeFeed.vue.d.ts +11 -0
- package/dist/identity/shared/PageBar.vue.d.ts +12 -0
- package/dist/identity/shared/SectionIntro.vue.d.ts +16 -0
- package/dist/identity/shared/SessionList.vue.d.ts +19 -0
- package/dist/{phone/CountryFlag.vue.d.ts → identity/shared/SignInTable.vue.d.ts} +5 -4
- package/dist/identity/shared/ViewTabs.vue.d.ts +23 -0
- package/dist/identity/shared/signInEvents.d.ts +9 -0
- package/dist/identity/signIn.d.ts +27 -0
- package/dist/identity/useSignInForm.d.ts +20 -0
- package/dist/identity/user.d.ts +6 -0
- package/dist/identity/users/DeactivateDialog.vue.d.ts +18 -0
- package/dist/identity/users/NewUserDialog.vue.d.ts +9 -0
- package/dist/identity/users/SetPasswordDialog.vue.d.ts +16 -0
- package/dist/identity/users/UserRecord.vue.d.ts +2 -0
- package/dist/identity/users/UsersList.vue.d.ts +2 -0
- package/dist/identity/users/access.d.ts +4 -0
- package/dist/identity/users/context.d.ts +9 -0
- package/dist/identity/users/feature.d.ts +34 -0
- package/dist/identity/users/languages.d.ts +4 -0
- package/dist/identity/users/list.d.ts +8 -0
- package/dist/identity/users/person.d.ts +26 -0
- package/dist/identity/users/personSections.d.ts +22 -0
- package/dist/identity/users/routes.d.ts +22 -0
- package/dist/identity/users/sections/Activity.vue.d.ts +2 -0
- package/dist/identity/users/sections/Changes.vue.d.ts +2 -0
- package/dist/identity/users/sections/General.vue.d.ts +2 -0
- package/dist/identity/users/sections/Sessions.vue.d.ts +2 -0
- package/dist/identity/users/sections/SignIn.vue.d.ts +2 -0
- package/dist/identity/users/sections/SignIns.vue.d.ts +2 -0
- package/dist/identity/users/status.d.ts +4 -0
- package/dist/index-B2dbYZR9.js +706 -0
- package/dist/index-BAcl44SC.js +459 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/internal/CountryFlag.vue.d.ts +10 -0
- package/dist/internal/languageName.d.ts +2 -0
- package/dist/keepAlive-WYQGRhuz.js +48 -0
- package/dist/languageName-CItV_SOv.js +11 -0
- package/dist/languages-BShG9LpE.js +10 -0
- package/dist/leaveGuard-Cc8yeLxM.js +72 -0
- package/dist/modal/Modal.vue.d.ts +4 -0
- package/dist/modal/ShortcutHelp.vue.d.ts +2 -0
- package/dist/modal/index.d.ts +2 -0
- package/dist/modal/index.js +64 -6
- package/dist/modal/placement.d.ts +22 -0
- package/dist/modules/access/entities.d.ts +112 -0
- package/dist/modules/access/routes.d.ts +67 -0
- package/dist/modules/access/schemas.d.ts +73 -0
- package/dist/modules/identity/entities.d.ts +150 -0
- package/dist/modules/identity/routes.d.ts +118 -0
- package/dist/modules/identity/schemas.d.ts +145 -0
- package/dist/{navigation-B33ikiCS.js → navigation-BPWa63ge.js} +21 -20
- package/dist/neighbors-D0WRBxXI.js +86 -0
- package/dist/{options-CjSz2dQK.js → options-BXkMR63B.js} +48 -49
- package/dist/overlay/AlertDialog.vue.d.ts +3 -3
- package/dist/overlay/Popover.vue.d.ts +4 -1
- package/dist/overlay/closeOverlays.d.ts +7 -0
- package/dist/overlay/dialogStack.d.ts +9 -0
- package/dist/overlay/index.d.ts +1 -1
- package/dist/overlay/index.js +20 -18
- package/dist/page/AdaptivePageShell.vue.d.ts +2 -2
- package/dist/page/ResourceHeader.vue.d.ts +2 -2
- package/dist/page/index.js +99 -457
- package/dist/phone/PhoneField.vue.d.ts +2 -2
- package/dist/phone/index.js +247 -540
- package/dist/platform/AccessGate.vue.d.ts +50 -0
- package/dist/platform/index.d.ts +4 -2
- package/dist/platform/index.js +38 -35
- package/dist/platform/platform.d.ts +2 -2
- package/dist/platform/session.d.ts +22 -1
- package/dist/platform-hunMqFdB.js +255 -0
- package/dist/resource/index.js +8 -248
- package/dist/routeResource-DstM0hvf.js +82 -0
- package/dist/router/guards.d.ts +7 -1
- package/dist/router/index.js +23 -37
- package/dist/router/navigation.d.ts +1 -1
- package/dist/rowLayout-BI7a3Kom.js +603 -0
- package/dist/sectionIndex-BS0ic5W7.js +86 -0
- package/dist/{sections-LtxV5Mtk.js → sections-BEqW1dOc.js} +1 -1
- package/dist/shell/AccountMenuItem.vue.d.ts +4 -1
- package/dist/shell/BackofficeShell.vue.d.ts +2 -2
- package/dist/shell/ShellBrand.vue.d.ts +1 -1
- package/dist/shell/backofficeShell.d.ts +1 -1
- package/dist/shell/identity.d.ts +1 -1
- package/dist/shell/index.js +476 -532
- package/dist/state/Badge.vue.d.ts +17 -10
- package/dist/state/ProgressTrack.vue.d.ts +1 -1
- package/dist/state/hue.d.ts +8 -0
- package/dist/state/index.d.ts +2 -0
- package/dist/state/index.js +34 -31
- package/dist/state/useLoad.d.ts +41 -0
- package/dist/status-C9aXR-Jb.js +33 -0
- package/dist/styles.css +1 -1
- package/dist/suggestions-BJAqOj4c.js +138 -0
- package/dist/testing/app.d.ts +61 -0
- package/dist/testing/async.d.ts +12 -0
- package/dist/testing/collection.d.ts +18 -0
- package/dist/testing/format.d.ts +9 -0
- package/dist/testing/i18n.d.ts +16 -0
- package/dist/testing/index.d.ts +14 -0
- package/dist/testing/index.js +178 -0
- package/dist/testing/media.d.ts +23 -0
- package/dist/testing/platform.d.ts +40 -0
- package/dist/testing/transport.d.ts +40 -0
- package/dist/toast-D9Z5To38.js +13 -0
- package/dist/useCommand-BgRwnYlV.js +135 -0
- package/dist/{useDialog-wmyNx2j_.js → useDialog-CXR3hN0G.js} +1 -1
- package/dist/useLoad-CYRVx6HW.js +39 -0
- package/dist/useResourceForm-Bgc9jMcu.js +52 -0
- package/dist/useSaveChrome-chi6D3HY.js +25 -0
- package/dist/useSheetDrag-OsD6Eb6I.js +72 -0
- package/package.json +26 -5
- package/src/styles/theme.css +60 -0
- package/dist/Badge.vue_vue_type_script_setup_true_lang-DKc6ugmr.js +0 -31
- package/dist/Button.vue_vue_type_script_setup_true_lang-3f0emVNU.js +0 -141
- package/dist/NoAccess.vue_vue_type_script_setup_true_lang-OKW8pKYU.js +0 -78
- package/dist/SectionList.vue_vue_type_script_setup_true_lang-DGcKX_OJ.js +0 -230
- package/dist/SelectField.vue_vue_type_script_setup_true_lang-SyFWE33A.js +0 -422
- package/dist/Sheet.vue_vue_type_script_setup_true_lang-BLBD5ps8.js +0 -210
- package/dist/SwipeActions.vue_vue_type_script_setup_true_lang-CGTuEnTv.js +0 -243
- package/dist/chrome-D9pwD6iS.js +0 -101
- package/dist/dialogStack-DiTG1rZc.js +0 -26
- package/dist/environment-D3nozt9a.js +0 -75
- package/dist/feature-DyDtyMLU.js +0 -47
- package/dist/platform-jqlKVJ2e.js +0 -244
- package/dist/toast-BTeX0r66.js +0 -129
- /package/dist/{phone → internal}/flagLoaders.d.ts +0 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { AccessQualifier } from "../platform";
|
|
2
|
+
/**
|
|
3
|
+
* What go-core's catalogue says about one permission: the shape of `authzts`'s `PermissionMeta`, so the
|
|
4
|
+
* `permissions` object its generator writes (`frontend/generated/permissions.ts`) is the catalogue as it is.
|
|
5
|
+
*/
|
|
6
|
+
export interface PermissionMeta {
|
|
7
|
+
readonly module: string;
|
|
8
|
+
/** Empty for a permission of the module itself. */
|
|
9
|
+
readonly resource: string;
|
|
10
|
+
readonly verb: string;
|
|
11
|
+
/** i18n keys; the texts live in the application. */
|
|
12
|
+
readonly labelKey: string;
|
|
13
|
+
readonly descriptionKey: string;
|
|
14
|
+
readonly sensitive: boolean;
|
|
15
|
+
readonly system: boolean;
|
|
16
|
+
readonly organizationOnly: boolean;
|
|
17
|
+
/** The record type the "whose" qualifiers refer to; null when the permission has no owner. */
|
|
18
|
+
readonly ownable: string | null;
|
|
19
|
+
readonly unownedIsOwn: boolean;
|
|
20
|
+
readonly feature: string | null;
|
|
21
|
+
readonly attributes: readonly string[];
|
|
22
|
+
readonly requires: readonly string[];
|
|
23
|
+
}
|
|
24
|
+
/** Every permission of the application by identifier (`module.resource:verb`). */
|
|
25
|
+
export type PermissionCatalogue = Readonly<Record<string, PermissionMeta>>;
|
|
26
|
+
/** A permission with its identifier. */
|
|
27
|
+
export interface PermissionEntry extends PermissionMeta {
|
|
28
|
+
readonly id: string;
|
|
29
|
+
}
|
|
30
|
+
/** The permissions of one screen (a resource of a module). */
|
|
31
|
+
export interface PermissionScreen {
|
|
32
|
+
/** `module` or `module_resource` (dots turned into underscores): the i18n key of its heading, under `access.resources`. */
|
|
33
|
+
readonly key: string;
|
|
34
|
+
readonly permissions: readonly PermissionEntry[];
|
|
35
|
+
}
|
|
36
|
+
/** One tab of the editor: a module's screens. Permissions that run the system are together in the group `system`. */
|
|
37
|
+
export interface PermissionGroup {
|
|
38
|
+
readonly key: string;
|
|
39
|
+
readonly screens: readonly PermissionScreen[];
|
|
40
|
+
}
|
|
41
|
+
export declare const SYSTEM_GROUP = "system";
|
|
42
|
+
export declare const groupOf: (meta: Pick<PermissionMeta, "module" | "system">) => string;
|
|
43
|
+
export declare const screenKeyOf: (meta: Pick<PermissionMeta, "module" | "resource">) => string;
|
|
44
|
+
/** The catalogue as the editor shows it: module, then screen, then action (view, create, update, manage, delete, the rest by name). */
|
|
45
|
+
export declare function permissionTree(catalogue: PermissionCatalogue): readonly PermissionGroup[];
|
|
46
|
+
/** Everything `id` needs, transitively (not `id` itself). */
|
|
47
|
+
export declare function requiredClosure(catalogue: PermissionCatalogue, id: string): string[];
|
|
48
|
+
/** Everything that needs `id`, transitively (not `id` itself). */
|
|
49
|
+
export declare function dependantsClosure(catalogue: PermissionCatalogue, id: string): string[];
|
|
50
|
+
/** What a role holds: each permission with whose records it reaches (`all` for a permission that has no owner). */
|
|
51
|
+
export type Grants = Record<string, AccessQualifier>;
|
|
52
|
+
/** The whose the role holds of a record type: its view permission's, else any granted one's; null when it holds none. */
|
|
53
|
+
export declare function ownableQualifier(catalogue: PermissionCatalogue, grants: Grants, ownable: string): AccessQualifier | null;
|
|
54
|
+
/** Grants `id` and what it needs; the whose of an ownable one is what the role already holds of its record type, else `own`. */
|
|
55
|
+
export declare function grant(catalogue: PermissionCatalogue, grants: Grants, id: string): void;
|
|
56
|
+
/** Takes `id` away, and what needs it. */
|
|
57
|
+
export declare function revoke(catalogue: PermissionCatalogue, grants: Grants, id: string): void;
|
|
58
|
+
/** Applies one whose to every granted permission of the record type. */
|
|
59
|
+
export declare function setOwnableQualifier(catalogue: PermissionCatalogue, grants: Grants, ownable: string, qualifier: AccessQualifier): void;
|
|
60
|
+
/**
|
|
61
|
+
* Grants what the granted permissions need but the role lacks (a role saved before a permission gained a
|
|
62
|
+
* requirement, which the server would refuse as it is). Returns what was added.
|
|
63
|
+
*/
|
|
64
|
+
export declare function completeRequired(catalogue: PermissionCatalogue, grants: Grants): string[];
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { RouteLocationRaw } from "vue-router";
|
|
2
|
+
import type { ScopeOptions, SubjectRef } from "../modules/access/entities";
|
|
3
|
+
import type { PermissionCatalogue } from "./catalogue";
|
|
4
|
+
/** What the access screens need from the feature that installed them. */
|
|
5
|
+
export interface AccessContext {
|
|
6
|
+
readonly catalogue: PermissionCatalogue;
|
|
7
|
+
/** Where a holder's name leads (their record), or null for a name that is not a link. */
|
|
8
|
+
readonly subjectRoute: (subject: SubjectRef) => RouteLocationRaw | null;
|
|
9
|
+
/** The places `subject` may be given roles at; by default what the server says (`GET /v1/iam/users/:id/scopes`). */
|
|
10
|
+
readonly scopes: ((subject: SubjectRef, signal: AbortSignal) => Promise<ScopeOptions>) | null;
|
|
11
|
+
}
|
|
12
|
+
export declare const accessContextKey: import("vue").InjectionKey<AccessContext>, useAccessContext: () => AccessContext;
|
|
13
|
+
/** The permissions go-core's access module guards its routes with: fixed, so a screen can name them. */
|
|
14
|
+
export declare const accessPermissions: {
|
|
15
|
+
readonly viewRoles: "iam.role:view";
|
|
16
|
+
readonly manageRoles: "iam.role:manage";
|
|
17
|
+
readonly deleteRoles: "iam.role:delete";
|
|
18
|
+
readonly viewAccess: "iam.user:view";
|
|
19
|
+
readonly manageBindings: "iam.user:manage";
|
|
20
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { AccessQualifier } from "../platform";
|
|
2
|
+
import type { EffectiveGrant, EffectivePermission, Scope } from "../modules/access/entities";
|
|
3
|
+
import { type PermissionCatalogue } from "./catalogue";
|
|
4
|
+
/** A role that gives a screen's permissions, with the widest whose it gives them at. */
|
|
5
|
+
export interface EffectiveSource {
|
|
6
|
+
readonly roleKey: string;
|
|
7
|
+
readonly roleName: string;
|
|
8
|
+
readonly qualifier: AccessQualifier;
|
|
9
|
+
readonly scope: Scope;
|
|
10
|
+
}
|
|
11
|
+
/** One permission the person holds, with every grant behind it. */
|
|
12
|
+
export interface EffectiveAction {
|
|
13
|
+
readonly permission: string;
|
|
14
|
+
readonly verb: string;
|
|
15
|
+
/** Granted by a role but switched off for this tenant. */
|
|
16
|
+
readonly unavailable: boolean;
|
|
17
|
+
readonly grants: readonly EffectiveGrant[];
|
|
18
|
+
}
|
|
19
|
+
/** One screen: what is held of it, which roles give it, and how wide. */
|
|
20
|
+
export interface EffectiveScreen {
|
|
21
|
+
readonly key: string;
|
|
22
|
+
readonly actions: readonly EffectiveAction[];
|
|
23
|
+
readonly sources: readonly EffectiveSource[];
|
|
24
|
+
/** The widest whose over the screen's ownable actions; null when none of them is ownable. */
|
|
25
|
+
readonly qualifier: AccessQualifier | null;
|
|
26
|
+
/** Where the screen's permissions apply, each place once, the root first. */
|
|
27
|
+
readonly scopes: readonly Scope[];
|
|
28
|
+
readonly ownable: boolean;
|
|
29
|
+
/** Every action here is switched off for the tenant. */
|
|
30
|
+
readonly allUnavailable: boolean;
|
|
31
|
+
}
|
|
32
|
+
export interface EffectiveGroup {
|
|
33
|
+
readonly key: string;
|
|
34
|
+
readonly screens: readonly EffectiveScreen[];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* *What a person can do*: the effective permissions by module and screen, worked out from the roles. The server sends one entry per
|
|
38
|
+
* permission with every grant behind it (`EffectivePermission.grants`); this turns them into the rows the panel shows: a screen with the
|
|
39
|
+
* actions held, the roles that give them, and how wide (whose records, which places). A permission the catalogue does not know (a role
|
|
40
|
+
* saved before it was removed) is grouped by its module and shown by its identifier.
|
|
41
|
+
*/
|
|
42
|
+
export declare function groupEffective(catalogue: PermissionCatalogue, effective: readonly EffectivePermission[]): readonly EffectiveGroup[];
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { RouteLocationRaw } from "vue-router";
|
|
2
|
+
import { type Feature } from "../app";
|
|
3
|
+
import type { ScopeOptions, SubjectRef } from "../modules/access/entities";
|
|
4
|
+
import type { Destination } from "../router";
|
|
5
|
+
import type { PermissionCatalogue } from "./catalogue";
|
|
6
|
+
export interface AccessFeatureOptions {
|
|
7
|
+
/**
|
|
8
|
+
* The application's permissions: the `permissions` object go-core's `authzts` writes (`frontend/generated/permissions.ts`).
|
|
9
|
+
* The role editor's tree is this catalogue; the texts are the application's (`labelKey`, `access.modules.<module>`, ...).
|
|
10
|
+
*/
|
|
11
|
+
catalogue: PermissionCatalogue;
|
|
12
|
+
/** Where a holder's name leads (their record). Default: nowhere, the name is not a link. */
|
|
13
|
+
subjectRoute?: (subject: SubjectRef) => RouteLocationRaw | null;
|
|
14
|
+
/** The places a person may be given roles at. Default: what the server says (`GET /v1/iam/users/:id/scopes`). */
|
|
15
|
+
scopes?: (subject: SubjectRef, signal: AbortSignal) => Promise<ScopeOptions>;
|
|
16
|
+
/** The backend's navigation destination that opens the roles list. Without it the application links to `accessPages.roles` itself. */
|
|
17
|
+
destination?: Destination;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The screens of go-core's access module, one feature to install: the roles list (`/iam/roles`), a role's page and the editor of
|
|
21
|
+
* a new role (`/iam/roles/new`, `?copy=` to start from another role), compare and replace, with every action behind the module's
|
|
22
|
+
* own permissions (`iam.role:view`, `manage`, `delete`). Pair it with `identityFeature()`; the module's routes must be mounted
|
|
23
|
+
* on the server (`access.Install`).
|
|
24
|
+
*
|
|
25
|
+
* createApplication({ platform, shell: backofficeShell(), features: [identityFeature(), accessFeature({ catalogue: permissions })] })
|
|
26
|
+
*/
|
|
27
|
+
export declare function accessFeature(options: AccessFeatureOptions): Feature;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type * from "../modules/access/entities";
|
|
2
|
+
export type * as Inputs from "../modules/access/schemas";
|
|
3
|
+
export { accessRoutes } from "../modules/access/routes";
|
|
4
|
+
export { accessFeature } from "./feature";
|
|
5
|
+
export type { AccessFeatureOptions } from "./feature";
|
|
6
|
+
export { accessPages, personRolesSection } from "./routes";
|
|
7
|
+
export { accessPermissions } from "./context";
|
|
8
|
+
export { dependantsClosure, permissionTree, requiredClosure } from "./catalogue";
|
|
9
|
+
export type { Grants, PermissionCatalogue, PermissionEntry, PermissionGroup, PermissionMeta, PermissionScreen } from "./catalogue";
|
|
10
|
+
export { useAccessLabels } from "./labels";
|
|
11
|
+
export { useRefusalMessage } from "./refusals";
|
|
12
|
+
export { default as PersonAccess } from "./PersonAccess.vue";
|
|
13
|
+
export { default as BindingRow } from "./BindingRow.vue";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { _ as a, i as c, j as o, c as r, b as n, k as i, l as u, p as l, m as p, n as t, u as d, f as m } from "../index-B2dbYZR9.js";
|
|
2
|
+
export {
|
|
3
|
+
a as BindingRow,
|
|
4
|
+
c as PersonAccess,
|
|
5
|
+
o as accessFeature,
|
|
6
|
+
r as accessPages,
|
|
7
|
+
n as accessPermissions,
|
|
8
|
+
i as accessRoutes,
|
|
9
|
+
u as dependantsClosure,
|
|
10
|
+
l as permissionTree,
|
|
11
|
+
p as personRolesSection,
|
|
12
|
+
t as requiredClosure,
|
|
13
|
+
d as useAccessLabels,
|
|
14
|
+
m as useRefusalMessage
|
|
15
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** A role as the screens name it: predefined roles by their key, custom ones by the name they were saved with. */
|
|
2
|
+
export interface RoleName {
|
|
3
|
+
readonly key?: string | null;
|
|
4
|
+
readonly name: string;
|
|
5
|
+
}
|
|
6
|
+
/** A place as the server names it. */
|
|
7
|
+
export interface ScopeName {
|
|
8
|
+
readonly level: string;
|
|
9
|
+
readonly name?: string | null;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* The words of access. The library's own texts are `core.access.*`; the application's catalogue
|
|
13
|
+
* brings its own: a permission's label and description by the keys the catalogue holds, modules under
|
|
14
|
+
* `access.modules.<module>`, screens under `access.resources.<module_resource>`, record types under
|
|
15
|
+
* `access.ownable.<type>`, predefined roles under `access.roles.<key>`, hierarchy levels under
|
|
16
|
+
* `access.levels.<level>`. A name nobody wrote a text for is shown as it is.
|
|
17
|
+
*/
|
|
18
|
+
export declare function useAccessLabels(): {
|
|
19
|
+
roleName: (role: RoleName) => string;
|
|
20
|
+
permissionLabel: (id: string) => string;
|
|
21
|
+
permissionDescription: (id: string) => string;
|
|
22
|
+
groupLabel: (group: string) => string;
|
|
23
|
+
screenLabel: (key: string) => string;
|
|
24
|
+
ownableLabel: (ownable: string) => string;
|
|
25
|
+
qualifierLabel: (qualifier: string) => string;
|
|
26
|
+
qualifierHint: (qualifier: string) => string;
|
|
27
|
+
qualifierNoun: (qualifier: string) => string;
|
|
28
|
+
levelLabel: (level: string) => string;
|
|
29
|
+
/** A place: the level and its name (`Dealer · Auto Zagreb`); the root, which has no name, by its level. */
|
|
30
|
+
scopeLabel: (scope: ScopeName) => string;
|
|
31
|
+
roleKind: (role: {
|
|
32
|
+
predefined: boolean;
|
|
33
|
+
computed: boolean;
|
|
34
|
+
}) => string;
|
|
35
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* For a form's `failureMessage`: a refusal of go-core's delegation rules (`authz.escalation`, `self_assignment`, `last_admin`,
|
|
3
|
+
* `role_in_use`, ...) says which rule it was, in the app's language (`core.errors.authz.*`, overridable with `errors.authz.*`);
|
|
4
|
+
* any other failure keeps the form's own sentence for its kind. Call it in `setup`.
|
|
5
|
+
*/
|
|
6
|
+
export declare function useRefusalMessage(): (kind: unknown, error: unknown) => string | undefined;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pages of the access feature as typed targets (`accessPages.role({ ref })`), for a link from the application's own
|
|
3
|
+
* pages. `/iam/roles/new` is declared before `/iam/roles/:ref`, so "new" is never read as a role's ref.
|
|
4
|
+
*/
|
|
5
|
+
export declare const accessPages: import("../router").DefinedRoutes<{
|
|
6
|
+
readonly roles: {
|
|
7
|
+
readonly name: "access.roles";
|
|
8
|
+
readonly path: "/iam/roles";
|
|
9
|
+
readonly component: () => Promise<typeof import("./RolesPage.vue")>;
|
|
10
|
+
readonly meta: {
|
|
11
|
+
readonly access: "iam.role:view";
|
|
12
|
+
readonly titleKey: "core.access.title";
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
readonly newRole: {
|
|
16
|
+
readonly name: "access.roles.new";
|
|
17
|
+
readonly path: "/iam/roles/new";
|
|
18
|
+
readonly component: () => Promise<typeof import("./NewRolePage.vue")>;
|
|
19
|
+
readonly meta: {
|
|
20
|
+
readonly access: "iam.role:manage";
|
|
21
|
+
readonly titleKey: "core.access.new_title";
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
readonly role: {
|
|
25
|
+
readonly name: "access.role";
|
|
26
|
+
readonly path: "/iam/roles/:ref";
|
|
27
|
+
readonly component: () => Promise<typeof import("./RolePage.vue")>;
|
|
28
|
+
readonly meta: {
|
|
29
|
+
readonly access: "iam.role:view";
|
|
30
|
+
readonly titleKey: "core.access.title";
|
|
31
|
+
readonly remountOnParam: "ref";
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
}>;
|
|
35
|
+
/**
|
|
36
|
+
* What a person's record needs to list *Roles* among its sections (`meta` of a child route whose component shows `PersonAccess`): the
|
|
37
|
+
* label, the icon and the permission go-core guards the person's access with. Spread it into the route's `meta`.
|
|
38
|
+
*/
|
|
39
|
+
export declare const personRolesSection: {
|
|
40
|
+
readonly access: "iam.user:view";
|
|
41
|
+
readonly section: {
|
|
42
|
+
readonly labelKey: "core.access.person_roles";
|
|
43
|
+
readonly icon: "shieldStarFill";
|
|
44
|
+
};
|
|
45
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ScopeOption, ScopeOptions } from "../modules/access/entities";
|
|
2
|
+
/** A way to say where a role applies: a level of the hierarchy, and the chain of places down to it (a dealer, then its location). */
|
|
3
|
+
export interface ScopeLevel {
|
|
4
|
+
readonly level: string;
|
|
5
|
+
/** The levels from just below the root down to this one; empty for the root itself. */
|
|
6
|
+
readonly chain: readonly string[];
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The levels a person may be given roles at, from what the server says (`GET /v1/iam/users/:id/scopes`): each level that has places,
|
|
10
|
+
* narrowest first, then the root when roles may be given there. The hierarchy is read off the places (each says its parent level), so
|
|
11
|
+
* the library knows no level names.
|
|
12
|
+
*/
|
|
13
|
+
export declare function scopeLevels(options: ScopeOptions): readonly ScopeLevel[];
|
|
14
|
+
/** Where to start: the broadest level below the root (the usual choice), else the root. */
|
|
15
|
+
export declare const defaultLevel: (levels: readonly ScopeLevel[]) => ScopeLevel | null;
|
|
16
|
+
/**
|
|
17
|
+
* The places to choose from at step `index` of `level`'s chain, given what was chosen above (`chosen[i]` is the id at `chain[i]`). A place
|
|
18
|
+
* that has nothing below it in the chain is left out when the level is deeper: it could not complete a choice.
|
|
19
|
+
*/
|
|
20
|
+
export declare function placesAt(options: ScopeOptions, level: ScopeLevel, index: number, chosen: readonly (number | null)[]): readonly ScopeOption[];
|
|
@@ -59,6 +59,11 @@ export interface ApplicationLocaleOptions {
|
|
|
59
59
|
fallback?: string;
|
|
60
60
|
/** The locales the application offers. Default: the library's (`en`, `hr`, `bs`, `sl`). */
|
|
61
61
|
supported?: readonly string[];
|
|
62
|
+
/**
|
|
63
|
+
* The flag shown beside each locale's name in the language menu, as an ISO 3166-1 country code: `{ en: "GB", sl: "SI" }`.
|
|
64
|
+
* A flag stands for a language here, so the app chooses (English is not one country). No entry: the name alone.
|
|
65
|
+
*/
|
|
66
|
+
flags?: Readonly<Record<string, string>>;
|
|
62
67
|
/**
|
|
63
68
|
* Called after a switch to another locale committed (not for the start locale, a switch to the locale already active, or a
|
|
64
69
|
* switch a later one superseded), so the application can save the choice on the user. Not awaited: the page has already
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type PropType } from "vue";
|
|
2
|
-
import type
|
|
2
|
+
import { type Session } from "../platform/session";
|
|
3
3
|
import type { ShellContribution, ShellSlot } from "./feature";
|
|
4
4
|
/** A contribution with the feature that declared it, for error messages. */
|
|
5
5
|
export interface OwnedContribution {
|
|
@@ -22,6 +22,8 @@ export interface ApplicationEnvironment {
|
|
|
22
22
|
/** The active locale. */
|
|
23
23
|
readonly locale: Readonly<Ref<string>>;
|
|
24
24
|
readonly locales: readonly string[];
|
|
25
|
+
/** The flag country of each locale that has one (`{ en: "GB" }`); a locale without one shows no flag. */
|
|
26
|
+
readonly localeFlags: Readonly<Record<string, string>>;
|
|
25
27
|
/** Switches the locale once the texts in use exist in it; see `MessageRuntime.setLocale`. */
|
|
26
28
|
setLocale(locale: string): Promise<boolean>;
|
|
27
29
|
/** Tries the start again after a failed one. */
|
package/dist/app/feature.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ export declare function provideContext<T>(key: InjectionKey<T>, value: T): Conte
|
|
|
20
20
|
*
|
|
21
21
|
* - `headerActions`: the actions of the top bar (a notification bell, a search button)
|
|
22
22
|
* - `accountMenu`: entries of the signed-in user's menu
|
|
23
|
+
* - `banner`: a strip across the top of the whole shell, above everything (a notice that must stay in view: signed in as somebody else)
|
|
23
24
|
* - `host`: components with no place of their own that must be mounted once (a command palette, a dialog host)
|
|
24
25
|
*/
|
|
25
26
|
export interface ShellSlots {
|
|
@@ -27,6 +28,7 @@ export interface ShellSlots {
|
|
|
27
28
|
interface DocumentedShellSlots {
|
|
28
29
|
headerActions: true;
|
|
29
30
|
accountMenu: true;
|
|
31
|
+
banner: true;
|
|
30
32
|
host: true;
|
|
31
33
|
}
|
|
32
34
|
export type ShellSlot = keyof DocumentedShellSlots | keyof ShellSlots;
|
|
@@ -93,6 +95,11 @@ export interface FeatureDefinition {
|
|
|
93
95
|
effects?: readonly FeatureEffect[];
|
|
94
96
|
/** Capabilities the backend must report (`platform.config.capabilities`); startup fails naming this feature when one is missing. */
|
|
95
97
|
backend?: readonly string[];
|
|
98
|
+
/**
|
|
99
|
+
* The feature shows its own prompt when a session expires in the middle of work (a sheet to sign in again), so the
|
|
100
|
+
* router keeps the person on their page instead of sending them to the login page.
|
|
101
|
+
*/
|
|
102
|
+
holdsExpiredSession?: boolean;
|
|
96
103
|
/** Features that must be installed too (for a shared integration); checked, never installed for you. */
|
|
97
104
|
requires?: readonly FeatureReference[];
|
|
98
105
|
}
|
|
@@ -106,6 +113,7 @@ export interface Feature {
|
|
|
106
113
|
readonly contributions: readonly ShellContribution[];
|
|
107
114
|
readonly effects: readonly FeatureEffect[];
|
|
108
115
|
readonly backend: readonly string[];
|
|
116
|
+
readonly holdsExpiredSession: boolean;
|
|
109
117
|
readonly requires: readonly string[];
|
|
110
118
|
}
|
|
111
119
|
/** Whether `value` came from `defineFeature`. */
|