@react-aria/selection
Advanced tools
Comparing version 3.0.0-nightly.1191 to 3.0.0-nightly.1193
157
dist/main.js
@@ -131,3 +131,6 @@ var { | ||
shouldUseVirtualFocus, | ||
allowsTabNavigation = false | ||
allowsTabNavigation = false, | ||
isVirtualized, | ||
// If no scrollRef is provided, assume the collection ref is the scrollable region | ||
scrollRef = ref | ||
} = options; | ||
@@ -391,3 +394,14 @@ let { | ||
autoFocusRef.current = false; // eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, []); | ||
}, []); // If not virtualized, scroll the focused element into view when the focusedKey changes. | ||
// When virtualized, Virtualizer handles this internally. | ||
useEffect(() => { | ||
if (!isVirtualized && manager.focusedKey && scrollRef != null && scrollRef.current) { | ||
let element = scrollRef.current.querySelector("[data-key=\"" + manager.focusedKey + "\"]"); | ||
if (element) { | ||
$f791fefd7189e0e4d903034fb2925$var$scrollIntoView(scrollRef.current, element); | ||
} | ||
} | ||
}, [isVirtualized, scrollRef, manager.focusedKey]); | ||
let handlers = { | ||
@@ -434,6 +448,67 @@ onKeyDown, | ||
} | ||
/** | ||
* Scrolls `scrollView` so that `element` is visible. | ||
* Similar to `element.scrollIntoView({block: 'nearest'})` (not supported in Edge), | ||
* but doesn't affect parents above `scrollView`. | ||
*/ | ||
exports.useSelectableCollection = useSelectableCollection; | ||
function $f791fefd7189e0e4d903034fb2925$var$scrollIntoView(scrollView, element) { | ||
let offsetX = $f791fefd7189e0e4d903034fb2925$var$relativeOffset(scrollView, element, 'left'); | ||
let offsetY = $f791fefd7189e0e4d903034fb2925$var$relativeOffset(scrollView, element, 'top'); | ||
let width = element.offsetWidth; | ||
let height = element.offsetHeight; | ||
let x = scrollView.scrollLeft; | ||
let y = scrollView.scrollTop; | ||
let maxX = x + scrollView.offsetWidth; | ||
let maxY = y + scrollView.offsetHeight; | ||
if (offsetX <= x) { | ||
x = offsetX; | ||
} else if (offsetX + width > maxX) { | ||
x += offsetX + width - maxX; | ||
} | ||
if (offsetY <= y) { | ||
y = offsetY; | ||
} else if (offsetY + height > maxY) { | ||
y += offsetY + height - maxY; | ||
} | ||
scrollView.scrollLeft = x; | ||
scrollView.scrollTop = y; | ||
} | ||
/** | ||
* Computes the offset left or top from child to ancestor by accumulating | ||
* offsetLeft or offsetTop through intervening offsetParents. | ||
*/ | ||
function $f791fefd7189e0e4d903034fb2925$var$relativeOffset(ancestor, child, axis) { | ||
const prop = axis === 'left' ? 'offsetLeft' : 'offsetTop'; | ||
let sum = 0; | ||
while (child.offsetParent) { | ||
sum += child[prop]; | ||
if (child.offsetParent === ancestor) { | ||
// Stop once we have found the ancestor we are interested in. | ||
break; | ||
} else if (child.offsetParent.contains(ancestor)) { | ||
// If the ancestor is not `position:relative`, then we stop at | ||
// _its_ offset parent, and we subtract off _its_ offset, so that | ||
// we end up with the proper offset from child to ancestor. | ||
sum -= ancestor[prop]; | ||
break; | ||
} | ||
child = child.offsetParent; | ||
} | ||
return sum; | ||
} | ||
/** | ||
* Handles interactions with an item in a selectable collection. | ||
@@ -698,14 +773,3 @@ */ | ||
}); | ||
let delegate = useMemo(() => keyboardDelegate || new ListKeyboardDelegate(collection, disabledKeys, ref, collator), [keyboardDelegate, collection, disabledKeys, ref, collator]); // If not virtualized, scroll the focused element into view when the focusedKey changes. | ||
// When virtualized, Virtualizer handles this internally. | ||
useEffect(() => { | ||
if (!isVirtualized && selectionManager.focusedKey && ref != null && ref.current) { | ||
let element = ref.current.querySelector("[data-key=\"" + selectionManager.focusedKey + "\"]"); | ||
if (element) { | ||
$e85d8307c59fae2ab45d73201aa19$var$scrollIntoView(ref.current, element); | ||
} | ||
} | ||
}, [isVirtualized, ref, selectionManager.focusedKey]); | ||
let delegate = useMemo(() => keyboardDelegate || new ListKeyboardDelegate(collection, disabledKeys, ref, collator), [keyboardDelegate, collection, disabledKeys, ref, collator]); | ||
let { | ||
@@ -723,3 +787,5 @@ collectionProps | ||
shouldUseVirtualFocus, | ||
allowsTabNavigation | ||
allowsTabNavigation, | ||
isVirtualized, | ||
scrollRef: ref | ||
}); | ||
@@ -730,65 +796,4 @@ return { | ||
} | ||
/** | ||
* Scrolls `scrollView` so that `element` is visible. | ||
* Similar to `element.scrollIntoView({block: 'nearest'})` (not supported in Edge), | ||
* but doesn't affect parents above `scrollView`. | ||
*/ | ||
exports.useSelectableList = useSelectableList; | ||
function $e85d8307c59fae2ab45d73201aa19$var$scrollIntoView(scrollView, element) { | ||
let offsetX = $e85d8307c59fae2ab45d73201aa19$var$relativeOffset(scrollView, element, 'left'); | ||
let offsetY = $e85d8307c59fae2ab45d73201aa19$var$relativeOffset(scrollView, element, 'top'); | ||
let width = element.offsetWidth; | ||
let height = element.offsetHeight; | ||
let x = scrollView.scrollLeft; | ||
let y = scrollView.scrollTop; | ||
let maxX = x + scrollView.offsetWidth; | ||
let maxY = y + scrollView.offsetHeight; | ||
if (offsetX <= x) { | ||
x = offsetX; | ||
} else if (offsetX + width > maxX) { | ||
x += offsetX + width - maxX; | ||
} | ||
if (offsetY <= y) { | ||
y = offsetY; | ||
} else if (offsetY + height > maxY) { | ||
y += offsetY + height - maxY; | ||
} | ||
scrollView.scrollLeft = x; | ||
scrollView.scrollTop = y; | ||
} | ||
/** | ||
* Computes the offset left or top from child to ancestor by accumulating | ||
* offsetLeft or offsetTop through intervening offsetParents. | ||
*/ | ||
function $e85d8307c59fae2ab45d73201aa19$var$relativeOffset(ancestor, child, axis) { | ||
const prop = axis === 'left' ? 'offsetLeft' : 'offsetTop'; | ||
let sum = 0; | ||
while (child.offsetParent) { | ||
sum += child[prop]; | ||
if (child.offsetParent === ancestor) { | ||
// Stop once we have found the ancestor we are interested in. | ||
break; | ||
} else if (child.offsetParent.contains(ancestor)) { | ||
// If the ancestor is not `position:relative`, then we stop at | ||
// _its_ offset parent, and we subtract off _its_ offset, so that | ||
// we end up with the proper offset from child to ancestor. | ||
sum -= ancestor[prop]; | ||
break; | ||
} | ||
child = child.offsetParent; | ||
} | ||
return sum; | ||
} | ||
//# sourceMappingURL=main.js.map |
@@ -107,3 +107,6 @@ import { useLocale, useCollator } from "@react-aria/i18n"; | ||
shouldUseVirtualFocus, | ||
allowsTabNavigation = false | ||
allowsTabNavigation = false, | ||
isVirtualized, | ||
// If no scrollRef is provided, assume the collection ref is the scrollable region | ||
scrollRef = ref | ||
} = options; | ||
@@ -367,3 +370,14 @@ let { | ||
autoFocusRef.current = false; // eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, []); | ||
}, []); // If not virtualized, scroll the focused element into view when the focusedKey changes. | ||
// When virtualized, Virtualizer handles this internally. | ||
useEffect(() => { | ||
if (!isVirtualized && manager.focusedKey && scrollRef != null && scrollRef.current) { | ||
let element = scrollRef.current.querySelector("[data-key=\"" + manager.focusedKey + "\"]"); | ||
if (element) { | ||
$a9b9aa71af07c56ab1d89ca45381f4b$var$scrollIntoView(scrollRef.current, element); | ||
} | ||
} | ||
}, [isVirtualized, scrollRef, manager.focusedKey]); | ||
let handlers = { | ||
@@ -410,4 +424,64 @@ onKeyDown, | ||
} | ||
/** | ||
* Scrolls `scrollView` so that `element` is visible. | ||
* Similar to `element.scrollIntoView({block: 'nearest'})` (not supported in Edge), | ||
* but doesn't affect parents above `scrollView`. | ||
*/ | ||
function $a9b9aa71af07c56ab1d89ca45381f4b$var$scrollIntoView(scrollView, element) { | ||
let offsetX = $a9b9aa71af07c56ab1d89ca45381f4b$var$relativeOffset(scrollView, element, 'left'); | ||
let offsetY = $a9b9aa71af07c56ab1d89ca45381f4b$var$relativeOffset(scrollView, element, 'top'); | ||
let width = element.offsetWidth; | ||
let height = element.offsetHeight; | ||
let x = scrollView.scrollLeft; | ||
let y = scrollView.scrollTop; | ||
let maxX = x + scrollView.offsetWidth; | ||
let maxY = y + scrollView.offsetHeight; | ||
if (offsetX <= x) { | ||
x = offsetX; | ||
} else if (offsetX + width > maxX) { | ||
x += offsetX + width - maxX; | ||
} | ||
if (offsetY <= y) { | ||
y = offsetY; | ||
} else if (offsetY + height > maxY) { | ||
y += offsetY + height - maxY; | ||
} | ||
scrollView.scrollLeft = x; | ||
scrollView.scrollTop = y; | ||
} | ||
/** | ||
* Computes the offset left or top from child to ancestor by accumulating | ||
* offsetLeft or offsetTop through intervening offsetParents. | ||
*/ | ||
function $a9b9aa71af07c56ab1d89ca45381f4b$var$relativeOffset(ancestor, child, axis) { | ||
const prop = axis === 'left' ? 'offsetLeft' : 'offsetTop'; | ||
let sum = 0; | ||
while (child.offsetParent) { | ||
sum += child[prop]; | ||
if (child.offsetParent === ancestor) { | ||
// Stop once we have found the ancestor we are interested in. | ||
break; | ||
} else if (child.offsetParent.contains(ancestor)) { | ||
// If the ancestor is not `position:relative`, then we stop at | ||
// _its_ offset parent, and we subtract off _its_ offset, so that | ||
// we end up with the proper offset from child to ancestor. | ||
sum -= ancestor[prop]; | ||
break; | ||
} | ||
child = child.offsetParent; | ||
} | ||
return sum; | ||
} | ||
/** | ||
* Handles interactions with an item in a selectable collection. | ||
@@ -668,14 +742,3 @@ */ | ||
}); | ||
let delegate = useMemo(() => keyboardDelegate || new ListKeyboardDelegate(collection, disabledKeys, ref, collator), [keyboardDelegate, collection, disabledKeys, ref, collator]); // If not virtualized, scroll the focused element into view when the focusedKey changes. | ||
// When virtualized, Virtualizer handles this internally. | ||
useEffect(() => { | ||
if (!isVirtualized && selectionManager.focusedKey && ref != null && ref.current) { | ||
let element = ref.current.querySelector("[data-key=\"" + selectionManager.focusedKey + "\"]"); | ||
if (element) { | ||
$a09ba753e08b703267f2392f7fc8e96$var$scrollIntoView(ref.current, element); | ||
} | ||
} | ||
}, [isVirtualized, ref, selectionManager.focusedKey]); | ||
let delegate = useMemo(() => keyboardDelegate || new ListKeyboardDelegate(collection, disabledKeys, ref, collator), [keyboardDelegate, collection, disabledKeys, ref, collator]); | ||
let { | ||
@@ -693,3 +756,5 @@ collectionProps | ||
shouldUseVirtualFocus, | ||
allowsTabNavigation | ||
allowsTabNavigation, | ||
isVirtualized, | ||
scrollRef: ref | ||
}); | ||
@@ -700,62 +765,2 @@ return { | ||
} | ||
/** | ||
* Scrolls `scrollView` so that `element` is visible. | ||
* Similar to `element.scrollIntoView({block: 'nearest'})` (not supported in Edge), | ||
* but doesn't affect parents above `scrollView`. | ||
*/ | ||
function $a09ba753e08b703267f2392f7fc8e96$var$scrollIntoView(scrollView, element) { | ||
let offsetX = $a09ba753e08b703267f2392f7fc8e96$var$relativeOffset(scrollView, element, 'left'); | ||
let offsetY = $a09ba753e08b703267f2392f7fc8e96$var$relativeOffset(scrollView, element, 'top'); | ||
let width = element.offsetWidth; | ||
let height = element.offsetHeight; | ||
let x = scrollView.scrollLeft; | ||
let y = scrollView.scrollTop; | ||
let maxX = x + scrollView.offsetWidth; | ||
let maxY = y + scrollView.offsetHeight; | ||
if (offsetX <= x) { | ||
x = offsetX; | ||
} else if (offsetX + width > maxX) { | ||
x += offsetX + width - maxX; | ||
} | ||
if (offsetY <= y) { | ||
y = offsetY; | ||
} else if (offsetY + height > maxY) { | ||
y += offsetY + height - maxY; | ||
} | ||
scrollView.scrollLeft = x; | ||
scrollView.scrollTop = y; | ||
} | ||
/** | ||
* Computes the offset left or top from child to ancestor by accumulating | ||
* offsetLeft or offsetTop through intervening offsetParents. | ||
*/ | ||
function $a09ba753e08b703267f2392f7fc8e96$var$relativeOffset(ancestor, child, axis) { | ||
const prop = axis === 'left' ? 'offsetLeft' : 'offsetTop'; | ||
let sum = 0; | ||
while (child.offsetParent) { | ||
sum += child[prop]; | ||
if (child.offsetParent === ancestor) { | ||
// Stop once we have found the ancestor we are interested in. | ||
break; | ||
} else if (child.offsetParent.contains(ancestor)) { | ||
// If the ancestor is not `position:relative`, then we stop at | ||
// _its_ offset parent, and we subtract off _its_ offset, so that | ||
// we end up with the proper offset from child to ancestor. | ||
sum -= ancestor[prop]; | ||
break; | ||
} | ||
child = child.offsetParent; | ||
} | ||
return sum; | ||
} | ||
//# sourceMappingURL=module.js.map |
@@ -80,2 +80,11 @@ import { HTMLAttributes, Key, RefObject } from "react"; | ||
allowsTabNavigation?: boolean; | ||
/** | ||
* Whether the collection items are contained in a virtual scroller. | ||
*/ | ||
isVirtualized?: boolean; | ||
/** | ||
* The ref attached to the scrollable body. Used to provide automatic scrolling on item focus for non-virtualized collections. | ||
* If not provided, defaults to the collection ref. | ||
*/ | ||
scrollRef?: RefObject<HTMLElement>; | ||
} | ||
@@ -82,0 +91,0 @@ interface SelectableCollectionAria { |
{ | ||
"name": "@react-aria/selection", | ||
"version": "3.0.0-nightly.1191+185cd9d89", | ||
"version": "3.0.0-nightly.1193+562b4006e", | ||
"description": "Spectrum UI components in React", | ||
@@ -21,9 +21,9 @@ "license": "Apache-2.0", | ||
"@babel/runtime": "^7.6.2", | ||
"@react-aria/focus": "3.0.0-nightly.1191+185cd9d89", | ||
"@react-aria/i18n": "3.0.0-nightly.1191+185cd9d89", | ||
"@react-aria/interactions": "3.0.0-nightly.1191+185cd9d89", | ||
"@react-aria/utils": "3.0.0-nightly.1191+185cd9d89", | ||
"@react-stately/collections": "3.0.0-nightly.1191+185cd9d89", | ||
"@react-stately/selection": "3.0.0-nightly.1191+185cd9d89", | ||
"@react-types/shared": "3.0.0-nightly.1191+185cd9d89" | ||
"@react-aria/focus": "3.0.0-nightly.1193+562b4006e", | ||
"@react-aria/i18n": "3.0.0-nightly.1193+562b4006e", | ||
"@react-aria/interactions": "3.0.0-nightly.1193+562b4006e", | ||
"@react-aria/utils": "3.0.0-nightly.1193+562b4006e", | ||
"@react-stately/collections": "3.0.0-nightly.1193+562b4006e", | ||
"@react-stately/selection": "3.0.0-nightly.1193+562b4006e", | ||
"@react-types/shared": "3.0.0-nightly.1193+562b4006e" | ||
}, | ||
@@ -36,3 +36,3 @@ "peerDependencies": { | ||
}, | ||
"gitHead": "185cd9d89d70618490e32895112774262cf25548" | ||
"gitHead": "562b4006e27f2c479d3498df44c4ea689ff37c3a" | ||
} |
@@ -79,3 +79,12 @@ /* | ||
*/ | ||
allowsTabNavigation?: boolean | ||
allowsTabNavigation?: boolean, | ||
/** | ||
* Whether the collection items are contained in a virtual scroller. | ||
*/ | ||
isVirtualized?: boolean, | ||
/** | ||
* The ref attached to the scrollable body. Used to provide automatic scrolling on item focus for non-virtualized collections. | ||
* If not provided, defaults to the collection ref. | ||
*/ | ||
scrollRef?: RefObject<HTMLElement> | ||
} | ||
@@ -103,3 +112,6 @@ | ||
shouldUseVirtualFocus, | ||
allowsTabNavigation = false | ||
allowsTabNavigation = false, | ||
isVirtualized, | ||
// If no scrollRef is provided, assume the collection ref is the scrollable region | ||
scrollRef = ref | ||
} = options; | ||
@@ -324,2 +336,13 @@ let {direction} = useLocale(); | ||
// If not virtualized, scroll the focused element into view when the focusedKey changes. | ||
// When virtualized, Virtualizer handles this internally. | ||
useEffect(() => { | ||
if (!isVirtualized && manager.focusedKey && scrollRef?.current) { | ||
let element = scrollRef.current.querySelector(`[data-key="${manager.focusedKey}"]`) as HTMLElement; | ||
if (element) { | ||
scrollIntoView(scrollRef.current, element); | ||
} | ||
} | ||
}, [isVirtualized, scrollRef, manager.focusedKey]); | ||
let handlers = { | ||
@@ -363,1 +386,55 @@ onKeyDown, | ||
} | ||
/** | ||
* Scrolls `scrollView` so that `element` is visible. | ||
* Similar to `element.scrollIntoView({block: 'nearest'})` (not supported in Edge), | ||
* but doesn't affect parents above `scrollView`. | ||
*/ | ||
function scrollIntoView(scrollView: HTMLElement, element: HTMLElement) { | ||
let offsetX = relativeOffset(scrollView, element, 'left'); | ||
let offsetY = relativeOffset(scrollView, element, 'top'); | ||
let width = element.offsetWidth; | ||
let height = element.offsetHeight; | ||
let x = scrollView.scrollLeft; | ||
let y = scrollView.scrollTop; | ||
let maxX = x + scrollView.offsetWidth; | ||
let maxY = y + scrollView.offsetHeight; | ||
if (offsetX <= x) { | ||
x = offsetX; | ||
} else if (offsetX + width > maxX) { | ||
x += offsetX + width - maxX; | ||
} | ||
if (offsetY <= y) { | ||
y = offsetY; | ||
} else if (offsetY + height > maxY) { | ||
y += offsetY + height - maxY; | ||
} | ||
scrollView.scrollLeft = x; | ||
scrollView.scrollTop = y; | ||
} | ||
/** | ||
* Computes the offset left or top from child to ancestor by accumulating | ||
* offsetLeft or offsetTop through intervening offsetParents. | ||
*/ | ||
function relativeOffset(ancestor: HTMLElement, child: HTMLElement, axis: 'left'|'top') { | ||
const prop = axis === 'left' ? 'offsetLeft' : 'offsetTop'; | ||
let sum = 0; | ||
while (child.offsetParent) { | ||
sum += child[prop]; | ||
if (child.offsetParent === ancestor) { | ||
// Stop once we have found the ancestor we are interested in. | ||
break; | ||
} else if (child.offsetParent.contains(ancestor)) { | ||
// If the ancestor is not `position:relative`, then we stop at | ||
// _its_ offset parent, and we subtract off _its_ offset, so that | ||
// we end up with the proper offset from child to ancestor. | ||
sum -= ancestor[prop]; | ||
break; | ||
} | ||
child = child.offsetParent as HTMLElement; | ||
} | ||
return sum; | ||
} |
@@ -14,3 +14,3 @@ /* | ||
import {Collection, FocusStrategy, KeyboardDelegate, Node} from '@react-types/shared'; | ||
import {HTMLAttributes, Key, RefObject, useEffect, useMemo} from 'react'; | ||
import {HTMLAttributes, Key, RefObject, useMemo} from 'react'; | ||
import {ListKeyboardDelegate} from './ListKeyboardDelegate'; | ||
@@ -113,13 +113,2 @@ import {MultipleSelectionManager} from '@react-stately/selection'; | ||
// If not virtualized, scroll the focused element into view when the focusedKey changes. | ||
// When virtualized, Virtualizer handles this internally. | ||
useEffect(() => { | ||
if (!isVirtualized && selectionManager.focusedKey && ref?.current) { | ||
let element = ref.current.querySelector(`[data-key="${selectionManager.focusedKey}"]`) as HTMLElement; | ||
if (element) { | ||
scrollIntoView(ref.current, element); | ||
} | ||
} | ||
}, [isVirtualized, ref, selectionManager.focusedKey]); | ||
let {collectionProps} = useSelectableCollection({ | ||
@@ -135,3 +124,5 @@ ref, | ||
shouldUseVirtualFocus, | ||
allowsTabNavigation | ||
allowsTabNavigation, | ||
isVirtualized, | ||
scrollRef: ref | ||
}); | ||
@@ -143,55 +134,1 @@ | ||
} | ||
/** | ||
* Scrolls `scrollView` so that `element` is visible. | ||
* Similar to `element.scrollIntoView({block: 'nearest'})` (not supported in Edge), | ||
* but doesn't affect parents above `scrollView`. | ||
*/ | ||
function scrollIntoView(scrollView: HTMLElement, element: HTMLElement) { | ||
let offsetX = relativeOffset(scrollView, element, 'left'); | ||
let offsetY = relativeOffset(scrollView, element, 'top'); | ||
let width = element.offsetWidth; | ||
let height = element.offsetHeight; | ||
let x = scrollView.scrollLeft; | ||
let y = scrollView.scrollTop; | ||
let maxX = x + scrollView.offsetWidth; | ||
let maxY = y + scrollView.offsetHeight; | ||
if (offsetX <= x) { | ||
x = offsetX; | ||
} else if (offsetX + width > maxX) { | ||
x += offsetX + width - maxX; | ||
} | ||
if (offsetY <= y) { | ||
y = offsetY; | ||
} else if (offsetY + height > maxY) { | ||
y += offsetY + height - maxY; | ||
} | ||
scrollView.scrollLeft = x; | ||
scrollView.scrollTop = y; | ||
} | ||
/** | ||
* Computes the offset left or top from child to ancestor by accumulating | ||
* offsetLeft or offsetTop through intervening offsetParents. | ||
*/ | ||
function relativeOffset(ancestor: HTMLElement, child: HTMLElement, axis: 'left'|'top') { | ||
const prop = axis === 'left' ? 'offsetLeft' : 'offsetTop'; | ||
let sum = 0; | ||
while (child.offsetParent) { | ||
sum += child[prop]; | ||
if (child.offsetParent === ancestor) { | ||
// Stop once we have found the ancestor we are interested in. | ||
break; | ||
} else if (child.offsetParent.contains(ancestor)) { | ||
// If the ancestor is not `position:relative`, then we stop at | ||
// _its_ offset parent, and we subtract off _its_ offset, so that | ||
// we end up with the proper offset from child to ancestor. | ||
sum -= ancestor[prop]; | ||
break; | ||
} | ||
child = child.offsetParent as HTMLElement; | ||
} | ||
return sum; | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
201183
2349