react-luminus-components 1.3.196 → 1.3.198
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 +349 -349
- package/dist/.vite/manifest.json +52 -52
- package/dist/Loading-D56RpfUK.cjs +1 -0
- package/dist/{Loading-BgeDcnw5.js → Loading-DBIjfMn3.js} +1 -1
- package/dist/components/Buttons/FloatingSubmit/FloatingFormSubmit.d.ts +2 -1
- package/dist/components/HookForm/DropdownPicker/HookFormDropdownPicker.d.ts +1 -2
- package/dist/contexts.cjs.js +1 -1
- package/dist/contexts.es.js +48 -48
- package/dist/hooks.cjs.js +1 -1
- package/dist/hooks.es.js +20 -20
- package/dist/layout.cjs.js +1 -1
- package/dist/layout.es.js +8 -8
- package/dist/main.cjs.js +2 -2
- package/dist/main.es.js +2622 -2622
- package/dist/{ShortcutLinksContext-CFwpSSiu.cjs → nivo-bar.es-2lqXXrZY.cjs} +6 -6
- package/dist/{ShortcutLinksContext-BgXfmTAm.js → nivo-bar.es-DyZJ2B06.js} +10816 -10818
- package/dist/{searchUtils-CGddTk1-.js → searchUtils-B2yYsfSO.js} +1 -1
- package/dist/searchUtils-DgYnlAYf.cjs +1 -0
- package/dist/style.css +1 -1
- package/dist/useClipboard-CC3Pjdh8.cjs +1 -0
- package/dist/{useClipboard-CXJkLH0p.js → useClipboard-CjBE5QoV.js} +1 -1
- package/dist/useGetApiData-BWVpal7c.cjs +1 -0
- package/dist/{useGetApiData-STVaje8p.js → useGetApiData-DJ2GBF0d.js} +6 -6
- package/dist/{usePermissions-DA56Ngwy.js → usePermissions-Cxf_kMRQ.js} +3 -3
- package/dist/usePermissions-OxqK7_7D.cjs +1 -0
- package/dist/utils.cjs.js +1 -1
- package/dist/utils.es.js +24 -24
- package/dist/variables.scss +165 -165
- package/package.json +116 -116
- package/dist/Loading-DpFClwwX.cjs +0 -1
- package/dist/searchUtils-CM82j7xO.cjs +0 -1
- package/dist/useClipboard-DmKTScZD.cjs +0 -1
- package/dist/useGetApiData-BUSJgW1o.cjs +0 -1
- package/dist/usePermissions-NmwiOkMA.cjs +0 -1
package/dist/hooks.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("./
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("./nivo-bar.es-2lqXXrZY.cjs"),q=require("./useWindowSize-CE6DJWzn.cjs"),T=require("./usePermissions-OxqK7_7D.cjs"),d=require("./useClipboard-CC3Pjdh8.cjs"),x=require("./useGetApiData-BWVpal7c.cjs"),c=require("react"),B=require("./useLocalStorageState-BFc8Gc8H.cjs");require("react-router-dom");require("react-hook-form");require("react-flexmonster");require("@azure/msal-browser");require("@azure/msal-react");const G=r=>{let e="pending",a;const t=r.then(s=>{e="success",a=s},s=>{e="error",a=s});return()=>{switch(e){case"pending":throw t;case"success":return a;case"error":throw a;default:throw new Error("Unknown status")}}};function L(r,e){const a=u.useAxios({silent:!0,differentBaseUrl:e==null?void 0:e.customBaseUrl,customToken:e==null?void 0:e.customToken}),[t,s]=c.useState(null);return c.useEffect(()=>{(async()=>{const n=a.get(r).then(o=>o.data);s(G(n))})()},[a,r]),t}const E=(r,e,a)=>{let t="pending",s;const l=r.then(n=>{t="success",s=n},n=>{const o=n==null?void 0:n.response;(o==null?void 0:o.status)===404&&a?(t="error-404",s=n):(t="error",s=n)});return()=>{switch(t){case"pending":throw l;case"success":return s;case"error":return null;case"error-404":throw new Error("404");default:throw new Error("Unknown status")}}},i={loadOnInit:!0,silent:!1,enabled:!0,nullStateBeforeLoad:!0,nullStateOnFail:!1},O=(r,{loadOnInit:e=i.loadOnInit,enabled:a=i.enabled,silent:t=i.silent,nullStateBeforeLoad:s=i.nullStateBeforeLoad,nullStateOnFail:l=i.nullStateOnFail,customApiUrl:n,customBearerToken:o,dataTransformer:h,errorBoundaryOn404:S}=i)=>{const g=u.useAxios({silent:t,customToken:o,differentBaseUrl:n,noToastOnStatus:S?[404]:void 0}),{startLoading:w,stopLoading:D}=c.useContext(u.LoadingContext),P=c.useRef(0),{isAuthenticated:y}=u.useAuth(),[b,m]=c.useState(null),p=c.useCallback(async(f,A)=>{if(!y()||a===!1)return;!t&&w(`loadData-${r}-${A}`),s&&m(null);const k=g.get(r,{signal:f}).then(C=>h?h(C.data):C.data).finally(()=>!t&&D(`loadData-${r}-${A}`));m(E(k,l??!1,S??!1))},[y,a,t,w,r,s,g,h,D,l,S]);return c.useEffect(()=>{if(e===!1)return;const f=new AbortController;return p(f.signal,++P.current),()=>{f.abort()}},[p,e]),{data:b,setData:m,reloadData:p}};exports.cancelToken=u.cancelToken;exports.useAuth=u.useAuth;exports.useAxios=u.useAxios;exports.useConfirm=u.useConfirm;exports.useFormControlType=u.useFormControlType;exports.useNotifications=u.useNotifications;exports.usePrompt=u.usePrompt;exports.useZodSchemaTypes=u.useZodSchemaTypes;exports.useClickOutside=q.useClickOutside;exports.useWindowSize=q.useWindowSize;exports.usePermissions=T.usePermissions;exports.useClipboard=d.useClipboard;exports.useEmployeePhotoPath=d.useEmployeePhotoPath;exports.useKeyPress=d.useKeyPress;exports.useSearchQuery=d.useSearchQuery;exports.useSearchQueryState=d.useSearchQueryState;exports.useGetApiData=x.useGetApiData;exports.useLocalStorageState=B.useLocalStorageState;exports.useGetApiDataBound=O;exports.useGetDataBound=L;
|
package/dist/hooks.es.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { bt as
|
|
1
|
+
import { ap as S, ar as L, aW as P } from "./nivo-bar.es-DyZJ2B06.js";
|
|
2
|
+
import { bt as j, ao as q, ac as H, as as J, an as M, bu as V } from "./nivo-bar.es-DyZJ2B06.js";
|
|
3
3
|
import { a as Y, u as _ } from "./useWindowSize-OLYtjFv_.js";
|
|
4
|
-
import { u as et } from "./usePermissions-
|
|
5
|
-
import { u as at, d as ot, a as rt, b as nt, c as ut } from "./useClipboard-
|
|
6
|
-
import { u as lt } from "./useGetApiData-
|
|
7
|
-
import { useState as b, useEffect as C, useContext as
|
|
4
|
+
import { u as et } from "./usePermissions-Cxf_kMRQ.js";
|
|
5
|
+
import { u as at, d as ot, a as rt, b as nt, c as ut } from "./useClipboard-CjBE5QoV.js";
|
|
6
|
+
import { u as lt } from "./useGetApiData-DJ2GBF0d.js";
|
|
7
|
+
import { useState as b, useEffect as C, useContext as T, useRef as U, useCallback as $ } from "react";
|
|
8
8
|
import { u as ft } from "./useLocalStorageState-Bt99kkCr.js";
|
|
9
9
|
import "react-router-dom";
|
|
10
10
|
import "react-hook-form";
|
|
11
11
|
import "react-flexmonster";
|
|
12
12
|
import "@azure/msal-browser";
|
|
13
13
|
import "@azure/msal-react";
|
|
14
|
-
const
|
|
14
|
+
const B = (o) => {
|
|
15
15
|
let t = "pending", a;
|
|
16
16
|
const e = o.then((s) => {
|
|
17
17
|
t = "success", a = s;
|
|
@@ -31,7 +31,7 @@ const $ = (o) => {
|
|
|
31
31
|
}
|
|
32
32
|
};
|
|
33
33
|
};
|
|
34
|
-
function
|
|
34
|
+
function I(o, t) {
|
|
35
35
|
const a = S({
|
|
36
36
|
silent: !0,
|
|
37
37
|
differentBaseUrl: t == null ? void 0 : t.customBaseUrl,
|
|
@@ -40,7 +40,7 @@ function H(o, t) {
|
|
|
40
40
|
return C(() => {
|
|
41
41
|
(async () => {
|
|
42
42
|
const r = a.get(o).then((n) => n.data);
|
|
43
|
-
s(
|
|
43
|
+
s(B(r));
|
|
44
44
|
})();
|
|
45
45
|
}, [a, o]), e;
|
|
46
46
|
}
|
|
@@ -72,13 +72,13 @@ const E = (o, t, a) => {
|
|
|
72
72
|
enabled: !0,
|
|
73
73
|
nullStateBeforeLoad: !0,
|
|
74
74
|
nullStateOnFail: !1
|
|
75
|
-
},
|
|
75
|
+
}, K = (o, { loadOnInit: t = u.loadOnInit, enabled: a = u.enabled, silent: e = u.silent, nullStateBeforeLoad: s = u.nullStateBeforeLoad, nullStateOnFail: c = u.nullStateOnFail, customApiUrl: r, customBearerToken: n, dataTransformer: i, errorBoundaryOn404: f } = u) => {
|
|
76
76
|
const p = S({
|
|
77
77
|
silent: e,
|
|
78
78
|
customToken: n,
|
|
79
79
|
differentBaseUrl: r,
|
|
80
80
|
noToastOnStatus: f ? [404] : void 0
|
|
81
|
-
}), { startLoading: h, stopLoading: w } =
|
|
81
|
+
}), { startLoading: h, stopLoading: w } = T(L), k = U(0), { isAuthenticated: g } = P(), [y, d] = b(null), m = $(async (l, D) => {
|
|
82
82
|
if (!g() || a === !1)
|
|
83
83
|
return;
|
|
84
84
|
!e && h(`loadData-${o}-${D}`), s && d(null);
|
|
@@ -109,24 +109,24 @@ const E = (o, t, a) => {
|
|
|
109
109
|
}, [m, t]), { data: y, setData: d, reloadData: m };
|
|
110
110
|
};
|
|
111
111
|
export {
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
j as cancelToken,
|
|
113
|
+
P as useAuth,
|
|
114
114
|
S as useAxios,
|
|
115
115
|
Y as useClickOutside,
|
|
116
116
|
at as useClipboard,
|
|
117
|
-
|
|
117
|
+
q as useConfirm,
|
|
118
118
|
ot as useEmployeePhotoPath,
|
|
119
|
-
|
|
119
|
+
H as useFormControlType,
|
|
120
120
|
lt as useGetApiData,
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
K as useGetApiDataBound,
|
|
122
|
+
I as useGetDataBound,
|
|
123
123
|
rt as useKeyPress,
|
|
124
124
|
ft as useLocalStorageState,
|
|
125
|
-
|
|
125
|
+
J as useNotifications,
|
|
126
126
|
et as usePermissions,
|
|
127
|
-
|
|
127
|
+
M as usePrompt,
|
|
128
128
|
nt as useSearchQuery,
|
|
129
129
|
ut as useSearchQueryState,
|
|
130
130
|
_ as useWindowSize,
|
|
131
|
-
|
|
131
|
+
V as useZodSchemaTypes
|
|
132
132
|
};
|
package/dist/layout.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./nivo-bar.es-2lqXXrZY.cjs"),m=require("react"),y=require("react-router-dom");require("react-hook-form");require("react-flexmonster");require("@azure/msal-browser");require("@azure/msal-react");const g=require("./useWindowSize-CE6DJWzn.cjs"),C=require("./usePermissions-OxqK7_7D.cjs"),P="_side-menu-item_1o1uo_1",w="_disabled_1o1uo_6",z="_nav-button_1o1uo_10",I="_child_1o1uo_18",f="_text_1o1uo_23",S="_icon_1o1uo_30",q="_collapse-icon_1o1uo_36",L="_collapsed_1o1uo_46",T="_collapse-icon-mini_1o1uo_49",O="_expanded_1o1uo_80",$="_children-container_1o1uo_86",A="_visible_1o1uo_94",K="_children_1o1uo_86",D="_mobile_1o1uo_106",o={"side-menu-item":"_side-menu-item_1o1uo_1",sideMenuItem:P,disabled:w,"nav-button":"_nav-button_1o1uo_10",navButton:z,child:I,text:f,icon:S,"collapse-icon":"_collapse-icon_1o1uo_36",collapseIcon:q,collapsed:L,"collapse-icon-mini":"_collapse-icon-mini_1o1uo_49",collapseIconMini:T,expanded:O,"children-container":"_children-container_1o1uo_86",childrenContainer:$,visible:A,children:K,mobile:D},F=({item:n,menuExpanded:t,useTooltips:i,children:a})=>n.tooltip&&!t&&i?e.jsxRuntimeExports.jsx(e.SimpleTooltip,{text:n.tooltip,placement:"top",delay:{show:1e3,hide:0},children:e.jsxRuntimeExports.jsx("div",{children:a})}):a,B=({item:n,menuExpanded:t,collapsed:i,onCollapse:a,currentPath:l,useHover:x,useTooltips:v,isMobile:c})=>{var M,h,R,j;const[N,_]=m.useState(!1),[p]=l.split("?"),d=n.linkTo===p||((M=n.children)==null?void 0:M.some(s=>s.linkTo===p)),E=m.useRef(null);return g.useClickOutside([E],()=>i&&a()),e.jsxRuntimeExports.jsxs("li",{ref:E,className:e.classNames("luminus-side-menu-item",o.sideMenuItem,{[o.mobile]:c},{[o.expanded]:t},{active:N||d},{open:i&&n.children},{[o.disabled]:n.disabled||n.notPermitted||((h=n.children)==null?void 0:h.every(s=>s.notPermitted||s.disabled))},{disabled:n.disabled||n.notPermitted||((R=n.children)==null?void 0:R.every(s=>s.notPermitted||s.disabled))}),onMouseEnter:()=>_(!0),onMouseLeave:()=>_(!1),children:[e.jsxRuntimeExports.jsx(F,{item:n,menuExpanded:t,useTooltips:v,children:n.children?e.jsxRuntimeExports.jsx(e.jsxRuntimeExports.Fragment,{children:e.jsxRuntimeExports.jsxs("button",{type:"button",className:e.classNames("nav-link",o.navButton),onClick:()=>{a()},children:[e.jsxRuntimeExports.jsx("div",{className:e.classNames("icon",o.icon),children:n.icon}),!x&&!t&&e.jsxRuntimeExports.jsx("div",{className:e.classNames("collapse-icon-mini rounded",o.collapseIconMini,{[o.collapsed]:i}),children:e.jsxRuntimeExports.jsx(e.MdOutlineKeyboardArrowRight,{})}),t&&e.jsxRuntimeExports.jsx("div",{className:e.classNames("text",o.text,"text-nowrap"),children:n.title}),t&&e.jsxRuntimeExports.jsx("div",{className:e.classNames("collapse-icon",o.collapseIcon,{[o.collapsed]:i}),children:e.jsxRuntimeExports.jsx(e.MdOutlineKeyboardArrowRight,{})})]})}):e.jsxRuntimeExports.jsxs(y.Link,{to:n.disabled||n.notPermitted?"/":n.linkTo??"/",className:e.classNames("nav-link",o.navButton),children:[e.jsxRuntimeExports.jsx("div",{className:e.classNames("icon",o.icon),children:n.icon}),t&&e.jsxRuntimeExports.jsx("div",{className:e.classNames("text",o.text,"text-nowrap"),children:n.title})]})}),e.jsxRuntimeExports.jsx("div",{className:e.classNames("children-container",o.childrenContainer,{[o.visible]:i}),children:e.jsxRuntimeExports.jsx("div",{className:e.classNames("shadow rounded children",o.children),children:(j=n.children)==null?void 0:j.map(s=>e.jsxRuntimeExports.jsx(y.Link,{to:s.disabled||s.notPermitted?"/":s.linkTo??"/",className:e.classNames("nav-link child rounded",o.navButton,o.child,{[o.disabled]:s.disabled||s.notPermitted},{disabled:s.disabled||s.notPermitted}),onClick:a,children:e.jsxRuntimeExports.jsx("div",{className:e.classNames("text",o.text,"text-nowrap"),children:s.title})},s.linkTo))})})]})},W="_side-menu_15z3o_1",U="_sidebar-header_15z3o_13",G="_side-menu-content_15z3o_20",J="_expand_15z3o_24",Q="_only-logo_15z3o_28",V="_mobile_15z3o_31",X="_divider_15z3o_45",u={"side-menu":"_side-menu_15z3o_1",sideMenu:W,"sidebar-header":"_sidebar-header_15z3o_13",sidebarHeader:U,"side-menu-content":"_side-menu-content_15z3o_20",sideMenuContent:G,expand:J,"only-logo":"_only-logo_15z3o_28",onlyLogo:Q,mobile:V,divider:X},Y=({headerItem:n,searchItem:t,mainItems:i,secondaryItems:a,expanded:l,setExpanded:x,currentPath:v,useHover:c,useTooltips:N})=>{const[_,p]=m.useState(-1),{checkUserHasPermissions:d}=C.usePermissions(),E=m.useMemo(()=>i.map(s=>{var r;return{...s,notPermitted:!d(s.permissions??[],"any"),children:(r=s.children)==null?void 0:r.map(b=>({...b,notPermitted:!d(b.permissions??[],"any"),disabled:s.disabled||b.disabled}))}}),[i,d]),M=m.useMemo(()=>a.map(s=>{var r;return{...s,notPermitted:!d(s.permissions??[],"any"),children:(r=s.children)==null?void 0:r.map(b=>({...b,notPermitted:!d(b.permissions??[],"any")}))}}),[a,d]),h=s=>{p(s===_?-1:s)};m.useEffect(()=>{l||p(-1)},[l]);const R=m.useRef(null);g.useClickOutside([R],()=>x(!1));const{isMobile:j}=g.useWindowSize();return e.jsxRuntimeExports.jsxs("section",{ref:R,className:e.classNames("luminus-side-menu shadow",u.sideMenu,{[u.mobile]:j},{[u.expand]:l},{expand:l}),onMouseEnter:()=>c&&x(!0),onMouseLeave:()=>c&&x(!1),children:[e.jsxRuntimeExports.jsx("div",{className:e.classNames("sidebar-header",u.sidebarHeader,{[u.onlyLogo]:c}),role:c?void 0:"button",onClick:c?void 0:()=>x(!l),children:c?n:l?e.jsxRuntimeExports.jsxs(e.jsxRuntimeExports.Fragment,{children:[e.jsxRuntimeExports.jsx(e.MdOutlineKeyboardDoubleArrowLeft,{}),n]}):e.jsxRuntimeExports.jsx(e.MdOutlineMenu,{})}),e.jsxRuntimeExports.jsxs("ul",{className:u.sideMenuContent,children:[t?e.jsxRuntimeExports.jsx("div",{className:"p-3",children:t}):null,E.map((s,r)=>e.jsxRuntimeExports.jsx(B,{item:s,menuExpanded:l,collapsed:r===_,onCollapse:()=>h(r),currentPath:v,useHover:c,useTooltips:N,isMobile:j},s.title)),e.jsxRuntimeExports.jsx("hr",{className:e.classNames("divider",u.divider)}),M.map((s,r)=>e.jsxRuntimeExports.jsx(B,{item:s,menuExpanded:l,collapsed:r===_,onCollapse:()=>h(r),currentPath:v,useHover:c,useTooltips:N,isMobile:j},s.title))]})]})},Z="_top-bar_1usoa_1",H="_top-bar-brand_1usoa_13",k={"top-bar":"_top-bar_1usoa_1",topBar:Z,"top-bar-brand":"_top-bar-brand_1usoa_13",topBarBrand:H},ee=({appName:n,leftOffset:t,leftContent:i,centerContent:a,rightContent:l})=>e.jsxRuntimeExports.jsxs("nav",{className:e.classNames("luminus-top-bar shadow gap-1 gap-lg-3",k.topBar),style:{width:t?`calc(100% - ${t}px)`:void 0,left:t?`${t}px`:void 0},children:[e.jsxRuntimeExports.jsxs("div",{className:"d-flex gap-4 align-items-center",children:[e.jsxRuntimeExports.jsx(y.Link,{to:"/",className:e.classNames("luminus-top-bar-brand",k.topBarBrand),children:n}),i]}),a&&e.jsxRuntimeExports.jsx("div",{children:a}),e.jsxRuntimeExports.jsx("div",{className:"d-flex justify-content-end align-items-center",children:l??null})]});exports.PageContainer=e.PageContainer;exports.SideContentBar=e.SideContentBar;exports.SideMenu=Y;exports.TopBar=ee;
|
package/dist/layout.es.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { j as e, c as i, a9 as B,
|
|
2
|
-
import {
|
|
1
|
+
import { j as e, c as i, a9 as B, aE as L, bg as T, bh as R } from "./nivo-bar.es-DyZJ2B06.js";
|
|
2
|
+
import { au as Ne, bi as ye } from "./nivo-bar.es-DyZJ2B06.js";
|
|
3
3
|
import { useState as I, useRef as z, useMemo as k, useEffect as S } from "react";
|
|
4
4
|
import { Link as f } from "react-router-dom";
|
|
5
5
|
import "react-hook-form";
|
|
@@ -7,19 +7,19 @@ import "react-flexmonster";
|
|
|
7
7
|
import "@azure/msal-browser";
|
|
8
8
|
import "@azure/msal-react";
|
|
9
9
|
import { a as w, u as $ } from "./useWindowSize-OLYtjFv_.js";
|
|
10
|
-
import { u as A } from "./usePermissions-
|
|
11
|
-
const F = "_side-menu-item_1o1uo_1", K = "_disabled_1o1uo_6", O = "_nav-button_1o1uo_10", D = "_child_1o1uo_18",
|
|
10
|
+
import { u as A } from "./usePermissions-Cxf_kMRQ.js";
|
|
11
|
+
const F = "_side-menu-item_1o1uo_1", K = "_disabled_1o1uo_6", O = "_nav-button_1o1uo_10", D = "_child_1o1uo_18", E = "_text_1o1uo_23", U = "_icon_1o1uo_30", W = "_collapse-icon_1o1uo_36", q = "_collapsed_1o1uo_46", G = "_collapse-icon-mini_1o1uo_49", J = "_expanded_1o1uo_80", Q = "_children-container_1o1uo_86", V = "_visible_1o1uo_94", X = "_children_1o1uo_86", Y = "_mobile_1o1uo_106", s = {
|
|
12
12
|
"side-menu-item": "_side-menu-item_1o1uo_1",
|
|
13
13
|
sideMenuItem: F,
|
|
14
14
|
disabled: K,
|
|
15
15
|
"nav-button": "_nav-button_1o1uo_10",
|
|
16
16
|
navButton: O,
|
|
17
17
|
child: D,
|
|
18
|
-
text:
|
|
19
|
-
icon:
|
|
18
|
+
text: E,
|
|
19
|
+
icon: U,
|
|
20
20
|
"collapse-icon": "_collapse-icon_1o1uo_36",
|
|
21
|
-
collapseIcon:
|
|
22
|
-
collapsed:
|
|
21
|
+
collapseIcon: W,
|
|
22
|
+
collapsed: q,
|
|
23
23
|
"collapse-icon-mini": "_collapse-icon-mini_1o1uo_49",
|
|
24
24
|
collapseIconMini: G,
|
|
25
25
|
expanded: J,
|