@strapi/upload 5.36.0 → 5.36.1
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/admin/future/App.js +5 -12
- package/dist/admin/future/App.js.map +1 -1
- package/dist/admin/future/App.mjs +5 -12
- package/dist/admin/future/App.mjs.map +1 -1
- package/dist/admin/future/components/UploadProgressDialog.js +494 -0
- package/dist/admin/future/components/UploadProgressDialog.js.map +1 -0
- package/dist/admin/future/components/UploadProgressDialog.mjs +473 -0
- package/dist/admin/future/components/UploadProgressDialog.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/AssetsPage.js +149 -180
- package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
- package/dist/admin/future/pages/Assets/AssetsPage.mjs +156 -187
- package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZone.js +127 -0
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZone.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZone.mjs +105 -0
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZone.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js +77 -0
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs +74 -0
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs.map +1 -0
- package/dist/admin/future/services/api.js +419 -9
- package/dist/admin/future/services/api.js.map +1 -1
- package/dist/admin/future/services/api.mjs +417 -9
- package/dist/admin/future/services/api.mjs.map +1 -1
- package/dist/admin/future/store/hooks.js +10 -0
- package/dist/admin/future/store/hooks.js.map +1 -0
- package/dist/admin/future/store/hooks.mjs +7 -0
- package/dist/admin/future/store/hooks.mjs.map +1 -0
- package/dist/admin/future/store/uploadProgress.js +156 -0
- package/dist/admin/future/store/uploadProgress.js.map +1 -0
- package/dist/admin/future/store/uploadProgress.mjs +143 -0
- package/dist/admin/future/store/uploadProgress.mjs.map +1 -0
- package/dist/admin/index.js +11 -0
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +11 -0
- package/dist/admin/index.mjs.map +1 -1
- package/dist/admin/package.json.js +10 -9
- package/dist/admin/package.json.js.map +1 -1
- package/dist/admin/package.json.mjs +10 -9
- package/dist/admin/package.json.mjs.map +1 -1
- package/dist/admin/src/future/components/UploadProgressDialog.d.ts +1 -0
- package/dist/admin/src/future/pages/Assets/components/DropZone/UploadDropZone.d.ts +9 -0
- package/dist/admin/src/future/pages/Assets/hooks/useInfiniteAssets.d.ts +17 -0
- package/dist/admin/src/future/services/api.d.ts +21 -3
- package/dist/admin/src/future/store/hooks.d.ts +6 -0
- package/dist/admin/src/future/store/uploadProgress.d.ts +46 -0
- package/dist/admin/translations/en.json.js +22 -0
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +22 -0
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/server/controllers/admin-upload.js +151 -2
- package/dist/server/controllers/admin-upload.js.map +1 -1
- package/dist/server/controllers/admin-upload.mjs +151 -2
- package/dist/server/controllers/admin-upload.mjs.map +1 -1
- package/dist/server/controllers/content-api.js +8 -2
- package/dist/server/controllers/content-api.js.map +1 -1
- package/dist/server/controllers/content-api.mjs +9 -3
- package/dist/server/controllers/content-api.mjs.map +1 -1
- package/dist/server/routes/admin.js +10 -0
- package/dist/server/routes/admin.js.map +1 -1
- package/dist/server/routes/admin.mjs +10 -0
- package/dist/server/routes/admin.mjs.map +1 -1
- package/dist/server/src/controllers/admin-upload.d.ts +12 -0
- package/dist/server/src/controllers/admin-upload.d.ts.map +1 -1
- package/dist/server/src/controllers/content-api.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts +1 -0
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +1 -0
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/routes/admin.d.ts.map +1 -1
- package/dist/server/src/utils/mime-validation.d.ts +5 -0
- package/dist/server/src/utils/mime-validation.d.ts.map +1 -1
- package/dist/server/utils/mime-validation.js +7 -4
- package/dist/server/utils/mime-validation.js.map +1 -1
- package/dist/server/utils/mime-validation.mjs +7 -4
- package/dist/server/utils/mime-validation.mjs.map +1 -1
- package/dist/shared/contracts/files.d.ts +52 -0
- package/dist/shared/contracts/files.d.ts.map +1 -0
- package/package.json +10 -9
- package/dist/admin/future/pages/AIGenerationPage.js +0 -24
- package/dist/admin/future/pages/AIGenerationPage.js.map +0 -1
- package/dist/admin/future/pages/AIGenerationPage.mjs +0 -22
- package/dist/admin/future/pages/AIGenerationPage.mjs.map +0 -1
- package/dist/admin/future/pages/Assets/components/DropZone/DropZoneWithOverlay.js +0 -33
- package/dist/admin/future/pages/Assets/components/DropZone/DropZoneWithOverlay.js.map +0 -1
- package/dist/admin/future/pages/Assets/components/DropZone/DropZoneWithOverlay.mjs +0 -31
- package/dist/admin/future/pages/Assets/components/DropZone/DropZoneWithOverlay.mjs.map +0 -1
- package/dist/admin/src/future/pages/AIGenerationPage.d.ts +0 -1
- package/dist/admin/src/future/pages/Assets/components/DropZone/DropZoneWithOverlay.d.ts +0 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UploadDropZone.js","sources":["../../../../../../../admin/src/future/pages/Assets/components/DropZone/UploadDropZone.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Box, Flex, Typography } from '@strapi/design-system';\nimport { Folder } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { getTranslationKey } from '../../../../utils/translations';\n\nimport { useUploadDropZone } from './UploadDropZoneContext';\n\n/* -------------------------------------------------------------------------------------------------\n * DropZoneOverlay\n * -----------------------------------------------------------------------------------------------*/\n\nconst setOpacity = (hex: string, alpha: number) =>\n `${hex}${Math.floor(alpha * 255)\n .toString(16)\n .padStart(2, '0')}`;\n\nconst DropZoneOverlay = styled(Box)`\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: ${({ theme }) => setOpacity(theme.colors.primary200, 0.3)};\n border: 1px solid ${({ theme }) => theme.colors.primary700};\n border-radius: ${({ theme }) => theme.borderRadius};\n z-index: 1;\n pointer-events: none;\n`;\n\nconst DropZoneWithOverlay = ({ children }: { children: React.ReactNode }) => {\n const { isDragging } = useUploadDropZone();\n return (\n <Box position=\"relative\">\n {isDragging && <DropZoneOverlay />}\n {children}\n </Box>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * DropZoneMessage\n * -----------------------------------------------------------------------------------------------*/\n\nconst DropFilesMessageImpl = styled(Box)<{ $leftContentWidth: number }>`\n position: fixed;\n bottom: ${({ theme }) => theme.spaces[8]};\n left: 50%;\n transform: translateX(calc(-50% + ${({ $leftContentWidth }) => $leftContentWidth / 2}px));\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: ${({ theme }) => theme.spaces[2]};\n background: ${({ theme }) => theme.colors.primary600};\n padding: ${({ theme }) => theme.spaces[4]} ${({ theme }) => theme.spaces[6]};\n border-radius: ${({ theme }) => theme.borderRadius};\n z-index: 2;\n`;\n\ninterface DropFilesMessageProps {\n uploadDropZoneRef?: React.RefObject<HTMLDivElement>;\n}\n\nconst DropFilesMessage = ({ uploadDropZoneRef }: DropFilesMessageProps) => {\n const { formatMessage } = useIntl();\n const { isDragging } = useUploadDropZone();\n\n // Dropzone message position (relative to main content)\n const [leftContentWidth, setLeftContentWidth] = React.useState(0);\n\n // Calculate the left content width to position the dropzone message correctly\n React.useEffect(() => {\n if (!uploadDropZoneRef?.current) return;\n\n const updateRect = () => {\n const rect = uploadDropZoneRef.current?.getBoundingClientRect();\n if (rect) {\n setLeftContentWidth((prev) => (prev !== rect.left ? rect.left : prev));\n }\n };\n\n updateRect();\n const resizeObserver = new ResizeObserver(updateRect);\n resizeObserver.observe(uploadDropZoneRef.current);\n return () => resizeObserver.disconnect();\n }, [uploadDropZoneRef]);\n\n if (!isDragging) return null;\n\n return (\n <DropFilesMessageImpl $leftContentWidth={leftContentWidth}>\n <Typography textColor=\"neutral0\">\n {formatMessage({\n id: getTranslationKey('dropzone.upload.message'),\n defaultMessage: 'Drop here to upload to',\n })}\n </Typography>\n <Flex gap={2} alignItems=\"center\">\n <Folder width={20} height={20} fill=\"neutral0\" />\n <Typography textColor=\"neutral0\" fontWeight=\"semiBold\">\n Current folder{/* TODO: Replace this later with the current folder name */}\n </Typography>\n </Flex>\n </DropFilesMessageImpl>\n );\n};\n\nexport { DropZoneWithOverlay, DropFilesMessage };\n"],"names":["setOpacity","hex","alpha","Math","floor","toString","padStart","DropZoneOverlay","styled","Box","theme","colors","primary200","primary700","borderRadius","DropZoneWithOverlay","children","isDragging","useUploadDropZone","_jsxs","position","_jsx","DropFilesMessageImpl","spaces","$leftContentWidth","primary600","DropFilesMessage","uploadDropZoneRef","formatMessage","useIntl","leftContentWidth","setLeftContentWidth","React","useState","useEffect","current","updateRect","rect","getBoundingClientRect","prev","left","resizeObserver","ResizeObserver","observe","disconnect","Typography","textColor","id","getTranslationKey","defaultMessage","Flex","gap","alignItems","Folder","width","height","fill","fontWeight"],"mappings":"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"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { Box, Typography, Flex } from '@strapi/design-system';
|
|
4
|
+
import { Folder } from '@strapi/icons';
|
|
5
|
+
import { useIntl } from 'react-intl';
|
|
6
|
+
import { styled } from 'styled-components';
|
|
7
|
+
import { getTranslationKey } from '../../../../utils/translations.mjs';
|
|
8
|
+
import { useUploadDropZone } from './UploadDropZoneContext.mjs';
|
|
9
|
+
|
|
10
|
+
/* -------------------------------------------------------------------------------------------------
|
|
11
|
+
* DropZoneOverlay
|
|
12
|
+
* -----------------------------------------------------------------------------------------------*/ const setOpacity = (hex, alpha)=>`${hex}${Math.floor(alpha * 255).toString(16).padStart(2, '0')}`;
|
|
13
|
+
const DropZoneOverlay = styled(Box)`
|
|
14
|
+
position: absolute;
|
|
15
|
+
top: 0;
|
|
16
|
+
left: 0;
|
|
17
|
+
right: 0;
|
|
18
|
+
bottom: 0;
|
|
19
|
+
background: ${({ theme })=>setOpacity(theme.colors.primary200, 0.3)};
|
|
20
|
+
border: 1px solid ${({ theme })=>theme.colors.primary700};
|
|
21
|
+
border-radius: ${({ theme })=>theme.borderRadius};
|
|
22
|
+
z-index: 1;
|
|
23
|
+
pointer-events: none;
|
|
24
|
+
`;
|
|
25
|
+
const DropZoneWithOverlay = ({ children })=>{
|
|
26
|
+
const { isDragging } = useUploadDropZone();
|
|
27
|
+
return /*#__PURE__*/ jsxs(Box, {
|
|
28
|
+
position: "relative",
|
|
29
|
+
children: [
|
|
30
|
+
isDragging && /*#__PURE__*/ jsx(DropZoneOverlay, {}),
|
|
31
|
+
children
|
|
32
|
+
]
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
/* -------------------------------------------------------------------------------------------------
|
|
36
|
+
* DropZoneMessage
|
|
37
|
+
* -----------------------------------------------------------------------------------------------*/ const DropFilesMessageImpl = styled(Box)`
|
|
38
|
+
position: fixed;
|
|
39
|
+
bottom: ${({ theme })=>theme.spaces[8]};
|
|
40
|
+
left: 50%;
|
|
41
|
+
transform: translateX(calc(-50% + ${({ $leftContentWidth })=>$leftContentWidth / 2}px));
|
|
42
|
+
display: flex;
|
|
43
|
+
flex-direction: column;
|
|
44
|
+
align-items: center;
|
|
45
|
+
justify-content: center;
|
|
46
|
+
gap: ${({ theme })=>theme.spaces[2]};
|
|
47
|
+
background: ${({ theme })=>theme.colors.primary600};
|
|
48
|
+
padding: ${({ theme })=>theme.spaces[4]} ${({ theme })=>theme.spaces[6]};
|
|
49
|
+
border-radius: ${({ theme })=>theme.borderRadius};
|
|
50
|
+
z-index: 2;
|
|
51
|
+
`;
|
|
52
|
+
const DropFilesMessage = ({ uploadDropZoneRef })=>{
|
|
53
|
+
const { formatMessage } = useIntl();
|
|
54
|
+
const { isDragging } = useUploadDropZone();
|
|
55
|
+
// Dropzone message position (relative to main content)
|
|
56
|
+
const [leftContentWidth, setLeftContentWidth] = React.useState(0);
|
|
57
|
+
// Calculate the left content width to position the dropzone message correctly
|
|
58
|
+
React.useEffect(()=>{
|
|
59
|
+
if (!uploadDropZoneRef?.current) return;
|
|
60
|
+
const updateRect = ()=>{
|
|
61
|
+
const rect = uploadDropZoneRef.current?.getBoundingClientRect();
|
|
62
|
+
if (rect) {
|
|
63
|
+
setLeftContentWidth((prev)=>prev !== rect.left ? rect.left : prev);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
updateRect();
|
|
67
|
+
const resizeObserver = new ResizeObserver(updateRect);
|
|
68
|
+
resizeObserver.observe(uploadDropZoneRef.current);
|
|
69
|
+
return ()=>resizeObserver.disconnect();
|
|
70
|
+
}, [
|
|
71
|
+
uploadDropZoneRef
|
|
72
|
+
]);
|
|
73
|
+
if (!isDragging) return null;
|
|
74
|
+
return /*#__PURE__*/ jsxs(DropFilesMessageImpl, {
|
|
75
|
+
$leftContentWidth: leftContentWidth,
|
|
76
|
+
children: [
|
|
77
|
+
/*#__PURE__*/ jsx(Typography, {
|
|
78
|
+
textColor: "neutral0",
|
|
79
|
+
children: formatMessage({
|
|
80
|
+
id: getTranslationKey('dropzone.upload.message'),
|
|
81
|
+
defaultMessage: 'Drop here to upload to'
|
|
82
|
+
})
|
|
83
|
+
}),
|
|
84
|
+
/*#__PURE__*/ jsxs(Flex, {
|
|
85
|
+
gap: 2,
|
|
86
|
+
alignItems: "center",
|
|
87
|
+
children: [
|
|
88
|
+
/*#__PURE__*/ jsx(Folder, {
|
|
89
|
+
width: 20,
|
|
90
|
+
height: 20,
|
|
91
|
+
fill: "neutral0"
|
|
92
|
+
}),
|
|
93
|
+
/*#__PURE__*/ jsx(Typography, {
|
|
94
|
+
textColor: "neutral0",
|
|
95
|
+
fontWeight: "semiBold",
|
|
96
|
+
children: "Current folder"
|
|
97
|
+
})
|
|
98
|
+
]
|
|
99
|
+
})
|
|
100
|
+
]
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export { DropFilesMessage, DropZoneWithOverlay };
|
|
105
|
+
//# sourceMappingURL=UploadDropZone.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UploadDropZone.mjs","sources":["../../../../../../../admin/src/future/pages/Assets/components/DropZone/UploadDropZone.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Box, Flex, Typography } from '@strapi/design-system';\nimport { Folder } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { getTranslationKey } from '../../../../utils/translations';\n\nimport { useUploadDropZone } from './UploadDropZoneContext';\n\n/* -------------------------------------------------------------------------------------------------\n * DropZoneOverlay\n * -----------------------------------------------------------------------------------------------*/\n\nconst setOpacity = (hex: string, alpha: number) =>\n `${hex}${Math.floor(alpha * 255)\n .toString(16)\n .padStart(2, '0')}`;\n\nconst DropZoneOverlay = styled(Box)`\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: ${({ theme }) => setOpacity(theme.colors.primary200, 0.3)};\n border: 1px solid ${({ theme }) => theme.colors.primary700};\n border-radius: ${({ theme }) => theme.borderRadius};\n z-index: 1;\n pointer-events: none;\n`;\n\nconst DropZoneWithOverlay = ({ children }: { children: React.ReactNode }) => {\n const { isDragging } = useUploadDropZone();\n return (\n <Box position=\"relative\">\n {isDragging && <DropZoneOverlay />}\n {children}\n </Box>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * DropZoneMessage\n * -----------------------------------------------------------------------------------------------*/\n\nconst DropFilesMessageImpl = styled(Box)<{ $leftContentWidth: number }>`\n position: fixed;\n bottom: ${({ theme }) => theme.spaces[8]};\n left: 50%;\n transform: translateX(calc(-50% + ${({ $leftContentWidth }) => $leftContentWidth / 2}px));\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: ${({ theme }) => theme.spaces[2]};\n background: ${({ theme }) => theme.colors.primary600};\n padding: ${({ theme }) => theme.spaces[4]} ${({ theme }) => theme.spaces[6]};\n border-radius: ${({ theme }) => theme.borderRadius};\n z-index: 2;\n`;\n\ninterface DropFilesMessageProps {\n uploadDropZoneRef?: React.RefObject<HTMLDivElement>;\n}\n\nconst DropFilesMessage = ({ uploadDropZoneRef }: DropFilesMessageProps) => {\n const { formatMessage } = useIntl();\n const { isDragging } = useUploadDropZone();\n\n // Dropzone message position (relative to main content)\n const [leftContentWidth, setLeftContentWidth] = React.useState(0);\n\n // Calculate the left content width to position the dropzone message correctly\n React.useEffect(() => {\n if (!uploadDropZoneRef?.current) return;\n\n const updateRect = () => {\n const rect = uploadDropZoneRef.current?.getBoundingClientRect();\n if (rect) {\n setLeftContentWidth((prev) => (prev !== rect.left ? rect.left : prev));\n }\n };\n\n updateRect();\n const resizeObserver = new ResizeObserver(updateRect);\n resizeObserver.observe(uploadDropZoneRef.current);\n return () => resizeObserver.disconnect();\n }, [uploadDropZoneRef]);\n\n if (!isDragging) return null;\n\n return (\n <DropFilesMessageImpl $leftContentWidth={leftContentWidth}>\n <Typography textColor=\"neutral0\">\n {formatMessage({\n id: getTranslationKey('dropzone.upload.message'),\n defaultMessage: 'Drop here to upload to',\n })}\n </Typography>\n <Flex gap={2} alignItems=\"center\">\n <Folder width={20} height={20} fill=\"neutral0\" />\n <Typography textColor=\"neutral0\" fontWeight=\"semiBold\">\n Current folder{/* TODO: Replace this later with the current folder name */}\n </Typography>\n </Flex>\n </DropFilesMessageImpl>\n );\n};\n\nexport { DropZoneWithOverlay, DropFilesMessage };\n"],"names":["setOpacity","hex","alpha","Math","floor","toString","padStart","DropZoneOverlay","styled","Box","theme","colors","primary200","primary700","borderRadius","DropZoneWithOverlay","children","isDragging","useUploadDropZone","_jsxs","position","_jsx","DropFilesMessageImpl","spaces","$leftContentWidth","primary600","DropFilesMessage","uploadDropZoneRef","formatMessage","useIntl","leftContentWidth","setLeftContentWidth","React","useState","useEffect","current","updateRect","rect","getBoundingClientRect","prev","left","resizeObserver","ResizeObserver","observe","disconnect","Typography","textColor","id","getTranslationKey","defaultMessage","Flex","gap","alignItems","Folder","width","height","fill","fontWeight"],"mappings":";;;;;;;;;AAWA;;AAEkG,qGAElG,MAAMA,UAAa,GAAA,CAACC,KAAaC,KAC/B,GAAA,CAAA,EAAGD,MAAME,IAAKC,CAAAA,KAAK,CAACF,KAAAA,GAAQ,KACzBG,QAAQ,CAAC,IACTC,QAAQ,CAAC,GAAG,GAAM,CAAA,CAAA,CAAA;AAEvB,MAAMC,eAAAA,GAAkBC,MAAOC,CAAAA,GAAAA,CAAI;;;;;;cAMrB,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAKV,UAAWU,CAAAA,KAAAA,CAAMC,MAAM,CAACC,UAAU,EAAE,GAAK,CAAA,CAAA;oBACpD,EAAE,CAAC,EAAEF,KAAK,EAAE,GAAKA,KAAMC,CAAAA,MAAM,CAACE,UAAU,CAAC;AAC5C,iBAAA,EAAE,CAAC,EAAEH,KAAK,EAAE,GAAKA,KAAAA,CAAMI,YAAY,CAAC;;;AAGrD,CAAC;AAED,MAAMC,mBAAsB,GAAA,CAAC,EAAEC,QAAQ,EAAiC,GAAA;IACtE,MAAM,EAAEC,UAAU,EAAE,GAAGC,iBAAAA,EAAAA;AACvB,IAAA,qBACEC,IAACV,CAAAA,GAAAA,EAAAA;QAAIW,QAAS,EAAA,UAAA;;AACXH,YAAAA,UAAAA,kBAAcI,GAACd,CAAAA,eAAAA,EAAAA,EAAAA,CAAAA;AACfS,YAAAA;;;AAGP;AAEA;;AAEkG,qGAElG,MAAMM,oBAAAA,GAAuBd,MAAOC,CAAAA,GAAAA,CAAmC;;UAE7D,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAKA,KAAMa,CAAAA,MAAM,CAAC,CAAA,CAAE,CAAC;;AAEP,oCAAA,EAAE,CAAC,EAAEC,iBAAiB,EAAE,GAAKA,oBAAoB,CAAE,CAAA;;;;;OAKhF,EAAE,CAAC,EAAEd,KAAK,EAAE,GAAKA,KAAMa,CAAAA,MAAM,CAAC,CAAA,CAAE,CAAC;cAC1B,EAAE,CAAC,EAAEb,KAAK,EAAE,GAAKA,KAAMC,CAAAA,MAAM,CAACc,UAAU,CAAC;WAC5C,EAAE,CAAC,EAAEf,KAAK,EAAE,GAAKA,KAAMa,CAAAA,MAAM,CAAC,CAAE,CAAA,CAAC,CAAC,EAAE,CAAC,EAAEb,KAAK,EAAE,GAAKA,KAAMa,CAAAA,MAAM,CAAC,CAAA,CAAE,CAAC;AAC7D,iBAAA,EAAE,CAAC,EAAEb,KAAK,EAAE,GAAKA,KAAAA,CAAMI,YAAY,CAAC;;AAErD,CAAC;AAMD,MAAMY,gBAAmB,GAAA,CAAC,EAAEC,iBAAiB,EAAyB,GAAA;IACpE,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;IAC1B,MAAM,EAAEZ,UAAU,EAAE,GAAGC,iBAAAA,EAAAA;;AAGvB,IAAA,MAAM,CAACY,gBAAkBC,EAAAA,mBAAAA,CAAoB,GAAGC,KAAAA,CAAMC,QAAQ,CAAC,CAAA,CAAA;;AAG/DD,IAAAA,KAAAA,CAAME,SAAS,CAAC,IAAA;QACd,IAAI,CAACP,mBAAmBQ,OAAS,EAAA;AAEjC,QAAA,MAAMC,UAAa,GAAA,IAAA;YACjB,MAAMC,IAAAA,GAAOV,iBAAkBQ,CAAAA,OAAO,EAAEG,qBAAAA,EAAAA;AACxC,YAAA,IAAID,IAAM,EAAA;gBACRN,mBAAoB,CAAA,CAACQ,OAAUA,IAASF,KAAAA,IAAAA,CAAKG,IAAI,GAAGH,IAAAA,CAAKG,IAAI,GAAGD,IAAAA,CAAAA;AAClE;AACF,SAAA;AAEAH,QAAAA,UAAAA,EAAAA;QACA,MAAMK,cAAAA,GAAiB,IAAIC,cAAeN,CAAAA,UAAAA,CAAAA;QAC1CK,cAAeE,CAAAA,OAAO,CAAChB,iBAAAA,CAAkBQ,OAAO,CAAA;QAChD,OAAO,IAAMM,eAAeG,UAAU,EAAA;KACrC,EAAA;AAACjB,QAAAA;AAAkB,KAAA,CAAA;IAEtB,IAAI,CAACV,YAAY,OAAO,IAAA;AAExB,IAAA,qBACEE,IAACG,CAAAA,oBAAAA,EAAAA;QAAqBE,iBAAmBM,EAAAA,gBAAAA;;0BACvCT,GAACwB,CAAAA,UAAAA,EAAAA;gBAAWC,SAAU,EAAA,UAAA;0BACnBlB,aAAc,CAAA;AACbmB,oBAAAA,EAAAA,EAAIC,iBAAkB,CAAA,yBAAA,CAAA;oBACtBC,cAAgB,EAAA;AAClB,iBAAA;;0BAEF9B,IAAC+B,CAAAA,IAAAA,EAAAA;gBAAKC,GAAK,EAAA,CAAA;gBAAGC,UAAW,EAAA,QAAA;;kCACvB/B,GAACgC,CAAAA,MAAAA,EAAAA;wBAAOC,KAAO,EAAA,EAAA;wBAAIC,MAAQ,EAAA,EAAA;wBAAIC,IAAK,EAAA;;kCACpCnC,GAACwB,CAAAA,UAAAA,EAAAA;wBAAWC,SAAU,EAAA,UAAA;wBAAWW,UAAW,EAAA,UAAA;AAAW,wBAAA,QAAA,EAAA;;;;;;AAM/D;;;;"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
var assets = require('../../../services/assets.js');
|
|
5
|
+
|
|
6
|
+
const PAGE_SIZE = 20;
|
|
7
|
+
const useInfiniteAssets = ({ folder = null, sort } = {})=>{
|
|
8
|
+
const [page, setPage] = React.useState(1);
|
|
9
|
+
const lastResultsRef = React.useRef([]);
|
|
10
|
+
const isMountRef = React.useRef(true);
|
|
11
|
+
const { currentData: data, isLoading, isFetching, error } = assets.useGetAssetsQuery({
|
|
12
|
+
folder,
|
|
13
|
+
page,
|
|
14
|
+
pageSize: PAGE_SIZE,
|
|
15
|
+
sort
|
|
16
|
+
});
|
|
17
|
+
const pagination = data?.pagination;
|
|
18
|
+
// Accumulate pages. When cache is invalidated the current page is refetched
|
|
19
|
+
// detect this and reset to avoid a gap in the results.
|
|
20
|
+
const assets$1 = React.useMemo(()=>{
|
|
21
|
+
if (!data) {
|
|
22
|
+
return lastResultsRef.current;
|
|
23
|
+
}
|
|
24
|
+
const currentPageResults = data.results;
|
|
25
|
+
if (page === 1) {
|
|
26
|
+
lastResultsRef.current = currentPageResults;
|
|
27
|
+
} else {
|
|
28
|
+
// If accumulated length doesn't match expectation, cache was cleared
|
|
29
|
+
const expectedPrior = (page - 1) * PAGE_SIZE;
|
|
30
|
+
if (lastResultsRef.current.length < expectedPrior - PAGE_SIZE) {
|
|
31
|
+
return lastResultsRef.current;
|
|
32
|
+
}
|
|
33
|
+
// Only append if these aren't already accumulated
|
|
34
|
+
if (lastResultsRef.current.length < page * PAGE_SIZE) {
|
|
35
|
+
lastResultsRef.current = [
|
|
36
|
+
...lastResultsRef.current,
|
|
37
|
+
...currentPageResults
|
|
38
|
+
];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return lastResultsRef.current;
|
|
42
|
+
}, [
|
|
43
|
+
data,
|
|
44
|
+
page
|
|
45
|
+
]);
|
|
46
|
+
// Reset on filter/sort change — skip the initial mount since the memo
|
|
47
|
+
// already handles page 1 correctly
|
|
48
|
+
React.useEffect(()=>{
|
|
49
|
+
if (isMountRef.current) {
|
|
50
|
+
isMountRef.current = false;
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
setPage(1);
|
|
54
|
+
lastResultsRef.current = [];
|
|
55
|
+
}, [
|
|
56
|
+
folder,
|
|
57
|
+
sort
|
|
58
|
+
]);
|
|
59
|
+
const hasNextPage = pagination ? page < pagination.pageCount : false;
|
|
60
|
+
const isFetchingMore = isFetching && page > 1;
|
|
61
|
+
const fetchNextPage = React.useCallback(()=>{
|
|
62
|
+
setPage((prev)=>prev + 1);
|
|
63
|
+
}, []);
|
|
64
|
+
return {
|
|
65
|
+
assets: assets$1,
|
|
66
|
+
pagination,
|
|
67
|
+
isLoading,
|
|
68
|
+
isFetchingMore,
|
|
69
|
+
hasNextPage,
|
|
70
|
+
fetchNextPage,
|
|
71
|
+
error
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
exports.PAGE_SIZE = PAGE_SIZE;
|
|
76
|
+
exports.useInfiniteAssets = useInfiniteAssets;
|
|
77
|
+
//# sourceMappingURL=useInfiniteAssets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useInfiniteAssets.js","sources":["../../../../../../admin/src/future/pages/Assets/hooks/useInfiniteAssets.ts"],"sourcesContent":["import { useState, useCallback, useMemo, useEffect, useRef } from 'react';\n\nimport { useGetAssetsQuery } from '../../../services/assets';\n\nimport type { File } from '../../../../../../shared/contracts/files';\n\nconst PAGE_SIZE = 20;\n\ninterface UseInfiniteAssetsOptions {\n folder?: number | null;\n sort?: string;\n}\n\nconst useInfiniteAssets = ({ folder = null, sort }: UseInfiniteAssetsOptions = {}) => {\n const [page, setPage] = useState(1);\n const lastResultsRef = useRef<File[]>([]);\n const isMountRef = useRef(true);\n\n const {\n currentData: data,\n isLoading,\n isFetching,\n error,\n } = useGetAssetsQuery({\n folder,\n page,\n pageSize: PAGE_SIZE,\n sort,\n });\n\n const pagination = data?.pagination;\n\n // Accumulate pages. When cache is invalidated the current page is refetched\n // detect this and reset to avoid a gap in the results.\n const assets = useMemo(() => {\n if (!data) {\n return lastResultsRef.current;\n }\n\n const currentPageResults = data.results;\n\n if (page === 1) {\n lastResultsRef.current = currentPageResults;\n } else {\n // If accumulated length doesn't match expectation, cache was cleared\n const expectedPrior = (page - 1) * PAGE_SIZE;\n if (lastResultsRef.current.length < expectedPrior - PAGE_SIZE) {\n return lastResultsRef.current;\n }\n\n // Only append if these aren't already accumulated\n if (lastResultsRef.current.length < page * PAGE_SIZE) {\n lastResultsRef.current = [...lastResultsRef.current, ...currentPageResults];\n }\n }\n\n return lastResultsRef.current;\n }, [data, page]);\n\n // Reset on filter/sort change — skip the initial mount since the memo\n // already handles page 1 correctly\n useEffect(() => {\n if (isMountRef.current) {\n isMountRef.current = false;\n\n return;\n }\n setPage(1);\n lastResultsRef.current = [];\n }, [folder, sort]);\n\n const hasNextPage = pagination ? page < pagination.pageCount : false;\n const isFetchingMore = isFetching && page > 1;\n\n const fetchNextPage = useCallback(() => {\n setPage((prev) => prev + 1);\n }, []);\n\n return { assets, pagination, isLoading, isFetchingMore, hasNextPage, fetchNextPage, error };\n};\n\nexport { useInfiniteAssets };\nexport { PAGE_SIZE };\n"],"names":["PAGE_SIZE","useInfiniteAssets","folder","sort","page","setPage","useState","lastResultsRef","useRef","isMountRef","currentData","data","isLoading","isFetching","error","useGetAssetsQuery","pageSize","pagination","assets","useMemo","current","currentPageResults","results","expectedPrior","length","useEffect","hasNextPage","pageCount","isFetchingMore","fetchNextPage","useCallback","prev"],"mappings":";;;;;AAMA,MAAMA,SAAY,GAAA;AAOZC,MAAAA,iBAAAA,GAAoB,CAAC,EAAEC,MAAS,GAAA,IAAI,EAAEC,IAAI,EAA4B,GAAG,EAAE,GAAA;AAC/E,IAAA,MAAM,CAACC,IAAAA,EAAMC,OAAQ,CAAA,GAAGC,cAAS,CAAA,CAAA,CAAA;IACjC,MAAMC,cAAAA,GAAiBC,aAAe,EAAE,CAAA;AACxC,IAAA,MAAMC,aAAaD,YAAO,CAAA,IAAA,CAAA;IAE1B,MAAM,EACJE,WAAaC,EAAAA,IAAI,EACjBC,SAAS,EACTC,UAAU,EACVC,KAAK,EACN,GAAGC,wBAAkB,CAAA;AACpBb,QAAAA,MAAAA;AACAE,QAAAA,IAAAA;QACAY,QAAUhB,EAAAA,SAAAA;AACVG,QAAAA;AACF,KAAA,CAAA;AAEA,IAAA,MAAMc,aAAaN,IAAMM,EAAAA,UAAAA;;;AAIzB,IAAA,MAAMC,WAASC,aAAQ,CAAA,IAAA;AACrB,QAAA,IAAI,CAACR,IAAM,EAAA;AACT,YAAA,OAAOJ,eAAea,OAAO;AAC/B;QAEA,MAAMC,kBAAAA,GAAqBV,KAAKW,OAAO;AAEvC,QAAA,IAAIlB,SAAS,CAAG,EAAA;AACdG,YAAAA,cAAAA,CAAea,OAAO,GAAGC,kBAAAA;SACpB,MAAA;;AAEL,YAAA,MAAME,aAAgB,GAACnB,CAAAA,IAAAA,GAAO,CAAA,IAAKJ,SAAAA;AACnC,YAAA,IAAIO,eAAea,OAAO,CAACI,MAAM,GAAGD,gBAAgBvB,SAAW,EAAA;AAC7D,gBAAA,OAAOO,eAAea,OAAO;AAC/B;;AAGA,YAAA,IAAIb,eAAea,OAAO,CAACI,MAAM,GAAGpB,OAAOJ,SAAW,EAAA;AACpDO,gBAAAA,cAAAA,CAAea,OAAO,GAAG;AAAIb,oBAAAA,GAAAA,cAAAA,CAAea,OAAO;AAAKC,oBAAAA,GAAAA;AAAmB,iBAAA;AAC7E;AACF;AAEA,QAAA,OAAOd,eAAea,OAAO;KAC5B,EAAA;AAACT,QAAAA,IAAAA;AAAMP,QAAAA;AAAK,KAAA,CAAA;;;IAIfqB,eAAU,CAAA,IAAA;QACR,IAAIhB,UAAAA,CAAWW,OAAO,EAAE;AACtBX,YAAAA,UAAAA,CAAWW,OAAO,GAAG,KAAA;AAErB,YAAA;AACF;QACAf,OAAQ,CAAA,CAAA,CAAA;QACRE,cAAea,CAAAA,OAAO,GAAG,EAAE;KAC1B,EAAA;AAAClB,QAAAA,MAAAA;AAAQC,QAAAA;AAAK,KAAA,CAAA;AAEjB,IAAA,MAAMuB,WAAcT,GAAAA,UAAAA,GAAab,IAAOa,GAAAA,UAAAA,CAAWU,SAAS,GAAG,KAAA;IAC/D,MAAMC,cAAAA,GAAiBf,cAAcT,IAAO,GAAA,CAAA;AAE5C,IAAA,MAAMyB,gBAAgBC,iBAAY,CAAA,IAAA;QAChCzB,OAAQ,CAAA,CAAC0B,OAASA,IAAO,GAAA,CAAA,CAAA;AAC3B,KAAA,EAAG,EAAE,CAAA;IAEL,OAAO;AAAEb,gBAAAA,QAAAA;AAAQD,QAAAA,UAAAA;AAAYL,QAAAA,SAAAA;AAAWgB,QAAAA,cAAAA;AAAgBF,QAAAA,WAAAA;AAAaG,QAAAA,aAAAA;AAAef,QAAAA;AAAM,KAAA;AAC5F;;;;;"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { useState, useRef, useMemo, useEffect, useCallback } from 'react';
|
|
2
|
+
import { useGetAssetsQuery } from '../../../services/assets.mjs';
|
|
3
|
+
|
|
4
|
+
const PAGE_SIZE = 20;
|
|
5
|
+
const useInfiniteAssets = ({ folder = null, sort } = {})=>{
|
|
6
|
+
const [page, setPage] = useState(1);
|
|
7
|
+
const lastResultsRef = useRef([]);
|
|
8
|
+
const isMountRef = useRef(true);
|
|
9
|
+
const { currentData: data, isLoading, isFetching, error } = useGetAssetsQuery({
|
|
10
|
+
folder,
|
|
11
|
+
page,
|
|
12
|
+
pageSize: PAGE_SIZE,
|
|
13
|
+
sort
|
|
14
|
+
});
|
|
15
|
+
const pagination = data?.pagination;
|
|
16
|
+
// Accumulate pages. When cache is invalidated the current page is refetched
|
|
17
|
+
// detect this and reset to avoid a gap in the results.
|
|
18
|
+
const assets = useMemo(()=>{
|
|
19
|
+
if (!data) {
|
|
20
|
+
return lastResultsRef.current;
|
|
21
|
+
}
|
|
22
|
+
const currentPageResults = data.results;
|
|
23
|
+
if (page === 1) {
|
|
24
|
+
lastResultsRef.current = currentPageResults;
|
|
25
|
+
} else {
|
|
26
|
+
// If accumulated length doesn't match expectation, cache was cleared
|
|
27
|
+
const expectedPrior = (page - 1) * PAGE_SIZE;
|
|
28
|
+
if (lastResultsRef.current.length < expectedPrior - PAGE_SIZE) {
|
|
29
|
+
return lastResultsRef.current;
|
|
30
|
+
}
|
|
31
|
+
// Only append if these aren't already accumulated
|
|
32
|
+
if (lastResultsRef.current.length < page * PAGE_SIZE) {
|
|
33
|
+
lastResultsRef.current = [
|
|
34
|
+
...lastResultsRef.current,
|
|
35
|
+
...currentPageResults
|
|
36
|
+
];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return lastResultsRef.current;
|
|
40
|
+
}, [
|
|
41
|
+
data,
|
|
42
|
+
page
|
|
43
|
+
]);
|
|
44
|
+
// Reset on filter/sort change — skip the initial mount since the memo
|
|
45
|
+
// already handles page 1 correctly
|
|
46
|
+
useEffect(()=>{
|
|
47
|
+
if (isMountRef.current) {
|
|
48
|
+
isMountRef.current = false;
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
setPage(1);
|
|
52
|
+
lastResultsRef.current = [];
|
|
53
|
+
}, [
|
|
54
|
+
folder,
|
|
55
|
+
sort
|
|
56
|
+
]);
|
|
57
|
+
const hasNextPage = pagination ? page < pagination.pageCount : false;
|
|
58
|
+
const isFetchingMore = isFetching && page > 1;
|
|
59
|
+
const fetchNextPage = useCallback(()=>{
|
|
60
|
+
setPage((prev)=>prev + 1);
|
|
61
|
+
}, []);
|
|
62
|
+
return {
|
|
63
|
+
assets,
|
|
64
|
+
pagination,
|
|
65
|
+
isLoading,
|
|
66
|
+
isFetchingMore,
|
|
67
|
+
hasNextPage,
|
|
68
|
+
fetchNextPage,
|
|
69
|
+
error
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export { PAGE_SIZE, useInfiniteAssets };
|
|
74
|
+
//# sourceMappingURL=useInfiniteAssets.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useInfiniteAssets.mjs","sources":["../../../../../../admin/src/future/pages/Assets/hooks/useInfiniteAssets.ts"],"sourcesContent":["import { useState, useCallback, useMemo, useEffect, useRef } from 'react';\n\nimport { useGetAssetsQuery } from '../../../services/assets';\n\nimport type { File } from '../../../../../../shared/contracts/files';\n\nconst PAGE_SIZE = 20;\n\ninterface UseInfiniteAssetsOptions {\n folder?: number | null;\n sort?: string;\n}\n\nconst useInfiniteAssets = ({ folder = null, sort }: UseInfiniteAssetsOptions = {}) => {\n const [page, setPage] = useState(1);\n const lastResultsRef = useRef<File[]>([]);\n const isMountRef = useRef(true);\n\n const {\n currentData: data,\n isLoading,\n isFetching,\n error,\n } = useGetAssetsQuery({\n folder,\n page,\n pageSize: PAGE_SIZE,\n sort,\n });\n\n const pagination = data?.pagination;\n\n // Accumulate pages. When cache is invalidated the current page is refetched\n // detect this and reset to avoid a gap in the results.\n const assets = useMemo(() => {\n if (!data) {\n return lastResultsRef.current;\n }\n\n const currentPageResults = data.results;\n\n if (page === 1) {\n lastResultsRef.current = currentPageResults;\n } else {\n // If accumulated length doesn't match expectation, cache was cleared\n const expectedPrior = (page - 1) * PAGE_SIZE;\n if (lastResultsRef.current.length < expectedPrior - PAGE_SIZE) {\n return lastResultsRef.current;\n }\n\n // Only append if these aren't already accumulated\n if (lastResultsRef.current.length < page * PAGE_SIZE) {\n lastResultsRef.current = [...lastResultsRef.current, ...currentPageResults];\n }\n }\n\n return lastResultsRef.current;\n }, [data, page]);\n\n // Reset on filter/sort change — skip the initial mount since the memo\n // already handles page 1 correctly\n useEffect(() => {\n if (isMountRef.current) {\n isMountRef.current = false;\n\n return;\n }\n setPage(1);\n lastResultsRef.current = [];\n }, [folder, sort]);\n\n const hasNextPage = pagination ? page < pagination.pageCount : false;\n const isFetchingMore = isFetching && page > 1;\n\n const fetchNextPage = useCallback(() => {\n setPage((prev) => prev + 1);\n }, []);\n\n return { assets, pagination, isLoading, isFetchingMore, hasNextPage, fetchNextPage, error };\n};\n\nexport { useInfiniteAssets };\nexport { PAGE_SIZE };\n"],"names":["PAGE_SIZE","useInfiniteAssets","folder","sort","page","setPage","useState","lastResultsRef","useRef","isMountRef","currentData","data","isLoading","isFetching","error","useGetAssetsQuery","pageSize","pagination","assets","useMemo","current","currentPageResults","results","expectedPrior","length","useEffect","hasNextPage","pageCount","isFetchingMore","fetchNextPage","useCallback","prev"],"mappings":";;;AAMA,MAAMA,SAAY,GAAA;AAOZC,MAAAA,iBAAAA,GAAoB,CAAC,EAAEC,MAAS,GAAA,IAAI,EAAEC,IAAI,EAA4B,GAAG,EAAE,GAAA;AAC/E,IAAA,MAAM,CAACC,IAAAA,EAAMC,OAAQ,CAAA,GAAGC,QAAS,CAAA,CAAA,CAAA;IACjC,MAAMC,cAAAA,GAAiBC,OAAe,EAAE,CAAA;AACxC,IAAA,MAAMC,aAAaD,MAAO,CAAA,IAAA,CAAA;IAE1B,MAAM,EACJE,WAAaC,EAAAA,IAAI,EACjBC,SAAS,EACTC,UAAU,EACVC,KAAK,EACN,GAAGC,iBAAkB,CAAA;AACpBb,QAAAA,MAAAA;AACAE,QAAAA,IAAAA;QACAY,QAAUhB,EAAAA,SAAAA;AACVG,QAAAA;AACF,KAAA,CAAA;AAEA,IAAA,MAAMc,aAAaN,IAAMM,EAAAA,UAAAA;;;AAIzB,IAAA,MAAMC,SAASC,OAAQ,CAAA,IAAA;AACrB,QAAA,IAAI,CAACR,IAAM,EAAA;AACT,YAAA,OAAOJ,eAAea,OAAO;AAC/B;QAEA,MAAMC,kBAAAA,GAAqBV,KAAKW,OAAO;AAEvC,QAAA,IAAIlB,SAAS,CAAG,EAAA;AACdG,YAAAA,cAAAA,CAAea,OAAO,GAAGC,kBAAAA;SACpB,MAAA;;AAEL,YAAA,MAAME,aAAgB,GAACnB,CAAAA,IAAAA,GAAO,CAAA,IAAKJ,SAAAA;AACnC,YAAA,IAAIO,eAAea,OAAO,CAACI,MAAM,GAAGD,gBAAgBvB,SAAW,EAAA;AAC7D,gBAAA,OAAOO,eAAea,OAAO;AAC/B;;AAGA,YAAA,IAAIb,eAAea,OAAO,CAACI,MAAM,GAAGpB,OAAOJ,SAAW,EAAA;AACpDO,gBAAAA,cAAAA,CAAea,OAAO,GAAG;AAAIb,oBAAAA,GAAAA,cAAAA,CAAea,OAAO;AAAKC,oBAAAA,GAAAA;AAAmB,iBAAA;AAC7E;AACF;AAEA,QAAA,OAAOd,eAAea,OAAO;KAC5B,EAAA;AAACT,QAAAA,IAAAA;AAAMP,QAAAA;AAAK,KAAA,CAAA;;;IAIfqB,SAAU,CAAA,IAAA;QACR,IAAIhB,UAAAA,CAAWW,OAAO,EAAE;AACtBX,YAAAA,UAAAA,CAAWW,OAAO,GAAG,KAAA;AAErB,YAAA;AACF;QACAf,OAAQ,CAAA,CAAA,CAAA;QACRE,cAAea,CAAAA,OAAO,GAAG,EAAE;KAC1B,EAAA;AAAClB,QAAAA,MAAAA;AAAQC,QAAAA;AAAK,KAAA,CAAA;AAEjB,IAAA,MAAMuB,WAAcT,GAAAA,UAAAA,GAAab,IAAOa,GAAAA,UAAAA,CAAWU,SAAS,GAAG,KAAA;IAC/D,MAAMC,cAAAA,GAAiBf,cAAcT,IAAO,GAAA,CAAA;AAE5C,IAAA,MAAMyB,gBAAgBC,WAAY,CAAA,IAAA;QAChCzB,OAAQ,CAAA,CAAC0B,OAASA,IAAO,GAAA,CAAA,CAAA;AAC3B,KAAA,EAAG,EAAE,CAAA;IAEL,OAAO;AAAEb,QAAAA,MAAAA;AAAQD,QAAAA,UAAAA;AAAYL,QAAAA,SAAAA;AAAWgB,QAAAA,cAAAA;AAAgBF,QAAAA,WAAAA;AAAaG,QAAAA,aAAAA;AAAef,QAAAA;AAAM,KAAA;AAC5F;;;;"}
|