@fountain-ui/lab 2.0.0-beta.34 → 2.0.0-beta.35

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.
Files changed (38) hide show
  1. package/build/commonjs/ComicViewer/ComicViewer.js +197 -143
  2. package/build/commonjs/ComicViewer/ComicViewer.js.map +1 -1
  3. package/build/commonjs/ComicViewer/ComicViewerProps.js +0 -12
  4. package/build/commonjs/ComicViewer/ComicViewerProps.js.map +1 -1
  5. package/build/commonjs/ComicViewer/ReloadButton.js +43 -0
  6. package/build/commonjs/ComicViewer/ReloadButton.js.map +1 -0
  7. package/build/commonjs/ComicViewer/ViewerItem.js +37 -171
  8. package/build/commonjs/ComicViewer/ViewerItem.js.map +1 -1
  9. package/build/commonjs/ComicViewer/checkered-loading.jpg +0 -0
  10. package/build/commonjs/ComicViewer/index.js.map +1 -1
  11. package/build/module/ComicViewer/ComicViewer.js +196 -143
  12. package/build/module/ComicViewer/ComicViewer.js.map +1 -1
  13. package/build/module/ComicViewer/ComicViewerProps.js +1 -6
  14. package/build/module/ComicViewer/ComicViewerProps.js.map +1 -1
  15. package/build/module/ComicViewer/ReloadButton.js +29 -0
  16. package/build/module/ComicViewer/ReloadButton.js.map +1 -0
  17. package/build/module/ComicViewer/ViewerItem.js +39 -173
  18. package/build/module/ComicViewer/ViewerItem.js.map +1 -1
  19. package/build/module/ComicViewer/checkered-loading.jpg +0 -0
  20. package/build/module/ComicViewer/index.js.map +1 -1
  21. package/build/typescript/ComicViewer/ComicViewer.d.ts +1 -1
  22. package/build/typescript/ComicViewer/ComicViewerProps.d.ts +14 -89
  23. package/build/typescript/ComicViewer/ReloadButton.d.ts +6 -0
  24. package/build/typescript/ComicViewer/ViewerItem.d.ts +37 -7
  25. package/build/typescript/ComicViewer/index.d.ts +2 -2
  26. package/package.json +2 -2
  27. package/src/ComicViewer/ComicViewer.tsx +212 -157
  28. package/src/ComicViewer/ComicViewerProps.ts +14 -106
  29. package/src/ComicViewer/ReloadButton.tsx +33 -0
  30. package/src/ComicViewer/ViewerItem.tsx +81 -184
  31. package/src/ComicViewer/checkered-loading.jpg +0 -0
  32. package/src/ComicViewer/index.ts +2 -2
  33. package/build/commonjs/ComicViewer/ComicViewerItemProps.js +0 -6
  34. package/build/commonjs/ComicViewer/ComicViewerItemProps.js.map +0 -1
  35. package/build/module/ComicViewer/ComicViewerItemProps.js +0 -2
  36. package/build/module/ComicViewer/ComicViewerItemProps.js.map +0 -1
  37. package/build/typescript/ComicViewer/ComicViewerItemProps.d.ts +0 -34
  38. package/src/ComicViewer/ComicViewerItemProps.ts +0 -42
@@ -3,184 +3,238 @@ function _extends() { _extends = Object.assign ? Object.assign.bind() : function
3
3
  import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
4
  import { FlatList } from 'react-native';
5
5
  import * as R from 'ramda';
6
- import { STATE } from './ComicViewerProps';
6
+ import { useDebounce } from '@fountain-ui/core';
7
7
  import ViewerItem from './ViewerItem';
8
8
 
9
- const getItemHeights = items => R.map(content => content.height)(items);
10
-
11
9
  const appender = (left, right) => [left + right, left + right];
12
10
 
13
- const getHeightAccum = itemHeights => R.mapAccum(appender, 0, itemHeights);
11
+ const getHeightAccum = heights => R.mapAccum(appender, 0, heights);
12
+
13
+ const keyExtractor = item => String(item.index);
14
+
15
+ const createInitialImageState = dimension => ({
16
+ isNewUrlIncoming: false,
17
+ totalErrorCount: 0,
18
+ dimension
19
+ });
14
20
 
15
- const keyExtractor = item => `${item.sortKey}`;
21
+ const mapImageStateToItemState = (index, imageState, autoHandleErrorCount) => {
22
+ var _imageState$urlState, _imageState$urlState2;
16
23
 
24
+ return {
25
+ index,
26
+ url: (_imageState$urlState = imageState.urlState) === null || _imageState$urlState === void 0 ? void 0 : _imageState$urlState.url,
27
+ reloadButtonVisible: ((_imageState$urlState2 = imageState.urlState) === null || _imageState$urlState2 === void 0 ? void 0 : _imageState$urlState2.validity) !== 'valid' && imageState.totalErrorCount >= autoHandleErrorCount,
28
+ dimension: imageState.dimension
29
+ };
30
+ };
31
+
32
+ const MAXIMUM_WIDTH = 720;
33
+ const NUMBER_OF_ADJACENT_ITEM = 5;
17
34
  export default function ComicViewer(props) {
18
35
  const {
19
- data,
20
- errorDebounceMillis = 500,
21
- errorRetryCount = 3,
22
- responseTimestamp,
36
+ debounceMillis = 100,
37
+ autoHandleErrorCount = 3,
38
+ getUrlByIndex,
23
39
  initialNumToRender = 1,
24
40
  initialScrollPercentage = 0,
25
41
  itemVisiblePercentThreshold = 0,
26
- onError,
27
- onScroll,
42
+ intrinsicDimensions,
28
43
  onItemPress,
29
- getNextPage,
30
- viewerWidth,
44
+ viewportWidth,
31
45
  windowSize = 3,
32
- pageUnit,
33
- ListFooterComponent,
34
46
  ...otherProps
35
47
  } = props;
36
48
  const flatListRef = useRef(null);
37
- const errors = useRef(new Map());
38
- const debounceTimeOut = useRef(null);
39
- const imageWidth = Math.min(viewerWidth, 720);
40
- const initialItems = R.map(itemData => ({ ...itemData,
41
- isViewable: false,
42
- width: imageWidth,
43
- height: itemData.height * imageWidth / itemData.width
44
- }))(data);
45
- const [items, setItems] = useState(initialItems);
46
- const initialItemState = R.map(itemData => ({
47
- sortKey: itemData.sortKey,
48
- state: R.isNil(itemData.id) ? STATE.INIT : STATE.URL_LOADED
49
- }))(data);
50
- const itemStates = useRef(initialItemState);
51
- const itemHeights = [...getItemHeights(items)];
52
- const itemHeightAccum = getHeightAccum(itemHeights);
49
+ const debounceTimeout = useRef(null);
50
+ const maybeLoadableItemsIndexRange = useRef([-1, 0]);
51
+ const actualImageWidth = Math.min(viewportWidth, MAXIMUM_WIDTH);
52
+ const initialImageStates = useMemo(() => R.map(createInitialImageState, intrinsicDimensions), []);
53
+ const imageStatesRef = useRef(initialImageStates);
54
+
55
+ const mapImageStatesToItemStates = imageStates => {
56
+ return imageStates.map((image, index) => mapImageStateToItemState(index, image, autoHandleErrorCount));
57
+ };
58
+
59
+ const [itemStates, setItemStates] = useState(() => {
60
+ return mapImageStatesToItemStates(imageStatesRef.current);
61
+ });
62
+ const renderedDimensions = useMemo(() => {
63
+ return R.map(intrinsicDimension => ({
64
+ width: actualImageWidth,
65
+ height: intrinsicDimension.height * actualImageWidth / intrinsicDimension.width
66
+ }), intrinsicDimensions);
67
+ }, [actualImageWidth]);
68
+ const layoutFromDimensions = useCallback(() => {
69
+ const itemHeights = R.map(dimension => dimension.height, renderedDimensions);
70
+ const [totalHeight, heightAccum] = getHeightAccum(itemHeights);
71
+ const itemOffsets = R.prepend(0, heightAccum);
72
+
73
+ const getItemLayout = (data, index) => ({
74
+ index,
75
+ length: itemHeights[index],
76
+ offset: itemOffsets[index]
77
+ });
78
+
79
+ return {
80
+ totalHeight,
81
+ getItemLayout
82
+ };
83
+ }, [renderedDimensions]);
84
+ const {
85
+ totalHeight,
86
+ getItemLayout
87
+ } = layoutFromDimensions();
53
88
  const viewabilityConfig = useMemo(() => ({
54
89
  itemVisiblePercentThreshold
55
90
  }), [itemVisiblePercentThreshold]);
56
- const getItemLayout = useCallback((data, index) => {
57
- const offsets = R.prepend(0, itemHeightAccum[1]);
58
- return {
59
- length: itemHeights[index],
60
- offset: offsets[index],
61
- index
62
- };
63
- }, [itemHeights]);
91
+
92
+ const updateImageState = updateFunction => {
93
+ const prevImageStates = imageStatesRef.current;
94
+ const newImageStates = prevImageStates.map(updateFunction);
95
+ imageStatesRef.current = newImageStates;
96
+ setItemStates(prevItemStates => {
97
+ const newItemStates = mapImageStatesToItemStates(newImageStates);
98
+ return R.equals(prevItemStates, newItemStates) ? prevItemStates : newItemStates;
99
+ });
100
+ };
101
+
102
+ const loadUrlByIndex = async indexes => {
103
+ const filteredIndexes = R.filter(index => {
104
+ var _state$urlState;
105
+
106
+ const state = imageStatesRef.current[index];
107
+ return R.isNil(state.urlState) || ((_state$urlState = state.urlState) === null || _state$urlState === void 0 ? void 0 : _state$urlState.validity) === 'invalid' && !state.isNewUrlIncoming;
108
+ }, indexes);
109
+ updateImageState((imageState, i) => {
110
+ return R.includes(i, filteredIndexes) ? { ...imageState,
111
+ isNewUrlIncoming: true
112
+ } : imageState;
113
+ });
114
+
115
+ try {
116
+ const urls = await getUrlByIndex(filteredIndexes);
117
+ updateImageState((imageState, i) => {
118
+ const newUrl = urls === null || urls === void 0 ? void 0 : urls.get(i);
119
+ const urlState = imageState.urlState;
120
+
121
+ if (newUrl !== undefined && (urlState === null || urlState === void 0 ? void 0 : urlState.validity) !== 'valid') {
122
+ return { ...imageState,
123
+ urlState: {
124
+ url: newUrl,
125
+ validity: 'unknown'
126
+ }
127
+ };
128
+ }
129
+
130
+ return imageState;
131
+ });
132
+ } finally {
133
+ updateImageState((imageState, i) => {
134
+ return R.includes(i, filteredIndexes) ? { ...imageState,
135
+ isNewUrlIncoming: false
136
+ } : imageState;
137
+ });
138
+ }
139
+ };
140
+
141
+ const loadMaybeLoadableItems = async () => {
142
+ const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;
143
+ const affectedIndexes = R.range(startIndex, endIndex);
144
+ await loadUrlByIndex(affectedIndexes);
145
+ };
146
+
147
+ const loadItemsDebounce = useDebounce(loadMaybeLoadableItems, debounceMillis);
64
148
  const onViewableItemsChanged = useRef(_ref => {
149
+ var _R$head, _R$last;
150
+
65
151
  let {
66
152
  viewableItems
67
153
  } = _ref;
68
- setItems(prev => {
69
- const viewableItemSortKeys = R.map(viewableItem => viewableItem.item.sortKey)(viewableItems);
70
- const firstViewableSortKey = R.head(viewableItemSortKeys);
71
- const lastViewableItemSortKey = R.last(viewableItemSortKeys);
72
- const firstItem = R.head(prev);
73
- const lastItem = R.last(prev);
74
-
75
- if (R.isNil(firstViewableSortKey) || R.isNil(lastViewableItemSortKey) || R.isNil(firstItem) || R.isNil(lastItem)) {
76
- return prev;
77
- }
154
+ const orderedViewableItems = R.sort((a, b) => (a.index || 0) - (b.index || 0), viewableItems);
155
+ const firstViewableIndex = (_R$head = R.head(orderedViewableItems)) === null || _R$head === void 0 ? void 0 : _R$head.index;
156
+ const lastViewableItemIndex = (_R$last = R.last(orderedViewableItems)) === null || _R$last === void 0 ? void 0 : _R$last.index;
78
157
 
79
- const frontBoundary = R.max(firstItem.sortKey, firstViewableSortKey - 1);
80
- const backBoundary = R.min(lastItem.sortKey, lastViewableItemSortKey + 1);
81
- const viewableItemBoundary = R.range(frontBoundary, backBoundary + 1);
82
- const newItems = R.map(prevItem => ({ ...prevItem,
83
- isViewable: R.includes(prevItem.sortKey, viewableItemBoundary)
84
- }))([...prev]);
85
- return newItems;
86
- });
87
- });
88
- const itemLoadedHandler = useCallback(sortKey => {
89
- const itemState = R.find(state => state.sortKey === sortKey)(itemStates.current);
90
-
91
- if (R.isNil(itemState)) {
158
+ if (R.isNil(firstViewableIndex) || R.isNil(lastViewableItemIndex)) {
92
159
  return;
93
160
  }
94
161
 
95
- itemState.state = STATE.LOADED;
96
- itemState.error = undefined;
97
- }, [itemStates]);
98
- const itemErrorHandler = useCallback(errorInfo => {
99
- const {
100
- sortKey,
101
- count
102
- } = errorInfo;
162
+ const startIndex = R.max(firstViewableIndex - NUMBER_OF_ADJACENT_ITEM, 0);
163
+ const endIndex = R.min(lastViewableItemIndex + NUMBER_OF_ADJACENT_ITEM, itemStates.length - 1);
164
+ maybeLoadableItemsIndexRange.current = [startIndex, endIndex + 1];
165
+ loadItemsDebounce();
166
+ });
167
+ const renderItem = useCallback(_ref2 => {
168
+ var _renderedDimensions$i, _renderedDimensions$i2;
103
169
 
104
- if (count >= errorRetryCount) {
105
- return;
106
- }
170
+ let {
171
+ item,
172
+ index
173
+ } = _ref2;
107
174
 
108
- errors.current.set(sortKey, errorInfo);
109
- const itemState = R.find(state => state.sortKey === sortKey)(itemStates.current);
175
+ const onError = () => {
176
+ updateImageState((imageState, i) => {
177
+ const urlState = imageState.urlState;
110
178
 
111
- if (R.isNil(itemState)) {
112
- return;
113
- }
179
+ if (i === index && urlState !== undefined) {
180
+ return { ...imageState,
181
+ totalErrorCount: imageState.totalErrorCount + 1,
182
+ urlState: { ...urlState,
183
+ validity: 'invalid'
184
+ }
185
+ };
186
+ }
187
+
188
+ return imageState;
189
+ });
190
+
191
+ if (item.reloadButtonVisible) {
192
+ return;
193
+ }
114
194
 
115
- itemState.state = STATE.FAIL;
116
- itemState.error = errorInfo;
117
-
118
- const handleError = () => {
119
- const errorsArray = Array.from(errors.current.entries());
120
- const errorsInfo = R.map(_ref2 => {
121
- let [key, value] = _ref2;
122
- return value;
123
- })(errorsArray);
124
- onError && onError([...errorsInfo]);
125
- errors.current.clear();
195
+ const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;
196
+
197
+ if (index >= startIndex || index < endIndex) {
198
+ loadItemsDebounce();
199
+ }
126
200
  };
127
201
 
128
- if (debounceTimeOut.current) {
129
- clearTimeout(debounceTimeOut.current);
130
- }
202
+ const onReloadPress = () => {
203
+ const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;
131
204
 
132
- if (errors.current.size === pageUnit) {
133
- handleError();
134
- } else {
135
- debounceTimeOut.current = setTimeout(handleError, errorDebounceMillis);
136
- }
137
- }, [errors.current, itemStates]);
138
- const renderItem = useCallback(_ref3 => {
139
- let {
140
- item
141
- } = _ref3;
142
- const itemState = R.find(state => state.sortKey === item.sortKey)(itemStates.current);
143
- const props = { ...item,
144
- itemState,
145
- responseTimestamp,
146
- errorRetryCount,
147
- onError: itemErrorHandler,
148
- onLoaded: itemLoadedHandler,
149
- onItemPress,
150
- getNextPage
205
+ if (index >= startIndex || index < endIndex) {
206
+ loadUrlByIndex([index]);
207
+ }
151
208
  };
152
- return /*#__PURE__*/React.createElement(ViewerItem, {
153
- props: props
154
- });
155
- }, [responseTimestamp, itemErrorHandler, itemLoadedHandler, onItemPress]);
156
- useEffect(() => {
157
- setItems(prev => {
158
- return R.map(prevItem => {
159
- const currentData = R.find(currentItemData => prevItem.sortKey === currentItemData.sortKey)(data);
160
- const itemState = R.find(state => state.sortKey === (currentData === null || currentData === void 0 ? void 0 : currentData.sortKey))(itemStates.current);
161
-
162
- if (currentData && currentData.id && itemState && itemState.state !== STATE.LOADED) {
163
- itemState.state = STATE.URL_LOADED;
164
- return { ...prevItem,
165
- url: currentData.url,
166
- expiresAt: currentData.expiresAt
209
+
210
+ const onLoad = () => {
211
+ updateImageState((imageState, i) => {
212
+ const urlState = imageState.urlState;
213
+
214
+ if (i === index && urlState !== undefined) {
215
+ return { ...imageState,
216
+ urlState: { ...urlState,
217
+ validity: 'valid'
218
+ }
167
219
  };
168
220
  }
169
221
 
170
- return prevItem;
171
- })([...prev]);
172
- ;
222
+ return imageState;
223
+ });
224
+ };
225
+
226
+ return /*#__PURE__*/React.createElement(ViewerItem, {
227
+ onError: onError,
228
+ onLoad: onLoad,
229
+ onPress: onItemPress,
230
+ onReloadPress: onReloadPress,
231
+ url: item.url,
232
+ width: ((_renderedDimensions$i = renderedDimensions[index]) === null || _renderedDimensions$i === void 0 ? void 0 : _renderedDimensions$i.width) ?? 0,
233
+ height: ((_renderedDimensions$i2 = renderedDimensions[index]) === null || _renderedDimensions$i2 === void 0 ? void 0 : _renderedDimensions$i2.height) ?? 0,
234
+ reloadButtonVisible: item.reloadButtonVisible
173
235
  });
174
- }, [responseTimestamp]);
175
- useEffect(() => {
176
- const newItems = R.map(item => ({ ...item,
177
- width: imageWidth,
178
- height: item.height * imageWidth / item.width
179
- }))(items);
180
- setItems(newItems);
181
- }, [imageWidth]);
236
+ }, [onItemPress, renderedDimensions]);
182
237
  useEffect(() => {
183
- const totalHeight = itemHeightAccum[0];
184
238
  const offset = Math.floor(initialScrollPercentage / 100 * totalHeight);
185
239
 
186
240
  if (flatListRef.current) {
@@ -189,19 +243,18 @@ export default function ComicViewer(props) {
189
243
  animated: false
190
244
  });
191
245
  }
192
- }, [flatListRef.current]);
246
+ }, []);
193
247
  return /*#__PURE__*/React.createElement(FlatList, _extends({
194
- data: items,
248
+ data: itemStates,
195
249
  getItemLayout: getItemLayout,
196
250
  initialNumToRender: initialNumToRender,
197
251
  keyExtractor: keyExtractor,
198
252
  onViewableItemsChanged: onViewableItemsChanged.current,
199
- onScroll: onScroll,
200
253
  ref: flatListRef,
254
+ removeClippedSubviews: false,
201
255
  renderItem: renderItem,
202
256
  viewabilityConfig: viewabilityConfig,
203
- windowSize: windowSize,
204
- ListFooterComponent: ListFooterComponent
257
+ windowSize: windowSize
205
258
  }, otherProps));
206
259
  }
207
260
  ;
@@ -1 +1 @@
1
- {"version":3,"names":["React","useCallback","useEffect","useMemo","useRef","useState","FlatList","R","STATE","ViewerItem","getItemHeights","items","map","content","height","appender","left","right","getHeightAccum","itemHeights","mapAccum","keyExtractor","item","sortKey","ComicViewer","props","data","errorDebounceMillis","errorRetryCount","responseTimestamp","initialNumToRender","initialScrollPercentage","itemVisiblePercentThreshold","onError","onScroll","onItemPress","getNextPage","viewerWidth","windowSize","pageUnit","ListFooterComponent","otherProps","flatListRef","errors","Map","debounceTimeOut","imageWidth","Math","min","initialItems","itemData","isViewable","width","setItems","initialItemState","state","isNil","id","INIT","URL_LOADED","itemStates","itemHeightAccum","viewabilityConfig","getItemLayout","index","offsets","prepend","length","offset","onViewableItemsChanged","viewableItems","prev","viewableItemSortKeys","viewableItem","firstViewableSortKey","head","lastViewableItemSortKey","last","firstItem","lastItem","frontBoundary","max","backBoundary","viewableItemBoundary","range","newItems","prevItem","includes","itemLoadedHandler","itemState","find","current","LOADED","error","undefined","itemErrorHandler","errorInfo","count","set","FAIL","handleError","errorsArray","Array","from","entries","errorsInfo","key","value","clear","clearTimeout","size","setTimeout","renderItem","onLoaded","currentData","currentItemData","url","expiresAt","totalHeight","floor","scrollToOffset","animated"],"sources":["ComicViewer.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { FlatList, ListRenderItem, ViewToken } from 'react-native';\nimport * as R from 'ramda';\nimport {\n ComicViewerItemData,\n ComicViewerItemState,\n default as ComicViewerProps,\n ErrorInfo,\n STATE,\n} from './ComicViewerProps';\nimport type ComicViewerItemProps from './ComicViewerItemProps';\nimport ViewerItem from './ViewerItem';\n\nconst getItemHeights = <T, >(items: ComicViewerItemProps<T>[]): number[] => R.map((content: ComicViewerItemProps<T>) => content.height)(items);\nconst appender = (left: number, right: number): [number, number] => [left + right, left + right];\nconst getHeightAccum = (itemHeights: number[]): [number, number[]] => R.mapAccum(appender, 0, itemHeights);\n\nconst keyExtractor = <T, >(item: ComicViewerItemProps<T>) => `${item.sortKey}`;\n\nexport default function ComicViewer<T>(props: ComicViewerProps<T>) {\n const {\n data,\n errorDebounceMillis = 500,\n errorRetryCount = 3,\n responseTimestamp,\n initialNumToRender = 1,\n initialScrollPercentage = 0,\n itemVisiblePercentThreshold = 0,\n onError,\n onScroll,\n onItemPress,\n getNextPage,\n viewerWidth,\n windowSize = 3,\n pageUnit,\n ListFooterComponent,\n ...otherProps\n } = props;\n\n const flatListRef = useRef<FlatList>(null);\n\n const errors = useRef<Map<number, ErrorInfo>>(new Map());\n\n const debounceTimeOut = useRef<NodeJS.Timeout | null>(null);\n\n const imageWidth = Math.min(viewerWidth, 720);\n const initialItems = R.map((itemData: ComicViewerItemData<T>) => ({\n ...itemData,\n isViewable: false,\n width: imageWidth,\n height: (itemData.height * imageWidth) / itemData.width,\n }))(data);\n\n const [items, setItems] = useState<ComicViewerItemProps<T>[]>(initialItems);\n\n const initialItemState: ComicViewerItemState[] = R.map((itemData: ComicViewerItemData<T>) => ({\n sortKey: itemData.sortKey,\n state: R.isNil(itemData.id) ? STATE.INIT : STATE.URL_LOADED,\n }))(data);\n\n const itemStates = useRef<Array<ComicViewerItemState>>(initialItemState);\n\n const itemHeights = [...getItemHeights(items)];\n const itemHeightAccum = getHeightAccum(itemHeights);\n\n const viewabilityConfig = useMemo(() => ({\n itemVisiblePercentThreshold,\n }), [itemVisiblePercentThreshold]);\n\n const getItemLayout = useCallback((data: any, index: number) => {\n const offsets = R.prepend(0, itemHeightAccum[1]);\n\n return {\n length: itemHeights[index],\n offset: offsets[index],\n index,\n };\n }, [itemHeights]);\n\n const onViewableItemsChanged = useRef(({ viewableItems }: {\n viewableItems: Array<ViewToken>,\n }) => {\n setItems((prev: ComicViewerItemProps<T>[]) => {\n const viewableItemSortKeys: number[] = R.map((viewableItem: ViewToken) => viewableItem.item.sortKey)(viewableItems);\n const firstViewableSortKey = R.head(viewableItemSortKeys);\n const lastViewableItemSortKey = R.last(viewableItemSortKeys);\n const firstItem = R.head(prev);\n const lastItem = R.last(prev);\n\n if (R.isNil(firstViewableSortKey)\n || R.isNil(lastViewableItemSortKey)\n || R.isNil(firstItem)\n || R.isNil(lastItem)\n ) {\n return prev;\n }\n\n const frontBoundary = R.max(firstItem.sortKey, firstViewableSortKey - 1);\n const backBoundary = R.min(lastItem.sortKey, lastViewableItemSortKey + 1);\n\n const viewableItemBoundary = R.range(frontBoundary, backBoundary + 1);\n const newItems = R.map((prevItem: ComicViewerItemProps<T>) => ({\n ...prevItem,\n isViewable: R.includes(prevItem.sortKey, viewableItemBoundary),\n }))([...prev]);\n\n return newItems;\n });\n });\n\n const itemLoadedHandler = useCallback((sortKey: number) => {\n const itemState: ComicViewerItemState | undefined = R.find((state: ComicViewerItemState) => state.sortKey === sortKey)(itemStates.current);\n\n if (R.isNil(itemState)) {\n return;\n }\n\n itemState.state = STATE.LOADED;\n itemState.error = undefined;\n }, [itemStates]);\n\n const itemErrorHandler = useCallback((errorInfo: ErrorInfo) => {\n const { sortKey, count } = errorInfo;\n\n if (count >= errorRetryCount) {\n return;\n }\n\n errors.current.set(sortKey, errorInfo);\n\n const itemState: ComicViewerItemState | undefined = R.find((state: ComicViewerItemState) => state.sortKey === sortKey)(itemStates.current);\n\n if (R.isNil(itemState)) {\n return;\n }\n\n itemState.state = STATE.FAIL;\n itemState.error = errorInfo;\n\n const handleError = () => {\n const errorsArray = Array.from(errors.current.entries());\n const errorsInfo = R.map(([key, value]: [number, ErrorInfo]) => value)(errorsArray);\n\n onError && onError([...errorsInfo]);\n errors.current.clear();\n };\n\n if (debounceTimeOut.current) {\n clearTimeout(debounceTimeOut.current);\n }\n\n if (errors.current.size === pageUnit) {\n handleError();\n } else {\n debounceTimeOut.current = setTimeout(handleError, errorDebounceMillis);\n }\n }, [errors.current, itemStates]);\n\n const renderItem: ListRenderItem<ComicViewerItemProps<T>> = useCallback(({ item }) => {\n const itemState: ComicViewerItemState | undefined = R.find((state: ComicViewerItemState) => state.sortKey === item.sortKey)(itemStates.current);\n\n const props = {\n ...item,\n itemState,\n responseTimestamp,\n errorRetryCount,\n onError: itemErrorHandler,\n onLoaded: itemLoadedHandler,\n onItemPress,\n getNextPage,\n };\n\n return <ViewerItem props={props}/>;\n }, [responseTimestamp, itemErrorHandler, itemLoadedHandler, onItemPress]);\n\n useEffect(() => {\n setItems((prev: ComicViewerItemProps<T>[]) => {\n return R.map((prevItem: ComicViewerItemProps<T>) => {\n const currentData: ComicViewerItemData | undefined = R.find((currentItemData: ComicViewerItemData<T>) => prevItem.sortKey === currentItemData.sortKey)(data);\n const itemState: ComicViewerItemState | undefined = R.find((state: ComicViewerItemState) => state.sortKey === currentData?.sortKey)(itemStates.current);\n\n if (currentData\n && currentData.id\n && itemState\n && itemState.state !== STATE.LOADED) {\n\n itemState.state = STATE.URL_LOADED;\n\n return {\n ...prevItem,\n url: currentData.url,\n expiresAt: currentData.expiresAt,\n };\n }\n\n return prevItem;\n })([...prev]);\n ;\n });\n }, [responseTimestamp]);\n\n useEffect(() => {\n const newItems = R.map((item: ComicViewerItemProps<T>) => ({\n ...item,\n width: imageWidth,\n height: (item.height * imageWidth) / item.width,\n }))(items);\n\n setItems(newItems);\n }, [imageWidth]);\n\n useEffect(() => {\n const totalHeight = itemHeightAccum[0];\n const offset = Math.floor((initialScrollPercentage / 100) * totalHeight);\n\n if (flatListRef.current) {\n flatListRef.current.scrollToOffset({ offset, animated: false });\n }\n }, [flatListRef.current]);\n\n return (\n <FlatList\n data={items}\n getItemLayout={getItemLayout}\n initialNumToRender={initialNumToRender}\n keyExtractor={keyExtractor}\n onViewableItemsChanged={onViewableItemsChanged.current}\n onScroll={onScroll}\n ref={flatListRef}\n renderItem={renderItem}\n viewabilityConfig={viewabilityConfig}\n windowSize={windowSize}\n ListFooterComponent={ListFooterComponent}\n {...otherProps}\n />\n );\n};"],"mappings":"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"}
1
+ {"version":3,"names":["React","useCallback","useEffect","useMemo","useRef","useState","FlatList","R","useDebounce","ViewerItem","appender","left","right","getHeightAccum","heights","mapAccum","keyExtractor","item","String","index","createInitialImageState","dimension","isNewUrlIncoming","totalErrorCount","mapImageStateToItemState","imageState","autoHandleErrorCount","url","urlState","reloadButtonVisible","validity","MAXIMUM_WIDTH","NUMBER_OF_ADJACENT_ITEM","ComicViewer","props","debounceMillis","getUrlByIndex","initialNumToRender","initialScrollPercentage","itemVisiblePercentThreshold","intrinsicDimensions","onItemPress","viewportWidth","windowSize","otherProps","flatListRef","debounceTimeout","maybeLoadableItemsIndexRange","actualImageWidth","Math","min","initialImageStates","map","imageStatesRef","mapImageStatesToItemStates","imageStates","image","itemStates","setItemStates","current","renderedDimensions","intrinsicDimension","width","height","layoutFromDimensions","itemHeights","totalHeight","heightAccum","itemOffsets","prepend","getItemLayout","data","length","offset","viewabilityConfig","updateImageState","updateFunction","prevImageStates","newImageStates","prevItemStates","newItemStates","equals","loadUrlByIndex","indexes","filteredIndexes","filter","state","isNil","i","includes","urls","newUrl","get","undefined","loadMaybeLoadableItems","startIndex","endIndex","affectedIndexes","range","loadItemsDebounce","onViewableItemsChanged","viewableItems","orderedViewableItems","sort","a","b","firstViewableIndex","head","lastViewableItemIndex","last","max","renderItem","onError","onReloadPress","onLoad","floor","scrollToOffset","animated"],"sources":["ComicViewer.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { FlatList, ListRenderItem, ViewToken } from 'react-native';\nimport * as R from 'ramda';\nimport { useDebounce } from '@fountain-ui/core';\nimport { default as ComicViewerProps, Dimension } from './ComicViewerProps';\nimport ViewerItem from './ViewerItem';\n\nconst appender = (left: number, right: number): [number, number] => [left + right, left + right];\nconst getHeightAccum = (heights: number[]): [number, number[]] => R.mapAccum(appender, 0, heights);\n\nconst keyExtractor = <T, >(item: ItemState) => String(item.index);\n\ninterface UrlState {\n url: string;\n validity: 'valid' | 'invalid' | 'unknown';\n}\n\ninterface ImageState {\n urlState?: UrlState;\n isNewUrlIncoming: boolean;\n totalErrorCount: number;\n dimension: Dimension;\n}\n\ninterface ItemState {\n index: number;\n url?: string;\n reloadButtonVisible: boolean;\n dimension: Dimension;\n}\n\nconst createInitialImageState = (dimension: Dimension): ImageState => ({\n isNewUrlIncoming: false,\n totalErrorCount: 0,\n dimension,\n});\n\nconst mapImageStateToItemState = (\n index: number,\n imageState: ImageState,\n autoHandleErrorCount: number,\n): ItemState => ({\n index,\n url: imageState.urlState?.url,\n reloadButtonVisible: (imageState.urlState?.validity !== 'valid') && imageState.totalErrorCount >= autoHandleErrorCount,\n dimension: imageState.dimension,\n});\n\nconst MAXIMUM_WIDTH = 720;\n\nconst NUMBER_OF_ADJACENT_ITEM = 5;\n\nexport default function ComicViewer(props: ComicViewerProps) {\n const {\n debounceMillis = 100,\n autoHandleErrorCount = 3,\n getUrlByIndex,\n initialNumToRender = 1,\n initialScrollPercentage = 0,\n itemVisiblePercentThreshold = 0,\n intrinsicDimensions,\n onItemPress,\n viewportWidth,\n windowSize = 3,\n ...otherProps\n } = props;\n\n const flatListRef = useRef<FlatList>(null);\n\n const debounceTimeout = useRef<NodeJS.Timeout | null>(null);\n\n const maybeLoadableItemsIndexRange = useRef<[number, number]>([-1, 0]);\n\n const actualImageWidth = Math.min(viewportWidth, MAXIMUM_WIDTH);\n\n const initialImageStates = useMemo<Array<ImageState>>(() => R.map(createInitialImageState, intrinsicDimensions), []);\n const imageStatesRef = useRef<Array<ImageState>>(initialImageStates);\n\n const mapImageStatesToItemStates = (imageStates: Array<ImageState>): Array<ItemState> => {\n return imageStates.map((image, index) => mapImageStateToItemState(\n index, image, autoHandleErrorCount,\n ));\n };\n\n const [itemStates, setItemStates] = useState<Array<ItemState>>(() => {\n return mapImageStatesToItemStates(imageStatesRef.current);\n });\n\n const renderedDimensions = useMemo<Array<Dimension>>(() => {\n return R.map(intrinsicDimension => ({\n width: actualImageWidth,\n height: (intrinsicDimension.height * actualImageWidth) / intrinsicDimension.width,\n }), intrinsicDimensions);\n }, [actualImageWidth]);\n\n const layoutFromDimensions = useCallback(() => {\n const itemHeights = R.map(dimension => dimension.height, renderedDimensions);\n const [totalHeight, heightAccum] = getHeightAccum(itemHeights);\n const itemOffsets = R.prepend(0, heightAccum);\n\n const getItemLayout = (data: any, index: number) => ({\n index,\n length: itemHeights[index],\n offset: itemOffsets[index],\n });\n\n return {\n totalHeight,\n getItemLayout,\n };\n }, [renderedDimensions]);\n\n const { totalHeight, getItemLayout } = layoutFromDimensions();\n\n const viewabilityConfig = useMemo(() => ({\n itemVisiblePercentThreshold,\n }), [itemVisiblePercentThreshold]);\n\n const updateImageState = (updateFunction: (prev: ImageState, index: number) => ImageState) => {\n const prevImageStates = imageStatesRef.current;\n const newImageStates = prevImageStates.map(updateFunction);\n\n imageStatesRef.current = newImageStates;\n\n setItemStates(prevItemStates => {\n const newItemStates = mapImageStatesToItemStates(newImageStates);\n\n return R.equals(prevItemStates, newItemStates) ? prevItemStates : newItemStates;\n });\n };\n\n const loadUrlByIndex = async (indexes: number[]) => {\n const filteredIndexes = R.filter(index => {\n const state = imageStatesRef.current[index];\n\n return R.isNil(state.urlState)\n || (state.urlState?.validity === 'invalid' && !state.isNewUrlIncoming);\n }, indexes);\n\n updateImageState((imageState, i) => {\n return R.includes(i, filteredIndexes)\n ? { ...imageState, isNewUrlIncoming: true }\n : imageState;\n });\n\n try {\n const urls = await getUrlByIndex(filteredIndexes);\n\n updateImageState((imageState, i) => {\n const newUrl = urls?.get(i);\n const urlState = imageState.urlState;\n\n if (newUrl !== undefined && urlState?.validity !== 'valid') {\n return {\n ...imageState,\n urlState: {\n url: newUrl,\n validity: 'unknown',\n },\n };\n }\n\n return imageState;\n });\n } finally {\n updateImageState((imageState, i) => {\n return R.includes(i, filteredIndexes)\n ? { ...imageState, isNewUrlIncoming: false }\n : imageState;\n });\n }\n };\n\n const loadMaybeLoadableItems = async () => {\n const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n const affectedIndexes = R.range(startIndex, endIndex);\n\n await loadUrlByIndex(affectedIndexes);\n };\n\n const loadItemsDebounce = useDebounce(loadMaybeLoadableItems, debounceMillis);\n\n const onViewableItemsChanged = useRef(({ viewableItems }: { viewableItems: Array<ViewToken> }) => {\n const orderedViewableItems = R.sort((a, b) => (a.index || 0) - (b.index || 0), viewableItems);\n\n const firstViewableIndex = R.head(orderedViewableItems)?.index;\n const lastViewableItemIndex = R.last(orderedViewableItems)?.index;\n\n if (R.isNil(firstViewableIndex) || R.isNil(lastViewableItemIndex)) {\n return;\n }\n\n const startIndex = R.max(firstViewableIndex - NUMBER_OF_ADJACENT_ITEM, 0);\n const endIndex = R.min(lastViewableItemIndex + NUMBER_OF_ADJACENT_ITEM, itemStates.length - 1);\n\n maybeLoadableItemsIndexRange.current = [startIndex, endIndex + 1];\n\n loadItemsDebounce();\n });\n\n const renderItem: ListRenderItem<ItemState> = useCallback(({ item, index }) => {\n const onError = () => {\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (i === index && urlState !== undefined) {\n return {\n ...imageState,\n totalErrorCount: imageState.totalErrorCount + 1,\n urlState: {\n ...urlState,\n validity: 'invalid',\n },\n };\n }\n\n return imageState;\n });\n\n if (item.reloadButtonVisible) {\n return;\n }\n\n const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n if (index >= startIndex || index < endIndex) {\n loadItemsDebounce();\n }\n };\n\n const onReloadPress = () => {\n const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n if (index >= startIndex || index < endIndex) {\n loadUrlByIndex([index]);\n }\n };\n\n const onLoad = () => {\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (i === index && urlState !== undefined) {\n return {\n ...imageState,\n urlState: {\n ...urlState,\n validity: 'valid',\n },\n };\n }\n\n return imageState;\n });\n };\n\n return (\n <ViewerItem\n onError={onError}\n onLoad={onLoad}\n onPress={onItemPress}\n onReloadPress={onReloadPress}\n url={item.url}\n width={renderedDimensions[index]?.width ?? 0}\n height={renderedDimensions[index]?.height ?? 0}\n reloadButtonVisible={item.reloadButtonVisible}\n />\n );\n }, [onItemPress, renderedDimensions]);\n\n useEffect(() => {\n const offset = Math.floor((initialScrollPercentage / 100) * totalHeight);\n\n if (flatListRef.current) {\n flatListRef.current.scrollToOffset({ offset, animated: false });\n }\n }, []);\n\n return (\n <FlatList\n data={itemStates}\n getItemLayout={getItemLayout}\n initialNumToRender={initialNumToRender}\n keyExtractor={keyExtractor}\n onViewableItemsChanged={onViewableItemsChanged.current}\n ref={flatListRef}\n removeClippedSubviews={false}\n renderItem={renderItem}\n viewabilityConfig={viewabilityConfig}\n windowSize={windowSize}\n {...otherProps}\n />\n );\n};\n"],"mappings":"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"}
@@ -1,7 +1,2 @@
1
- export const STATE = {
2
- INIT: 'init',
3
- URL_LOADED: 'url_loaded',
4
- LOADED: 'loaded',
5
- FAIL: 'fail'
6
- };
1
+
7
2
  //# sourceMappingURL=ComicViewerProps.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["STATE","INIT","URL_LOADED","LOADED","FAIL"],"sources":["ComicViewerProps.ts"],"sourcesContent":["import React from 'react';\nimport { ComponentProps } from '@fountain-ui/core';\nimport { NativeScrollEvent, NativeSyntheticEvent } from 'react-native';\n\nexport const STATE = {\n INIT: 'init',\n URL_LOADED: 'url_loaded',\n LOADED: 'loaded',\n FAIL: 'fail',\n} as const;\n\nexport type LoadingState = typeof STATE[keyof typeof STATE];\n\nexport interface ComicViewerItemState{\n /**\n * Comic viewer item sortKey.\n */\n sortKey: number;\n\n /**\n * Content's loading state.\n */\n state: LoadingState;\n\n /***\n * Content's error Info.\n */\n error?: ErrorInfo;\n}\n\nexport interface ErrorInfo {\n /**\n * ComicViewerItemData.sortKey.\n */\n sortKey: number;\n\n /**\n * Number of times an error occurred.\n */\n count: number;\n\n /**\n * Content is Expired: true\n */\n expired: boolean;\n}\n\nexport type ComicViewerItemData<T = {}> = T & {\n /**\n * Image height.\n */\n height: number;\n\n /**\n * Unique value for identifying.\n */\n id: number | undefined;\n\n /**\n * Image sourceUrl for displaying.\n */\n url: string;\n\n /**\n * Image width.\n */\n width: number;\n\n /**\n * SortKey\n */\n sortKey: number;\n\n /**\n * Image expire date.\n */\n expiresAt: string;\n\n /***\n * Timestamp when get content response\n */\n responseTimestamp: number;\n}\n\nexport default interface ComicViewerProps<T> extends ComponentProps <{\n /**\n * Data for render.\n */\n data: ComicViewerItemData<T>[];\n\n /**\n * Delay Time to call the error handler.\n * @default 500\n */\n errorDebounceMillis?: number;\n\n /**\n * How many times retry onError when same item error occur\n * @default 3\n */\n errorRetryCount?: number;\n\n /**\n * How many items to render in the initial batch.\n * @default 1\n */\n initialNumToRender?: number;\n\n /**\n * Start at initialScrollPercentage.\n * If over 100, scroll to end.\n * @default 0\n */\n initialScrollPercentage?: number;\n\n /**\n * The value for FlatList viewabilityConfig.itemVisiblePercentThreshold.\n * @default 0\n */\n itemVisiblePercentThreshold?: number;\n\n /***\n * Timestamp when get content response\n */\n responseTimestamp: number;\n\n /**\n * Comic viewer width.\n */\n viewerWidth: number;\n\n /**\n * The value for FlatList windowSize.\n * @default 3\n */\n windowSize?: number;\n\n /**\n * How many images in one page.\n */\n pageUnit: number;\n\n /**\n * Method for getting next page contents.\n * @param sortKey\n */\n getNextPage?: (sortKey: number) => void;\n\n /**\n * Handling all viewerItem errors at once.\n * @param errors Array of ViewerItems errorInfo.\n */\n onError?: (errors: ErrorInfo[]) => void;\n\n /**\n * Handle scroll event.\n * @param event Scroll event.\n */\n onScroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;\n\n /**\n * Handle item press event.\n */\n onItemPress?: () => void;\n\n /**\n * Component for comic viewer footer.\n */\n ListFooterComponent?: React.ReactElement;\n}> {}"],"mappings":"AAIA,OAAO,MAAMA,KAAK,GAAG;EACjBC,IAAI,EAAE,MADW;EAEjBC,UAAU,EAAE,YAFK;EAGjBC,MAAM,EAAE,QAHS;EAIjBC,IAAI,EAAE;AAJW,CAAd"}
1
+ {"version":3,"names":[],"sources":["ComicViewerProps.ts"],"sourcesContent":["import React from 'react';\nimport { ComponentProps } from '@fountain-ui/core';\nimport { NativeScrollEvent, NativeSyntheticEvent } from 'react-native';\n\nexport interface Dimension {\n width: number;\n height: number;\n}\n\nexport default interface ComicViewerProps extends ComponentProps <{\n /**\n * Delay Time to call the error handler.\n * @default 500\n */\n debounceMillis?: number;\n\n /**\n * How many times handle onError directly when item error occur\n * @default 3\n */\n autoHandleErrorCount?: number;\n\n /**\n * How many items to render in the initial batch.\n * @default 1\n */\n initialNumToRender?: number;\n\n /**\n * Start at initialScrollPercentage.\n * If over 100, scroll to end.\n * @default 0\n */\n initialScrollPercentage?: number;\n\n /**\n * The value for FlatList viewabilityConfig.itemVisiblePercentThreshold.\n * @default 0\n */\n itemVisiblePercentThreshold?: number;\n\n /**\n * Dimensions of each Image considering viewport.\n */\n intrinsicDimensions: Array<Dimension>;\n\n /**\n * TBD\n */\n viewportWidth: number;\n\n /**\n * The value for FlatList windowSize.\n * @default 3\n */\n windowSize?: number;\n\n /**\n * TBD\n */\n getUrlByIndex: (indexes: Array<number>) => Promise<Map<number, string> | undefined> ;\n\n /**\n * Handle scroll event.\n * @param event Scroll event.\n */\n onScroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;\n\n /**\n * Handle item press event.\n */\n onItemPress?: () => void;\n\n /**\n * Component for comic viewer footer.\n */\n ListFooterComponent?: React.ReactElement;\n}> {}\n"],"mappings":""}
@@ -0,0 +1,29 @@
1
+ function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
+
3
+ import React from 'react';
4
+ import { View } from 'react-native';
5
+ import { IconButton } from '@fountain-ui/core';
6
+ import { Restart } from '@fountain-ui/icons';
7
+ export default function ReloadButton(props) {
8
+ return /*#__PURE__*/React.createElement(View, {
9
+ style: {
10
+ width: '100%',
11
+ height: '100%',
12
+ alignItems: 'center',
13
+ paddingTop: 80
14
+ }
15
+ }, /*#__PURE__*/React.createElement(IconButton, _extends({}, props, {
16
+ children: /*#__PURE__*/React.createElement(Restart, {
17
+ fill: '#ffffff'
18
+ }),
19
+ style: {
20
+ width: 48,
21
+ height: 48,
22
+ borderRadius: 24,
23
+ color: '#ffffff',
24
+ backgroundColor: '#767676'
25
+ }
26
+ })));
27
+ }
28
+ ;
29
+ //# sourceMappingURL=ReloadButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["React","View","IconButton","Restart","ReloadButton","props","width","height","alignItems","paddingTop","borderRadius","color","backgroundColor"],"sources":["ReloadButton.tsx"],"sourcesContent":["import React from 'react';\nimport { View } from 'react-native';\nimport { IconButton, IconButtonProps } from '@fountain-ui/core';\nimport { Restart } from '@fountain-ui/icons';\n\ninterface ReloadButtonProps {\n onPress: IconButtonProps['onPress'];\n}\n\nexport default function ReloadButton(props: ReloadButtonProps) {\n return (\n <View\n style={{\n width: '100%',\n height: '100%',\n alignItems: 'center',\n paddingTop: 80,\n }}\n >\n <IconButton\n {...props}\n children={<Restart fill={'#ffffff'}/>}\n style={{\n width: 48,\n height: 48,\n borderRadius: 24,\n color: '#ffffff',\n backgroundColor: '#767676',\n }}\n />\n </View>\n );\n};\n"],"mappings":";;AAAA,OAAOA,KAAP,MAAkB,OAAlB;AACA,SAASC,IAAT,QAAqB,cAArB;AACA,SAASC,UAAT,QAA4C,mBAA5C;AACA,SAASC,OAAT,QAAwB,oBAAxB;AAMA,eAAe,SAASC,YAAT,CAAsBC,KAAtB,EAAgD;EAC3D,oBACI,oBAAC,IAAD;IACI,KAAK,EAAE;MACHC,KAAK,EAAE,MADJ;MAEHC,MAAM,EAAE,MAFL;MAGHC,UAAU,EAAE,QAHT;MAIHC,UAAU,EAAE;IAJT;EADX,gBAQI,oBAAC,UAAD,eACQJ,KADR;IAEI,QAAQ,eAAE,oBAAC,OAAD;MAAS,IAAI,EAAE;IAAf,EAFd;IAGI,KAAK,EAAE;MACHC,KAAK,EAAE,EADJ;MAEHC,MAAM,EAAE,EAFL;MAGHG,YAAY,EAAE,EAHX;MAIHC,KAAK,EAAE,SAJJ;MAKHC,eAAe,EAAE;IALd;EAHX,GARJ,CADJ;AAsBH;AAAA"}