UNPKG

251 kBSource Map (JSON)View Raw
1{"version":3,"file":"flicking.min.js","sources":["../src/consts.ts","../src/utils.ts","../src/components/Panel.ts","../src/components/PanelManager.ts","../src/states/State.ts","../src/states/IdleState.ts","../src/states/HoldingState.ts","../src/states/DraggingState.ts","../src/states/AnimatingState.ts","../src/states/DisabledState.ts","../src/components/StateMachine.ts","../src/moves/Snap.ts","../src/moves/MoveType.ts","../src/moves/FreeScroll.ts","../src/components/Viewport.ts","../src/Flicking.ts","../src/index.umd.ts"],"sourcesContent":["/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport { FlickingOptions, EventType, Direction, AxesEventType, StateType, MoveTypeSnapOption, MoveTypeFreeScrollOption, FlickingMethodsKeys } from \"./types\";\n\nexport const MOVE_TYPE: {\n SNAP: \"snap\";\n FREE_SCROLL: \"freeScroll\";\n} = {\n SNAP: \"snap\",\n FREE_SCROLL: \"freeScroll\",\n};\n\nexport const DEFAULT_MOVE_TYPE_OPTIONS: {\n snap: MoveTypeSnapOption,\n freeScroll: MoveTypeFreeScrollOption,\n} = {\n snap: {\n type: \"snap\",\n count: 1,\n },\n freeScroll: {\n type: \"freeScroll\",\n },\n};\nexport const isBrowser = typeof document !== \"undefined\";\n\n/**\n * Default options for creating Flicking.\n * @ko 플리킹을 만들 때 사용하는 기본 옵션들\n * @private\n * @memberof eg.Flicking\n */\nexport const DEFAULT_OPTIONS: Readonly<FlickingOptions> = {\n classPrefix: \"eg-flick\",\n deceleration: 0.0075,\n horizontal: true,\n circular: false,\n infinite: false,\n infiniteThreshold: 0,\n lastIndex: Infinity,\n threshold: 40,\n duration: 100,\n panelEffect: x => 1 - Math.pow(1 - x, 3),\n defaultIndex: 0,\n inputType: [\"touch\", \"mouse\"],\n thresholdAngle: 45,\n bounce: 10,\n autoResize: false,\n adaptive: false,\n zIndex: 2000,\n bound: false,\n overflow: false,\n hanger: \"50%\",\n anchor: \"50%\",\n gap: 0,\n moveType: DEFAULT_MOVE_TYPE_OPTIONS.snap,\n useOffset: false,\n isEqualSize: false,\n isConstantSize: false,\n renderOnlyVisible: false,\n renderExternal: false,\n resizeOnContentsReady: false,\n iOSEdgeSwipeThreshold: 30,\n collectStatistics: true,\n};\n\nexport const DEFAULT_VIEWPORT_CSS = {\n position: \"relative\",\n zIndex: DEFAULT_OPTIONS.zIndex,\n overflow: \"hidden\",\n};\n\nexport const DEFAULT_CAMERA_CSS = {\n width: \"100%\",\n height: \"100%\",\n willChange: \"transform\",\n};\n\nexport const DEFAULT_PANEL_CSS = {\n position: \"absolute\",\n};\n\nexport const EVENTS: EventType = {\n HOLD_START: \"holdStart\",\n HOLD_END: \"holdEnd\",\n MOVE_START: \"moveStart\",\n MOVE: \"move\",\n MOVE_END: \"moveEnd\",\n CHANGE: \"change\",\n RESTORE: \"restore\",\n SELECT: \"select\",\n NEED_PANEL: \"needPanel\",\n VISIBLE_CHANGE: \"visibleChange\",\n CONTENT_ERROR: \"contentError\",\n};\n\nexport const AXES_EVENTS: AxesEventType = {\n HOLD: \"hold\",\n CHANGE: \"change\",\n RELEASE: \"release\",\n ANIMATION_END: \"animationEnd\",\n FINISH: \"finish\",\n};\n\nexport const STATE_TYPE: StateType = {\n IDLE: 0,\n HOLDING: 1,\n DRAGGING: 2,\n ANIMATING: 3,\n DISABLED: 4,\n};\n\nexport const DIRECTION: Direction = {\n PREV: \"PREV\",\n NEXT: \"NEXT\",\n};\nexport const FLICKING_METHODS: {[key in FlickingMethodsKeys]: true} = {\n prev: true,\n next: true,\n moveTo: true,\n getIndex: true,\n getAllPanels: true,\n getCurrentPanel: true,\n getElement: true,\n getSize: true,\n getPanel: true,\n getPanelCount: true,\n getStatus: true,\n getVisiblePanels: true,\n enableInput: true,\n disableInput: true,\n destroy: true,\n resize: true,\n setStatus: true,\n isPlaying: true,\n};\n\n// Check whether browser supports transform: translate3d\n// https://stackoverflow.com/questions/5661671/detecting-transform-translate3d-support\nexport let checkTranslateSupport = () => {\n const transforms = {\n webkitTransform: \"-webkit-transform\",\n msTransform: \"-ms-transform\",\n MozTransform: \"-moz-transform\",\n OTransform: \"-o-transform\",\n transform: \"transform\",\n };\n\n if (!isBrowser) {\n return {\n name: transforms.transform,\n has3d: true,\n };\n }\n const supportedStyle = document.documentElement.style;\n let transformName = \"\";\n for (const prefixedTransform in transforms) {\n if (prefixedTransform in supportedStyle) {\n transformName = prefixedTransform;\n }\n }\n\n if (!transformName) {\n throw new Error(\"Browser doesn't support CSS3 2D Transforms.\");\n }\n\n const el = document.createElement(\"div\");\n\n document.documentElement.insertBefore(el, null);\n\n el.style[transformName] = \"translate3d(1px, 1px, 1px)\";\n const styleVal = window.getComputedStyle(el).getPropertyValue(transforms[transformName]);\n\n el.parentElement!.removeChild(el);\n\n const transformInfo = {\n name: transformName,\n has3d: styleVal.length > 0 && styleVal !== \"none\",\n };\n\n checkTranslateSupport = () => transformInfo;\n\n return transformInfo;\n};\n\nexport const TRANSFORM = checkTranslateSupport();\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport { ElementLike, OriginalStyle, BoundingBox } from \"./types\";\nimport Flicking from \"./Flicking\";\nimport { FLICKING_METHODS } from \"./consts\";\n\nexport function merge(target: object, ...srcs: object[]): object {\n srcs.forEach(source => {\n Object.keys(source).forEach(key => {\n const value = source[key];\n target[key] = value;\n });\n });\n\n return target;\n}\n\nexport function parseElement(element: ElementLike | ElementLike[]): HTMLElement[] {\n if (!Array.isArray(element)) {\n element = [element];\n }\n\n const elements: HTMLElement[] = [];\n element.forEach(el => {\n if (isString(el)) {\n const tempDiv = document.createElement(\"div\");\n tempDiv.innerHTML = el;\n\n elements.push(...toArray(tempDiv.children) as HTMLElement[]);\n while (tempDiv.firstChild) {\n tempDiv.removeChild(tempDiv.firstChild);\n }\n } else {\n elements.push(el as HTMLElement);\n }\n });\n\n return elements;\n}\n\nexport function isString(value: any): value is string {\n return typeof value === \"string\";\n}\n\n// Get class list of element as string array\nexport function classList(element: HTMLElement): string[] {\n return element.classList\n ? toArray(element.classList)\n : element.className.split(\" \");\n}\n\n// Add class to specified element\nexport function addClass(element: HTMLElement, className: string): void {\n if (element.classList) {\n element.classList.add(className);\n } else {\n if (!hasClass(element, className)) {\n element.className = (`${element.className} ${className}`).replace(/\\s{2,}/g, \" \");\n }\n }\n}\n\nexport function hasClass(element: HTMLElement, className: string): boolean {\n if (element.classList) {\n return element.classList.contains(className);\n } else {\n return (element.className.split(\" \").indexOf(className) >= 0);\n }\n}\n\nexport function applyCSS(element: HTMLElement, cssObj: object): void {\n Object.keys(cssObj).forEach(property => {\n element.style[property] = cssObj[property];\n });\n}\n\nexport function clamp(val: number, min: number, max: number) {\n return Math.max(Math.min(val, max), min);\n}\n\n// Min: inclusive, Max: exclusive\nexport function isBetween(val: number, min: number, max: number) {\n return val >= min && val <= max;\n}\n\nexport interface ArrayLike<T> {\n length: number;\n [index: number]: T;\n}\n\nexport function toArray<T>(iterable: ArrayLike<T>): T[] {\n return [].slice.call(iterable);\n}\n\nexport function isArray(arr: any): boolean {\n return arr && arr.constructor === Array;\n}\n\nexport function parseArithmeticExpression(cssValue: number | string, base: number, defaultVal?: number): number {\n // Set base / 2 to default value, if it's undefined\n const defaultValue = defaultVal != null ? defaultVal : base / 2;\n const cssRegex = /(?:(\\+|\\-)\\s*)?(\\d+(?:\\.\\d+)?(%|px)?)/g;\n\n if (typeof cssValue === \"number\") {\n return clamp(cssValue, 0, base);\n }\n\n let idx = 0;\n let calculatedValue = 0;\n let matchResult = cssRegex.exec(cssValue);\n while (matchResult != null) {\n let sign = matchResult[1];\n const value = matchResult[2];\n const unit = matchResult[3];\n\n let parsedValue = parseFloat(value);\n\n if (idx <= 0) {\n sign = sign || \"+\";\n }\n\n // Return default value for values not in good form\n if (!sign) {\n return defaultValue;\n }\n\n if (unit === \"%\") {\n parsedValue = (parsedValue / 100) * base;\n }\n\n calculatedValue += sign === \"+\"\n ? parsedValue\n : -parsedValue;\n\n // Match next occurrence\n ++idx;\n matchResult = cssRegex.exec(cssValue);\n }\n\n // None-matched\n if (idx === 0) {\n return defaultValue;\n }\n\n // Clamp between 0 ~ base\n return clamp(calculatedValue, 0, base);\n}\n\nexport function getProgress(pos: number, range: number[]) {\n // start, anchor, end\n // -1 , 0 , 1\n const [min, center, max] = range;\n\n if (pos > center && (max - center)) {\n // 0 ~ 1\n return (pos - center) / (max - center);\n } else if (pos < center && (center - min)) {\n // -1 ~ 0\n return (pos - center) / (center - min);\n } else if (pos !== center && max - min) {\n return (pos - min) / (max - min);\n }\n return 0;\n}\n\nexport function findIndex<T>(iterable: T[], callback: (el: T) => boolean): number {\n for (let i = 0; i < iterable.length; i += 1) {\n const element = iterable[i];\n if (element && callback(element)) {\n return i;\n }\n }\n\n return -1;\n}\n\n// return [0, 1, ...., max - 1]\nexport function counter(max: number): number[] {\n const counterArray: number[] = [];\n for (let i = 0; i < max; i += 1) {\n counterArray[i] = i;\n }\n return counterArray;\n}\n\n// Circulate number between range [min, max]\n/*\n * \"indexed\" means min and max is not same, so if it's true \"min - 1\" should be max\n * While if it's false, \"min - 1\" should be \"max - 1\"\n * use `indexed: true` when it should be used for circulating integers like index\n * or `indexed: false` when it should be used for something like positions.\n */\nexport function circulate(value: number, min: number, max: number, indexed: boolean): number {\n const size = indexed\n ? max - min + 1\n : max - min;\n if (value < min) {\n const offset = indexed\n ? (min - value - 1) % size\n : (min - value) % size;\n value = max - offset;\n } else if (value > max) {\n const offset = indexed\n ? (value - max - 1) % size\n : (value - max) % size;\n value = min + offset;\n }\n\n return value;\n}\n\nexport function restoreStyle(element: HTMLElement, originalStyle: OriginalStyle): void {\n originalStyle.className\n ? element.setAttribute(\"class\", originalStyle.className)\n : element.removeAttribute(\"class\");\n originalStyle.style\n ? element.setAttribute(\"style\", originalStyle.style)\n : element.removeAttribute(\"style\");\n}\n\n/**\n * Decorator that makes the method of flicking available in the framework.\n * @ko 프레임워크에서 플리킹의 메소드를 사용할 수 있게 하는 데코레이터.\n * @memberof eg.Flicking\n * @private\n * @example\n * ```js\n * import Flicking, { withFlickingMethods } from \"@egjs/flicking\";\n *\n * class Flicking extends React.Component<Partial<FlickingProps & FlickingOptions>> {\n * &#64;withFlickingMethods\n * private flicking: Flicking;\n * }\n * ```\n */\nexport function withFlickingMethods(prototype: any, flickingName: string) {\n Object.keys(FLICKING_METHODS).forEach((name: keyof Flicking) => {\n if (prototype[name]) {\n return;\n }\n prototype[name] = function(...args) {\n const result = this[flickingName][name](...args);\n\n // fix `this` type to return your own `flicking` instance to the instance using the decorator.\n if (result === this[flickingName]) {\n return this;\n } else {\n return result;\n }\n };\n });\n}\n\nexport function getBbox(element: HTMLElement, useOffset: boolean) {\n let bbox: BoundingBox;\n if (useOffset) {\n bbox = {\n x: 0,\n y: 0,\n width: element.offsetWidth,\n height: element.offsetHeight,\n };\n } else {\n const clientRect = element.getBoundingClientRect();\n bbox = {\n x: clientRect.left,\n y: clientRect.top,\n width: clientRect.width,\n height: clientRect.height,\n };\n }\n return bbox;\n}\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport Viewport from \"./Viewport\";\nimport { OriginalStyle, FlickingPanel, ElementLike, DestroyOption, BoundingBox } from \"../types\";\nimport { DEFAULT_PANEL_CSS, EVENTS } from \"../consts\";\nimport { addClass, applyCSS, parseArithmeticExpression, parseElement, getProgress, restoreStyle, hasClass, getBbox } from \"../utils\";\n\nclass Panel implements FlickingPanel {\n public viewport: Viewport;\n public prevSibling: Panel | null;\n public nextSibling: Panel | null;\n\n protected state: {\n index: number;\n position: number;\n relativeAnchorPosition: number;\n size: number;\n isClone: boolean;\n isVirtual: boolean;\n // Index of cloned panel, zero-based integer(original: -1, cloned: [0, 1, 2, ...])\n // if cloneIndex is 0, that means it's first cloned panel of original panel\n cloneIndex: number;\n originalStyle: OriginalStyle;\n cachedBbox: BoundingBox | null;\n };\n private element: HTMLElement;\n private original?: Panel;\n private clonedPanels: Panel[];\n\n public constructor(\n element?: HTMLElement | null,\n index?: number,\n viewport?: Viewport,\n ) {\n this.viewport = viewport!;\n this.prevSibling = null;\n this.nextSibling = null;\n this.clonedPanels = [];\n\n this.state = {\n index: index!,\n position: 0,\n relativeAnchorPosition: 0,\n size: 0,\n isClone: false,\n isVirtual: false,\n cloneIndex: -1,\n originalStyle: {\n className: \"\",\n style: \"\",\n },\n cachedBbox: null,\n };\n this.setElement(element);\n }\n\n public resize(givenBbox?: BoundingBox): void {\n const state = this.state;\n const options = this.viewport.options;\n const bbox = givenBbox\n ? givenBbox\n : this.getBbox();\n this.state.cachedBbox = bbox;\n const prevSize = state.size;\n\n state.size = options.horizontal\n ? bbox.width\n : bbox.height;\n\n if (prevSize !== state.size) {\n state.relativeAnchorPosition = parseArithmeticExpression(options.anchor, state.size);\n }\n\n if (!state.isClone) {\n this.clonedPanels.forEach(panel => {\n const cloneState = panel.state;\n\n cloneState.size = state.size;\n cloneState.cachedBbox = state.cachedBbox;\n cloneState.relativeAnchorPosition = state.relativeAnchorPosition;\n });\n }\n }\n\n public unCacheBbox(): void {\n this.state.cachedBbox = null;\n }\n\n public getProgress() {\n const viewport = this.viewport;\n const options = viewport.options;\n const panelCount = viewport.panelManager.getPanelCount();\n const scrollAreaSize = viewport.getScrollAreaSize();\n\n const relativeIndex = (options.circular ? Math.floor(this.getPosition() / scrollAreaSize) * panelCount : 0) + this.getIndex();\n const progress = relativeIndex - viewport.getCurrentProgress();\n\n return progress;\n }\n\n public getOutsetProgress() {\n const viewport = this.viewport;\n const outsetRange = [\n -this.getSize(),\n viewport.getRelativeHangerPosition() - this.getRelativeAnchorPosition(),\n viewport.getSize(),\n ];\n const relativePanelPosition = this.getPosition() - viewport.getCameraPosition();\n const outsetProgress = getProgress(relativePanelPosition, outsetRange);\n\n return outsetProgress;\n }\n\n public getVisibleRatio() {\n const viewport = this.viewport;\n const panelSize = this.getSize();\n const relativePanelPosition = this.getPosition() - viewport.getCameraPosition();\n const rightRelativePanelPosition = relativePanelPosition + panelSize;\n\n const visibleSize = Math.min(viewport.getSize(), rightRelativePanelPosition) - Math.max(relativePanelPosition, 0);\n const visibleRatio = visibleSize >= 0\n ? visibleSize / panelSize\n : 0;\n\n return visibleRatio;\n }\n\n public focus(duration?: number): void {\n const viewport = this.viewport;\n const currentPanel = viewport.getCurrentPanel();\n const hangerPosition = viewport.getHangerPosition();\n const anchorPosition = this.getAnchorPosition();\n if (hangerPosition === anchorPosition || !currentPanel) {\n return;\n }\n\n const currentPosition = currentPanel.getPosition();\n const eventType = currentPosition === this.getPosition()\n ? \"\"\n : EVENTS.CHANGE;\n\n viewport.moveTo(this, viewport.findEstimatedPosition(this), eventType, null, duration);\n }\n\n public update(updateFunction: ((element: HTMLElement) => any) | null = null, shouldResize: boolean = true): void {\n const identicalPanels = this.getIdenticalPanels();\n\n if (updateFunction) {\n identicalPanels.forEach(eachPanel => {\n updateFunction(eachPanel.getElement());\n });\n }\n\n if (shouldResize) {\n identicalPanels.forEach(eachPanel => {\n eachPanel.unCacheBbox();\n });\n this.viewport.addVisiblePanel(this);\n this.viewport.resize();\n }\n }\n\n public prev(): FlickingPanel | null {\n const viewport = this.viewport;\n const options = viewport.options;\n const prevSibling = this.prevSibling;\n\n if (!prevSibling) {\n return null;\n }\n\n const currentIndex = this.getIndex();\n const currentPosition = this.getPosition();\n const prevPanelIndex = prevSibling.getIndex();\n const prevPanelPosition = prevSibling.getPosition();\n const prevPanelSize = prevSibling.getSize();\n\n const hasEmptyPanelBetween = currentIndex - prevPanelIndex > 1;\n const notYetMinPanel = options.infinite\n && currentIndex > 0\n && prevPanelIndex > currentIndex;\n\n if (hasEmptyPanelBetween || notYetMinPanel) {\n // Empty panel exists between\n return null;\n }\n\n const newPosition = currentPosition - prevPanelSize - options.gap;\n\n let prevPanel = prevSibling;\n if (prevPanelPosition !== newPosition) {\n prevPanel = prevSibling.clone(prevSibling.getCloneIndex(), true);\n prevPanel.setPosition(newPosition);\n }\n\n return prevPanel;\n }\n\n public next(): FlickingPanel | null {\n const viewport = this.viewport;\n const options = viewport.options;\n const nextSibling = this.nextSibling;\n const lastIndex = viewport.panelManager.getLastIndex();\n\n if (!nextSibling) {\n return null;\n }\n\n const currentIndex = this.getIndex();\n const currentPosition = this.getPosition();\n const nextPanelIndex = nextSibling.getIndex();\n const nextPanelPosition = nextSibling.getPosition();\n\n const hasEmptyPanelBetween = nextPanelIndex - currentIndex > 1;\n const notYetMaxPanel = options.infinite\n && currentIndex < lastIndex\n && nextPanelIndex < currentIndex;\n\n if (hasEmptyPanelBetween || notYetMaxPanel) {\n return null;\n }\n\n const newPosition = currentPosition + this.getSize() + options.gap;\n\n let nextPanel = nextSibling;\n if (nextPanelPosition !== newPosition) {\n nextPanel = nextSibling.clone(nextSibling.getCloneIndex(), true);\n nextPanel.setPosition(newPosition);\n }\n\n return nextPanel;\n }\n\n public insertBefore(element: ElementLike | ElementLike[]): FlickingPanel[] {\n const viewport = this.viewport;\n const parsedElements = parseElement(element);\n const firstPanel = viewport.panelManager.firstPanel()!;\n const prevSibling = this.prevSibling;\n // Finding correct inserting index\n // While it should insert removing empty spaces,\n // It also should have to be bigger than prevSibling' s index\n const targetIndex = prevSibling && firstPanel.getIndex() !== this.getIndex()\n ? Math.max(prevSibling.getIndex() + 1, this.getIndex() - parsedElements.length)\n : Math.max(this.getIndex() - parsedElements.length, 0);\n\n return viewport.insert(targetIndex, parsedElements);\n }\n\n public insertAfter(element: ElementLike | ElementLike[]): FlickingPanel[] {\n return this.viewport.insert(this.getIndex() + 1, element);\n }\n\n public remove(): FlickingPanel {\n this.viewport.remove(this.getIndex());\n\n return this;\n }\n\n public destroy(option: Partial<DestroyOption>): void {\n if (!option.preserveUI) {\n const originalStyle = this.state.originalStyle;\n\n restoreStyle(this.element, originalStyle);\n }\n\n // release resources\n for (const x in this) {\n (this as any)[x] = null;\n }\n }\n\n public getElement(): HTMLElement {\n return this.element;\n }\n\n public getAnchorPosition(): number {\n return this.state.position + this.state.relativeAnchorPosition;\n }\n\n public getRelativeAnchorPosition(): number {\n return this.state.relativeAnchorPosition;\n }\n\n public getIndex(): number {\n return this.state.index;\n }\n\n public getPosition(): number {\n return this.state.position;\n }\n\n public getSize(): number {\n return this.state.size;\n }\n\n public getBbox(): BoundingBox {\n const state = this.state;\n const viewport = this.viewport;\n const element = this.element;\n const options = viewport.options;\n\n if (!element) {\n state.cachedBbox = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n };\n } else if (!state.cachedBbox) {\n const wasVisible = Boolean(element.parentNode);\n const cameraElement = viewport.getCameraElement();\n if (!wasVisible) {\n cameraElement.appendChild(element);\n viewport.addVisiblePanel(this);\n }\n state.cachedBbox = getBbox(element, options.useOffset);\n\n if (!wasVisible && viewport.options.renderExternal) {\n cameraElement.removeChild(element);\n }\n }\n return state.cachedBbox!;\n }\n\n public isClone(): boolean {\n return this.state.isClone;\n }\n\n public getOverlappedClass(classes: string[]): string | undefined {\n const element = this.element;\n\n for (const className of classes) {\n if (hasClass(element, className)) {\n return className;\n }\n }\n }\n\n public getCloneIndex(): number {\n return this.state.cloneIndex;\n }\n\n public getClonedPanels(): Panel[] {\n const state = this.state;\n\n return state.isClone\n ? this.original!.getClonedPanels()\n : this.clonedPanels;\n }\n\n public getIdenticalPanels(): Panel[] {\n const state = this.state;\n\n return state.isClone\n ? this.original!.getIdenticalPanels()\n : [this, ...this.clonedPanels];\n }\n\n public getOriginalPanel(): Panel {\n return this.state.isClone\n ? this.original!\n : this;\n }\n\n public setIndex(index: number): void {\n const state = this.state;\n\n state.index = index;\n this.clonedPanels.forEach(panel => panel.state.index = index);\n }\n\n public setPosition(pos: number): this {\n this.state.position = pos;\n\n return this;\n }\n\n public setPositionCSS(offset: number = 0): void {\n if (!this.element) {\n return;\n }\n const state = this.state;\n const pos = state.position;\n const options = this.viewport.options;\n const elementStyle = this.element.style;\n const currentElementStyle = options.horizontal\n ? elementStyle.left\n : elementStyle.top;\n const styleToApply = `${pos - offset}px`;\n\n if (!state.isVirtual && currentElementStyle !== styleToApply) {\n options.horizontal\n ? elementStyle.left = styleToApply\n : elementStyle.top = styleToApply;\n }\n }\n\n public clone(cloneIndex: number, isVirtual: boolean = false, element?: HTMLElement | null): Panel {\n const state = this.state;\n const viewport = this.viewport;\n let cloneElement = element;\n\n if (!cloneElement && this.element) {\n cloneElement = isVirtual ? this.element : this.element.cloneNode(true) as HTMLElement;\n }\n const clonedPanel = new Panel(cloneElement, state.index, viewport);\n const clonedState = clonedPanel.state;\n\n clonedPanel.original = state.isClone\n ? this.original\n : this;\n clonedState.isClone = true;\n clonedState.isVirtual = isVirtual;\n clonedState.cloneIndex = cloneIndex;\n // Inherit some state values\n clonedState.size = state.size;\n clonedState.relativeAnchorPosition = state.relativeAnchorPosition;\n clonedState.originalStyle = state.originalStyle;\n clonedState.cachedBbox = state.cachedBbox;\n\n if (!isVirtual) {\n this.clonedPanels.push(clonedPanel);\n } else {\n clonedPanel.prevSibling = this.prevSibling;\n clonedPanel.nextSibling = this.nextSibling;\n }\n\n return clonedPanel;\n }\n\n public removeElement(): void {\n if (!this.viewport.options.renderExternal) {\n const element = this.element;\n element.parentNode && element.parentNode.removeChild(element);\n }\n\n // Do the same thing for clones\n if (!this.state.isClone) {\n this.removeClonedPanelsAfter(0);\n }\n }\n\n public removeClonedPanelsAfter(start: number): void {\n const options = this.viewport.options;\n const removingPanels = this.clonedPanels.splice(start);\n\n if (!options.renderExternal) {\n removingPanels.forEach(panel => {\n panel.removeElement();\n });\n }\n }\n\n public setElement(element?: HTMLElement | null): void {\n if (!element) {\n return;\n }\n const currentElement = this.element;\n if (element !== currentElement) {\n const options = this.viewport.options;\n\n if (currentElement) {\n if (options.horizontal) {\n element.style.left = currentElement.style.left;\n } else {\n element.style.top = currentElement.style.top;\n }\n } else {\n const originalStyle = this.state.originalStyle;\n\n originalStyle.className = element.getAttribute(\"class\");\n originalStyle.style = element.getAttribute(\"style\");\n }\n\n this.element = element;\n\n if (options.classPrefix) {\n addClass(element, `${options.classPrefix}-panel`);\n }\n\n // Update size info after applying panel css\n applyCSS(this.element, DEFAULT_PANEL_CSS);\n }\n }\n}\n\nexport default Panel;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport Panel from \"./Panel\";\nimport { FlickingOptions } from \"../types\";\nimport { findIndex, counter } from \"../utils\";\n\nclass PanelManager {\n private cameraElement: HTMLElement;\n private options: FlickingOptions;\n private panels: Panel[];\n private clones: Panel[][];\n // index range of existing panels\n private range: {\n min: number;\n max: number;\n };\n private length: number;\n private lastIndex: number;\n private cloneCount: number;\n\n constructor(\n cameraElement: HTMLElement,\n options: FlickingOptions,\n ) {\n this.cameraElement = cameraElement;\n this.panels = [];\n this.clones = [];\n this.range = {\n min: -1,\n max: -1,\n };\n this.length = 0;\n this.cloneCount = 0;\n this.options = options;\n this.lastIndex = options.lastIndex;\n }\n\n public firstPanel(): Panel | undefined {\n return this.panels[this.range.min];\n }\n\n public lastPanel(): Panel | undefined {\n return this.panels[this.range.max];\n }\n\n public allPanels(): ReadonlyArray<Panel> {\n return [\n ...this.panels,\n ...this.clones.reduce((allClones, clones) => [...allClones, ...clones], []),\n ];\n }\n\n public originalPanels(): ReadonlyArray<Panel> {\n return this.panels;\n }\n\n public clonedPanels(): ReadonlyArray<Panel[]> {\n return this.clones;\n }\n\n public replacePanels(newPanels: Panel[], newClones: Panel[][]): void {\n this.panels = newPanels;\n this.clones = newClones;\n\n this.range = {\n min: findIndex(newPanels, panel => Boolean(panel)),\n max: newPanels.length - 1,\n };\n this.length = newPanels.filter(panel => Boolean(panel)).length;\n }\n\n public has(index: number): boolean {\n return !!this.panels[index];\n }\n\n public get(index: number): Panel | undefined {\n return this.panels[index];\n }\n\n public getPanelCount(): number {\n return this.length;\n }\n\n public getLastIndex(): number {\n return this.lastIndex;\n }\n\n public getRange(): Readonly<{ min: number, max: number }> {\n return this.range;\n }\n\n public getCloneCount(): number {\n return this.cloneCount;\n }\n\n public setLastIndex(lastIndex: number): void {\n this.lastIndex = lastIndex;\n\n const firstPanel = this.firstPanel();\n const lastPanel = this.lastPanel();\n\n if (!firstPanel || !lastPanel) {\n return; // no meaning of updating range & length\n }\n\n // Remove panels above new last index\n const range = this.range;\n if (lastPanel.getIndex() > lastIndex) {\n const removingPanels = this.panels.splice(lastIndex + 1);\n this.length -= removingPanels.length;\n\n const firstRemovedPanel = removingPanels.filter(panel => !!panel)[0];\n const possibleLastPanel = firstRemovedPanel.prevSibling;\n if (possibleLastPanel) {\n range.max = possibleLastPanel.getIndex();\n } else {\n range.min = -1;\n range.max = -1;\n }\n\n if (this.shouldRender()) {\n removingPanels.forEach(panel => panel.removeElement());\n }\n }\n }\n\n public setCloneCount(cloneCount: number): void {\n this.cloneCount = cloneCount;\n }\n\n // Insert at index\n // Returns pushed elements from index, inserting at 'empty' position doesn't push elements behind it\n public insert(index: number, newPanels: Panel[]): number {\n const panels = this.panels;\n const range = this.range;\n const isCircular = this.options.circular;\n const lastIndex = this.lastIndex;\n\n // Find first panel that index is greater than inserting index\n const nextSibling = this.findFirstPanelFrom(index);\n\n // if it's null, element will be inserted at last position\n // https://developer.mozilla.org/ko/docs/Web/API/Node/insertBefore#Syntax\n const firstPanel = this.firstPanel();\n const siblingElement = nextSibling\n ? nextSibling.getElement()\n : isCircular && firstPanel\n ? firstPanel.getClonedPanels()[0].getElement()\n : null;\n\n // Insert panels before sibling element\n this.insertNewPanels(newPanels, siblingElement);\n\n let pushedIndex = newPanels.length;\n // Like when setting index 50 while visible panels are 0, 1, 2\n if (index > range.max) {\n newPanels.forEach((panel, offset) => {\n panels[index + offset] = panel;\n });\n } else {\n const panelsAfterIndex = panels.slice(index, index + newPanels.length);\n // Find empty from beginning\n let emptyPanelCount = findIndex(panelsAfterIndex, panel => !!panel);\n if (emptyPanelCount < 0) {\n // All empty\n emptyPanelCount = panelsAfterIndex.length;\n }\n pushedIndex = newPanels.length - emptyPanelCount;\n\n // Insert removing empty panels\n panels.splice(index, emptyPanelCount, ...newPanels);\n\n // Remove panels after last index\n if (panels.length > lastIndex + 1) {\n const removedPanels = panels.splice(lastIndex + 1)\n .filter(panel => Boolean(panel));\n this.length -= removedPanels.length;\n\n // Find first\n const newLastIndex = lastIndex - findIndex(this.panels.concat().reverse(), panel => !!panel);\n\n // Can be filled with empty after newLastIndex\n this.panels.splice(newLastIndex + 1);\n this.range.max = newLastIndex;\n\n if (this.shouldRender()) {\n removedPanels.forEach(panel => panel.removeElement());\n }\n }\n }\n\n // Update index of previous panels\n if (pushedIndex > 0) {\n panels.slice(index + newPanels.length).forEach(panel => {\n panel.setIndex(panel.getIndex() + pushedIndex);\n });\n }\n\n // Update state\n this.length += newPanels.length;\n this.updateIndex(index);\n\n if (isCircular) {\n this.addNewClones(index, newPanels, newPanels.length - pushedIndex, nextSibling);\n const clones = this.clones;\n const panelCount = this.panels.length;\n if (clones[0] && clones[0].length > lastIndex + 1) {\n clones.forEach(cloneSet => {\n cloneSet.splice(panelCount);\n });\n }\n }\n\n return pushedIndex;\n }\n\n public replace(index: number, newPanels: Panel[]): Panel[] {\n const panels = this.panels;\n const range = this.range;\n const options = this.options;\n const isCircular = options.circular;\n\n // Find first panel that index is greater than inserting index\n const nextSibling = this.findFirstPanelFrom(index + newPanels.length);\n\n // if it's null, element will be inserted at last position\n // https://developer.mozilla.org/ko/docs/Web/API/Node/insertBefore#Syntax\n const firstPanel = this.firstPanel();\n const siblingElement = nextSibling\n ? nextSibling.getElement()\n : isCircular && firstPanel\n ? firstPanel.getClonedPanels()[0].getElement()\n : null;\n\n // Insert panels before sibling element\n this.insertNewPanels(newPanels, siblingElement);\n\n if (index > range.max) {\n // Temporarily insert null at index to use splice()\n (panels[index] as any) = null;\n }\n\n const replacedPanels = panels.splice(index, newPanels.length, ...newPanels);\n const wasNonEmptyCount = replacedPanels.filter(panel => Boolean(panel)).length;\n\n // Suppose inserting [1, 2, 3] at 0 position when there were [empty, 1]\n // So length should be increased by 3(inserting panels) - 1(non-empty panels)\n this.length += newPanels.length - wasNonEmptyCount;\n this.updateIndex(index);\n\n if (isCircular) {\n this.addNewClones(index, newPanels, newPanels.length, nextSibling);\n }\n\n if (this.shouldRender()) {\n replacedPanels.forEach(panel => panel && panel.removeElement());\n }\n\n return replacedPanels;\n }\n\n public remove(index: number, deleteCount: number = 1): Panel[] {\n const isCircular = this.options.circular;\n const panels = this.panels;\n const clones = this.clones;\n // Delete count should be equal or larger than 0\n deleteCount = Math.max(deleteCount, 0);\n\n const deletedPanels = panels\n .splice(index, deleteCount)\n .filter(panel => !!panel);\n\n if (this.shouldRender()) {\n deletedPanels.forEach(panel => panel.removeElement());\n }\n\n if (isCircular) {\n clones.forEach(cloneSet => {\n cloneSet.splice(index, deleteCount);\n });\n }\n\n // Update indexes\n panels\n .slice(index)\n .forEach(panel => {\n panel.setIndex(panel.getIndex() - deleteCount);\n });\n\n // Check last panel is empty\n let lastIndex = panels.length - 1;\n if (!panels[lastIndex]) {\n const reversedPanels = panels.concat().reverse();\n const nonEmptyIndexFromLast = findIndex(reversedPanels, panel => !!panel);\n lastIndex = nonEmptyIndexFromLast < 0\n ? -1 // All empty\n : lastIndex - nonEmptyIndexFromLast;\n\n // Remove all empty panels from last\n panels.splice(lastIndex + 1);\n if (isCircular) {\n clones.forEach(cloneSet => {\n cloneSet.splice(lastIndex + 1);\n });\n }\n }\n\n // Update range & length\n this.range = {\n min: findIndex(panels, panel => !!panel),\n max: lastIndex,\n };\n this.length -= deletedPanels.length;\n\n if (this.length <= 0) {\n // Reset clones\n this.clones = [];\n this.cloneCount = 0;\n }\n\n return deletedPanels;\n }\n\n public chainAllPanels() {\n const allPanels = this.allPanels().filter(panel => !!panel);\n const allPanelsCount = allPanels.length;\n\n if (allPanelsCount <= 1) {\n return;\n }\n\n allPanels.slice(1, allPanels.length - 1).forEach((panel, idx) => {\n const prevPanel = allPanels[idx];\n const nextPanel = allPanels[idx + 2];\n\n panel.prevSibling = prevPanel;\n panel.nextSibling = nextPanel;\n });\n\n const firstPanel = allPanels[0];\n const lastPanel = allPanels[allPanelsCount - 1];\n\n firstPanel.prevSibling = null;\n firstPanel.nextSibling = allPanels[1];\n lastPanel.prevSibling = allPanels[allPanelsCount - 2];\n lastPanel.nextSibling = null;\n\n if (this.options.circular) {\n firstPanel.prevSibling = lastPanel;\n lastPanel.nextSibling = firstPanel;\n }\n }\n\n public insertClones(cloneIndex: number, index: number, clonedPanels: Panel[], deleteCount: number = 0): void {\n const clones = this.clones;\n const lastIndex = this.lastIndex;\n\n if (!clones[cloneIndex]) {\n const newClones: Panel[] = [];\n clonedPanels.forEach((panel, offset) => {\n newClones[index + offset] = panel;\n });\n\n clones[cloneIndex] = newClones;\n } else {\n const insertTarget = clones[cloneIndex];\n\n if (index >= insertTarget.length) {\n clonedPanels.forEach((panel, offset) => {\n insertTarget[index + offset] = panel;\n });\n } else {\n insertTarget.splice(index, deleteCount, ...clonedPanels);\n // Remove panels after last index\n if (clonedPanels.length > lastIndex + 1) {\n clonedPanels.splice(lastIndex + 1);\n }\n }\n }\n }\n\n // clones are operating in set\n public removeClonesAfter(cloneIndex: number): void {\n const panels = this.panels;\n\n panels.forEach(panel => {\n panel.removeClonedPanelsAfter(cloneIndex);\n });\n this.clones.splice(cloneIndex);\n }\n\n public findPanelOf(element: HTMLElement): Panel | undefined {\n const allPanels = this.allPanels();\n for (const panel of allPanels) {\n if (!panel) {\n continue;\n }\n const panelElement = panel.getElement();\n if (panelElement.contains(element)) {\n return panel;\n }\n }\n }\n\n public findFirstPanelFrom(index: number): Panel | undefined {\n for (const panel of this.panels.slice(index)) {\n if (panel && panel.getIndex() >= index && panel.getElement().parentNode) {\n return panel;\n }\n }\n }\n\n private addNewClones(index: number, originalPanels: Panel[], deleteCount: number, nextSibling: Panel | undefined) {\n const cameraElement = this.cameraElement;\n const cloneCount = this.getCloneCount();\n const lastPanel = this.lastPanel();\n const lastPanelClones: Panel[] = lastPanel\n ? lastPanel.getClonedPanels()\n : [];\n const nextSiblingClones: Panel[] = nextSibling\n ? nextSibling.getClonedPanels()\n : [];\n\n for (const cloneIndex of counter(cloneCount)) {\n const cloneNextSibling = nextSiblingClones[cloneIndex];\n const lastPanelSibling = lastPanelClones[cloneIndex];\n\n const cloneSiblingElement = cloneNextSibling\n ? cloneNextSibling.getElement()\n : lastPanelSibling\n ? lastPanelSibling.getElement().nextElementSibling\n : null;\n\n const newClones = originalPanels.map(panel => {\n const clone = panel.clone(cloneIndex);\n\n if (this.shouldRender()) {\n cameraElement.insertBefore(clone.getElement(), cloneSiblingElement);\n }\n\n return clone;\n });\n\n this.insertClones(cloneIndex, index, newClones, deleteCount);\n }\n }\n\n private updateIndex(insertingIndex: number) {\n const panels = this.panels;\n const range = this.range;\n\n const newLastIndex = panels.length - 1;\n if (newLastIndex > range.max) {\n range.max = newLastIndex;\n }\n if (insertingIndex < range.min || range.min < 0) {\n range.min = insertingIndex;\n }\n }\n\n private insertNewPanels(newPanels: Panel[], siblingElement: HTMLElement | null) {\n if (this.shouldRender()) {\n const fragment = document.createDocumentFragment();\n newPanels.forEach(panel => fragment.appendChild(panel.getElement()));\n this.cameraElement.insertBefore(fragment, siblingElement);\n }\n }\n\n private shouldRender(): boolean {\n const options = this.options;\n\n return !options.renderExternal && !options.renderOnlyVisible;\n }\n}\n\nexport default PanelManager;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport Panel from \"../components/Panel\";\nimport { ValueOf, Direction, StateType, FlickingContext } from \"../types\";\n\nabstract class State {\n public delta: number = 0;\n public direction: ValueOf<Direction> | null = null;\n public targetPanel: Panel | null = null;\n public lastPosition: number = 0;\n public abstract readonly type: ValueOf<StateType>;\n public abstract readonly holding: boolean;\n public abstract readonly playing: boolean;\n\n public onEnter(prevState: State): void {\n this.delta = prevState.delta;\n this.direction = prevState.direction;\n this.targetPanel = prevState.targetPanel;\n this.lastPosition = prevState.lastPosition;\n }\n\n public onExit(nextState: State): void {\n // DO NOTHING\n }\n\n public onHold(e: any, context: FlickingContext): void {\n // DO NOTHING\n }\n\n public onChange(e: any, context: FlickingContext): void {\n // DO NOTHING\n }\n\n public onRelease(e: any, context: FlickingContext): void {\n // DO NOTHING\n }\n\n public onAnimationEnd(e: any, context: FlickingContext): void {\n // DO NOTHING\n }\n\n public onFinish(e: any, context: FlickingContext): void {\n // DO NOTHING\n }\n}\n\nexport default State;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport State from \"./State\";\nimport { EVENTS, STATE_TYPE } from \"../consts\";\nimport { FlickingContext } from \"../types\";\n\nclass IdleState extends State {\n public readonly type = STATE_TYPE.IDLE;\n public readonly holding = false;\n public readonly playing = false;\n\n public onEnter() {\n this.direction = null;\n this.targetPanel = null;\n this.delta = 0;\n this.lastPosition = 0;\n }\n\n public onHold(e: any, { flicking, viewport, triggerEvent, transitTo }: FlickingContext): void {\n // Shouldn't do any action until any panels on flicking area\n if (flicking.getPanelCount() <= 0) {\n if (viewport.options.infinite) {\n viewport.moveCamera(viewport.getCameraPosition(), e);\n }\n transitTo(STATE_TYPE.DISABLED);\n return;\n }\n\n this.lastPosition = viewport.getCameraPosition();\n triggerEvent(EVENTS.HOLD_START, e, true)\n .onSuccess(() => {\n transitTo(STATE_TYPE.HOLDING);\n })\n .onStopped(() => {\n transitTo(STATE_TYPE.DISABLED);\n });\n }\n\n // By methods call\n public onChange(e: any, context: FlickingContext): void {\n const { triggerEvent, transitTo } = context;\n\n triggerEvent(EVENTS.MOVE_START, e, false)\n .onSuccess(() => {\n // Trigger AnimatingState's onChange, to trigger \"move\" event immediately\n transitTo(STATE_TYPE.ANIMATING)\n .onChange(e, context);\n })\n .onStopped(() => {\n transitTo(STATE_TYPE.DISABLED);\n });\n }\n}\n\nexport default IdleState;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport State from \"./State\";\nimport { STATE_TYPE, EVENTS, DIRECTION } from \"../consts\";\nimport { FlickingContext } from \"../types\";\n\nclass HoldingState extends State {\n public readonly type = STATE_TYPE.HOLDING;\n public readonly holding = true;\n public readonly playing = true;\n\n private releaseEvent: any = null;\n\n public onChange(e: any, context: FlickingContext): void {\n const { flicking, triggerEvent, transitTo } = context;\n\n const offset = flicking.options.horizontal\n ? e.inputEvent.offsetX\n : e.inputEvent.offsetY;\n this.direction = offset < 0\n ? DIRECTION.NEXT\n : DIRECTION.PREV;\n\n triggerEvent(EVENTS.MOVE_START, e, true)\n .onSuccess(() => {\n // Trigger DraggingState's onChange, to trigger \"move\" event immediately\n transitTo(STATE_TYPE.DRAGGING)\n .onChange(e, context);\n })\n .onStopped(() => {\n transitTo(STATE_TYPE.DISABLED);\n });\n }\n\n public onRelease(e: any, context: FlickingContext): void {\n const { viewport, triggerEvent, transitTo } = context;\n\n triggerEvent(EVENTS.HOLD_END, e, true);\n\n if (e.delta.flick !== 0) {\n // Sometimes \"release\" event on axes triggered before \"change\" event\n // Especially if user flicked panel fast in really short amount of time\n // if delta is not zero, that means above case happened.\n\n // Event flow should be HOLD_START -> MOVE_START -> MOVE -> HOLD_END\n // At least one move event should be included between holdStart and holdEnd\n e.setTo({ flick: viewport.getCameraPosition() }, 0);\n transitTo(STATE_TYPE.IDLE);\n return;\n }\n\n // Can't handle select event here,\n // As \"finish\" axes event happens\n this.releaseEvent = e;\n }\n\n public onFinish(e: any, { viewport, triggerEvent, transitTo }: FlickingContext): void {\n // Should transite to IDLE state before select event\n // As user expects hold is already finished\n transitTo(STATE_TYPE.IDLE);\n\n if (!this.releaseEvent) {\n return;\n }\n\n // Handle release event here\n // To prevent finish event called twice\n const releaseEvent = this.releaseEvent;\n\n // Static click\n const srcEvent = releaseEvent.inputEvent.srcEvent;\n\n let clickedElement: HTMLElement;\n if (srcEvent.type === \"touchend\") {\n const touchEvent = srcEvent as TouchEvent;\n const touch = touchEvent.changedTouches[0];\n clickedElement = document.elementFromPoint(touch.clientX, touch.clientY) as HTMLElement;\n } else {\n clickedElement = srcEvent.target;\n }\n const clickedPanel = viewport.panelManager.findPanelOf(clickedElement);\n const cameraPosition = viewport.getCameraPosition();\n\n if (clickedPanel) {\n const clickedPanelPosition = clickedPanel.getPosition();\n const direction = clickedPanelPosition > cameraPosition\n ? DIRECTION.NEXT\n : clickedPanelPosition < cameraPosition\n ? DIRECTION.PREV\n : null;\n\n // Don't provide axes event, to use axes instance instead\n triggerEvent(EVENTS.SELECT, null, true, {\n direction, // Direction to the clicked panel\n index: clickedPanel.getIndex(),\n panel: clickedPanel,\n });\n }\n }\n}\n\nexport default HoldingState;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport State from \"./State\";\nimport { STATE_TYPE, EVENTS } from \"../consts\";\nimport { FlickingContext } from \"../types\";\n\nclass DraggingState extends State {\n public readonly type = STATE_TYPE.DRAGGING;\n public readonly holding = true;\n public readonly playing = true;\n\n public onChange(e: any, { moveCamera, transitTo }: FlickingContext): void {\n if (!e.delta.flick) {\n return;\n }\n\n moveCamera(e)\n .onStopped(() => {\n transitTo(STATE_TYPE.DISABLED);\n });\n }\n\n public onRelease(e: any, context: FlickingContext): void {\n const { flicking, viewport, triggerEvent, transitTo, stopCamera } = context;\n\n const delta = this.delta;\n const absDelta = Math.abs(delta);\n const options = flicking.options;\n const horizontal = options.horizontal;\n const moveType = viewport.moveType;\n const inputEvent = e.inputEvent;\n\n const velocity = horizontal\n ? inputEvent.velocityX\n : inputEvent.velocityY;\n const inputDelta = horizontal\n ? inputEvent.deltaX\n : inputEvent.deltaY;\n const isNextDirection = Math.abs(velocity) > 1\n ? velocity < 0\n : absDelta > 0\n ? delta > 0\n : inputDelta < 0;\n\n const swipeDistance = viewport.options.bound\n ? Math.max(absDelta, Math.abs(inputDelta))\n : absDelta;\n const swipeAngle = inputEvent.deltaX\n ? Math.abs(180 * Math.atan(inputEvent.deltaY / inputEvent.deltaX) / Math.PI)\n : 90;\n const belowAngleThreshold = horizontal\n ? swipeAngle <= options.thresholdAngle\n : swipeAngle > options.thresholdAngle;\n const overThreshold = swipeDistance >= options.threshold\n && belowAngleThreshold;\n\n const moveTypeContext = {\n viewport,\n axesEvent: e,\n state: this,\n swipeDistance,\n isNextDirection,\n };\n\n // Update last position to cope with Axes's animating behavior\n // Axes uses start position when animation start\n triggerEvent(EVENTS.HOLD_END, e, true);\n\n const targetPanel = this.targetPanel;\n if (!overThreshold && targetPanel) {\n // Interrupted while animating\n const interruptDestInfo = moveType.findPanelWhenInterrupted(moveTypeContext);\n\n viewport.moveTo(\n interruptDestInfo.panel,\n interruptDestInfo.destPos,\n interruptDestInfo.eventType,\n e,\n interruptDestInfo.duration,\n );\n transitTo(STATE_TYPE.ANIMATING);\n return;\n }\n\n const currentPanel = viewport.getCurrentPanel();\n const nearestPanel = viewport.getNearestPanel();\n\n if (!currentPanel || !nearestPanel) {\n // There're no panels\n e.stop();\n transitTo(STATE_TYPE.IDLE);\n return;\n }\n\n const destInfo = overThreshold\n ? moveType.findTargetPanel(moveTypeContext)\n : moveType.findRestorePanel(moveTypeContext);\n\n viewport.moveTo(\n destInfo.panel,\n destInfo.destPos,\n destInfo.eventType,\n e,\n destInfo.duration,\n ).onSuccess(() => {\n transitTo(STATE_TYPE.ANIMATING);\n }).onStopped(() => {\n transitTo(STATE_TYPE.DISABLED);\n stopCamera(e);\n });\n }\n}\n\nexport default DraggingState;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport State from \"./State\";\nimport { STATE_TYPE, EVENTS } from \"../consts\";\nimport { FlickingContext } from \"../types\";\nimport { circulate } from \"../utils\";\n\nclass AnimatingState extends State {\n public readonly type = STATE_TYPE.ANIMATING;\n public readonly holding = false;\n public readonly playing = true;\n\n public onHold(e: any, { viewport, triggerEvent, transitTo }: FlickingContext): void {\n const options = viewport.options;\n const scrollArea = viewport.getScrollArea();\n const scrollAreaSize = viewport.getScrollAreaSize();\n const loopCount = Math.floor((this.lastPosition + this.delta - scrollArea.prev) / scrollAreaSize);\n\n const targetPanel = this.targetPanel;\n if (options.circular && loopCount !== 0 && targetPanel) {\n const cloneCount = viewport.panelManager.getCloneCount();\n const originalTargetPosition = targetPanel.getPosition();\n\n // cloneIndex is from -1 to cloneCount - 1\n const newCloneIndex = circulate(targetPanel.getCloneIndex() - loopCount, -1, cloneCount - 1, true);\n const newTargetPosition = originalTargetPosition - loopCount * scrollAreaSize;\n const newTargetPanel = targetPanel.getIdenticalPanels()[newCloneIndex + 1].clone(newCloneIndex, true);\n\n // Set new target panel considering looped count\n newTargetPanel.setPosition(newTargetPosition);\n this.targetPanel = newTargetPanel;\n }\n\n // Reset last position and delta\n this.delta = 0;\n this.lastPosition = viewport.getCameraPosition();\n\n // Update current panel as current nearest panel\n viewport.setCurrentPanel(viewport.getNearestPanel()!);\n triggerEvent(EVENTS.HOLD_START, e, true)\n .onSuccess(() => {\n transitTo(STATE_TYPE.DRAGGING);\n })\n .onStopped(() => {\n transitTo(STATE_TYPE.DISABLED);\n });\n }\n\n public onChange(e: any, { moveCamera, transitTo }: FlickingContext): void {\n if (!e.delta.flick) {\n return;\n }\n\n moveCamera(e)\n .onStopped(() => {\n transitTo(STATE_TYPE.DISABLED);\n });\n }\n\n public onFinish(e: any, { flicking, viewport, triggerEvent, transitTo }: FlickingContext) {\n const isTrusted = e && e.isTrusted;\n\n viewport.options.bound\n ? viewport.setCurrentPanel(this.targetPanel!)\n : viewport.setCurrentPanel(viewport.getNearestPanel()!);\n\n if (flicking.options.adaptive) {\n viewport.updateAdaptiveSize();\n }\n\n transitTo(STATE_TYPE.IDLE);\n viewport.updateCameraPosition();\n triggerEvent(EVENTS.MOVE_END, e, isTrusted, {\n direction: this.direction,\n });\n }\n}\n\nexport default AnimatingState;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport State from \"./State\";\nimport { STATE_TYPE } from \"../consts\";\nimport { FlickingContext } from \"../types\";\n\nclass DisabledState extends State {\n public readonly type = STATE_TYPE.DISABLED;\n public readonly holding = false;\n public readonly playing = true;\n\n public onAnimationEnd(e: any, { transitTo }: FlickingContext): void {\n transitTo(STATE_TYPE.IDLE);\n }\n\n public onChange(e: any, { viewport, transitTo }: FlickingContext): void {\n // Can stop Axes's change event\n e.stop();\n\n // Should update axes position as it's already changed at this moment\n viewport.updateAxesPosition(viewport.getCameraPosition());\n transitTo(STATE_TYPE.IDLE);\n }\n\n public onRelease(e: any, { transitTo }: FlickingContext): void {\n // This is needed when stopped hold start event\n if (e.delta.flick === 0) {\n transitTo(STATE_TYPE.IDLE);\n }\n }\n}\n\nexport default DisabledState;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport State from \"../states/State\";\nimport { AxesEventType, ValueOf, FlickingContext, StateType } from \"../types\";\nimport { AXES_EVENTS, STATE_TYPE } from \"../consts\";\nimport IdleState from \"../states/IdleState\";\nimport HoldingState from \"../states/HoldingState\";\nimport DraggingState from \"../states/DraggingState\";\nimport AnimatingState from \"../states/AnimatingState\";\nimport DisabledState from \"../states/DisabledState\";\n\nclass StateMachine {\n private state: State = new IdleState();\n\n public fire(eventType: ValueOf<AxesEventType>, e: any, context: FlickingContext) {\n const currentState = this.state;\n switch (eventType) {\n case AXES_EVENTS.HOLD:\n currentState.onHold(e, context);\n break;\n case AXES_EVENTS.CHANGE:\n currentState.onChange(e, context);\n break;\n case AXES_EVENTS.RELEASE:\n currentState.onRelease(e, context);\n break;\n case AXES_EVENTS.ANIMATION_END:\n currentState.onAnimationEnd(e, context);\n break;\n case AXES_EVENTS.FINISH:\n currentState.onFinish(e, context);\n break;\n }\n }\n\n public getState(): State {\n return this.state;\n }\n\n public transitTo = (nextStateType: ValueOf<StateType>): State => {\n const currentState = this.state;\n\n if (currentState.type !== nextStateType) {\n let nextState: State;\n\n switch (nextStateType) {\n case STATE_TYPE.IDLE:\n nextState = new IdleState();\n break;\n case STATE_TYPE.HOLDING:\n nextState = new HoldingState();\n break;\n case STATE_TYPE.DRAGGING:\n nextState = new DraggingState();\n break;\n case STATE_TYPE.ANIMATING:\n nextState = new AnimatingState();\n break;\n case STATE_TYPE.DISABLED:\n nextState = new DisabledState();\n break;\n }\n\n currentState.onExit(nextState!);\n nextState!.onEnter(currentState);\n\n this.state = nextState!;\n }\n return this.state;\n }\n}\n\nexport default StateMachine;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport MoveType from \"./MoveType\";\nimport { MOVE_TYPE, EVENTS } from \"../consts\";\nimport { MoveTypeContext, DestinationInfo } from \"../types\";\nimport { clamp } from \"../utils\";\n\nclass Snap extends MoveType {\n protected readonly type: string = MOVE_TYPE.SNAP;\n protected count: number;\n\n constructor(count: number) {\n super();\n this.count = count;\n }\n\n public findTargetPanel(ctx: MoveTypeContext): DestinationInfo {\n const { viewport, axesEvent, swipeDistance } = ctx;\n const snapCount = this.count;\n const eventDelta = Math.abs(axesEvent.delta.flick);\n const currentPanel = viewport.getCurrentPanel()!;\n const nearestPanel = viewport.getNearestPanel()!;\n const minimumDistanceToChange = this.calcBrinkOfChange(ctx);\n const nearestIsCurrent = nearestPanel.getIndex() === currentPanel.getIndex();\n\n // This can happen when bounce is 0\n const shouldMoveWhenBounceIs0 = viewport.canSetBoundMode() && nearestIsCurrent;\n const shouldMoveToAdjacent = !viewport.isOutOfBound()\n && (swipeDistance <= minimumDistanceToChange || shouldMoveWhenBounceIs0);\n\n if (snapCount > 1 && eventDelta > minimumDistanceToChange) {\n return this.findSnappedPanel(ctx);\n } else if (shouldMoveToAdjacent) {\n return this.findAdjacentPanel(ctx);\n } else {\n return {\n panel: nearestPanel,\n duration: viewport.options.duration,\n destPos: viewport.findEstimatedPosition(nearestPanel),\n // As swipeDistance holds mouse/touch position change regardless of bounce option value\n // swipDistance > minimumDistanceToChange can happen in bounce area\n // Second condition is for handling that.\n eventType: (swipeDistance <= minimumDistanceToChange)\n || (viewport.isOutOfBound() && nearestIsCurrent)\n ? EVENTS.RESTORE\n : EVENTS.CHANGE,\n };\n }\n }\n\n protected findSnappedPanel(ctx: MoveTypeContext): DestinationInfo {\n const { axesEvent, viewport, state, isNextDirection } = ctx;\n\n const eventDelta = Math.abs(axesEvent.delta.flick);\n const minimumDistanceToChange = this.calcBrinkOfChange(ctx);\n const snapCount = this.count;\n const options = viewport.options;\n const scrollAreaSize = viewport.getScrollAreaSize();\n const halfGap = options.gap / 2;\n const estimatedHangerPos = axesEvent.destPos.flick + viewport.getRelativeHangerPosition();\n\n let panelToMove = viewport.getNearestPanel()!;\n let cycleIndex = panelToMove.getCloneIndex() + 1; // 0(original) or 1(clone)\n let passedPanelCount = 0;\n\n while (passedPanelCount < snapCount) {\n // Since panelToMove holds also cloned panels, we should use original panel's position\n const originalPanel = panelToMove.getOriginalPanel();\n const panelPosition = originalPanel.getPosition() + cycleIndex * scrollAreaSize;\n const panelSize = originalPanel.getSize();\n\n const panelNextPosition = panelPosition + panelSize + halfGap;\n const panelPrevPosition = panelPosition - halfGap;\n\n // Current panelToMove contains destPos\n if (\n (isNextDirection && panelNextPosition > estimatedHangerPos)\n || (!isNextDirection && panelPrevPosition < estimatedHangerPos)\n ) {\n break;\n }\n\n const siblingPanel = isNextDirection\n ? panelToMove.nextSibling\n : panelToMove.prevSibling;\n if (!siblingPanel) {\n break;\n }\n\n const panelIndex = panelToMove.getIndex();\n const siblingIndex = siblingPanel.getIndex();\n if ((isNextDirection && siblingIndex <= panelIndex)\n || (!isNextDirection && siblingIndex >= panelIndex)\n ) {\n cycleIndex = isNextDirection\n ? cycleIndex + 1\n : cycleIndex - 1;\n }\n panelToMove = siblingPanel;\n passedPanelCount += 1;\n }\n\n const originalPosition = panelToMove.getOriginalPanel().getPosition();\n\n if (cycleIndex !== 0) {\n panelToMove = panelToMove.clone(panelToMove.getCloneIndex(), true);\n panelToMove.setPosition(originalPosition + cycleIndex * scrollAreaSize);\n }\n\n const defaultDuration = viewport.options.duration;\n const duration = clamp(axesEvent.duration, defaultDuration, defaultDuration * passedPanelCount);\n\n return {\n panel: panelToMove,\n destPos: viewport.findEstimatedPosition(panelToMove),\n duration,\n eventType: Math.max(eventDelta, state.delta) > minimumDistanceToChange\n ? EVENTS.CHANGE\n : EVENTS.RESTORE,\n };\n }\n\n private findAdjacentPanel(ctx: MoveTypeContext): DestinationInfo {\n const { viewport, isNextDirection } = ctx;\n\n const options = viewport.options;\n const currentIndex = viewport.getCurrentIndex();\n const currentPanel = viewport.panelManager.get(currentIndex)!;\n const hangerPosition = viewport.getHangerPosition();\n const scrollArea = viewport.getScrollArea();\n\n const firstClonedPanel = currentPanel.getIdenticalPanels()[1];\n const lapped = options.circular\n && (Math.abs(currentPanel.getAnchorPosition() - hangerPosition)\n > Math.abs(firstClonedPanel.getAnchorPosition() - hangerPosition));\n\n // If lapped in circular mode, use first cloned panel as base panel\n const basePanel = lapped\n ? firstClonedPanel\n : currentPanel;\n const basePosition = basePanel.getPosition();\n\n const adjacentPanel = isNextDirection\n ? basePanel.nextSibling\n : basePanel.prevSibling;\n\n const eventType = adjacentPanel\n ? EVENTS.CHANGE\n : EVENTS.RESTORE;\n const panelToMove = adjacentPanel\n ? adjacentPanel\n : basePanel;\n const targetRelativeAnchorPosition = panelToMove.getRelativeAnchorPosition();\n\n const estimatedPanelPosition = options.circular\n ? isNextDirection\n ? basePosition + basePanel.getSize() + targetRelativeAnchorPosition + options.gap\n : basePosition - (panelToMove.getSize() - targetRelativeAnchorPosition) - options.gap\n : panelToMove.getAnchorPosition();\n const estimatedPosition = estimatedPanelPosition - viewport.getRelativeHangerPosition();\n const destPos = viewport.canSetBoundMode()\n ? clamp(estimatedPosition, scrollArea.prev, scrollArea.next)\n : estimatedPosition;\n\n return {\n panel: panelToMove,\n destPos,\n duration: options.duration,\n eventType,\n };\n }\n}\n\nexport default Snap;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport { MoveTypeStringOption, MoveTypeContext, DestinationInfo } from \"../types\";\nimport Panel from \"../components/Panel\";\nimport { EVENTS } from \"../consts\";\n\nabstract class MoveType {\n protected readonly abstract type: string;\n\n public abstract findTargetPanel(ctx: MoveTypeContext): DestinationInfo;\n\n public is(type: MoveTypeStringOption): boolean {\n return type === this.type;\n }\n\n public findRestorePanel(ctx: MoveTypeContext): DestinationInfo {\n const viewport = ctx.viewport;\n const options = viewport.options;\n\n const panel = options.circular\n ? this.findRestorePanelInCircularMode(ctx)\n : viewport.getCurrentPanel()!;\n\n return {\n panel,\n destPos: viewport.findEstimatedPosition(panel),\n duration: options.duration,\n eventType: EVENTS.RESTORE,\n };\n }\n\n public findPanelWhenInterrupted(ctx: MoveTypeContext): DestinationInfo {\n const { state, viewport } = ctx;\n const targetPanel = state.targetPanel!;\n\n return {\n panel: targetPanel,\n destPos: viewport.findEstimatedPosition(targetPanel),\n duration: viewport.options.duration,\n eventType: \"\",\n };\n }\n\n // Calculate minimum distance to \"change\" panel\n protected calcBrinkOfChange(ctx: MoveTypeContext): number {\n const { viewport, isNextDirection } = ctx;\n\n const options = viewport.options;\n const currentPanel = viewport.getCurrentPanel()!;\n const halfGap = options.gap / 2;\n\n const relativeAnchorPosition = currentPanel.getRelativeAnchorPosition();\n\n // Minimum distance needed to decide prev/next panel as nearest\n /*\n * | Prev | Next |\n * |--------|--------------|\n * [][ |<-Anchor ][] <- Panel + Half-Gap\n */\n let minimumDistanceToChange = isNextDirection\n ? currentPanel.getSize() - relativeAnchorPosition + halfGap\n : relativeAnchorPosition + halfGap;\n\n minimumDistanceToChange = Math.max(minimumDistanceToChange, options.threshold);\n\n return minimumDistanceToChange;\n }\n\n private findRestorePanelInCircularMode(ctx: MoveTypeContext): Panel {\n const viewport = ctx.viewport;\n const originalPanel = viewport.getCurrentPanel()!.getOriginalPanel();\n const hangerPosition = viewport.getHangerPosition();\n\n const firstClonedPanel = originalPanel.getIdenticalPanels()[1];\n const lapped = Math.abs(originalPanel.getAnchorPosition() - hangerPosition)\n > Math.abs(firstClonedPanel.getAnchorPosition() - hangerPosition);\n\n return (!ctx.isNextDirection && lapped)\n ? firstClonedPanel\n : originalPanel;\n }\n}\n\nexport default MoveType;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport Snap from \"./Snap\";\nimport { MOVE_TYPE, EVENTS } from \"../consts\";\nimport { MoveTypeContext, DestinationInfo } from \"../types\";\nimport { circulate, clamp } from \"../utils\";\n\nclass FreeScroll extends Snap {\n protected readonly type: string = MOVE_TYPE.FREE_SCROLL;\n\n constructor() {\n // Set snap count to Infinity\n super(Infinity);\n }\n\n public findTargetPanel(ctx: MoveTypeContext): DestinationInfo {\n const { axesEvent, state, viewport } = ctx;\n const destPos = axesEvent.destPos.flick;\n const minimumDistanceToChange = this.calcBrinkOfChange(ctx);\n const scrollArea = viewport.getScrollArea();\n const currentPanel = viewport.getCurrentPanel()!;\n const options = viewport.options;\n\n const delta = Math.abs(axesEvent.delta.flick + state.delta);\n if (delta > minimumDistanceToChange) {\n const destInfo = super.findSnappedPanel(ctx);\n\n destInfo.duration = axesEvent.duration;\n destInfo.destPos = destPos;\n destInfo.eventType = !options.circular && destInfo.panel === currentPanel\n ? \"\"\n : EVENTS.CHANGE;\n\n return destInfo;\n } else {\n let estimatedPosition = options.circular\n ? circulate(destPos, scrollArea.prev, scrollArea.next, false)\n : destPos;\n estimatedPosition = clamp(estimatedPosition, scrollArea.prev, scrollArea.next);\n estimatedPosition += viewport.getRelativeHangerPosition();\n\n const estimatedPanel = viewport.findNearestPanelAt(estimatedPosition)!;\n\n return {\n panel: estimatedPanel,\n destPos,\n duration: axesEvent.duration,\n eventType: \"\",\n };\n }\n }\n\n public findRestorePanel(ctx: MoveTypeContext): DestinationInfo {\n return this.findTargetPanel(ctx);\n }\n\n public findPanelWhenInterrupted(ctx: MoveTypeContext): DestinationInfo {\n const { viewport } = ctx;\n\n return {\n panel: viewport.getNearestPanel()!,\n destPos: viewport.getCameraPosition(),\n duration: 0,\n eventType: \"\",\n };\n }\n\n protected calcBrinkOfChange(ctx: MoveTypeContext): number {\n const { viewport, isNextDirection } = ctx;\n\n const options = viewport.options;\n const currentPanel = viewport.getCurrentPanel()!;\n const halfGap = options.gap / 2;\n\n const lastPosition = viewport.stateMachine.getState().lastPosition;\n const currentPanelPosition = currentPanel.getPosition();\n\n // As camera can stop anywhere in free scroll mode,\n // minimumDistanceToChange should be calculated differently.\n // Ref #191(https://github.com/naver/egjs-flicking/issues/191)\n const lastHangerPosition = lastPosition + viewport.getRelativeHangerPosition();\n\n const scrollAreaSize = viewport.getScrollAreaSize();\n let minimumDistanceToChange = isNextDirection\n ? currentPanelPosition + currentPanel.getSize() - lastHangerPosition + halfGap\n : lastHangerPosition - currentPanelPosition + halfGap;\n minimumDistanceToChange = Math.abs(minimumDistanceToChange % scrollAreaSize);\n\n return Math.min(minimumDistanceToChange, scrollAreaSize - minimumDistanceToChange);\n }\n}\n\nexport default FreeScroll;\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Axes, { PanInput } from \"@egjs/axes\";\n\nimport Flicking from \"../Flicking\";\nimport Panel from \"./Panel\";\nimport PanelManager from \"./PanelManager\";\nimport StateMachine from \"./StateMachine\";\nimport MoveType from \"../moves/MoveType\";\nimport { FlickingOptions, FlickingPanel, FlickingStatus, ElementLike, EventType, TriggerCallback, NeedPanelEvent, FlickingEvent, MoveTypeObjectOption, OriginalStyle, Plugin, DestroyOption, BoundingBox } from \"../types\";\nimport { DEFAULT_VIEWPORT_CSS, DEFAULT_CAMERA_CSS, TRANSFORM, DEFAULT_OPTIONS, EVENTS, DIRECTION, STATE_TYPE, MOVE_TYPE } from \"../consts\";\nimport { clamp, applyCSS, toArray, parseArithmeticExpression, isBetween, isArray, parseElement, hasClass, restoreStyle, circulate, findIndex, getBbox } from \"../utils\";\nimport Snap from \"../moves/Snap\";\nimport FreeScroll from \"../moves/FreeScroll\";\n\nexport default class Viewport {\n public options: FlickingOptions;\n public stateMachine: StateMachine;\n public panelManager: PanelManager;\n public moveType: MoveType;\n\n private flicking: Flicking;\n private axes: Axes;\n private panInput: PanInput | null;\n\n private viewportElement: HTMLElement;\n private cameraElement: HTMLElement;\n\n private triggerEvent: Flicking[\"triggerEvent\"];\n private axesHandlers: { [key: string]: any };\n\n private currentPanel: Panel | undefined;\n private nearestPanel: Panel | undefined;\n private visiblePanels: Panel[];\n\n private plugins: Plugin[] = [];\n private panelBboxes: { [className: string]: BoundingBox };\n private state: {\n size: number;\n position: number;\n panelMaintainRatio: number;\n relativeHangerPosition: number;\n positionOffset: number;\n scrollArea: {\n prev: number;\n next: number;\n };\n translate: {\n name: string,\n has3d: boolean,\n };\n infiniteThreshold: number;\n checkedIndexes: Array<[number, number]>;\n isAdaptiveCached: boolean;\n isViewportGiven: boolean;\n isCameraGiven: boolean;\n originalViewportStyle: OriginalStyle;\n originalCameraStyle: OriginalStyle;\n cachedBbox: BoundingBox | null;\n };\n\n constructor(\n flicking: Flicking,\n options: FlickingOptions,\n triggerEvent: Flicking[\"triggerEvent\"],\n ) {\n this.flicking = flicking;\n this.triggerEvent = triggerEvent;\n\n this.state = {\n size: 0,\n position: 0,\n panelMaintainRatio: 0,\n relativeHangerPosition: 0,\n positionOffset: 0,\n scrollArea: {\n prev: 0,\n next: 0,\n },\n translate: TRANSFORM,\n infiniteThreshold: 0,\n checkedIndexes: [],\n isAdaptiveCached: false,\n isViewportGiven: false,\n isCameraGiven: false,\n originalViewportStyle: {\n className: null,\n style: null,\n },\n originalCameraStyle: {\n className: null,\n style: null,\n },\n cachedBbox: null,\n };\n this.options = options;\n this.stateMachine = new StateMachine();\n this.visiblePanels = [];\n this.panelBboxes = {};\n\n this.build();\n }\n\n public moveTo(\n panel: Panel,\n destPos: number,\n eventType: EventType[\"CHANGE\"] | EventType[\"RESTORE\"] | \"\",\n axesEvent: any,\n duration: number = this.options.duration,\n ): TriggerCallback {\n const state = this.state;\n const currentState = this.stateMachine.getState();\n const currentPosition = state.position;\n\n const isTrusted = axesEvent\n ? axesEvent.isTrusted\n : false;\n const direction = destPos === currentPosition\n ? null\n : destPos > currentPosition\n ? DIRECTION.NEXT\n : DIRECTION.PREV;\n\n let eventResult: TriggerCallback;\n if (eventType === EVENTS.CHANGE) {\n eventResult = this.triggerEvent(EVENTS.CHANGE, axesEvent, isTrusted, {\n index: panel.getIndex(),\n panel,\n direction,\n });\n } else if (eventType === EVENTS.RESTORE) {\n eventResult = this.triggerEvent(EVENTS.RESTORE, axesEvent, isTrusted);\n } else {\n eventResult = {\n onSuccess(callback: () => void): TriggerCallback {\n callback();\n return this;\n },\n onStopped(): TriggerCallback {\n return this;\n },\n };\n }\n\n eventResult.onSuccess(() => {\n currentState.delta = 0;\n currentState.lastPosition = this.getCameraPosition();\n currentState.targetPanel = panel;\n currentState.direction = destPos === currentPosition\n ? null\n : destPos > currentPosition\n ? DIRECTION.NEXT\n : DIRECTION.PREV;\n\n if (destPos === currentPosition) {\n // no move\n this.nearestPanel = panel;\n this.currentPanel = panel;\n }\n\n if (axesEvent && axesEvent.setTo) {\n // freeScroll only occurs in release events\n axesEvent.setTo({ flick: destPos }, duration);\n } else {\n this.axes.setTo({ flick: destPos }, duration);\n }\n });\n\n return eventResult;\n }\n\n public moveCamera(pos: number, axesEvent?: any): void {\n const state = this.state;\n const options = this.options;\n const transform = state.translate.name;\n const scrollArea = state.scrollArea;\n\n // Update position & nearestPanel\n if (options.circular && !isBetween(pos, scrollArea.prev, scrollArea.next)) {\n pos = circulate(pos, scrollArea.prev, scrollArea.next, false);\n }\n state.position = pos;\n this.nearestPanel = this.findNearestPanel();\n const nearestPanel = this.nearestPanel;\n const originalNearestPosition = nearestPanel\n ? nearestPanel.getPosition()\n : 0;\n\n // From 0(panel position) to 1(panel position + panel size)\n // When it's on gap area value will be (val > 1 || val < 0)\n if (nearestPanel) {\n const hangerPosition = this.getHangerPosition();\n const panelPosition = nearestPanel.getPosition();\n const panelSize = nearestPanel.getSize();\n const halfGap = options.gap / 2;\n\n // As panel's range is from panel position - half gap ~ panel pos + panel size + half gap\n state.panelMaintainRatio = (hangerPosition - panelPosition + halfGap) / (panelSize + 2 * halfGap);\n } else {\n state.panelMaintainRatio = 0;\n }\n\n this.checkNeedPanel(axesEvent);\n\n // Possibly modified after need panel, if it's looped\n const modifiedNearestPosition = nearestPanel\n ? nearestPanel.getPosition()\n : 0;\n\n pos += (modifiedNearestPosition - originalNearestPosition);\n state.position = pos;\n\n this.updateVisiblePanels();\n\n // Offset is needed to fix camera layer size in visible-only rendering mode\n const posOffset = options.renderOnlyVisible\n ? state.positionOffset\n : 0;\n const moveVector = options.horizontal\n ? [-(pos - posOffset), 0] : [0, -(pos - posOffset)];\n const moveCoord = moveVector.map(coord => `${Math.round(coord)}px`).join(\", \");\n\n this.cameraElement.style[transform] = state.translate.has3d\n ? `translate3d(${moveCoord}, 0px)`\n : `translate(${moveCoord})`;\n }\n\n public stopCamera = (axesEvent: any): void => {\n if (axesEvent && axesEvent.setTo) {\n axesEvent.setTo({ flick: this.state.position }, 0);\n }\n\n this.stateMachine.transitTo(STATE_TYPE.IDLE);\n }\n\n public unCacheBbox(): void {\n const state = this.state;\n const options = this.options;\n\n state.cachedBbox = null;\n this.visiblePanels = [];\n\n const viewportElement = this.viewportElement;\n if (!options.horizontal) {\n // Don't preserve previous width for adaptive resizing\n viewportElement.style.width = \"\";\n } else {\n viewportElement.style.height = \"\";\n }\n state.isAdaptiveCached = false;\n this.panelBboxes = {};\n }\n\n public resize(): void {\n this.updateSize();\n this.updateOriginalPanelPositions();\n this.updateAdaptiveSize();\n this.updateScrollArea();\n this.updateClonePanels();\n this.updateVisiblePanelPositions();\n this.updateCameraPosition();\n this.updatePlugins();\n }\n\n // Find nearest anchor from current hanger position\n public findNearestPanel(): Panel | undefined {\n const state = this.state;\n const panelManager = this.panelManager;\n const hangerPosition = this.getHangerPosition();\n\n if (this.isOutOfBound()) {\n const position = state.position;\n\n return position <= state.scrollArea.prev\n ? panelManager.firstPanel()\n : panelManager.lastPanel();\n }\n\n return this.findNearestPanelAt(hangerPosition);\n }\n\n public findNearestPanelAt(position: number): Panel | undefined {\n const panelManager = this.panelManager;\n\n const allPanels = panelManager.allPanels();\n let minimumDistance = Infinity;\n let nearestPanel: Panel | undefined;\n\n for (const panel of allPanels) {\n if (!panel) {\n continue;\n }\n const prevPosition = panel.getPosition();\n const nextPosition = prevPosition + panel.getSize();\n\n // Use shortest distance from panel's range\n const distance = isBetween(position, prevPosition, nextPosition)\n ? 0\n : Math.min(\n Math.abs(prevPosition - position),\n Math.abs(nextPosition - position),\n );\n\n if (distance > minimumDistance) {\n break;\n } else if (distance === minimumDistance) {\n const minimumAnchorDistance = Math.abs(position - nearestPanel!.getAnchorPosition());\n const anchorDistance = Math.abs(position - panel.getAnchorPosition());\n\n if (anchorDistance > minimumAnchorDistance) {\n break;\n }\n }\n\n minimumDistance = distance;\n nearestPanel = panel;\n }\n\n return nearestPanel;\n }\n\n public findNearestIdenticalPanel(panel: Panel): Panel {\n let nearest = panel;\n let shortestDistance = Infinity;\n const hangerPosition = this.getHangerPosition();\n\n const identicals = panel.getIdenticalPanels();\n identicals.forEach(identical => {\n const anchorPosition = identical.getAnchorPosition();\n const distance = Math.abs(anchorPosition - hangerPosition);\n\n if (distance < shortestDistance) {\n nearest = identical;\n shortestDistance = distance;\n }\n });\n\n return nearest;\n }\n\n // Find shortest camera position that distance is minimum\n public findShortestPositionToPanel(panel: Panel): number {\n const state = this.state;\n const options = this.options;\n const anchorPosition = panel.getAnchorPosition();\n const hangerPosition = this.getHangerPosition();\n const distance = Math.abs(hangerPosition - anchorPosition);\n const scrollAreaSize = state.scrollArea.next - state.scrollArea.prev;\n\n if (!options.circular) {\n const position = anchorPosition - state.relativeHangerPosition;\n return this.canSetBoundMode()\n ? clamp(position, state.scrollArea.prev, state.scrollArea.next)\n : position;\n } else {\n // If going out of viewport border is more efficient way of moving, choose that position\n return distance <= scrollAreaSize - distance\n ? anchorPosition - state.relativeHangerPosition\n : anchorPosition > hangerPosition\n // PREV TO NEXT\n ? anchorPosition - state.relativeHangerPosition - scrollAreaSize\n // NEXT TO PREV\n : anchorPosition - state.relativeHangerPosition + scrollAreaSize;\n }\n }\n\n public findEstimatedPosition(panel: Panel): number {\n const scrollArea = this.getScrollArea();\n\n let estimatedPosition = panel.getAnchorPosition() - this.getRelativeHangerPosition();\n estimatedPosition = this.canSetBoundMode()\n ? clamp(estimatedPosition, scrollArea.prev, scrollArea.next)\n : estimatedPosition;\n\n return estimatedPosition;\n }\n\n public addVisiblePanel(panel: Panel): void {\n if (this.getVisibleIndexOf(panel) < 0) {\n this.visiblePanels.push(panel);\n }\n }\n\n public enable(): void {\n if (!this.panInput) {\n this.createPanInput();\n }\n }\n\n public disable(): void {\n if (this.panInput) {\n this.panInput.destroy();\n this.panInput = null;\n\n this.stateMachine.transitTo(STATE_TYPE.IDLE);\n }\n }\n\n public insert(index: number, element: ElementLike | ElementLike[]): FlickingPanel[] {\n const lastIndex = this.panelManager.getLastIndex();\n\n // Index should not below 0\n if (index < 0 || index > lastIndex) {\n return [];\n }\n\n const state = this.state;\n const options = this.options;\n const parsedElements = parseElement(element);\n\n const panels = parsedElements\n .map((el, idx) => new Panel(el, index + idx, this))\n .slice(0, lastIndex - index + 1);\n\n if (panels.length <= 0) {\n return [];\n }\n\n const pushedIndex = this.panelManager.insert(index, panels);\n\n // ...then calc bbox for all panels\n this.resizePanels(panels);\n\n if (!this.currentPanel) {\n this.currentPanel = panels[0];\n this.nearestPanel = panels[0];\n\n const newCenterPanel = panels[0];\n const newPanelPosition = this.findEstimatedPosition(newCenterPanel);\n state.position = newPanelPosition;\n this.updateAxesPosition(newPanelPosition);\n state.panelMaintainRatio = (newCenterPanel.getRelativeAnchorPosition() + options.gap / 2) / (newCenterPanel.getSize() + options.gap);\n }\n\n // Update checked indexes in infinite mode\n this.updateCheckedIndexes({ min: index, max: index });\n state.checkedIndexes.forEach((indexes, idx) => {\n const [min, max] = indexes;\n if (index < min) {\n // Push checked index\n state.checkedIndexes.splice(idx, 1, [min + pushedIndex, max + pushedIndex]);\n }\n });\n\n this.resize();\n\n return panels;\n }\n\n public replace(index: number, element: ElementLike | ElementLike[]): FlickingPanel[] {\n const state = this.state;\n const options = this.options;\n const panelManager = this.panelManager;\n const lastIndex = panelManager.getLastIndex();\n\n // Index should not below 0\n if (index < 0 || index > lastIndex) {\n return [];\n }\n\n const parsedElements = parseElement(element);\n const panels = parsedElements\n .map((el, idx) => new Panel(el, index + idx, this))\n .slice(0, lastIndex - index + 1);\n\n if (panels.length <= 0) {\n return [];\n }\n\n const replacedPanels = panelManager.replace(index, panels);\n\n replacedPanels.forEach(panel => {\n const visibleIndex = this.getVisibleIndexOf(panel);\n if (visibleIndex > -1) {\n this.visiblePanels.splice(visibleIndex, 1);\n }\n });\n\n // ...then calc bbox for all panels\n this.resizePanels(panels);\n\n const currentPanel = this.currentPanel;\n const wasEmpty = !currentPanel;\n if (wasEmpty) {\n this.currentPanel = panels[0];\n this.nearestPanel = panels[0];\n\n const newCenterPanel = panels[0];\n const newPanelPosition = this.findEstimatedPosition(newCenterPanel);\n state.position = newPanelPosition;\n this.updateAxesPosition(newPanelPosition);\n state.panelMaintainRatio = (newCenterPanel.getRelativeAnchorPosition() + options.gap / 2) / (newCenterPanel.getSize() + options.gap);\n } else if (isBetween(currentPanel!.getIndex(), index, index + panels.length - 1)) {\n // Current panel is replaced\n this.currentPanel = panelManager.get(currentPanel!.getIndex());\n }\n\n // Update checked indexes in infinite mode\n this.updateCheckedIndexes({ min: index, max: index + panels.length - 1 });\n\n this.resize();\n\n return panels;\n }\n\n public remove(index: number, deleteCount: number = 1): FlickingPanel[] {\n const state = this.state;\n // Index should not below 0\n index = Math.max(index, 0);\n\n const panelManager = this.panelManager;\n const currentIndex = this.getCurrentIndex();\n\n const removedPanels = panelManager.remove(index, deleteCount);\n if (isBetween(currentIndex, index, index + deleteCount - 1)) {\n // Current panel is removed\n // Use panel at removing index - 1 as new current panel if it exists\n const newCurrentIndex = Math.max(index - 1, panelManager.getRange().min);\n this.currentPanel = panelManager.get(newCurrentIndex);\n }\n\n // Update checked indexes in infinite mode\n if (deleteCount > 0) {\n // Check whether removing index will affect checked indexes\n // Suppose index 0 is empty and removed index 1, then checked index 0 should be deleted and vice versa.\n this.updateCheckedIndexes({ min: index - 1, max: index + deleteCount });\n // Uncache visible panels to refresh panels\n this.visiblePanels = [];\n }\n\n if (panelManager.getPanelCount() <= 0) {\n this.currentPanel = undefined;\n this.nearestPanel = undefined;\n }\n\n this.resize();\n\n const scrollArea = state.scrollArea;\n if (state.position < scrollArea.prev || state.position > scrollArea.next) {\n const newPosition = circulate(state.position, scrollArea.prev, scrollArea.next, false);\n this.moveCamera(newPosition);\n this.updateAxesPosition(newPosition);\n }\n\n return removedPanels;\n }\n\n public updateAdaptiveSize(): void {\n const state = this.state;\n const options = this.options;\n const horizontal = options.horizontal;\n const currentPanel = this.getCurrentPanel();\n\n if (!currentPanel) {\n return;\n }\n\n const shouldApplyAdaptive = options.adaptive || !state.isAdaptiveCached;\n const viewportStyle = this.viewportElement.style;\n if (shouldApplyAdaptive) {\n let sizeToApply: number;\n if (options.adaptive) {\n const panelBbox = currentPanel.getBbox();\n\n sizeToApply = horizontal ? panelBbox.height : panelBbox.width;\n } else {\n // Find minimum height of panels to maximum panel size\n const maximumPanelSize = this.panelManager.originalPanels().reduce((maximum, panel) => {\n const panelBbox = panel.getBbox();\n return Math.max(maximum, horizontal ? panelBbox.height : panelBbox.width);\n }, 0);\n\n sizeToApply = maximumPanelSize;\n }\n\n if (!state.isAdaptiveCached) {\n const viewportBbox = this.updateBbox();\n sizeToApply = Math.max(sizeToApply, horizontal ? viewportBbox.height : viewportBbox.width);\n state.isAdaptiveCached = true;\n }\n\n const viewportSize = `${sizeToApply}px`;\n if (horizontal) {\n viewportStyle.height = viewportSize;\n state.cachedBbox!.height = sizeToApply;\n } else {\n viewportStyle.width = viewportSize;\n state.cachedBbox!.width = sizeToApply;\n }\n }\n }\n\n // Update camera position after resizing\n public updateCameraPosition(): void {\n const state = this.state;\n const currentPanel = this.getCurrentPanel();\n const cameraPosition = this.getCameraPosition();\n const currentState = this.stateMachine.getState();\n const isFreeScroll = this.moveType.is(MOVE_TYPE.FREE_SCROLL);\n const relativeHangerPosition = this.getRelativeHangerPosition();\n const halfGap = this.options.gap / 2;\n\n if (currentState.holding || currentState.playing) {\n this.updateVisiblePanels();\n return;\n }\n\n let newPosition: number;\n if (isFreeScroll) {\n const positionBounded = this.canSetBoundMode() && (cameraPosition === state.scrollArea.prev || cameraPosition === state.scrollArea.next);\n const nearestPanel = this.getNearestPanel();\n\n // Preserve camera position if it is bound to scroll area limit\n newPosition = positionBounded || !nearestPanel\n ? cameraPosition\n : nearestPanel.getPosition() - halfGap + (nearestPanel.getSize() + 2 * halfGap) * state.panelMaintainRatio - relativeHangerPosition;\n } else {\n newPosition = currentPanel\n ? currentPanel.getAnchorPosition() - relativeHangerPosition\n : cameraPosition;\n }\n\n if (this.canSetBoundMode()) {\n newPosition = clamp(newPosition, state.scrollArea.prev, state.scrollArea.next);\n }\n\n // Pause & resume axes to prevent axes's \"change\" event triggered\n // This should be done before moveCamera, as moveCamera can trigger needPanel\n this.updateAxesPosition(newPosition);\n\n this.moveCamera(newPosition);\n }\n\n public updateBbox(): BoundingBox {\n const state = this.state;\n const options = this.options;\n const viewportElement = this.viewportElement;\n\n if (!state.cachedBbox) {\n state.cachedBbox = getBbox(viewportElement, options.useOffset);\n }\n\n return state.cachedBbox!;\n }\n\n public updatePlugins(): void {\n // update for resize\n this.plugins.forEach(plugin => {\n plugin.update && plugin.update(this.flicking);\n });\n }\n\n public destroy(option: Partial<DestroyOption>): void {\n const state = this.state;\n const wrapper = this.flicking.getElement();\n const viewportElement = this.viewportElement;\n const cameraElement = this.cameraElement;\n const originalPanels = this.panelManager.originalPanels();\n\n this.removePlugins(this.plugins);\n if (!option.preserveUI) {\n restoreStyle(viewportElement, state.originalViewportStyle);\n restoreStyle(cameraElement, state.originalCameraStyle);\n\n if (!state.isCameraGiven && !this.options.renderExternal) {\n const topmostElement = state.isViewportGiven\n ? viewportElement\n : wrapper;\n const deletingElement = state.isViewportGiven\n ? cameraElement\n : viewportElement;\n\n originalPanels.forEach(panel => {\n topmostElement.appendChild(panel.getElement());\n });\n\n topmostElement.removeChild(deletingElement);\n }\n }\n\n this.axes.destroy();\n this.panInput?.destroy();\n\n originalPanels.forEach(panel => { panel.destroy(option); });\n\n // release resources\n for (const x in this) {\n (this as any)[x] = null;\n }\n }\n\n public restore(status: FlickingStatus): void {\n const panels = status.panels;\n const defaultIndex = this.options.defaultIndex;\n const cameraElement = this.cameraElement;\n const panelManager = this.panelManager;\n\n // Restore index\n cameraElement.innerHTML = panels.map(panel => panel.html).join(\"\");\n\n // Create panels first\n this.refreshPanels();\n const createdPanels = panelManager.originalPanels();\n\n // ...then order it by its index\n const orderedPanels: Panel[] = [];\n panels.forEach((panel, idx) => {\n const createdPanel = createdPanels[idx];\n createdPanel.setIndex(panel.index);\n orderedPanels[panel.index] = createdPanel;\n });\n panelManager.replacePanels(orderedPanels, []);\n panelManager.setCloneCount(0); // No clones at this point\n\n const panelCount = panelManager.getPanelCount();\n if (panelCount > 0) {\n this.currentPanel = panelManager.get(status.index)\n || panelManager.get(defaultIndex)\n || panelManager.firstPanel();\n this.nearestPanel = this.currentPanel;\n } else {\n this.currentPanel = undefined;\n this.nearestPanel = undefined;\n }\n this.visiblePanels = orderedPanels.filter(panel => Boolean(panel));\n\n this.resize();\n\n this.axes.setTo({ flick: status.position }, 0);\n this.moveCamera(status.position);\n }\n\n public calcVisiblePanels(): Panel[] {\n const allPanels = this.panelManager.allPanels();\n if (this.options.renderOnlyVisible) {\n const cameraPos = this.getCameraPosition();\n const viewportSize = this.getSize();\n const basePanel = this.nearestPanel!;\n\n const getNextPanel = (panel: Panel) => {\n const nextPanel = panel.nextSibling;\n\n if (nextPanel && nextPanel.getPosition() >= panel.getPosition()) {\n return nextPanel;\n } else {\n return null;\n }\n };\n\n const getPrevPanel = (panel: Panel) => {\n const prevPanel = panel.prevSibling;\n\n if (prevPanel && prevPanel.getPosition() <= panel.getPosition()) {\n return prevPanel;\n } else {\n return null;\n }\n };\n\n const isOutOfBoundNext = (panel: Panel) => panel.getPosition() >= cameraPos + viewportSize;\n const isOutOfBoundPrev = (panel: Panel) => panel.getPosition() + panel.getSize() <= cameraPos;\n\n const getVisiblePanels = (\n panel: Panel,\n getNext: (panel: Panel) => Panel | null,\n isOutOfViewport: (panel: Panel) => boolean,\n ): Panel[] => {\n const visiblePanels: Panel[] = [];\n\n let lastPanel = panel;\n while (true) {\n const nextPanel = getNext(lastPanel);\n if (!nextPanel || isOutOfViewport(nextPanel)) {\n break;\n }\n visiblePanels.push(nextPanel);\n lastPanel = nextPanel;\n }\n return visiblePanels;\n };\n\n const panelCount = this.panelManager.getPanelCount();\n const getAbsIndex = (panel: Panel) => panel.getIndex() + (panel.getCloneIndex() + 1) * panelCount;\n const nextPanels = getVisiblePanels(basePanel, getNextPanel, isOutOfBoundNext);\n const prevPanels = getVisiblePanels(basePanel, getPrevPanel, isOutOfBoundPrev);\n\n return [basePanel, ...nextPanels, ...prevPanels].sort((panel1, panel2) => getAbsIndex(panel1) - getAbsIndex(panel2));\n } else {\n return allPanels.filter(panel => {\n const outsetProgress = panel.getOutsetProgress();\n\n return outsetProgress > -1 && outsetProgress < 1;\n });\n }\n }\n\n public getCurrentPanel(): Panel | undefined {\n return this.currentPanel;\n }\n\n public getCurrentIndex(): number {\n const currentPanel = this.currentPanel;\n\n return currentPanel\n ? currentPanel.getIndex()\n : -1;\n }\n\n public getNearestPanel(): Panel | undefined {\n return this.nearestPanel;\n }\n\n // Get progress from nearest panel\n public getCurrentProgress(): number {\n const currentState = this.stateMachine.getState();\n let nearestPanel = currentState.playing || currentState.holding\n ? this.nearestPanel\n : this.currentPanel;\n\n const panelManager = this.panelManager;\n if (!nearestPanel) {\n // There're no panels\n return NaN;\n }\n const { prev: prevRange, next: nextRange } = this.getScrollArea();\n const cameraPosition = this.getCameraPosition();\n const isOutOfBound = this.isOutOfBound();\n let prevPanel = nearestPanel.prevSibling;\n let nextPanel = nearestPanel.nextSibling;\n let hangerPosition = this.getHangerPosition();\n let nearestAnchorPos = nearestPanel.getAnchorPosition();\n\n if (\n isOutOfBound\n && prevPanel\n && nextPanel\n && cameraPosition < nextRange\n // On the basis of anchor, prevPanel is nearestPanel.\n && (hangerPosition - prevPanel.getAnchorPosition() < nearestAnchorPos - hangerPosition)\n ) {\n nearestPanel = prevPanel;\n nextPanel = nearestPanel.nextSibling;\n prevPanel = nearestPanel.prevSibling;\n nearestAnchorPos = nearestPanel.getAnchorPosition();\n }\n const nearestIndex = nearestPanel.getIndex() + (nearestPanel.getCloneIndex() + 1) * panelManager.getPanelCount();\n const nearestSize = nearestPanel.getSize();\n\n if (isOutOfBound) {\n const relativeHangerPosition = this.getRelativeHangerPosition();\n\n if (nearestAnchorPos > nextRange + relativeHangerPosition) {\n // next bounce area: hangerPosition - relativeHangerPosition - nextRange\n hangerPosition = nearestAnchorPos + hangerPosition - relativeHangerPosition - nextRange;\n } else if (nearestAnchorPos < prevRange + relativeHangerPosition) {\n // prev bounce area: hangerPosition - relativeHangerPosition - prevRange\n hangerPosition = nearestAnchorPos + hangerPosition - relativeHangerPosition - prevRange;\n }\n }\n const hangerIsNextToNearestPanel = hangerPosition >= nearestAnchorPos;\n const gap = this.options.gap;\n\n let basePosition = nearestAnchorPos;\n let targetPosition = nearestAnchorPos;\n if (hangerIsNextToNearestPanel) {\n targetPosition = nextPanel\n ? nextPanel.getAnchorPosition()\n : nearestAnchorPos + nearestSize + gap;\n } else {\n basePosition = prevPanel\n ? prevPanel.getAnchorPosition()\n : nearestAnchorPos - nearestSize - gap;\n }\n\n const progressBetween = (hangerPosition - basePosition) / (targetPosition - basePosition);\n const startIndex = hangerIsNextToNearestPanel\n ? nearestIndex\n : prevPanel\n ? prevPanel.getIndex()\n : nearestIndex - 1;\n\n return startIndex + progressBetween;\n }\n\n // Update axes flick position without triggering event\n public updateAxesPosition(position: number) {\n const axes = this.axes;\n axes.off();\n axes.setTo({\n flick: position,\n }, 0);\n axes.on(this.axesHandlers);\n }\n\n public getSize(): number {\n return this.state.size;\n }\n\n public getScrollArea(): { prev: number, next: number } {\n return this.state.scrollArea;\n }\n\n public isOutOfBound(): boolean {\n const state = this.state;\n const options = this.options;\n const scrollArea = state.scrollArea;\n\n return !options.circular\n && options.bound\n && (state.position <= scrollArea.prev || state.position >= scrollArea.next);\n }\n\n public canSetBoundMode(): boolean {\n const options = this.options;\n\n return options.bound && !options.circular;\n }\n\n public getViewportElement(): HTMLElement {\n return this.viewportElement;\n }\n\n public getCameraElement(): HTMLElement {\n return this.cameraElement;\n }\n\n public getScrollAreaSize(): number {\n const scrollArea = this.state.scrollArea;\n\n return scrollArea.next - scrollArea.prev;\n }\n\n public getRelativeHangerPosition(): number {\n return this.state.relativeHangerPosition;\n }\n\n public getHangerPosition(): number {\n return this.state.position + this.state.relativeHangerPosition;\n }\n\n public getCameraPosition(): number {\n return this.state.position;\n }\n\n public getPositionOffset(): number {\n return this.state.positionOffset;\n }\n\n public getCheckedIndexes(): Array<[number, number]> {\n return this.state.checkedIndexes;\n }\n\n public getVisiblePanels(): Panel[] {\n return this.visiblePanels;\n }\n\n public setCurrentPanel(panel: Panel): void {\n this.currentPanel = panel;\n }\n\n public setLastIndex(index: number): void {\n const currentPanel = this.currentPanel;\n const panelManager = this.panelManager;\n\n panelManager.setLastIndex(index);\n if (currentPanel && currentPanel.getIndex() > index) {\n this.currentPanel = panelManager.lastPanel();\n }\n\n this.resize();\n }\n\n public setVisiblePanels(panels: Panel[]): void {\n this.visiblePanels = panels;\n }\n\n public connectAxesHandler(handlers: { [key: string]: (event: { [key: string]: any; }) => any }): void {\n const axes = this.axes;\n\n this.axesHandlers = handlers;\n axes.on(handlers);\n }\n\n public addPlugins(plugins: Plugin | Plugin[]) {\n const newPlugins = ([] as Plugin[]).concat(plugins);\n\n newPlugins.forEach(plugin => {\n plugin.init(this.flicking);\n });\n\n this.plugins = this.plugins.concat(newPlugins);\n return this;\n }\n\n public removePlugins(plugins: Plugin | Plugin[]) {\n const currentPlugins = this.plugins;\n const removedPlugins = ([] as Plugin[]).concat(plugins);\n\n removedPlugins.forEach(plugin => {\n const index = currentPlugins.indexOf(plugin);\n\n if (index > -1) {\n currentPlugins.splice(index, 1);\n }\n\n plugin.destroy(this.flicking);\n });\n return this;\n }\n\n public updateCheckedIndexes(changedRange: { min: number, max: number }): void {\n const state = this.state;\n\n let removed = 0;\n state.checkedIndexes.concat().forEach((indexes, idx) => {\n const [min, max] = indexes;\n // Can fill part of indexes in range\n if (changedRange.min <= max && changedRange.max >= min) {\n // Remove checked index from list\n state.checkedIndexes.splice(idx - removed, 1);\n removed++;\n }\n });\n }\n\n public appendUncachedPanelElements(panels: Panel[]): void {\n const options = this.options;\n const fragment = document.createDocumentFragment();\n\n if (options.isEqualSize) {\n const prevVisiblePanels = this.visiblePanels;\n const equalSizeClasses = options.isEqualSize as string[]; // for readability\n const cached: { [className: string]: boolean } = {};\n\n this.visiblePanels = [];\n\n Object.keys(this.panelBboxes).forEach(className => {\n cached[className] = true;\n });\n\n panels.forEach(panel => {\n const overlappedClass = panel.getOverlappedClass(equalSizeClasses);\n if (overlappedClass && !cached[overlappedClass]) {\n if (!options.renderExternal) {\n fragment.appendChild(panel.getElement());\n }\n this.visiblePanels.push(panel);\n cached[overlappedClass] = true;\n } else if (!overlappedClass) {\n if (!options.renderExternal) {\n fragment.appendChild(panel.getElement());\n }\n this.visiblePanels.push(panel);\n }\n });\n prevVisiblePanels.forEach(panel => {\n this.addVisiblePanel(panel);\n });\n } else {\n if (!options.renderExternal) {\n panels.forEach(panel => fragment.appendChild(panel.getElement()));\n }\n this.visiblePanels = panels.filter(panel => Boolean(panel));\n }\n\n if (!options.renderExternal) {\n this.cameraElement.appendChild(fragment);\n }\n }\n\n private updateClonePanels() {\n const panelManager = this.panelManager;\n\n // Clone panels in circular mode\n if (this.options.circular && panelManager.getPanelCount() > 0) {\n this.clonePanels();\n this.updateClonedPanelPositions();\n }\n panelManager.chainAllPanels();\n }\n\n private getVisibleIndexOf(panel: Panel): number {\n return findIndex(this.visiblePanels, visiblePanel => visiblePanel === panel);\n }\n\n private build(): void {\n this.setElements();\n this.applyCSSValue();\n this.setMoveType();\n this.setAxesInstance();\n this.refreshPanels();\n this.setDefaultPanel();\n this.resize();\n this.moveToDefaultPanel();\n }\n\n private setElements(): void {\n const state = this.state;\n const options = this.options;\n const wrapper = this.flicking.getElement();\n const classPrefix = options.classPrefix;\n\n const viewportCandidate = wrapper.children[0] as HTMLElement;\n const hasViewportElement = viewportCandidate && hasClass(viewportCandidate, `${classPrefix}-viewport`);\n\n const viewportElement = hasViewportElement\n ? viewportCandidate\n : document.createElement(\"div\");\n\n const cameraCandidate = hasViewportElement\n ? viewportElement.children[0] as HTMLElement\n : wrapper.children[0] as HTMLElement;\n const hasCameraElement = cameraCandidate && hasClass(cameraCandidate, `${classPrefix}-camera`);\n\n const cameraElement = hasCameraElement\n ? cameraCandidate\n : document.createElement(\"div\");\n\n if (!hasCameraElement) {\n cameraElement.className = `${classPrefix}-camera`;\n\n const panelElements = hasViewportElement\n ? viewportElement.children\n : wrapper.children;\n\n // Make all panels to be a child of camera element\n // wrapper <- viewport <- camera <- panels[1...n]\n toArray(panelElements).forEach(child => {\n cameraElement.appendChild(child);\n });\n } else {\n state.originalCameraStyle = {\n className: cameraElement.getAttribute(\"class\"),\n style: cameraElement.getAttribute(\"style\"),\n };\n }\n\n if (!hasViewportElement) {\n viewportElement.className = `${classPrefix}-viewport`;\n\n // Add viewport element to wrapper\n wrapper.appendChild(viewportElement);\n } else {\n state.originalViewportStyle = {\n className: viewportElement.getAttribute(\"class\"),\n style: viewportElement.getAttribute(\"style\"),\n };\n }\n\n if (!hasCameraElement || !hasViewportElement) {\n viewportElement.appendChild(cameraElement);\n }\n\n this.viewportElement = viewportElement;\n this.cameraElement = cameraElement;\n state.isViewportGiven = hasViewportElement;\n state.isCameraGiven = hasCameraElement;\n }\n\n private applyCSSValue(): void {\n const options = this.options;\n const viewportElement = this.viewportElement;\n const cameraElement = this.cameraElement;\n const viewportStyle = this.viewportElement.style;\n\n // Set default css values for each element\n applyCSS(viewportElement, DEFAULT_VIEWPORT_CSS);\n applyCSS(cameraElement, DEFAULT_CAMERA_CSS);\n\n viewportElement.style.zIndex = `${options.zIndex}`;\n if (options.horizontal) {\n viewportStyle.minHeight = \"100%\";\n viewportStyle.width = \"100%\";\n } else {\n viewportStyle.minWidth = \"100%\";\n viewportStyle.height = \"100%\";\n }\n if (options.overflow) {\n viewportStyle.overflow = \"visible\";\n }\n\n this.panelManager = new PanelManager(this.cameraElement, options);\n }\n\n private setMoveType(): void {\n const moveType = this.options.moveType as MoveTypeObjectOption;\n\n switch (moveType.type) {\n case MOVE_TYPE.SNAP:\n this.moveType = new Snap(moveType.count);\n break;\n case MOVE_TYPE.FREE_SCROLL:\n this.moveType = new FreeScroll();\n break;\n default:\n throw new Error(\"moveType is not correct!\");\n }\n }\n\n private setAxesInstance(): void {\n const state = this.state;\n const options = this.options;\n\n const scrollArea = state.scrollArea;\n\n this.axes = new Axes({\n flick: {\n range: [scrollArea.prev, scrollArea.next],\n circular: options.circular,\n bounce: [0, 0], // will be updated in resize()\n },\n }, {\n easing: options.panelEffect,\n deceleration: options.deceleration,\n interruptable: true,\n });\n\n this.createPanInput();\n }\n\n private refreshPanels(): void {\n const panelManager = this.panelManager;\n // Panel elements were attached to camera element by Flicking class\n const panelElements = this.cameraElement.children;\n\n // Initialize panels\n const panels = toArray(panelElements).map(\n (el: HTMLElement, idx: number) => new Panel(el, idx, this),\n );\n\n panelManager.replacePanels(panels, []);\n this.visiblePanels = panels.filter(panel => Boolean(panel));\n }\n\n private setDefaultPanel(): void {\n const options = this.options;\n const panelManager = this.panelManager;\n const indexRange = this.panelManager.getRange();\n const index = clamp(options.defaultIndex, indexRange.min, indexRange.max);\n\n this.currentPanel = panelManager.get(index);\n }\n\n private clonePanels() {\n const state = this.state;\n const options = this.options;\n const panelManager = this.panelManager;\n\n const gap = options.gap;\n const viewportSize = state.size;\n const firstPanel = panelManager.firstPanel();\n const lastPanel = panelManager.lastPanel()!;\n\n // There're no panels exist\n if (!firstPanel) {\n return;\n }\n\n // For each panels, clone itself while last panel's position + size is below viewport size\n const panels = panelManager.originalPanels();\n const reversedPanels = panels.concat().reverse();\n\n const sumOriginalPanelSize = lastPanel.getPosition() + lastPanel.getSize() - firstPanel.getPosition() + gap;\n const relativeAnchorPosition = firstPanel.getRelativeAnchorPosition();\n const relativeHangerPosition = this.getRelativeHangerPosition();\n\n const areaPrev = (relativeHangerPosition - relativeAnchorPosition) % sumOriginalPanelSize;\n let sizeSum = 0;\n let panelAtLeftBoundary!: Panel;\n for (const panel of reversedPanels) {\n if (!panel) {\n continue;\n }\n sizeSum += panel.getSize() + gap;\n if (sizeSum >= areaPrev) {\n panelAtLeftBoundary = panel;\n break;\n }\n }\n\n const areaNext = (viewportSize - relativeHangerPosition + relativeAnchorPosition) % sumOriginalPanelSize;\n sizeSum = 0;\n let panelAtRightBoundary!: Panel;\n for (const panel of panels) {\n if (!panel) {\n continue;\n }\n sizeSum += panel.getSize() + gap;\n if (sizeSum >= areaNext) {\n panelAtRightBoundary = panel;\n break;\n }\n }\n\n // Need one more set of clones on prev area of original panel 0\n const needCloneOnPrev = panelAtLeftBoundary.getIndex() !== 0\n && panelAtLeftBoundary.getIndex() <= panelAtRightBoundary.getIndex();\n\n // Visible count of panel 0 on first screen\n const panel0OnFirstscreen = Math.ceil((relativeHangerPosition + firstPanel.getSize() - relativeAnchorPosition) / sumOriginalPanelSize)\n + Math.ceil((viewportSize - relativeHangerPosition + relativeAnchorPosition) / sumOriginalPanelSize)\n - 1; // duplication\n\n const cloneCount = panel0OnFirstscreen\n + (needCloneOnPrev ? 1 : 0);\n const prevCloneCount = panelManager.getCloneCount();\n\n panelManager.setCloneCount(cloneCount);\n if (options.renderExternal) {\n return;\n }\n\n if (cloneCount > prevCloneCount) {\n // should clone more\n for (let cloneIndex = prevCloneCount; cloneIndex < cloneCount; cloneIndex++) {\n const clones = panels.map(origPanel => origPanel.clone(cloneIndex));\n const fragment = document.createDocumentFragment();\n clones.forEach(panel => fragment.appendChild(panel.getElement()));\n\n this.cameraElement.appendChild(fragment);\n this.visiblePanels.push(...clones.filter(clone => Boolean(clone)));\n panelManager.insertClones(cloneIndex, 0, clones);\n }\n } else if (cloneCount < prevCloneCount) {\n // should remove some\n panelManager.removeClonesAfter(cloneCount);\n }\n }\n\n private moveToDefaultPanel(): void {\n const state = this.state;\n const panelManager = this.panelManager;\n const options = this.options;\n const indexRange = this.panelManager.getRange();\n\n const defaultIndex = clamp(options.defaultIndex, indexRange.min, indexRange.max);\n const defaultPanel = panelManager.get(defaultIndex);\n\n let defaultPosition = 0;\n if (defaultPanel) {\n defaultPosition = defaultPanel.getAnchorPosition() - state.relativeHangerPosition;\n defaultPosition = this.canSetBoundMode()\n ? clamp(defaultPosition, state.scrollArea.prev, state.scrollArea.next)\n : defaultPosition;\n }\n\n this.moveCamera(defaultPosition);\n this.axes.setTo({ flick: defaultPosition }, 0);\n }\n\n private updateSize(): void {\n const state = this.state;\n const options = this.options;\n const panels = this.panelManager.originalPanels()\n .filter(panel => Boolean(panel));\n const bbox = this.updateBbox();\n\n const prevSize = state.size;\n // Update size & hanger position\n state.size = options.horizontal\n ? bbox.width\n : bbox.height;\n\n if (prevSize !== state.size) {\n state.relativeHangerPosition = parseArithmeticExpression(options.hanger, state.size);\n state.infiniteThreshold = parseArithmeticExpression(options.infiniteThreshold, state.size);\n }\n\n if (panels.length <= 0) {\n return;\n }\n\n this.resizePanels(panels);\n }\n\n private updateOriginalPanelPositions(): void {\n const gap = this.options.gap;\n const panelManager = this.panelManager;\n\n const firstPanel = panelManager.firstPanel();\n const panels = panelManager.originalPanels();\n\n if (!firstPanel) {\n return;\n }\n\n const currentPanel = this.currentPanel!;\n const nearestPanel = this.nearestPanel;\n const currentState = this.stateMachine.getState();\n const scrollArea = this.state.scrollArea;\n\n // Update panel position && fit to wrapper\n let nextPanelPos = firstPanel.getPosition();\n let maintainingPanel: Panel = firstPanel;\n if (nearestPanel) {\n // We should maintain nearestPanel's position\n const looped = !isBetween(currentState.lastPosition + currentState.delta, scrollArea.prev, scrollArea.next);\n\n maintainingPanel = looped\n ? currentPanel\n : nearestPanel;\n } else if (firstPanel.getIndex() > 0) {\n maintainingPanel = currentPanel;\n }\n\n const panelsBeforeMaintainPanel = panels.slice(0, maintainingPanel.getIndex() + (maintainingPanel.getCloneIndex() + 1) * panels.length);\n const accumulatedSize = panelsBeforeMaintainPanel.reduce((total, panel) => {\n return total + panel.getSize() + gap;\n }, 0);\n\n nextPanelPos = maintainingPanel.getPosition() - accumulatedSize;\n\n panels.forEach(panel => {\n const newPosition = nextPanelPos;\n const panelSize = panel.getSize();\n\n panel.setPosition(newPosition);\n nextPanelPos += panelSize + gap;\n });\n\n if (!this.options.renderOnlyVisible) {\n panels.forEach(panel => panel.setPositionCSS());\n }\n }\n\n private updateClonedPanelPositions(): void {\n const state = this.state;\n const options = this.options;\n const panelManager = this.panelManager;\n const clonedPanels = panelManager.clonedPanels()\n .reduce((allClones, clones) => [...allClones, ...clones], [])\n .filter(panel => Boolean(panel));\n\n const scrollArea = state.scrollArea;\n\n const firstPanel = panelManager.firstPanel();\n const lastPanel = panelManager.lastPanel()!;\n\n if (!firstPanel) {\n return;\n }\n\n const sumOriginalPanelSize = lastPanel.getPosition() + lastPanel.getSize() - firstPanel.getPosition() + options.gap;\n\n // Locate all cloned panels linearly first\n for (const panel of clonedPanels) {\n const origPanel = panel.getOriginalPanel();\n const cloneIndex = panel.getCloneIndex();\n const cloneBasePos = sumOriginalPanelSize * (cloneIndex + 1);\n const clonedPanelPos = cloneBasePos + origPanel.getPosition();\n\n panel.setPosition(clonedPanelPos);\n }\n\n let lastReplacePosition = firstPanel.getPosition();\n // reverse() pollutes original array, so copy it with concat()\n for (const panel of clonedPanels.concat().reverse()) {\n const panelSize = panel.getSize();\n const replacePosition = lastReplacePosition - panelSize - options.gap;\n\n if (replacePosition + panelSize <= scrollArea.prev) {\n // Replace is not meaningful, as it won't be seen in current scroll area\n break;\n }\n\n panel.setPosition(replacePosition);\n lastReplacePosition = replacePosition;\n }\n\n if (!this.options.renderOnlyVisible) {\n clonedPanels.forEach(panel => {\n panel.setPositionCSS();\n });\n }\n }\n\n private updateVisiblePanelPositions(): void {\n if (this.options.renderOnlyVisible) {\n this.visiblePanels.forEach(panel => {\n panel.setPositionCSS(this.state.positionOffset);\n });\n }\n }\n\n private updateScrollArea(): void {\n const state = this.state;\n const panelManager = this.panelManager;\n const options = this.options;\n const axes = this.axes;\n\n // Set viewport scrollable area\n const firstPanel = panelManager.firstPanel();\n const lastPanel = panelManager.lastPanel() as Panel;\n const relativeHangerPosition = state.relativeHangerPosition;\n\n if (!firstPanel) {\n state.scrollArea = {\n prev: 0,\n next: 0,\n };\n } else if (this.canSetBoundMode()) {\n const sumOriginalPanelSize = lastPanel.getPosition() + lastPanel.getSize() - firstPanel.getPosition();\n\n if (sumOriginalPanelSize >= state.size) {\n state.scrollArea = {\n prev: firstPanel.getPosition(),\n next: lastPanel.getPosition() + lastPanel.getSize() - state.size,\n };\n } else {\n // Find anchor position of set of the combined panels\n const relAnchorPosOfCombined = parseArithmeticExpression(options.anchor, sumOriginalPanelSize);\n const anchorPos = firstPanel.getPosition() + clamp(\n relAnchorPosOfCombined,\n sumOriginalPanelSize - (state.size - relativeHangerPosition),\n relativeHangerPosition,\n );\n\n state.scrollArea = {\n prev: anchorPos - relativeHangerPosition,\n next: anchorPos - relativeHangerPosition,\n };\n }\n } else if (options.circular) {\n const sumOriginalPanelSize = lastPanel.getPosition() + lastPanel.getSize() - firstPanel.getPosition() + options.gap;\n\n // Maximum scroll extends to first clone sequence's first panel\n state.scrollArea = {\n prev: firstPanel.getAnchorPosition() - relativeHangerPosition,\n next: sumOriginalPanelSize + firstPanel.getAnchorPosition() - relativeHangerPosition,\n };\n } else {\n state.scrollArea = {\n prev: firstPanel.getAnchorPosition() - relativeHangerPosition,\n next: lastPanel.getAnchorPosition() - relativeHangerPosition,\n };\n }\n\n const viewportSize = state.size;\n const bounce = options.bounce;\n\n let parsedBounce: number[];\n if (isArray(bounce)) {\n parsedBounce = (bounce as string[]).map(val => parseArithmeticExpression(val, viewportSize, DEFAULT_OPTIONS.bounce as number));\n } else {\n const parsedVal = parseArithmeticExpression(bounce as number | string, viewportSize, DEFAULT_OPTIONS.bounce as number);\n parsedBounce = [parsedVal, parsedVal];\n }\n\n // Update axes range and bounce\n const flick = axes.axis.flick;\n flick.range = [state.scrollArea.prev, state.scrollArea.next];\n flick.bounce = parsedBounce;\n }\n\n private checkNeedPanel(axesEvent?: any): void {\n const state = this.state;\n const options = this.options;\n const panelManager = this.panelManager;\n const currentPanel = this.currentPanel;\n const nearestPanel = this.nearestPanel;\n const currentState = this.stateMachine.getState();\n\n if (!options.infinite) {\n return;\n }\n\n const gap = options.gap;\n const infiniteThreshold = state.infiniteThreshold;\n const maxLastIndex = panelManager.getLastIndex();\n\n if (maxLastIndex < 0) {\n return;\n }\n\n if (!currentPanel || !nearestPanel) {\n // There're no panels\n this.triggerNeedPanel({\n axesEvent,\n siblingPanel: null,\n direction: null,\n indexRange: {\n min: 0,\n max: maxLastIndex,\n length: maxLastIndex + 1,\n },\n });\n return;\n }\n\n const originalNearestPosition = nearestPanel.getPosition();\n\n // Check next direction\n let checkingPanel: Panel | null = !currentState.holding && !currentState.playing\n ? currentPanel\n : nearestPanel;\n\n while (checkingPanel) {\n const currentIndex = checkingPanel.getIndex();\n const nextSibling = checkingPanel.nextSibling;\n const lastPanel = panelManager.lastPanel()!;\n const atLastPanel = currentIndex === lastPanel.getIndex();\n const nextIndex = !atLastPanel && nextSibling\n ? nextSibling.getIndex()\n : maxLastIndex + 1;\n const currentNearestPosition = nearestPanel.getPosition();\n const panelRight = checkingPanel.getPosition() + checkingPanel.getSize() - (currentNearestPosition - originalNearestPosition);\n const cameraNext = state.position + state.size;\n\n // There're empty panels between\n const emptyPanelExistsBetween = (nextIndex - currentIndex > 1);\n // Expected prev panel's left position is smaller than camera position\n const overThreshold = panelRight + gap - infiniteThreshold <= cameraNext;\n\n if (emptyPanelExistsBetween && overThreshold) {\n this.triggerNeedPanel({\n axesEvent,\n siblingPanel: checkingPanel,\n direction: DIRECTION.NEXT,\n indexRange: {\n min: currentIndex + 1,\n max: nextIndex - 1,\n length: nextIndex - currentIndex - 1,\n },\n });\n }\n\n // Trigger needPanel in circular & at max panel index\n if (options.circular && currentIndex === maxLastIndex && overThreshold) {\n const firstPanel = panelManager.firstPanel();\n const firstIndex = firstPanel\n ? firstPanel.getIndex()\n : -1;\n\n if (firstIndex > 0) {\n this.triggerNeedPanel({\n axesEvent,\n siblingPanel: checkingPanel,\n direction: DIRECTION.NEXT,\n indexRange: {\n min: 0,\n max: firstIndex - 1,\n length: firstIndex,\n },\n });\n }\n }\n\n // Check whether panels are changed\n const lastPanelAfterNeed = panelManager.lastPanel()!;\n const atLastPanelAfterNeed = lastPanelAfterNeed && currentIndex === lastPanelAfterNeed.getIndex();\n\n if (atLastPanelAfterNeed || !overThreshold) {\n break;\n }\n\n checkingPanel = checkingPanel.nextSibling;\n }\n\n // Check prev direction\n checkingPanel = nearestPanel;\n while (checkingPanel) {\n const cameraPrev = state.position;\n const checkingIndex = checkingPanel.getIndex();\n const prevSibling = checkingPanel.prevSibling;\n const firstPanel = panelManager.firstPanel()!;\n const atFirstPanel = checkingIndex === firstPanel.getIndex();\n const prevIndex = !atFirstPanel && prevSibling\n ? prevSibling.getIndex()\n : -1;\n const currentNearestPosition = nearestPanel.getPosition();\n const panelLeft = checkingPanel.getPosition() - (currentNearestPosition - originalNearestPosition);\n\n // There're empty panels between\n const emptyPanelExistsBetween = checkingIndex - prevIndex > 1;\n // Expected prev panel's right position is smaller than camera position\n const overThreshold = panelLeft - gap + infiniteThreshold >= cameraPrev;\n if (emptyPanelExistsBetween && overThreshold) {\n this.triggerNeedPanel({\n axesEvent,\n siblingPanel: checkingPanel,\n direction: DIRECTION.PREV,\n indexRange: {\n min: prevIndex + 1,\n max: checkingIndex - 1,\n length: checkingIndex - prevIndex - 1,\n },\n });\n }\n\n // Trigger needPanel in circular & at panel 0\n if (options.circular && checkingIndex === 0 && overThreshold) {\n const lastPanel = panelManager.lastPanel();\n\n if (lastPanel && lastPanel.getIndex() < maxLastIndex) {\n const lastIndex = lastPanel.getIndex();\n\n this.triggerNeedPanel({\n axesEvent,\n siblingPanel: checkingPanel,\n direction: DIRECTION.PREV,\n indexRange: {\n min: lastIndex + 1,\n max: maxLastIndex,\n length: maxLastIndex - lastIndex,\n },\n });\n }\n }\n\n // Check whether panels were changed\n const firstPanelAfterNeed = panelManager.firstPanel();\n const atFirstPanelAfterNeed = firstPanelAfterNeed && checkingIndex === firstPanelAfterNeed.getIndex();\n\n // Looped in circular mode\n if (atFirstPanelAfterNeed || !overThreshold) {\n break;\n }\n\n checkingPanel = checkingPanel.prevSibling;\n }\n }\n\n private triggerNeedPanel(params: {\n axesEvent: any;\n siblingPanel: Panel | null,\n direction: FlickingEvent[\"direction\"];\n indexRange: NeedPanelEvent[\"range\"];\n }): void {\n const { axesEvent, siblingPanel, direction, indexRange } = params;\n const options = this.options;\n const checkedIndexes = this.state.checkedIndexes;\n const alreadyTriggered = checkedIndexes.some(([min, max]) => min === indexRange.min || max === indexRange.max);\n const hasHandler = this.flicking.hasOn(EVENTS.NEED_PANEL);\n\n if (alreadyTriggered || !hasHandler) {\n return;\n }\n\n // Should done before triggering event, as we can directly add panels by event callback\n checkedIndexes.push([indexRange.min, indexRange.max]);\n\n const index = siblingPanel\n ? siblingPanel.getIndex()\n : 0;\n const isTrusted = axesEvent\n ? axesEvent.isTrusted\n : false;\n\n this.triggerEvent(\n EVENTS.NEED_PANEL,\n axesEvent,\n isTrusted,\n {\n index,\n panel: siblingPanel,\n direction,\n range: indexRange,\n fill: (element: ElementLike | ElementLike[]) => {\n const panelManager = this.panelManager;\n if (!siblingPanel) {\n return this.insert(panelManager.getRange().max + 1, element);\n }\n\n const parsedElements = parseElement(element);\n // Slice elements to fit size equal to empty spaces\n const elements = direction === DIRECTION.NEXT\n ? parsedElements.slice(0, indexRange.length)\n : parsedElements.slice(-indexRange.length);\n\n if (direction === DIRECTION.NEXT) {\n if (options.circular && index === panelManager.getLastIndex()) {\n // needPanel event is triggered on last index, insert at index 0\n return this.insert(0, elements);\n } else {\n return siblingPanel.insertAfter(elements);\n }\n } else if (direction === DIRECTION.PREV) {\n if (options.circular && index === 0) {\n // needPanel event is triggered on first index(0), insert at the last index\n return this.insert(indexRange.max - elements.length + 1, elements);\n } else {\n return siblingPanel.insertBefore(elements);\n }\n } else {\n // direction is null when there're no panels exist\n return this.insert(0, elements);\n }\n },\n } as Partial<NeedPanelEvent>,\n );\n }\n\n private updateVisiblePanels() {\n const state = this.state;\n const options = this.options;\n const panelManager = this.panelManager;\n const currentState = this.stateMachine.getState();\n const cameraElement = this.cameraElement;\n const { renderExternal, renderOnlyVisible } = options;\n if (!renderOnlyVisible) {\n return;\n }\n\n if (!this.nearestPanel) {\n this.visiblePanels = [];\n while (cameraElement.firstChild) {\n cameraElement.removeChild(cameraElement.firstChild);\n }\n return;\n }\n\n const prevVisiblePanels = this.visiblePanels;\n const newVisiblePanels = this.calcVisiblePanels();\n\n const { addedPanels, removedPanels } = this.checkVisiblePanelChange(prevVisiblePanels, newVisiblePanels);\n\n if (addedPanels.length <= 0 && removedPanels.length <= 0) {\n // Visible panels not changed\n return;\n }\n\n if (currentState.holding) {\n newVisiblePanels.push(...removedPanels);\n } else {\n const firstVisiblePanelPos = newVisiblePanels[0].getPosition();\n state.positionOffset = firstVisiblePanelPos;\n }\n\n newVisiblePanels.forEach(panel => {\n panel.setPositionCSS(state.positionOffset);\n });\n\n if (!renderExternal) {\n if (!currentState.holding) {\n removedPanels.forEach(panel => {\n const panelElement = panel.getElement();\n panelElement.parentNode && cameraElement.removeChild(panelElement);\n });\n }\n\n const fragment = document.createDocumentFragment();\n addedPanels.forEach(panel => {\n fragment.appendChild(panel.getElement());\n });\n\n cameraElement.appendChild(fragment);\n }\n\n const firstVisiblePanel = newVisiblePanels[0];\n const lastVisiblePanel = newVisiblePanels[newVisiblePanels.length - 1];\n const getAbsIndex = (panel: Panel) => panel.getIndex() + (panel.getCloneIndex() + 1) * panelManager.getPanelCount();\n\n const newVisibleRange = {\n min: getAbsIndex(firstVisiblePanel),\n max: getAbsIndex(lastVisiblePanel),\n };\n this.visiblePanels = newVisiblePanels;\n this.flicking.trigger(EVENTS.VISIBLE_CHANGE, {\n type: EVENTS.VISIBLE_CHANGE,\n range: newVisibleRange,\n });\n }\n\n private checkVisiblePanelChange(prevVisiblePanels: Panel[], newVisiblePanels: Panel[]) {\n const prevRefCount = prevVisiblePanels.map(() => 0);\n const newRefCount = newVisiblePanels.map(() => 0);\n\n prevVisiblePanels.forEach((prevPanel, prevIndex) => {\n newVisiblePanels.forEach((newPanel, newIndex) => {\n if (prevPanel === newPanel) {\n prevRefCount[prevIndex]++;\n newRefCount[newIndex]++;\n }\n });\n });\n\n const removedPanels = prevRefCount.reduce((removed: Panel[], count, index) => {\n return count === 0\n ? [...removed, prevVisiblePanels[index]]\n : removed;\n }, []);\n const addedPanels = newRefCount.reduce((added: Panel[], count, index) => {\n return count === 0\n ? [...added, newVisiblePanels[index]]\n : added;\n }, []);\n\n return { removedPanels, addedPanels };\n }\n\n private resizePanels(panels: Panel[]): void {\n const options = this.options;\n const panelBboxes = this.panelBboxes;\n\n if (options.isEqualSize === true) {\n if (!panelBboxes.default) {\n const defaultPanel = panels[0];\n panelBboxes.default = defaultPanel.getBbox();\n }\n\n const defaultBbox = panelBboxes.default;\n\n panels.forEach(panel => {\n panel.resize(defaultBbox);\n });\n return;\n } else if (options.isEqualSize) {\n const equalSizeClasses = options.isEqualSize;\n\n panels.forEach(panel => {\n const overlappedClass = panel.getOverlappedClass(equalSizeClasses);\n if (overlappedClass) {\n panel.resize(panelBboxes[overlappedClass]);\n panelBboxes[overlappedClass] = panel.getBbox();\n } else {\n panel.resize();\n }\n });\n return;\n }\n panels.forEach(panel => {\n panel.resize();\n });\n }\n\n private createPanInput() {\n const options = this.options;\n\n this.panInput = new PanInput(this.viewportElement, {\n inputType: options.inputType,\n thresholdAngle: options.thresholdAngle,\n iOSEdgeSwipeThreshold: options.iOSEdgeSwipeThreshold,\n scale: options.horizontal ? [-1, 0] : [0, -1],\n });\n\n this.axes.connect(options.horizontal ? [\"flick\", \"\"] : [\"\", \"flick\"], this.panInput);\n }\n}\n","/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport Component from \"@egjs/component\";\nimport ImReady from \"@egjs/imready\";\nimport Viewport from \"./components/Viewport\";\nimport Panel from \"./components/Panel\";\n\nimport { merge, getProgress, parseElement, isString, counter, findIndex } from \"./utils\";\nimport { DEFAULT_OPTIONS, EVENTS, DIRECTION, AXES_EVENTS, STATE_TYPE, DEFAULT_MOVE_TYPE_OPTIONS } from \"./consts\";\nimport {\n FlickingOptions,\n FlickingEvent,\n Direction,\n EventType,\n FlickingPanel,\n TriggerCallback,\n FlickingContext,\n FlickingStatus,\n Plugin,\n ElementLike,\n DestroyOption,\n BeforeSyncResult,\n SyncResult,\n ChangeEvent,\n SelectEvent,\n NeedPanelEvent,\n VisibleChangeEvent,\n ContentErrorEvent,\n MoveTypeStringOption,\n ValueOf,\n} from \"./types\";\n// import { sendEvent } from \"./ga/ga\";\nimport { DiffResult } from \"@egjs/list-differ\";\n\n/**\n * @memberof eg\n * @extends eg.Component\n * @support {\"ie\": \"10+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\" , \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"4.X+\"}\n * @requires {@link https://github.com/naver/egjs-component|eg.Component}\n * @requires {@link https://github.com/naver/egjs-axes|eg.Axes}\n * @see Easing Functions Cheat Sheet {@link http://easings.net/} <ko>이징 함수 Cheat Sheet {@link http://easings.net/}</ko>\n */\nclass Flicking extends Component<{\n holdStart: FlickingEvent;\n holdEnd: FlickingEvent;\n moveStart: FlickingEvent;\n move: FlickingEvent;\n moveEnd: FlickingEvent;\n change: ChangeEvent;\n restore: FlickingEvent;\n select: SelectEvent;\n needPanel: NeedPanelEvent;\n visibleChange: VisibleChangeEvent;\n contentError: ContentErrorEvent;\n}> {\n /**\n * Version info string\n * @ko 버전정보 문자열\n * @example\n * eg.Flicking.VERSION; // ex) 3.0.0\n * @memberof eg.Flicking\n */\n public static VERSION: string = \"#__VERSION__#\";\n /**\n * Direction constant - \"PREV\" or \"NEXT\"\n * @ko 방향 상수 - \"PREV\" 또는 \"NEXT\"\n * @type {object}\n * @property {\"PREV\"} PREV - Prev direction from current hanger position.<br/>It's `left(←️)` direction when `horizontal: true`.<br/>Or, `up(↑️)` direction when `horizontal: false`.<ko>현재 행어를 기준으로 이전 방향.<br/>`horizontal: true`일 경우 `왼쪽(←️)` 방향.<br/>`horizontal: false`일 경우 `위쪽(↑️)`방향이다.</ko>\n * @property {\"NEXT\"} NEXT - Next direction from current hanger position.<br/>It's `right(→)` direction when `horizontal: true`.<br/>Or, `down(↓️)` direction when `horizontal: false`.<ko>현재 행어를 기준으로 다음 방향.<br/>`horizontal: true`일 경우 `오른쪽(→)` 방향.<br/>`horizontal: false`일 경우 `아래쪽(↓️)`방향이다.</ko>\n * @example\n * eg.Flicking.DIRECTION.PREV; // \"PREV\"\n * eg.Flicking.DIRECTION.NEXT; // \"NEXT\"\n */\n public static DIRECTION: Direction = DIRECTION;\n\n /**\n * Event type object with event name strings.\n * @ko 이벤트 이름 문자열들을 담은 객체\n * @type {object}\n * @property {\"holdStart\"} HOLD_START - holdStart event<ko>holdStart 이벤트</ko>\n * @property {\"holdEnd\"} HOLD_END - holdEnd event<ko>holdEnd 이벤트</ko>\n * @property {\"moveStart\"} MOVE_START - moveStart event<ko>moveStart 이벤트</ko>\n * @property {\"move\"} MOVE - move event<ko>move 이벤트</ko>\n * @property {\"moveEnd\"} MOVE_END - moveEnd event<ko>moveEnd 이벤트</ko>\n * @property {\"change\"} CHANGE - change event<ko>change 이벤트</ko>\n * @property {\"restore\"} RESTORE - restore event<ko>restore 이벤트</ko>\n * @property {\"select\"} SELECT - select event<ko>select 이벤트</ko>\n * @property {\"needPanel\"} NEED_PANEL - needPanel event<ko>needPanel 이벤트</ko>\n * @example\n * eg.Flicking.EVENTS.MOVE_START; // \"MOVE_START\"\n */\n public static EVENTS: EventType = EVENTS;\n\n public options: FlickingOptions;\n\n private wrapper: HTMLElement;\n private viewport: Viewport;\n private contentsReadyChecker: ImReady | null = null;\n\n private eventContext: FlickingContext;\n private isPanelChangedAtBeforeSync: boolean = false;\n\n /**\n * @param element A base element for the eg.Flicking module. When specifying a value as a `string` type, you must specify a css selector string to select the element.<ko>eg.Flicking 모듈을 사용할 기준 요소. `string`타입으로 값 지정시 요소를 선택하기 위한 css 선택자 문자열을 지정해야 한다.</ko>\n * @param options An option object of the eg.Flicking module<ko>eg.Flicking 모듈의 옵션 객체</ko>\n * @param {string} [options.classPrefix=\"eg-flick\"] A prefix of class names will be added for the panels, viewport, and camera.<ko>패널들과 뷰포트, 카메라에 추가될 클래스 이름의 접두사.</ko>\n * @param {number} [options.deceleration=0.0075] Deceleration value for panel movement animation for animation triggered by manual user input. A higher value means a shorter running time.<ko>사용자의 동작으로 가속도가 적용된 패널 이동 애니메이션의 감속도. 값이 높을수록 애니메이션 실행 시간이 짧아진다.</ko>\n * @param {boolean} [options.horizontal=true] The direction of panel movement. (true: horizontal, false: vertical)<ko>패널 이동 방향. (true: 가로방향, false: 세로방향)</ko>\n * @param {boolean} [options.circular=false] Enables circular mode, which connects first/last panel for continuous scrolling.<ko>순환 모드를 활성화한다. 순환 모드에서는 양 끝의 패널이 서로 연결되어 끊김없는 스크롤이 가능하다.</ko>\n * @param {boolean} [options.infinite=false] Enables infinite mode, which can automatically trigger needPanel until reaching the last panel's index reaches the lastIndex.<ko>무한 모드를 활성화한다. 무한 모드에서는 needPanel 이벤트를 자동으로 트리거한다. 해당 동작은 마지막 패널의 인덱스가 lastIndex와 일치할때까지 일어난다.</ko>\n * @param {number} [options.infiniteThreshold=0] A Threshold from viewport edge before triggering `needPanel` event in infinite mode.<ko>무한 모드에서 `needPanel`이벤트가 발생하기 위한 뷰포트 끝으로부터의 최대 거리.</ko>\n * @param {number} [options.lastIndex=Infinity] Maximum panel index that Flicking can set. Flicking won't trigger `needPanel` when the event's panel index is greater than it.<br/>Also, if the last panel's index reached a given index, you can't add more panels.<ko>Flicking이 설정 가능한 패널의 최대 인덱스. `needPanel` 이벤트에 지정된 인덱스가 최대 패널의 개수보다 같거나 커야 하는 경우에 이벤트를 트리거하지 않게 한다.<br>또한, 마지막 패널의 인덱스가 주어진 인덱스와 동일할 경우, 새로운 패널을 더 이상 추가할 수 없다.</ko>\n * @param {number} [options.threshold=40] Movement threshold to change panel(unit: pixel). It should be dragged above the threshold to change the current panel.<ko>패널 변경을 위한 이동 임계값 (단위: 픽셀). 주어진 값 이상으로 스크롤해야만 패널 변경이 가능하다.</ko>\n * @param {number} [options.duration=100] Duration of the panel movement animation. (unit: ms)<ko>패널 이동 애니메이션 진행 시간.(단위: ms)</ko>\n * @param {function} [options.panelEffect=x => 1 - Math.pow(1 - x, 3)] An easing function applied to the panel movement animation. Default value is `easeOutCubic`.<ko>패널 이동 애니메이션에 적용할 easing함수. 기본값은 `easeOutCubic`이다.</ko>\n * @param {number} [options.defaultIndex=0] Index of the panel to set as default when initializing. A zero-based integer.<ko>초기화시 지정할 디폴트 패널의 인덱스로, 0부터 시작하는 정수.</ko>\n * @param {string[]} [options.inputType=[\"touch,\"mouse\"]] Types of input devices to enable.({@link https://naver.github.io/egjs-axes/release/latest/doc/global.html#PanInputOption Reference})<ko>활성화할 입력 장치 종류. ({@link https://naver.github.io/egjs-axes/release/latest/doc/global.html#PanInputOption 참고})</ko>\n * @param {number} [options.thresholdAngle=45] The threshold angle value(0 ~ 90).<br>If the input angle from click/touched position is above or below this value in horizontal and vertical mode each, scrolling won't happen.<ko>스크롤 동작을 막기 위한 임계각(0 ~ 90).<br>클릭/터치한 지점으로부터 계산된 사용자 입력의 각도가 horizontal/vertical 모드에서 각각 크거나 작으면, 스크롤 동작이 이루어지지 않는다.</ko>\n * @param {number|string|number[]|string[]} [options.bounce=[10,10]] The size value of the bounce area. Only can be enabled when `circular=false`.<br>You can set different bounce value for prev/next direction by using array.<br>`number` for px value, and `string` for px, and % value relative to viewport size.(ex - 0, \"10px\", \"20%\")<ko>바운스 영역의 크기값. `circular=false`인 경우에만 사용할 수 있다.<br>배열을 통해 prev/next 방향에 대해 서로 다른 바운스 값을 지정 가능하다.<br>`number`를 통해 px값을, `stirng`을 통해 px 혹은 뷰포트 크기 대비 %값을 사용할 수 있다.(ex - 0, \"10px\", \"20%\")</ko>\n * @param {boolean} [options.autoResize=false] Whether the `resize` method should be called automatically after a window resize event.<ko>window의 `resize` 이벤트 이후 자동으로 resize()메소드를 호출할지의 여부.</ko>\n * @param {boolean} [options.adaptive=false] Whether the height(horizontal)/width(vertical) of the viewport element reflects the height/width value of the panel after completing the movement.<ko>목적 패널로 이동한 후 그 패널의 높이(horizontal)/너비(vertical)값을 뷰포트 요소의 높이/너비값에 반영할지 여부.</ko>\n * @param {number|\"\"} [options.zIndex=2000] z-index value for viewport element.<ko>뷰포트 엘리먼트의 z-index 값.</ko>\n * @param {boolean} [options.bound=false] Prevent the view from going out of the first/last panel. Only can be enabled when `circular=false`.<ko>뷰가 첫번째와 마지막 패널 밖으로 나가는 것을 막아준다. `circular=false`인 경우에만 사용할 수 있다.</ko>\n * @param {boolean} [options.overflow=false] Disables CSS property `overflow: hidden` in viewport if `true`.<ko>`true`로 설정시 뷰포트에 `overflow: hidden` 속성을 해제한다.</ko>\n * @param {string} [options.hanger=\"50%\"] The reference position of the hanger in the viewport, which hangs panel anchors should be stopped at.<br>It should be provided in px or % value of viewport size.<br>You can combinate those values with plus/minus sign.<br>ex) \"50\", \"100px\", \"0%\", \"25% + 100px\"<ko>뷰포트 내부의 행어의 위치. 패널의 앵커들이 뷰포트 내에서 멈추는 지점에 해당한다.<br>px값이나, 뷰포트의 크기 대비 %값을 사용할 수 있고, 이를 + 혹은 - 기호로 연계하여 사용할 수도 있다.<br>예) \"50\", \"100px\", \"0%\", \"25% + 100px\"</ko>\n * @param {string} [options.anchor=\"50%\"] The reference position of the anchor in panels, which can be hanged by viewport hanger.<br>It should be provided in px or % value of panel size.<br>You can combinate those values with plus/minus sign.<br>ex) \"50\", \"100px\", \"0%\", \"25% + 100px\"<ko>패널 내부의 앵커의 위치. 뷰포트의 행어와 연계하여 패널이 화면 내에서 멈추는 지점을 설정할 수 있다.<br>px값이나, 패널의 크기 대비 %값을 사용할 수 있고, 이를 + 혹은 - 기호로 연계하여 사용할 수도 있다.<br>예) \"50\", \"100px\", \"0%\", \"25% + 100px\"</ko>\n * @param {number} [options.gap=0] Space value between panels. Should be given in number.(px)<ko>패널간에 부여할 간격의 크기를 나타내는 숫자.(px)</ko>\n * @param {eg.Flicking.MoveTypeOption} [options.moveType=\"snap\"] Movement style by user input. (ex: snap, freeScroll)<ko>사용자 입력에 의한 이동 방식.(ex: snap, freeScroll)</ko>\n * @param {boolean} [options.useOffset=false] Whether to use `offsetWidth`/`offsetHeight` instead of `getBoundingClientRect` for panel/viewport size calculation.<br/>You can use this option to calculate the original panel size when CSS transform is applied to viewport or panel.<br/>⚠️ If panel size is not fixed integer value, there can be a 1px gap between panels.<ko>패널과 뷰포트의 크기를 계산할 때 `offsetWidth`/`offsetHeight`를 `getBoundingClientRect` 대신 사용할지 여부.<br/>패널이나 뷰포트에 CSS transform이 설정되어 있을 때 원래 패널 크기를 계산하려면 옵션을 활성화한다.<br/>⚠️ 패널의 크기가 정수로 고정되어있지 않다면 패널 사이에 1px의 공간이 생길 수 있다.</ko>\n * @param {boolean} [options.renderOnlyVisible=false] Whether to render visible panels only. This can dramatically increase performance when there're many panels.<ko>보이는 패널만 렌더링할지 여부를 설정한다. 패널이 많을 경우에 퍼포먼스를 크게 향상시킬 수 있다.</ko>\n * @param {boolean|string[]} [options.isEqualSize=false] This option indicates whether all panels have the same size(true) of first panel, or it can hold a list of class names that determines panel size.<br/>Enabling this option can increase performance while recalculating panel size.<ko>모든 패널의 크기가 동일한지(true), 혹은 패널 크기를 결정하는 패널 클래스들의 리스트.<br/>이 옵션을 설정하면 패널 크기 재설정시에 성능을 높일 수 있다.</ko>\n * @param {boolean} [options.isConstantSize=false] Whether all panels have a constant size that won't be changed after resize. Enabling this option can increase performance while recalculating panel size.<ko>모든 패널의 크기가 불변인지의 여부. 이 옵션을 'true'로 설정하면 패널 크기 재설정시에 성능을 높일 수 있다.</ko>\n * @param {boolean} [options.renderExternal=false] Whether to use external rendering. It will delegate DOM manipulation and can synchronize the rendered state by calling `sync()` method. You can use this option to use in frameworks like React, Vue, Angular, which has its states and rendering methods.<ko>외부 렌더링을 사용할 지의 여부. 이 옵션을 사용시 렌더링을 외부에 위임할 수 있고, `sync()`를 호출하여 그 상태를 동기화할 수 있다. 이 옵션을 사용하여, React, Vue, Angular 등 자체적인 상태와 렌더링 방법을 갖는 프레임워크에 대응할 수 있다.</ko>\n * @param {boolean} [options.resizeOnContentsReady=false] Whether to resize the Flicking after the image/video elements inside viewport are ready.<br/>Use this property to prevent wrong Flicking layout caused by dynamic image / video sizes.<ko>Flicking 내부의 이미지 / 비디오 엘리먼트들이 전부 로드되었을 때 Flicking의 크기를 재계산하기 위한 옵션.<br/>이미지 / 비디오 크기가 고정 크기가 아닐 경우 사용하여 레이아웃이 잘못되는 것을 방지할 수 있다.</ko>\n * @param {boolean} [options.collectStatistics=true] Whether to collect statistics on how you are using `Flicking`. These statistical data do not contain any personal information and are used only as a basis for the development of a user-friendly product.<ko>어떻게 `Flicking`을 사용하고 있는지에 대한 통계 수집 여부를 나타낸다. 이 통계자료는 개인정보를 포함하고 있지 않으며 오직 사용자 친화적인 제품으로 발전시키기 위한 근거자료로서 활용한다.</ko>\n */\n constructor(\n element: string | HTMLElement,\n options: Partial<FlickingOptions> = {},\n ) {\n super();\n\n // Set flicking wrapper user provided\n let wrapper: HTMLElement | null;\n if (isString(element)) {\n wrapper = document.querySelector(element);\n if (!wrapper) {\n throw new Error(\"Base element doesn't exist.\");\n }\n } else if (element.nodeName && element.nodeType === 1) {\n wrapper = element;\n } else {\n throw new Error(\"Element should be provided in string or HTMLElement.\");\n }\n\n this.wrapper = wrapper;\n // Override default options\n this.options = merge({}, DEFAULT_OPTIONS, options) as FlickingOptions;\n // Override moveType option\n const currentOptions = this.options;\n const moveType = currentOptions.moveType as MoveTypeStringOption;\n\n if (moveType in DEFAULT_MOVE_TYPE_OPTIONS) {\n currentOptions.moveType = DEFAULT_MOVE_TYPE_OPTIONS[moveType as keyof typeof DEFAULT_MOVE_TYPE_OPTIONS];\n }\n\n // Make viewport instance with panel container element\n this.viewport = new Viewport(this, this.options, this.triggerEvent);\n this.listenInput();\n this.listenResize();\n\n // if (this.options.collectStatistics) {\n // sendEvent(\n // \"usage\",\n // \"options\",\n // options,\n // );\n // }\n }\n\n /**\n * Move to the previous panel if it exists.\n * @ko 이전 패널이 존재시 해당 패널로 이동한다.\n * @param [duration=options.duration] Duration of the panel movement animation.(unit: ms)<ko>패널 이동 애니메이션 진행 시간.(단위: ms)</ko>\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public prev(duration?: number): this {\n const currentPanel = this.getCurrentPanel();\n const currentState = this.viewport.stateMachine.getState();\n\n if (currentPanel && currentState.type === STATE_TYPE.IDLE) {\n const prevPanel = currentPanel.prev();\n if (prevPanel) {\n prevPanel.focus(duration);\n }\n }\n\n return this;\n }\n\n /**\n * Move to the next panel if it exists.\n * @ko 다음 패널이 존재시 해당 패널로 이동한다.\n * @param [duration=options.duration] Duration of the panel movement animation(unit: ms).<ko>패널 이동 애니메이션 진행 시간.(단위: ms)</ko>\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public next(duration?: number): this {\n const currentPanel = this.getCurrentPanel();\n const currentState = this.viewport.stateMachine.getState();\n\n if (currentPanel && currentState.type === STATE_TYPE.IDLE) {\n const nextPanel = currentPanel.next();\n if (nextPanel) {\n nextPanel.focus(duration);\n }\n }\n\n return this;\n }\n\n /**\n * Move to the panel of given index.\n * @ko 주어진 인덱스에 해당하는 패널로 이동한다.\n * @param index The index number of the panel to move.<ko>이동할 패널의 인덱스 번호.</ko>\n * @param duration [duration=options.duration] Duration of the panel movement.(unit: ms)<ko>패널 이동 애니메이션 진행 시간.(단위: ms)</ko>\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public moveTo(index: number, duration?: number): this {\n const viewport = this.viewport;\n const panel = viewport.panelManager.get(index);\n const state = viewport.stateMachine.getState();\n\n if (!panel || state.type !== STATE_TYPE.IDLE) {\n return this;\n }\n\n const anchorPosition = panel.getAnchorPosition();\n const hangerPosition = viewport.getHangerPosition();\n\n let targetPanel = panel;\n if (this.options.circular) {\n const scrollAreaSize = viewport.getScrollAreaSize();\n // Check all three possible locations, find the nearest position among them.\n const possiblePositions = [\n anchorPosition - scrollAreaSize,\n anchorPosition,\n anchorPosition + scrollAreaSize,\n ];\n const nearestPosition = possiblePositions.reduce((nearest, current) => {\n return (Math.abs(current - hangerPosition) < Math.abs(nearest - hangerPosition))\n ? current\n : nearest;\n }, Infinity) - panel.getRelativeAnchorPosition();\n\n const identicals = panel.getIdenticalPanels();\n const offset = nearestPosition - anchorPosition;\n if (offset > 0) {\n // First cloned panel is nearest\n targetPanel = identicals[1];\n } else if (offset < 0) {\n // Last cloned panel is nearest\n targetPanel = identicals[identicals.length - 1];\n }\n\n targetPanel = targetPanel.clone(targetPanel.getCloneIndex(), true);\n targetPanel.setPosition(nearestPosition);\n }\n const currentIndex = this.getIndex();\n\n if (hangerPosition === targetPanel.getAnchorPosition() && currentIndex === index) {\n return this;\n }\n\n const eventType = panel.getIndex() === viewport.getCurrentIndex()\n ? \"\"\n : EVENTS.CHANGE;\n\n viewport.moveTo(\n targetPanel,\n viewport.findEstimatedPosition(targetPanel),\n eventType,\n null,\n duration,\n );\n return this;\n }\n\n /**\n * Return index of the current panel. `-1` if no panel exists.\n * @ko 현재 패널의 인덱스 번호를 반환한다. 패널이 하나도 없을 경우 `-1`을 반환한다.\n * @return Current panel's index, zero-based integer.<ko>현재 패널의 인덱스 번호. 0부터 시작하는 정수.</ko>\n */\n public getIndex(): number {\n return this.viewport.getCurrentIndex();\n }\n\n /**\n * Return the wrapper element user provided in constructor.\n * @ko 사용자가 생성자에서 제공한 래퍼 엘리먼트를 반환한다.\n * @return Wrapper element user provided.<ko>사용자가 제공한 래퍼 엘리먼트.</ko>\n */\n public getElement(): HTMLElement {\n return this.wrapper;\n }\n\n /**\n * Return the viewport element's size.\n * @ko 뷰포트 엘리먼트의 크기를 반환한다.\n * @return Width if horizontal: true, height if horizontal: false\n */\n public getSize(): number {\n return this.viewport.getSize();\n }\n\n /**\n * Return current panel. `null` if no panel exists.\n * @ko 현재 패널을 반환한다. 패널이 하나도 없을 경우 `null`을 반환한다.\n * @return Current panel.<ko>현재 패널.</ko>\n */\n public getCurrentPanel(): FlickingPanel | null {\n const viewport = this.viewport;\n const panel = viewport.getCurrentPanel();\n return panel\n ? panel\n : null;\n }\n\n /**\n * Return the panel of given index. `null` if it doesn't exists.\n * @ko 주어진 인덱스에 해당하는 패널을 반환한다. 해당 패널이 존재하지 않을 시 `null`이다.\n * @return Panel of given index.<ko>주어진 인덱스에 해당하는 패널.</ko>\n */\n public getPanel(index: number): FlickingPanel | null {\n const viewport = this.viewport;\n const panel = viewport.panelManager.get(index);\n return panel\n ? panel\n : null;\n }\n\n /**\n * Return all panels.\n * @ko 모든 패널들을 반환한다.\n * @param - Should include cloned panels or not.<ko>복사된 패널들을 포함할지의 여부.</ko>\n * @return All panels.<ko>모든 패널들.</ko>\n */\n public getAllPanels(includeClone?: boolean): FlickingPanel[] {\n const viewport = this.viewport;\n const panelManager = viewport.panelManager;\n const panels = includeClone\n ? panelManager.allPanels()\n : panelManager.originalPanels();\n\n return panels\n .filter(panel => !!panel);\n }\n\n /**\n * Return the panels currently shown in viewport area.\n * @ko 현재 뷰포트 영역에서 보여지고 있는 패널들을 반환한다.\n * @return Panels currently shown in viewport area.<ko>현재 뷰포트 영역에 보여지는 패널들</ko>\n */\n public getVisiblePanels(): FlickingPanel[] {\n return this.viewport.calcVisiblePanels();\n }\n\n /**\n * Return length of original panels.\n * @ko 원본 패널의 개수를 반환한다.\n * @return Length of original panels.<ko>원본 패널의 개수</ko>\n */\n public getPanelCount(): number {\n return this.viewport.panelManager.getPanelCount();\n }\n\n /**\n * Return how many groups of clones are created.\n * @ko 몇 개의 클론 그룹이 생성되었는지를 반환한다.\n * @return Length of cloned panel groups.<ko>클론된 패널 그룹의 개수</ko>\n */\n public getCloneCount(): number {\n return this.viewport.panelManager.getCloneCount();\n }\n\n /**\n * Get maximum panel index for `infinite` mode.\n * @ko `infinite` 모드에서 적용되는 추가 가능한 패널의 최대 인덱스 값을 반환한다.\n * @see {@link eg.Flicking.FlickingOptions}\n * @return Maximum index of panel that can be added.<ko>최대 추가 가능한 패널의 인덱스.</ko>\n */\n public getLastIndex(): number {\n return this.viewport.panelManager.getLastIndex();\n }\n\n /**\n * Set maximum panel index for `infinite' mode.<br>[needPanel]{@link eg.Flicking#events:needPanel} won't be triggered anymore when last panel's index reaches it.<br>Also, you can't add more panels after it.\n * @ko `infinite` 모드에서 적용되는 패널의 최대 인덱스를 설정한다.<br>마지막 패널의 인덱스가 설정한 값에 도달할 경우 더 이상 [needPanel]{@link eg.Flicking#events:needPanel} 이벤트가 발생되지 않는다.<br>또한, 설정한 인덱스 이후로 새로운 패널을 추가할 수 없다.\n * @param - Maximum panel index.\n * @see {@link eg.Flicking.FlickingOptions}\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public setLastIndex(index: number): this {\n this.viewport.setLastIndex(index);\n\n return this;\n }\n\n /**\n * Return panel movement animation.\n * @ko 현재 패널 이동 애니메이션이 진행 중인지를 반환한다.\n * @return Is animating or not.<ko>애니메이션 진행 여부.</ko>\n */\n public isPlaying(): boolean {\n return this.viewport.stateMachine.getState().playing;\n }\n\n /**\n * Unblock input devices.\n * @ko 막았던 입력 장치로부터의 입력을 푼다.\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public enableInput(): this {\n this.viewport.enable();\n\n return this;\n }\n\n /**\n * Block input devices.\n * @ko 입력 장치로부터의 입력을 막는다.\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public disableInput(): this {\n this.viewport.disable();\n\n return this;\n }\n\n /**\n * Get current flicking status. You can restore current state by giving returned value to [setStatus()]{@link eg.Flicking#setStatus}.\n * @ko 현재 상태 값을 반환한다. 반환받은 값을 [setStatus()]{@link eg.Flicking#setStatus} 메소드의 인자로 지정하면 현재 상태를 복원할 수 있다.\n * @return An object with current status value information.<ko>현재 상태값 정보를 가진 객체.</ko>\n */\n public getStatus(): FlickingStatus {\n const viewport = this.viewport;\n\n const panels = viewport.panelManager.originalPanels()\n .filter(panel => !!panel)\n .map(panel => {\n return {\n html: panel.getElement().outerHTML,\n index: panel.getIndex(),\n };\n });\n\n return {\n index: viewport.getCurrentIndex(),\n panels,\n position: viewport.getCameraPosition(),\n };\n }\n\n /**\n * Restore to the state of the `status`.\n * @ko `status`의 상태로 복원한다.\n * @param status Status value to be restored. You can specify the return value of the [getStatus()]{@link eg.Flicking#getStatus} method.<ko>복원할 상태 값. [getStatus()]{@link eg.Flicking#getStatus}메서드의 반환값을 지정하면 된다.</ko>\n */\n public setStatus(status: FlickingStatus): void {\n this.viewport.restore(status);\n }\n\n /**\n * Add plugins that can have different effects on Flicking.\n * @ko 플리킹에 다양한 효과를 부여할 수 있는 플러그인을 추가한다.\n * @param - The plugin(s) to add.<ko>추가할 플러그인(들).</ko>\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public addPlugins(plugins: Plugin | Plugin[]) {\n this.viewport.addPlugins(plugins);\n return this;\n }\n\n /**\n * Remove plugins from Flicking.\n * @ko 플리킹으로부터 플러그인들을 제거한다.\n * @param - The plugin(s) to remove.<ko>제거 플러그인(들).</ko>\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public removePlugins(plugins: Plugin | Plugin[]) {\n this.viewport.removePlugins(plugins);\n return this;\n }\n\n /**\n * Return the reference element and all its children to the state they were in before the instance was created. Remove all attached event handlers. Specify `null` for all attributes of the instance (including inherited attributes).\n * @ko 기준 요소와 그 하위 패널들을 인스턴스 생성전의 상태로 되돌린다. 부착된 모든 이벤트 핸들러를 탈거한다. 인스턴스의 모든 속성(상속받은 속성포함)에 `null`을 지정한다.\n * @example\n * const flick = new eg.Flicking(\"#flick\");\n * flick.destroy();\n * console.log(flick.moveTo); // null\n */\n public destroy(option: Partial<DestroyOption> = {}): void {\n this.off();\n\n if (this.options.autoResize) {\n window.removeEventListener(\"resize\", this.resize);\n }\n\n this.viewport.destroy(option);\n this.contentsReadyChecker?.destroy();\n\n // release resources\n for (const x in this) {\n (this as any)[x] = null;\n }\n }\n\n /**\n * Update panels to current state.\n * @ko 패널들을 현재 상태에 맞춰 갱신한다.\n * @method\n * @return {eg.Flicking} The instance itself.<ko>인스턴스 자기 자신.</ko>\n */\n public resize = (): this => {\n const viewport = this.viewport;\n const options = this.options;\n const wrapper = this.getElement();\n\n const allPanels = viewport.panelManager.allPanels();\n if (!options.isConstantSize) {\n allPanels.forEach(panel => panel.unCacheBbox());\n }\n\n const shouldResetElements = options.renderOnlyVisible\n && !options.isConstantSize\n && options.isEqualSize !== true;\n\n // Temporarily set parent's height to prevent scroll (#333)\n const parent = wrapper.parentElement!;\n const origStyle = parent.style.height;\n parent.style.height = `${parent.offsetHeight}px`;\n\n viewport.unCacheBbox();\n // This should be done before adding panels, to lower performance issue\n viewport.updateBbox();\n\n if (shouldResetElements) {\n viewport.appendUncachedPanelElements(allPanels as Panel[]);\n }\n\n viewport.resize();\n parent.style.height = origStyle;\n\n return this;\n }\n\n /**\n * Add new panels at the beginning of panels.\n * @ko 제일 앞에 새로운 패널을 추가한다.\n * @param element - Either HTMLElement, HTML string, or array of them.<br>It can be also HTML string of multiple elements with same depth.<ko>HTMLElement 혹은 HTML 문자열, 혹은 그것들의 배열도 가능하다.<br>또한, 같은 depth의 여러 개의 엘리먼트에 해당하는 HTML 문자열도 가능하다.</ko>\n * @return Array of appended panels.<ko>추가된 패널들의 배열</ko>\n * @example\n * // Suppose there were no panels at initialization\n * const flicking = new eg.Flicking(\"#flick\");\n * flicking.replace(3, document.createElement(\"div\")); // Add new panel at index 3\n * flicking.prepend(\"\\<div\\>Panel\\</div\\>\"); // Prepended at index 2\n * flicking.prepend([\"\\<div\\>Panel\\</div\\>\", document.createElement(\"div\")]); // Prepended at index 0, 1\n * flicking.prepend(\"\\<div\\>Panel\\</div\\>\"); // Prepended at index 0, pushing every panels behind it.\n */\n public prepend(element: ElementLike | ElementLike[]): FlickingPanel[] {\n const viewport = this.viewport;\n const parsedElements = parseElement(element);\n\n const insertingIndex = Math.max(viewport.panelManager.getRange().min - parsedElements.length, 0);\n const prependedPanels = viewport.insert(insertingIndex, parsedElements);\n\n this.checkContentsReady(prependedPanels);\n\n return prependedPanels;\n }\n\n /**\n * Add new panels at the end of panels.\n * @ko 제일 끝에 새로운 패널을 추가한다.\n * @param element - Either HTMLElement, HTML string, or array of them.<br>It can be also HTML string of multiple elements with same depth.<ko>HTMLElement 혹은 HTML 문자열, 혹은 그것들의 배열도 가능하다.<br>또한, 같은 depth의 여러 개의 엘리먼트에 해당하는 HTML 문자열도 가능하다.</ko>\n * @return Array of appended panels.<ko>추가된 패널들의 배열</ko>\n * @example\n * // Suppose there were no panels at initialization\n * const flicking = new eg.Flicking(\"#flick\");\n * flicking.append(document.createElement(\"div\")); // Appended at index 0\n * flicking.append(\"\\<div\\>Panel\\</div\\>\"); // Appended at index 1\n * flicking.append([\"\\<div\\>Panel\\</div\\>\", document.createElement(\"div\")]); // Appended at index 2, 3\n * // Even this is possible\n * flicking.append(\"\\<div\\>Panel 1\\</div\\>\\<div\\>Panel 2\\</div\\>\"); // Appended at index 4, 5\n */\n public append(element: ElementLike | ElementLike[]): FlickingPanel[] {\n const viewport = this.viewport;\n const appendedPanels = viewport.insert(viewport.panelManager.getRange().max + 1, element);\n\n this.checkContentsReady(appendedPanels);\n\n return appendedPanels;\n }\n\n /**\n * Replace existing panels with new panels from given index. If target index is empty, add new panel at target index.\n * @ko 주어진 인덱스로부터의 패널들을 새로운 패널들로 교체한다. 인덱스에 해당하는 자리가 비어있다면, 새로운 패널을 해당 자리에 집어넣는다.\n * @param index - Start index to replace new panels.<ko>새로운 패널들로 교체할 시작 인덱스</ko>\n * @param element - Either HTMLElement, HTML string, or array of them.<br>It can be also HTML string of multiple elements with same depth.<ko>HTMLElement 혹은 HTML 문자열, 혹은 그것들의 배열도 가능하다.<br>또한, 같은 depth의 여러 개의 엘리먼트에 해당하는 HTML 문자열도 가능하다.</ko>\n * @return Array of created panels by replace.<ko>교체되어 새롭게 추가된 패널들의 배열</ko>\n * @example\n * // Suppose there were no panels at initialization\n * const flicking = new eg.Flicking(\"#flick\");\n *\n * // This will add new panel at index 3,\n * // Index 0, 1, 2 is empty at this moment.\n * // [empty, empty, empty, PANEL]\n * flicking.replace(3, document.createElement(\"div\"));\n *\n * // As index 2 was empty, this will also add new panel at index 2.\n * // [empty, empty, PANEL, PANEL]\n * flicking.replace(2, \"\\<div\\>Panel\\</div\\>\");\n *\n * // Index 3 was not empty, so it will replace previous one.\n * // It will also add new panels at index 4 and 5.\n * // before - [empty, empty, PANEL, PANEL]\n * // after - [empty, empty, PANEL, NEW_PANEL, NEW_PANEL, NEW_PANEL]\n * flicking.replace(3, [\"\\<div\\>Panel\\</div\\>\", \"\\<div\\>Panel\\</div\\>\", \"\\<div\\>Panel\\</div\\>\"])\n */\n public replace(index: number, element: ElementLike | ElementLike[]): FlickingPanel[] {\n const replacedPanels = this.viewport.replace(index, element);\n\n this.checkContentsReady(replacedPanels);\n\n return replacedPanels;\n }\n\n /**\n * Remove panel at target index. This will decrease index of panels behind it.\n * @ko `index`에 해당하는 자리의 패널을 제거한다. 수행시 `index` 이후의 패널들의 인덱스가 감소된다.\n * @param index - Index of panel to remove.<ko>제거할 패널의 인덱스</ko>\n * @param {number} [deleteCount=1] - Number of panels to remove from index.<ko>`index` 이후로 제거할 패널의 개수.</ko>\n * @return Array of removed panels<ko>제거된 패널들의 배열</ko>\n */\n public remove(index: number, deleteCount: number = 1): FlickingPanel[] {\n return this.viewport.remove(index, deleteCount);\n }\n\n /**\n * Get indexes to render. Should be used with `renderOnlyVisible` option.\n * `beforeSync` should be called before this method for a correct result.\n * @private\n * @ko 렌더링이 필요한 인덱스들을 반환한다. `renderOnlyVisible` 옵션과 함께 사용해야 한다. 정확한 결과를 위해선 `beforeSync`를 이전에 호출해야만 합니다.\n * @param - Info object of how panel infos are changed.<ko>패널 정보들의 변경 정보를 담는 오브젝트.</ko>\n * @return Array of indexes to render.<ko>렌더링할 인덱스의 배열</ko>\n */\n public getRenderingIndexes(diffResult: DiffResult<any>): number[] {\n const viewport = this.viewport;\n const visiblePanels = viewport.getVisiblePanels();\n const maintained = diffResult.maintained.reduce((values: {[key: number]: number}, [before, after]) => {\n values[after] = before;\n return values;\n }, {});\n\n const panelCount = diffResult.list.length;\n const added = diffResult.added;\n const getPanelAbsIndex = (panel: Panel) => {\n return panel.getIndex() + (panel.getCloneIndex() + 1) * panelCount;\n };\n\n const visibleIndexes = visiblePanels.map(panel => getPanelAbsIndex(panel))\n .filter(val => maintained[val % panelCount] != null);\n\n const renderingPanels = [...visibleIndexes, ...added];\n const allPanels = viewport.panelManager.allPanels();\n\n viewport.setVisiblePanels(renderingPanels.map(index => allPanels[index]));\n\n return renderingPanels;\n }\n\n /**\n * Synchronize info of panels instance with info given by external rendering.\n * @ko 외부 렌더링 방식에 의해 입력받은 패널의 정보와 현재 플리킹이 갖는 패널 정보를 동기화한다.\n * @private\n * @param - Info object of how panel infos are changed.<ko>패널 정보들의 변경 정보를 담는 오브젝트.</ko>\n * @param - Whether called from sync method <ko> sync 메소드로부터 호출됐는지 여부 </ko>\n */\n public beforeSync(diffInfo: BeforeSyncResult) {\n const { maintained, added, changed, removed } = diffInfo;\n const viewport = this.viewport;\n const panelManager = viewport.panelManager;\n const isCircular = this.options.circular;\n const cloneCount = panelManager.getCloneCount();\n const prevClonedPanels = panelManager.clonedPanels();\n\n // Update visible panels\n const newVisiblePanels = viewport.getVisiblePanels()\n .filter(panel => findIndex(removed, index => {\n return index === panel.getIndex();\n }) < 0);\n viewport.setVisiblePanels(newVisiblePanels);\n\n // Did not changed at all\n if (\n added.length <= 0\n && removed.length <= 0\n && changed.length <= 0\n && cloneCount === prevClonedPanels.length\n ) {\n return this;\n }\n const prevOriginalPanels = panelManager.originalPanels();\n const newPanels: Panel[] = [];\n const newClones: Panel[][] = counter(cloneCount).map(() => []);\n\n maintained.forEach(([beforeIdx, afterIdx]) => {\n newPanels[afterIdx] = prevOriginalPanels[beforeIdx];\n newPanels[afterIdx].setIndex(afterIdx);\n });\n\n added.forEach(addIndex => {\n newPanels[addIndex] = new Panel(null, addIndex, this.viewport);\n });\n\n if (isCircular) {\n counter(cloneCount).forEach(groupIndex => {\n const prevCloneGroup = prevClonedPanels[groupIndex];\n const newCloneGroup = newClones[groupIndex];\n\n maintained.forEach(([beforeIdx, afterIdx]) => {\n newCloneGroup[afterIdx] = prevCloneGroup\n ? prevCloneGroup[beforeIdx]\n : newPanels[afterIdx].clone(groupIndex, false);\n\n newCloneGroup[afterIdx].setIndex(afterIdx);\n });\n\n added.forEach(addIndex => {\n const newPanel = newPanels[addIndex];\n\n newCloneGroup[addIndex] = newPanel.clone(groupIndex, false);\n });\n });\n }\n\n added.forEach(index => { viewport.updateCheckedIndexes({ min: index, max: index }); });\n removed.forEach(index => { viewport.updateCheckedIndexes({ min: index - 1, max: index + 1 }); });\n\n const checkedIndexes = viewport.getCheckedIndexes();\n checkedIndexes.forEach(([min, max], idx) => {\n // Push checked indexes backward\n const pushedIndex = added.filter(index => index < min && panelManager.has(index)).length\n - removed.filter(index => index < min).length;\n checkedIndexes.splice(idx, 1, [min + pushedIndex, max + pushedIndex]);\n });\n\n // Only effective only when there are least one panel which have changed its index\n if (changed.length > 0) {\n // Removed checked index by changed ones after pushing\n maintained.forEach(([, next]) => { viewport.updateCheckedIndexes({ min: next, max: next }); });\n }\n panelManager.replacePanels(newPanels, newClones);\n this.isPanelChangedAtBeforeSync = true;\n }\n\n /**\n * Synchronize info of panels with DOM info given by external rendering.\n * @ko 외부 렌더링 방식에 의해 입력받은 DOM의 정보와 현재 플리킹이 갖는 패널 정보를 동기화 한다.\n * @private\n * @param - Info object of how panel elements are changed.<ko>패널의 DOM 요소들의 변경 정보를 담는 오브젝트.</ko>\n */\n public sync(diffInfo: SyncResult): this {\n const { list, maintained, added, changed, removed } = diffInfo;\n\n // Did not changed at all\n if (added.length <= 0 && removed.length <= 0 && changed.length <= 0) {\n return this;\n }\n const viewport = this.viewport;\n const { renderOnlyVisible, circular } = this.options;\n const panelManager = viewport.panelManager;\n\n if (!renderOnlyVisible) {\n const indexRange = panelManager.getRange();\n let beforeDiffInfo: BeforeSyncResult = diffInfo;\n\n if (circular) {\n const prevOriginalPanelCount = indexRange.max;\n const originalPanelCount = (list.length / (panelManager.getCloneCount() + 1)) >> 0;\n const originalAdded = added.filter(index => index < originalPanelCount);\n const originalRemoved = removed.filter(index => index <= prevOriginalPanelCount);\n const originalMaintained = maintained.filter(([beforeIdx]) => beforeIdx <= prevOriginalPanelCount);\n const originalChanged = changed.filter(([beforeIdx]) => beforeIdx <= prevOriginalPanelCount);\n\n beforeDiffInfo = {\n added: originalAdded,\n maintained: originalMaintained,\n removed: originalRemoved,\n changed: originalChanged,\n };\n }\n this.beforeSync(beforeDiffInfo);\n }\n\n const visiblePanels = renderOnlyVisible\n ? viewport.getVisiblePanels()\n : this.getAllPanels(true);\n\n added.forEach(addedIndex => {\n const addedElement = list[addedIndex];\n const beforePanel = visiblePanels[addedIndex] as Panel;\n\n beforePanel.setElement(addedElement);\n // As it can be 0\n beforePanel.unCacheBbox();\n });\n if (this.isPanelChangedAtBeforeSync) {\n // Reset visible panels\n viewport.setVisiblePanels([]);\n this.isPanelChangedAtBeforeSync = false;\n }\n viewport.resize();\n\n return this;\n }\n\n private listenInput(): void {\n const flicking = this;\n const viewport = flicking.viewport;\n const stateMachine = viewport.stateMachine;\n\n // Set event context\n flicking.eventContext = {\n flicking,\n viewport: flicking.viewport,\n transitTo: stateMachine.transitTo,\n triggerEvent: flicking.triggerEvent,\n moveCamera: flicking.moveCamera,\n stopCamera: viewport.stopCamera,\n };\n\n const handlers = {};\n for (const key in AXES_EVENTS) {\n const eventType = AXES_EVENTS[key];\n\n handlers[eventType] = (e: any) => stateMachine.fire(eventType, e, flicking.eventContext);\n }\n\n // Connect Axes instance with PanInput\n flicking.viewport.connectAxesHandler(handlers);\n }\n\n private listenResize(): void {\n const options = this.options;\n\n if (options.autoResize) {\n window.addEventListener(\"resize\", this.resize);\n }\n\n if (options.resizeOnContentsReady) {\n const contentsReadyChecker = new ImReady();\n\n contentsReadyChecker.on(\"preReady\", () => {\n this.resize();\n });\n contentsReadyChecker.on(\"readyElement\", e => {\n if (e.hasLoading && e.isPreReadyOver) {\n this.resize();\n }\n });\n contentsReadyChecker.on(\"error\", e => {\n this.trigger(EVENTS.CONTENT_ERROR, {\n type: EVENTS.CONTENT_ERROR,\n element: e.element,\n });\n });\n contentsReadyChecker.check([this.wrapper]);\n\n this.contentsReadyChecker = contentsReadyChecker;\n }\n }\n\n private triggerEvent = <T extends FlickingEvent>(\n eventName: ValueOf<Omit<EventType, \"VISIBLE_CHANGE\">>, // visibleChange event has no common event definition from other events\n axesEvent: any,\n isTrusted: boolean,\n params: Partial<T> = {},\n ): TriggerCallback => {\n const viewport = this.viewport;\n\n let canceled: boolean = true;\n\n // Ignore events before viewport is initialized\n if (viewport) {\n const state = viewport.stateMachine.getState();\n const { prev, next } = viewport.getScrollArea();\n const pos = viewport.getCameraPosition();\n let progress = getProgress(pos, [prev, prev, next]);\n\n if (this.options.circular) {\n progress %= 1;\n }\n canceled = !super.trigger(eventName, merge({\n type: eventName,\n index: this.getIndex(),\n panel: this.getCurrentPanel(),\n direction: state.direction,\n holding: state.holding,\n progress,\n axesEvent,\n isTrusted,\n }, params) as FlickingEvent);\n }\n\n return {\n onSuccess(callback: () => void): TriggerCallback {\n if (!canceled) {\n callback();\n }\n return this;\n },\n onStopped(callback: () => void): TriggerCallback {\n if (canceled) {\n callback();\n }\n return this;\n },\n } as TriggerCallback;\n }\n\n // Return result of \"move\" event triggered\n private moveCamera = (axesEvent: any): TriggerCallback => {\n const viewport = this.viewport;\n const state = viewport.stateMachine.getState();\n const options = this.options;\n\n const pos = axesEvent.pos.flick;\n const previousPosition = viewport.getCameraPosition();\n\n if (axesEvent.isTrusted && state.holding) {\n const inputOffset = options.horizontal\n ? axesEvent.inputEvent.offsetX\n : axesEvent.inputEvent.offsetY;\n\n const isNextDirection = inputOffset < 0;\n\n let cameraChange = pos - previousPosition;\n const looped = isNextDirection === (pos < previousPosition);\n if (options.circular && looped) {\n // Reached at max/min range of axes\n const scrollAreaSize = viewport.getScrollAreaSize();\n cameraChange = (cameraChange > 0 ? -1 : 1) * (scrollAreaSize - Math.abs(cameraChange));\n }\n\n const currentDirection = cameraChange === 0\n ? state.direction\n : cameraChange > 0\n ? DIRECTION.NEXT\n : DIRECTION.PREV;\n\n state.direction = currentDirection;\n }\n state.delta += axesEvent.delta.flick;\n\n viewport.moveCamera(pos, axesEvent);\n return this.triggerEvent(EVENTS.MOVE, axesEvent, axesEvent.isTrusted)\n .onStopped(() => {\n // Undo camera movement\n viewport.moveCamera(previousPosition, axesEvent);\n });\n }\n\n private checkContentsReady(panels: FlickingPanel[]) {\n this.contentsReadyChecker?.check(panels.map(panel => panel.getElement()));\n }\n}\n\nexport default Flicking;\n","import Flicking from \"./Flicking\";\nimport { withFlickingMethods } from \"./utils\";\nimport { DEFAULT_OPTIONS, MOVE_TYPE } from \"./consts\";\n\n(Flicking as any).withFlickingMethods = withFlickingMethods;\n(Flicking as any).DEFAULT_OPTIONS = DEFAULT_OPTIONS;\n(Flicking as any).MOVE_TYPE = MOVE_TYPE;\nexport default Flicking;\n"],"names":["MOVE_TYPE","SNAP","FREE_SCROLL","DEFAULT_MOVE_TYPE_OPTIONS","snap","type","count","freeScroll","isBrowser","document","DEFAULT_OPTIONS","classPrefix","deceleration","horizontal","circular","infinite","infiniteThreshold","lastIndex","Infinity","threshold","duration","panelEffect","x","Math","pow","defaultIndex","inputType","thresholdAngle","bounce","autoResize","adaptive","zIndex","bound","overflow","hanger","anchor","gap","moveType","useOffset","isEqualSize","isConstantSize","renderOnlyVisible","renderExternal","resizeOnContentsReady","iOSEdgeSwipeThreshold","collectStatistics","DEFAULT_VIEWPORT_CSS","position","DEFAULT_CAMERA_CSS","width","height","willChange","DEFAULT_PANEL_CSS","EVENTS","HOLD_START","HOLD_END","MOVE_START","MOVE","MOVE_END","CHANGE","RESTORE","SELECT","NEED_PANEL","VISIBLE_CHANGE","CONTENT_ERROR","AXES_EVENTS","HOLD","RELEASE","ANIMATION_END","FINISH","STATE_TYPE","DIRECTION","PREV","NEXT","FLICKING_METHODS","prev","next","moveTo","getIndex","getAllPanels","getCurrentPanel","getElement","getSize","getPanel","getPanelCount","getStatus","getVisiblePanels","enableInput","disableInput","destroy","resize","setStatus","isPlaying","checkTranslateSupport","transforms","webkitTransform","msTransform","MozTransform","OTransform","transform","name","has3d","supportedStyle","documentElement","style","transformName","prefixedTransform","Error","el","createElement","insertBefore","styleVal","window","getComputedStyle","getPropertyValue","parentElement","removeChild","transformInfo","length","TRANSFORM","merge","target","_i","srcs","forEach","source","Object","keys","key","value","parseElement","element","Array","isArray","elements","isString","tempDiv","innerHTML","push","toArray","children","firstChild","hasClass","className","classList","contains","split","indexOf","applyCSS","cssObj","property","clamp","val","min","max","isBetween","iterable","slice","call","parseArithmeticExpression","cssValue","base","defaultVal","defaultValue","cssRegex","idx","calculatedValue","matchResult","exec","sign","unit","parsedValue","parseFloat","getProgress","pos","range","center","findIndex","callback","i","counter","counterArray","circulate","indexed","size","restoreStyle","originalStyle","setAttribute","removeAttribute","getBbox","clientRect","y","offsetWidth","offsetHeight","getBoundingClientRect","left","top","index","viewport","prevSibling","nextSibling","clonedPanels","state","relativeAnchorPosition","isClone","isVirtual","cloneIndex","cachedBbox","setElement","givenBbox","this","options","bbox","prevSize","panel","cloneState","panelCount","panelManager","scrollAreaSize","getScrollAreaSize","floor","getPosition","getCurrentProgress","outsetRange","getRelativeHangerPosition","getRelativeAnchorPosition","getCameraPosition","panelSize","relativePanelPosition","rightRelativePanelPosition","visibleSize","eventType","currentPanel","getHangerPosition","getAnchorPosition","findEstimatedPosition","updateFunction","shouldResize","identicalPanels","getIdenticalPanels","eachPanel","unCacheBbox","addVisiblePanel","currentIndex","currentPosition","prevPanelIndex","prevPanelPosition","prevPanelSize","hasEmptyPanelBetween","notYetMinPanel","newPosition","prevPanel","clone","getCloneIndex","setPosition","getLastIndex","nextPanelIndex","nextPanelPosition","notYetMaxPanel","nextPanel","parsedElements","firstPanel","targetIndex","insert","remove","option","preserveUI","wasVisible","cameraElement","Boolean","parentNode","getCameraElement","appendChild","classes","classes_1","original","getClonedPanels","offset","elementStyle","currentElementStyle","styleToApply","cloneElement","cloneNode","clonedPanel","Panel","clonedState","removeClonedPanelsAfter","start","removingPanels","splice","removeElement","currentElement","getAttribute","add","replace","panels","clones","cloneCount","reduce","allClones","newPanels","newClones","filter","possibleLastPanel","lastPanel","shouldRender","isCircular","findFirstPanelFrom","siblingElement","insertNewPanels","panelsAfterIndex","emptyPanelCount","removedPanels","newLastIndex","panelCount_1","pushedIndex","concat","reverse","setIndex","updateIndex","addNewClones","cloneSet","replacedPanels","wasNonEmptyCount","deleteCount","deletedPanels","nonEmptyIndexFromLast","allPanels","allPanelsCount","insertTarget_1","newClones_1","allPanels_1","_a","originalPanels","getCloneCount","lastPanelClones","nextSiblingClones","cloneNextSibling","lastPanelSibling","cloneSiblingElement","nextElementSibling","map","_this","this_1","insertClones","insertingIndex","fragment_1","createDocumentFragment","prevState","delta","direction","targetPanel","lastPosition","nextState","e","context","__extends","flicking","triggerEvent","transitTo","moveCamera","onSuccess","onStopped","onChange","State","inputEvent","offsetX","offsetY","flick","setTo","releaseEvent","srcEvent","touch","clickedElement","clickedPanel","cameraPosition","clickedPanelPosition","changedTouches","elementFromPoint","clientX","clientY","findPanelOf","stopCamera","absDelta","abs","velocity","velocityX","velocityY","inputDelta","deltaX","deltaY","isNextDirection","swipeDistance","swipeAngle","atan","PI","belowAngleThreshold","overThreshold","moveTypeContext","axesEvent","interruptDestInfo","findPanelWhenInterrupted","destPos","nearestPanel","getNearestPanel","stop","destInfo","findTargetPanel","findRestorePanel","originalTargetPosition","newCloneIndex","newTargetPosition","newTargetPanel","scrollArea","getScrollArea","loopCount","setCurrentPanel","isTrusted","updateAdaptiveSize","updateCameraPosition","updateAxesPosition","IdleState","nextStateType","currentState","HoldingState","DraggingState","AnimatingState","DisabledState","onExit","onEnter","onHold","onRelease","onAnimationEnd","onFinish","_super","ctx","snapCount","eventDelta","minimumDistanceToChange","calcBrinkOfChange","nearestIsCurrent","shouldMoveWhenBounceIs0","canSetBoundMode","shouldMoveToAdjacent","isOutOfBound","findSnappedPanel","findAdjacentPanel","halfGap","estimatedHangerPos","panelToMove","cycleIndex","passedPanelCount","originalPanel","getOriginalPanel","panelPosition","siblingPanel","panelIndex","siblingIndex","originalPosition","defaultDuration","getCurrentIndex","get","hangerPosition","firstClonedPanel","basePanel","basePosition","adjacentPanel","targetRelativeAnchorPosition","estimatedPosition","findRestorePanelInCircularMode","lapped","findNearestPanelAt","stateMachine","getState","currentPanelPosition","lastHangerPosition","Snap","panelMaintainRatio","relativeHangerPosition","positionOffset","translate","checkedIndexes","isAdaptiveCached","isViewportGiven","isCameraGiven","originalViewportStyle","originalCameraStyle","StateMachine","visiblePanels","panelBboxes","build","eventResult","axes","findNearestPanel","originalNearestPosition","checkNeedPanel","updateVisiblePanels","posOffset","moveCoord","coord","round","join","viewportElement","updateSize","updateOriginalPanelPositions","updateScrollArea","updateClonePanels","updateVisiblePanelPositions","updatePlugins","minimumDistance","prevPosition","nextPosition","distance","nearest","shortestDistance","identical","anchorPosition","getVisibleIndexOf","panInput","createPanInput","newCenterPanel","newPanelPosition","resizePanels","updateCheckedIndexes","indexes","visibleIndex","newCurrentIndex","getRange","undefined","shouldApplyAdaptive","viewportStyle","panelBbox","sizeToApply","viewportBbox","viewportSize","maximum","updateBbox","positionBounded","isFreeScroll","is","holding","playing","plugins","plugin","update","topmostElement_1","deletingElement","wrapper","removePlugins","status","html","refreshPanels","createdPanels","orderedPanels","createdPanel","replacePanels","setCloneCount","cameraPos_1","viewportSize_1","getNext","isOutOfViewport","getAbsIndex_1","__spreadArrays","sort","panel1","panel2","outsetProgress","getOutsetProgress","NaN","prevRange","nextRange","nearestAnchorPos","nearestIndex","nearestSize","hangerIsNextToNearestPanel","targetPosition","progressBetween","off","on","axesHandlers","setLastIndex","handlers","newPlugins","init","currentPlugins","changedRange","removed","prevVisiblePanels","equalSizeClasses_1","cached_1","fragment","overlappedClass","getOverlappedClass","clonePanels","updateClonedPanelPositions","chainAllPanels","visiblePanel","setElements","applyCSSValue","setMoveType","setAxesInstance","setDefaultPanel","moveToDefaultPanel","viewportCandidate","hasViewportElement","cameraCandidate","hasCameraElement","child","minHeight","minWidth","PanelManager","FreeScroll","Axes","easing","interruptable","indexRange","panelAtLeftBoundary","reversedPanels","sumOriginalPanelSize","areaPrev","sizeSum","reversedPanels_1","panelAtRightBoundary","areaNext","panels_1","needCloneOnPrev","ceil","prevCloneCount","origPanel","removeClonesAfter","defaultPanel","defaultPosition","maintainingPanel","accumulatedSize","nextPanelPos","total","setPositionCSS","clonedPanels_1","clonedPanelPos","lastReplacePosition","_b","replacePosition","relAnchorPosOfCombined","anchorPos","parsedVal","parsedBounce","arr","constructor","axis","maxLastIndex","checkingPanel","firstIndex","nextIndex","currentNearestPosition","triggerNeedPanel","lastPanelAfterNeed","cameraPrev","checkingIndex","prevIndex","firstPanelAfterNeed","params","alreadyTriggered","some","hasHandler","hasOn","fill","insertAfter","firstVisiblePanelPos","firstVisiblePanel","lastVisiblePanel","getAbsIndex","newVisibleRange","newVisiblePanels","calcVisiblePanels","checkVisiblePanelChange","addedPanels","panelElement","trigger","prevRefCount","newRefCount","newPanel","newIndex","added","equalSizeClasses_2","defaultBbox_1","default","PanInput","scale","connect","shouldResetElements","parent","origStyle","appendUncachedPanelElements","eventName","progress","canceled","inputOffset","looped","cameraChange","currentDirection","previousPosition","querySelector","nodeName","nodeType","currentOptions","Viewport","listenInput","listenResize","focus","nearestPosition","identicals","current","includeClone","enable","disable","outerHTML","restore","addPlugins","removeEventListener","contentsReadyChecker","prependedPanels","checkContentsReady","appendedPanels","diffResult","maintained","values","before","list","renderingPanels","setVisiblePanels","diffInfo","changed","prevClonedPanels","prevOriginalPanels","beforeIdx","afterIdx","addIndex","groupIndex","prevCloneGroup","newCloneGroup","getCheckedIndexes","has","isPanelChangedAtBeforeSync","prevOriginalPanelCount_1","originalPanelCount_1","originalAdded","originalRemoved","beforeDiffInfo","beforeSync","addedIndex","addedElement","beforePanel","eventContext","fire","connectAxesHandler","addEventListener","ImReady","hasLoading","isPreReadyOver","check","Flicking","Component","withFlickingMethods","prototype","flickingName","args","result"],"mappings":"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"}
\No newline at end of file