UNPKG

523 kBJavaScriptView Raw
1/*
2Copyright (c) 2015-present NAVER Corp.
3name: @egjs/flicking
4license: MIT
5author: NAVER Corp.
6repository: https://github.com/naver/egjs-flicking
7version: 4.3.0
8*/
9(function (global, factory) {
10 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
11 typeof define === 'function' && define.amd ? define(factory) :
12 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Flicking = factory());
13}(this, (function () { 'use strict';
14
15 /*! *****************************************************************************
16 Copyright (c) Microsoft Corporation.
17
18 Permission to use, copy, modify, and/or distribute this software for any
19 purpose with or without fee is hereby granted.
20
21 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
23 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
24 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
25 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27 PERFORMANCE OF THIS SOFTWARE.
28 ***************************************************************************** */
29
30 /* global Reflect, Promise */
31 var extendStatics$2 = function (d, b) {
32 extendStatics$2 = Object.setPrototypeOf || {
33 __proto__: []
34 } instanceof Array && function (d, b) {
35 d.__proto__ = b;
36 } || function (d, b) {
37 for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];
38 };
39
40 return extendStatics$2(d, b);
41 };
42
43 function __extends$2(d, b) {
44 if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
45 extendStatics$2(d, b);
46
47 function __() {
48 this.constructor = d;
49 }
50
51 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
52 }
53 var __assign$2 = function () {
54 __assign$2 = Object.assign || function __assign(t) {
55 for (var s, i = 1, n = arguments.length; i < n; i++) {
56 s = arguments[i];
57
58 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
59 }
60
61 return t;
62 };
63
64 return __assign$2.apply(this, arguments);
65 };
66 function __awaiter(thisArg, _arguments, P, generator) {
67 function adopt(value) {
68 return value instanceof P ? value : new P(function (resolve) {
69 resolve(value);
70 });
71 }
72
73 return new (P || (P = Promise))(function (resolve, reject) {
74 function fulfilled(value) {
75 try {
76 step(generator.next(value));
77 } catch (e) {
78 reject(e);
79 }
80 }
81
82 function rejected(value) {
83 try {
84 step(generator["throw"](value));
85 } catch (e) {
86 reject(e);
87 }
88 }
89
90 function step(result) {
91 result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
92 }
93
94 step((generator = generator.apply(thisArg, _arguments || [])).next());
95 });
96 }
97 function __generator(thisArg, body) {
98 var _ = {
99 label: 0,
100 sent: function () {
101 if (t[0] & 1) throw t[1];
102 return t[1];
103 },
104 trys: [],
105 ops: []
106 },
107 f,
108 y,
109 t,
110 g;
111 return g = {
112 next: verb(0),
113 "throw": verb(1),
114 "return": verb(2)
115 }, typeof Symbol === "function" && (g[Symbol.iterator] = function () {
116 return this;
117 }), g;
118
119 function verb(n) {
120 return function (v) {
121 return step([n, v]);
122 };
123 }
124
125 function step(op) {
126 if (f) throw new TypeError("Generator is already executing.");
127
128 while (_) try {
129 if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
130 if (y = 0, t) op = [op[0] & 2, t.value];
131
132 switch (op[0]) {
133 case 0:
134 case 1:
135 t = op;
136 break;
137
138 case 4:
139 _.label++;
140 return {
141 value: op[1],
142 done: false
143 };
144
145 case 5:
146 _.label++;
147 y = op[1];
148 op = [0];
149 continue;
150
151 case 7:
152 op = _.ops.pop();
153
154 _.trys.pop();
155
156 continue;
157
158 default:
159 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
160 _ = 0;
161 continue;
162 }
163
164 if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
165 _.label = op[1];
166 break;
167 }
168
169 if (op[0] === 6 && _.label < t[1]) {
170 _.label = t[1];
171 t = op;
172 break;
173 }
174
175 if (t && _.label < t[2]) {
176 _.label = t[2];
177
178 _.ops.push(op);
179
180 break;
181 }
182
183 if (t[2]) _.ops.pop();
184
185 _.trys.pop();
186
187 continue;
188 }
189
190 op = body.call(thisArg, _);
191 } catch (e) {
192 op = [6, e];
193 y = 0;
194 } finally {
195 f = t = 0;
196 }
197
198 if (op[0] & 5) throw op[1];
199 return {
200 value: op[0] ? op[1] : void 0,
201 done: true
202 };
203 }
204 }
205 function __values$3(o) {
206 var s = typeof Symbol === "function" && Symbol.iterator,
207 m = s && o[s],
208 i = 0;
209 if (m) return m.call(o);
210 if (o && typeof o.length === "number") return {
211 next: function () {
212 if (o && i >= o.length) o = void 0;
213 return {
214 value: o && o[i++],
215 done: !o
216 };
217 }
218 };
219 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
220 }
221 function __read$1(o, n) {
222 var m = typeof Symbol === "function" && o[Symbol.iterator];
223 if (!m) return o;
224 var i = m.call(o),
225 r,
226 ar = [],
227 e;
228
229 try {
230 while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
231 } catch (error) {
232 e = {
233 error: error
234 };
235 } finally {
236 try {
237 if (r && !r.done && (m = i["return"])) m.call(i);
238 } finally {
239 if (e) throw e.error;
240 }
241 }
242
243 return ar;
244 }
245 function __spreadArray(to, from) {
246 for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) to[j] = from[i];
247
248 return to;
249 }
250
251 /*
252 Copyright (c) NAVER Corp.
253 name: @egjs/component
254 license: MIT
255 author: NAVER Corp.
256 repository: https://github.com/naver/egjs-component
257 version: 3.0.1
258 */
259 /*! *****************************************************************************
260 Copyright (c) Microsoft Corporation.
261
262 Permission to use, copy, modify, and/or distribute this software for any
263 purpose with or without fee is hereby granted.
264
265 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
266 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
267 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
268 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
269 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
270 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
271 PERFORMANCE OF THIS SOFTWARE.
272 ***************************************************************************** */
273 function __values$2(o) {
274 var s = typeof Symbol === "function" && Symbol.iterator,
275 m = s && o[s],
276 i = 0;
277 if (m) return m.call(o);
278 if (o && typeof o.length === "number") return {
279 next: function () {
280 if (o && i >= o.length) o = void 0;
281 return {
282 value: o && o[i++],
283 done: !o
284 };
285 }
286 };
287 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
288 }
289 function __read(o, n) {
290 var m = typeof Symbol === "function" && o[Symbol.iterator];
291 if (!m) return o;
292 var i = m.call(o),
293 r,
294 ar = [],
295 e;
296
297 try {
298 while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
299 } catch (error) {
300 e = {
301 error: error
302 };
303 } finally {
304 try {
305 if (r && !r.done && (m = i["return"])) m.call(i);
306 } finally {
307 if (e) throw e.error;
308 }
309 }
310
311 return ar;
312 }
313 function __spread() {
314 for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
315
316 return ar;
317 }
318
319 /*
320 * Copyright (c) 2015 NAVER Corp.
321 * egjs projects are licensed under the MIT license
322 */
323 var isUndefined$2 = function (value) {
324 return typeof value === "undefined";
325 };
326
327 /**
328 * Event class to provide additional properties
329 * @ko Component에서 추가적인 프로퍼티를 제공하는 이벤트 클래스
330 */
331
332 var ComponentEvent =
333 /*#__PURE__*/
334 function () {
335 /**
336 * Create a new instance of ComponentEvent.
337 * @ko ComponentEvent의 새로운 인스턴스를 생성한다.
338 * @param eventType The name of the event.<ko>이벤트 이름.</ko>
339 * @param props An object that contains additional event properties.<ko>추가적인 이벤트 프로퍼티 오브젝트.</ko>
340 */
341 function ComponentEvent(eventType, props) {
342 var e_1, _a;
343
344 this.eventType = eventType;
345 this._canceled = false;
346 if (!props) return;
347
348 try {
349 for (var _b = __values$2(Object.keys(props)), _c = _b.next(); !_c.done; _c = _b.next()) {
350 var key = _c.value; // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
351
352 this[key] = props[key];
353 }
354 } catch (e_1_1) {
355 e_1 = {
356 error: e_1_1
357 };
358 } finally {
359 try {
360 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
361 } finally {
362 if (e_1) throw e_1.error;
363 }
364 }
365 }
366 /**
367 * Stop the event. {@link ComponentEvent#isCanceled} will return `true` after.
368 * @ko 이벤트를 중단한다. 이후 {@link ComponentEvent#isCanceled}가 `true`를 반환한다.
369 */
370
371
372 var __proto = ComponentEvent.prototype;
373
374 __proto.stop = function () {
375 this._canceled = true;
376 };
377 /**
378 * Returns a boolean value that indicates whether {@link ComponentEvent#stop} is called before.
379 * @ko {@link ComponentEvent#stop}이 호출되었는지 여부를 반환한다.
380 * @return {boolean} A boolean value that indicates whether {@link ComponentEvent#stop} is called before.<ko>이전에 {@link ComponentEvent#stop}이 불려졌는지 여부를 반환한다.</ko>
381 */
382
383
384 __proto.isCanceled = function () {
385 return this._canceled;
386 };
387
388 return ComponentEvent;
389 }();
390
391 /**
392 * A class used to manage events in a component
393 * @ko 컴포넌트의 이벤트을 관리할 수 있게 하는 클래스
394 */
395
396 var Component$2 =
397 /*#__PURE__*/
398 function () {
399 /**
400 * @support {"ie": "7+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.1+ (except 3.x)"}
401 */
402 function Component() {
403 this._eventHandler = {};
404 }
405 /**
406 * Trigger a custom event.
407 * @ko 커스텀 이벤트를 발생시킨다
408 * @param {string | ComponentEvent} event The name of the custom event to be triggered or an instance of the ComponentEvent<ko>발생할 커스텀 이벤트의 이름 또는 ComponentEvent의 인스턴스</ko>
409 * @param {any[]} params Event data to be sent when triggering a custom event <ko>커스텀 이벤트가 발생할 때 전달할 데이터</ko>
410 * @return An instance of the component itself<ko>컴포넌트 자신의 인스턴스</ko>
411 * @example
412 * ```ts
413 * import Component, { ComponentEvent } from "@egjs/component";
414 *
415 * class Some extends Component<{
416 * beforeHi: ComponentEvent<{ foo: number; bar: string }>;
417 * hi: { foo: { a: number; b: boolean } };
418 * someEvent: (foo: number, bar: string) => void;
419 * someOtherEvent: void; // When there's no event argument
420 * }> {
421 * some(){
422 * if(this.trigger("beforeHi")){ // When event call to stop return false.
423 * this.trigger("hi");// fire hi event.
424 * }
425 * }
426 * }
427 *
428 * const some = new Some();
429 * some.on("beforeHi", e => {
430 * if(condition){
431 * e.stop(); // When event call to stop, `hi` event not call.
432 * }
433 * // `currentTarget` is component instance.
434 * console.log(some === e.currentTarget); // true
435 *
436 * typeof e.foo; // number
437 * typeof e.bar; // string
438 * });
439 * some.on("hi", e => {
440 * typeof e.foo.b; // boolean
441 * });
442 * // If you want to more know event design. You can see article.
443 * // https://github.com/naver/egjs-component/wiki/How-to-make-Component-event-design%3F
444 * ```
445 */
446
447
448 var __proto = Component.prototype;
449
450 __proto.trigger = function (event) {
451 var params = [];
452
453 for (var _i = 1; _i < arguments.length; _i++) {
454 params[_i - 1] = arguments[_i];
455 }
456
457 var eventName = event instanceof ComponentEvent ? event.eventType : event;
458
459 var handlers = __spread(this._eventHandler[eventName] || []);
460
461 if (handlers.length <= 0) {
462 return this;
463 }
464
465 if (event instanceof ComponentEvent) {
466 event.currentTarget = this;
467 handlers.forEach(function (handler) {
468 handler(event);
469 });
470 } else {
471 handlers.forEach(function (handler) {
472 // eslint-disable-next-line @typescript-eslint/no-unsafe-call
473 handler.apply(void 0, __spread(params));
474 });
475 }
476
477 return this;
478 };
479 /**
480 * Executed event just one time.
481 * @ko 이벤트가 한번만 실행된다.
482 * @param {string} eventName The name of the event to be attached or an event name - event handler mapped object.<ko>등록할 이벤트의 이름 또는 이벤트 이름-핸들러 오브젝트</ko>
483 * @param {function} handlerToAttach The handler function of the event to be attached <ko>등록할 이벤트의 핸들러 함수</ko>
484 * @return An instance of the component itself<ko>컴포넌트 자신의 인스턴스</ko>
485 * @example
486 * ```ts
487 * import Component, { ComponentEvent } from "@egjs/component";
488 *
489 * class Some extends Component<{
490 * hi: ComponentEvent;
491 * }> {
492 * hi() {
493 * alert("hi");
494 * }
495 * thing() {
496 * this.once("hi", this.hi);
497 * }
498 * }
499 *
500 * var some = new Some();
501 * some.thing();
502 * some.trigger(new ComponentEvent("hi"));
503 * // fire alert("hi");
504 * some.trigger(new ComponentEvent("hi"));
505 * // Nothing happens
506 * ```
507 */
508
509
510 __proto.once = function (eventName, handlerToAttach) {
511 var _this = this;
512
513 if (typeof eventName === "object" && isUndefined$2(handlerToAttach)) {
514 var eventHash = eventName;
515
516 for (var key in eventHash) {
517 this.once(key, eventHash[key]);
518 }
519
520 return this;
521 } else if (typeof eventName === "string" && typeof handlerToAttach === "function") {
522 var listener_1 = function () {
523 var args = [];
524
525 for (var _i = 0; _i < arguments.length; _i++) {
526 args[_i] = arguments[_i];
527 } // eslint-disable-next-line @typescript-eslint/no-unsafe-call
528
529
530 handlerToAttach.apply(void 0, __spread(args));
531
532 _this.off(eventName, listener_1);
533 };
534
535 this.on(eventName, listener_1);
536 }
537
538 return this;
539 };
540 /**
541 * Checks whether an event has been attached to a component.
542 * @ko 컴포넌트에 이벤트가 등록됐는지 확인한다.
543 * @param {string} eventName The name of the event to be attached <ko>등록 여부를 확인할 이벤트의 이름</ko>
544 * @return {boolean} Indicates whether the event is attached. <ko>이벤트 등록 여부</ko>
545 * @example
546 * ```ts
547 * import Component from "@egjs/component";
548 *
549 * class Some extends Component<{
550 * hi: void;
551 * }> {
552 * some() {
553 * this.hasOn("hi");// check hi event.
554 * }
555 * }
556 * ```
557 */
558
559
560 __proto.hasOn = function (eventName) {
561 return !!this._eventHandler[eventName];
562 };
563 /**
564 * Attaches an event to a component.
565 * @ko 컴포넌트에 이벤트를 등록한다.
566 * @param {string} eventName The name of the event to be attached or an event name - event handler mapped object.<ko>등록할 이벤트의 이름 또는 이벤트 이름-핸들러 오브젝트</ko>
567 * @param {function} handlerToAttach The handler function of the event to be attached <ko>등록할 이벤트의 핸들러 함수</ko>
568 * @return An instance of a component itself<ko>컴포넌트 자신의 인스턴스</ko>
569 * @example
570 * ```ts
571 * import Component, { ComponentEvent } from "@egjs/component";
572 *
573 * class Some extends Component<{
574 * hi: void;
575 * }> {
576 * hi() {
577 * console.log("hi");
578 * }
579 * some() {
580 * this.on("hi",this.hi); //attach event
581 * }
582 * }
583 * ```
584 */
585
586
587 __proto.on = function (eventName, handlerToAttach) {
588 if (typeof eventName === "object" && isUndefined$2(handlerToAttach)) {
589 var eventHash = eventName;
590
591 for (var name in eventHash) {
592 this.on(name, eventHash[name]);
593 }
594
595 return this;
596 } else if (typeof eventName === "string" && typeof handlerToAttach === "function") {
597 var handlerList = this._eventHandler[eventName];
598
599 if (isUndefined$2(handlerList)) {
600 this._eventHandler[eventName] = [];
601 handlerList = this._eventHandler[eventName];
602 }
603
604 handlerList.push(handlerToAttach);
605 }
606
607 return this;
608 };
609 /**
610 * Detaches an event from the component.<br/>If the `eventName` is not given this will detach all event handlers attached.<br/>If the `handlerToDetach` is not given, this will detach all event handlers for `eventName`.
611 * @ko 컴포넌트에 등록된 이벤트를 해제한다.<br/>`eventName`이 주어지지 않았을 경우 모든 이벤트 핸들러를 제거한다.<br/>`handlerToAttach`가 주어지지 않았을 경우 `eventName`에 해당하는 모든 이벤트 핸들러를 제거한다.
612 * @param {string?} eventName The name of the event to be detached <ko>해제할 이벤트의 이름</ko>
613 * @param {function?} handlerToDetach The handler function of the event to be detached <ko>해제할 이벤트의 핸들러 함수</ko>
614 * @return An instance of a component itself <ko>컴포넌트 자신의 인스턴스</ko>
615 * @example
616 * ```ts
617 * import Component, { ComponentEvent } from "@egjs/component";
618 *
619 * class Some extends Component<{
620 * hi: void;
621 * }> {
622 * hi() {
623 * console.log("hi");
624 * }
625 * some() {
626 * this.off("hi",this.hi); //detach event
627 * }
628 * }
629 * ```
630 */
631
632
633 __proto.off = function (eventName, handlerToDetach) {
634 var e_1, _a; // Detach all event handlers.
635
636
637 if (isUndefined$2(eventName)) {
638 this._eventHandler = {};
639 return this;
640 } // Detach all handlers for eventname or detach event handlers by object.
641
642
643 if (isUndefined$2(handlerToDetach)) {
644 if (typeof eventName === "string") {
645 delete this._eventHandler[eventName];
646 return this;
647 } else {
648 var eventHash = eventName;
649
650 for (var name in eventHash) {
651 this.off(name, eventHash[name]);
652 }
653
654 return this;
655 }
656 } // Detach single event handler
657
658
659 var handlerList = this._eventHandler[eventName];
660
661 if (handlerList) {
662 var idx = 0;
663
664 try {
665 for (var handlerList_1 = __values$2(handlerList), handlerList_1_1 = handlerList_1.next(); !handlerList_1_1.done; handlerList_1_1 = handlerList_1.next()) {
666 var handlerFunction = handlerList_1_1.value;
667
668 if (handlerFunction === handlerToDetach) {
669 handlerList.splice(idx, 1);
670
671 if (handlerList.length <= 0) {
672 delete this._eventHandler[eventName];
673 }
674
675 break;
676 }
677
678 idx++;
679 }
680 } catch (e_1_1) {
681 e_1 = {
682 error: e_1_1
683 };
684 } finally {
685 try {
686 if (handlerList_1_1 && !handlerList_1_1.done && (_a = handlerList_1.return)) _a.call(handlerList_1);
687 } finally {
688 if (e_1) throw e_1.error;
689 }
690 }
691 }
692
693 return this;
694 };
695 /**
696 * Version info string
697 * @ko 버전정보 문자열
698 * @name VERSION
699 * @static
700 * @example
701 * Component.VERSION; // ex) 3.0.0
702 * @memberof Component
703 */
704
705
706 Component.VERSION = "3.0.1";
707 return Component;
708 }();
709
710 /*
711 * Copyright (c) 2015 NAVER Corp.
712 * egjs projects are licensed under the MIT license
713 */
714
715 var ComponentEvent$1 = ComponentEvent;
716
717 /*
718 * Copyright (c) 2015 NAVER Corp.
719 * egjs projects are licensed under the MIT license
720 */
721
722 /* eslint-disable @typescript-eslint/restrict-template-expressions */
723
724 /**
725 * Error codes of {@link FlickingError}. Below are the conditions where each error code occurs.
726 * @ko {@link FlickingError}의 에러 코드. 아래는 각각의 에러 코드가 발생하는 조건입니다.
727 * @name ERROR_CODE
728 * @constant
729 * @type object
730 * @property {number} WRONG_TYPE Parameter type is wrong<ko>패러미터의 타입이 잘못되었을 경우</ko>
731 * @property {number} ELEMENT_NOT_FOUND Element is not found inside page with the given CSS selector<ko>주어진 CSS selector로 페이지 내에서 해당 엘리먼트를 찾지 못했을 경우</ko>
732 * @property {number} VAL_MUST_NOT_NULL Expected non-null value, but given `null` or `undefined`<ko>값을 기대했으나, `null`이나 `undefined`를 받은 경우</ko>
733 * @property {number} NOT_ATTACHED_TO_FLICKING When Flicking's component is not initialized (i.e. {@link Flicking#init} is not called)<ko>Flicking 내부 컴포넌트가 초기화되지 않은 경우 ({@link Flicking#init}이 호출되지 않은 경우)</ko>
734 * @property {number} WRONG_OPTION One of the options is wrong<ko>옵션들 중 잘못된 값이 있을 때</ko>
735 * @property {number} INDEX_OUT_OF_RANGE When the given index is out of possible range<ko>인덱스가 주어진 범위를 벗어난 경우</ko>
736 * @property {number} POSITION_NOT_REACHABLE When {@link Control#moveToPosition}'s position parameter is out of possible range.<ko>{@link Control#moveToPosition}의 `position` 패러미터가 도달 가능한 범위를 벗어난 경우</ko>
737 * @property {number} TRANSFORM_NOT_SUPPORTED CSS `transform` property is not available(<=IE8) <ko>CSS `transform` 속성을 사용할 수 없는 경우(<=IE8)</ko>
738 * @property {number} STOP_CALLED_BY_USER When the event's `stop()` is called by user.<ko>사용자에 의해 이벤트의 `stop()`이 호출된 경우</ko>
739 * @property {number} ANIMATION_INTERRUPTED When the animation is interrupted by user.<ko>사용자에 의해 애니메이션이 중단된 경우</ko>
740 * @property {number} ANIMATION_ALREADY_PLAYING When the animation is already playing.<ko>현재 애니메이션이 이미 진행중인 경우</ko>
741 * @property {number} NOT_ALLOWED_IN_FRAMEWORK When the non-allowed method is called from frameworks (React, Angular, Vue...)
742 * <ko>프레임워크(React, Angular, Vue ...)에서 사용 불가능한 메소드를 호출했을 경우</ko>
743 * @property {number} NOT_INITIALIZED When the {@link Flicking#init} is not called before but is needed<ko>{@link Flicking#init}의 호출이 필요하나, 아직 호출되지 않았을 경우</ko>
744 * @property {number} NO_ACTIVE When there're no active panel that flicking has selected. This may be due to the absence of any panels<ko>현재 Flicking이 선택한 패널이 없을 경우. 일반적으로 패널이 하나도 없는 경우에 발생할 수 있습니다</ko>
745 */
746 var CODE = {
747 WRONG_TYPE: 0,
748 ELEMENT_NOT_FOUND: 1,
749 VAL_MUST_NOT_NULL: 2,
750 NOT_ATTACHED_TO_FLICKING: 3,
751 WRONG_OPTION: 4,
752 INDEX_OUT_OF_RANGE: 5,
753 POSITION_NOT_REACHABLE: 6,
754 TRANSFORM_NOT_SUPPORTED: 7,
755 STOP_CALLED_BY_USER: 8,
756 ANIMATION_INTERRUPTED: 9,
757 ANIMATION_ALREADY_PLAYING: 10,
758 NOT_ALLOWED_IN_FRAMEWORK: 11,
759 NOT_INITIALIZED: 12,
760 NO_ACTIVE: 13
761 };
762 var MESSAGE = {
763 WRONG_TYPE: function (wrongVal, correctTypes) {
764 return wrongVal + "(" + typeof wrongVal + ") is not a " + correctTypes.map(function (type) {
765 return "\"" + type + "\"";
766 }).join(" or ") + ".";
767 },
768 ELEMENT_NOT_FOUND: function (selector) {
769 return "Element with selector \"" + selector + "\" not found.";
770 },
771 VAL_MUST_NOT_NULL: function (val, name) {
772 return name + " should be provided. Given: " + val;
773 },
774 NOT_ATTACHED_TO_FLICKING: function (name) {
775 return name + " is not attached to the Flicking instance. \"init()\" should be called first.";
776 },
777 WRONG_OPTION: function (optionName, val) {
778 return "Option \"" + optionName + "\" is not in correct format, given: " + val;
779 },
780 INDEX_OUT_OF_RANGE: function (val, min, max) {
781 return "Index \"" + val + "\" is out of range: should be between " + min + " and " + max + ".";
782 },
783 POSITION_NOT_REACHABLE: function (position) {
784 return "Position \"" + position + "\" is not reachable.";
785 },
786 TRANSFORM_NOT_SUPPORTED: "Browser does not support CSS transform.",
787 STOP_CALLED_BY_USER: "Event stop() is called by user.",
788 ANIMATION_INTERRUPTED: "Animation is interrupted by user input.",
789 ANIMATION_ALREADY_PLAYING: "Animation is already playing.",
790 NOT_ALLOWED_IN_FRAMEWORK: "This behavior is not allowed in the frameworks like React, Vue, or Angular.",
791 NOT_INITIALIZED: "Flicking is not initialized yet, call init() first.",
792 NO_ACTIVE: "There's no active panel that Flicking has selected. This may be due to the absence of any panels."
793 };
794
795 /*
796 * Copyright (c) 2015 NAVER Corp.
797 * egjs projects are licensed under the MIT license
798 */
799 /**
800 * Event type object with event name strings of {@link Flicking}
801 * @ko {@link Flicking}의 이벤트 이름 문자열들을 담은 객체
802 * @type {object}
803 * @property {"holdStart"} HOLD_START holdStart event<ko>holdStart 이벤트</ko>
804 * @property {"holdEnd"} HOLD_END holdEnd event<ko>holdEnd 이벤트</ko>
805 * @property {"moveStart"} MOVE_START moveStart event<ko>moveStart 이벤트</ko>
806 * @property {"move"} MOVE move event<ko>move 이벤트</ko>
807 * @property {"moveEnd"} MOVE_END moveEnd event<ko>moveEnd 이벤트</ko>
808 * @property {"willChange"} WILL_CHANGE willChange event<ko>willChange 이벤트</ko>
809 * @property {"changed"} CHANGED changed event<ko>changed 이벤트</ko>
810 * @property {"willRestore"} WILL_RESTORE willRestore event<ko>willRestore 이벤트</ko>
811 * @property {"restored"} RESTORED restored event<ko>restored 이벤트</ko>
812 * @property {"select"} SELECT select event<ko>select 이벤트</ko>
813 * @property {"needPanel"} NEED_PANEL needPanel event<ko>needPanel 이벤트</ko>
814 * @property {"panelChange"} PANEL_CHANGE panelChange event<ko>panelChange 이벤트</ko>
815 * @example
816 * ```ts
817 * import { EVENTS } from "@egjs/flicking";
818 * EVENTS.MOVE_START; // "moveStart"
819 * ```
820 */
821
822 var EVENTS = {
823 READY: "ready",
824 BEFORE_RESIZE: "beforeResize",
825 AFTER_RESIZE: "afterResize",
826 HOLD_START: "holdStart",
827 HOLD_END: "holdEnd",
828 MOVE_START: "moveStart",
829 MOVE: "move",
830 MOVE_END: "moveEnd",
831 WILL_CHANGE: "willChange",
832 CHANGED: "changed",
833 WILL_RESTORE: "willRestore",
834 RESTORED: "restored",
835 SELECT: "select",
836 NEED_PANEL: "needPanel",
837 VISIBLE_CHANGE: "visibleChange",
838 REACH_EDGE: "reachEdge",
839 PANEL_CHANGE: "panelChange"
840 };
841 /**
842 * An object with all possible predefined literal string for the {@link Flicking#align align} option
843 * @ko {@link Flicking#align align} 옵션에 사용되는 미리 정의된 리터럴 상수들을 담고 있는 객체
844 * @type {object}
845 * @property {"prev"} PREV left/top align<ko>좌/상 정렬</ko>
846 * @property {"center"} CENTER center align<ko>중앙 정렬</ko>
847 * @property {"next"} NEXT right/bottom align<ko>우/하 정렬</ko>
848 */
849
850 var ALIGN = {
851 PREV: "prev",
852 CENTER: "center",
853 NEXT: "next"
854 };
855 /**
856 * An object of directions
857 * @ko 방향을 나타내는 값들을 담고 있는 객체
858 * @type {object}
859 * @property {"PREV"} PREV "left" when {@link Flicking#horizontal horizontal} is true, and "top" when {@link Flicking#horizontal horizontal} is false
860 * <ko>{@link Flicking#horizontal horizontal}가 `true`일 경우 왼쪽, {@link Flicking#horizontal horizontal}가 `false`일 경우 위쪽을 의미합니다</ko>
861 * @property {"NEXT"} NEXT "right" when {@link Flicking#horizontal horizontal} is true, and "bottom" when {@link Flicking#horizontal horizontal} is false
862 * <ko>{@link Flicking#horizontal horizontal}가 `true`일 경우 오른쪽, {@link Flicking#horizontal horizontal}가 `false`일 경우 아래쪽을 의미합니다</ko>
863 * @property {null} NONE This value usually means it's the same position<ko>주로 제자리인 경우를 의미합니다</ko>
864 */
865
866 var DIRECTION = {
867 PREV: "PREV",
868 NEXT: "NEXT",
869 NONE: null
870 };
871 /**
872 * An object with all possible {@link Flicking#moveType moveType}s
873 * @ko Flicking이 제공하는 {@link Flicking#moveType moveType}들을 담고 있는 객체
874 * @type {object}
875 * @property {"snap"} SNAP Flicking's {@link Flicking#moveType moveType} that enables {@link SnapControl} as a Flicking's {@link Flicking#control control}
876 * <ko>Flicking의 {@link Flicking#control control}을 {@link SnapControl}로 설정하게 하는 {@link Flicking#moveType moveType}</ko>
877 * @property {"freeScroll"} FREE_SCROLL Flicking's {@link Flicking#moveType moveType} that enables {@link FreeControl} as a Flicking's {@link Flicking#control control}
878 * <ko>Flicking의 {@link Flicking#control control}을 {@link FreeControl}로 설정하게 하는 {@link Flicking#moveType moveType}</ko>
879 * @property {"strict"} STRICT Flicking's {@link Flicking#moveType moveType} that enables {@link StrictControl} as a Flicking's {@link Flicking#control control}
880 * <ko>Flicking의 {@link Flicking#control control}을 {@link StrictControl}로 설정하게 하는 {@link Flicking#moveType moveType}</ko>
881 */
882
883 var MOVE_TYPE = {
884 SNAP: "snap",
885 FREE_SCROLL: "freeScroll",
886 STRICT: "strict"
887 };
888
889 var Constants = {
890 __proto__: null,
891 EVENTS: EVENTS,
892 ALIGN: ALIGN,
893 DIRECTION: DIRECTION,
894 MOVE_TYPE: MOVE_TYPE,
895 ERROR_CODE: CODE
896 };
897
898 var merge$1 = function (target) {
899 var sources = [];
900
901 for (var _i = 1; _i < arguments.length; _i++) {
902 sources[_i - 1] = arguments[_i];
903 }
904
905 sources.forEach(function (source) {
906 Object.keys(source).forEach(function (key) {
907 target[key] = source[key];
908 });
909 });
910 return target;
911 };
912 var getElement = function (el, parent) {
913 var targetEl = null;
914
915 if (isString(el)) {
916 var parentEl = parent ? parent : document;
917 var queryResult = parentEl.querySelector(el);
918
919 if (!queryResult) {
920 throw new FlickingError(MESSAGE.ELEMENT_NOT_FOUND(el), CODE.ELEMENT_NOT_FOUND);
921 }
922
923 targetEl = queryResult;
924 } else if (el && el.nodeType === Node.ELEMENT_NODE) {
925 targetEl = el;
926 }
927
928 if (!targetEl) {
929 throw new FlickingError(MESSAGE.WRONG_TYPE(el, ["HTMLElement", "string"]), CODE.WRONG_TYPE);
930 }
931
932 return targetEl;
933 };
934 var checkExistence = function (value, nameOnErrMsg) {
935 if (value == null) {
936 throw new FlickingError(MESSAGE.VAL_MUST_NOT_NULL(value, nameOnErrMsg), CODE.VAL_MUST_NOT_NULL);
937 }
938 };
939 var clamp = function (x, min, max) {
940 return Math.max(Math.min(x, max), min);
941 };
942 var getFlickingAttached = function (val, nameToThrowOnError) {
943 if (!val) {
944 throw new FlickingError(MESSAGE.NOT_ATTACHED_TO_FLICKING(nameToThrowOnError), CODE.NOT_ATTACHED_TO_FLICKING);
945 }
946
947 return val;
948 };
949 var toArray$3 = function (iterable) {
950 return [].slice.call(iterable);
951 };
952 var parseAlign$1 = function (align, size) {
953 var alignPoint;
954
955 if (isString(align)) {
956 switch (align) {
957 case ALIGN.PREV:
958 alignPoint = 0;
959 break;
960
961 case ALIGN.CENTER:
962 alignPoint = 0.5 * size;
963 break;
964
965 case ALIGN.NEXT:
966 alignPoint = size;
967 break;
968
969 default:
970 alignPoint = parseArithmeticSize(align, size);
971
972 if (alignPoint == null) {
973 throw new FlickingError(MESSAGE.WRONG_OPTION("align", align), CODE.WRONG_OPTION);
974 }
975
976 }
977 } else {
978 alignPoint = align;
979 }
980
981 return alignPoint;
982 };
983 var parseBounce = function (bounce, size) {
984 var parsedBounce;
985
986 if (Array.isArray(bounce)) {
987 parsedBounce = bounce.map(function (val) {
988 return parseArithmeticSize(val, size);
989 });
990 } else {
991 var parsedVal = parseArithmeticSize(bounce, size);
992 parsedBounce = [parsedVal, parsedVal];
993 }
994
995 return parsedBounce.map(function (val) {
996 if (val == null) {
997 throw new FlickingError(MESSAGE.WRONG_OPTION("bounce", bounce), CODE.WRONG_OPTION);
998 }
999
1000 return val;
1001 });
1002 };
1003 var parseArithmeticSize = function (cssValue, base) {
1004 var parsed = parseArithmeticExpression(cssValue);
1005 if (parsed == null) return null;
1006 return parsed.percentage * base + parsed.absolute;
1007 };
1008 var parseArithmeticExpression = function (cssValue) {
1009 var cssRegex = /(?:(\+|\-)\s*)?(\d+(?:\.\d+)?(%|px)?)/g;
1010
1011 if (typeof cssValue === "number") {
1012 return {
1013 percentage: 0,
1014 absolute: cssValue
1015 };
1016 }
1017
1018 var parsed = {
1019 percentage: 0,
1020 absolute: 0
1021 };
1022 var idx = 0;
1023 var matchResult = cssRegex.exec(cssValue);
1024
1025 while (matchResult != null) {
1026 var sign = matchResult[1];
1027 var value = matchResult[2];
1028 var unit = matchResult[3];
1029 var parsedValue = parseFloat(value);
1030
1031 if (idx <= 0) {
1032 sign = sign || "+";
1033 } // Return default value for values not in good form
1034
1035
1036 if (!sign) {
1037 return null;
1038 }
1039
1040 var signMultiplier = sign === "+" ? 1 : -1;
1041
1042 if (unit === "%") {
1043 parsed.percentage += signMultiplier * (parsedValue / 100);
1044 } else {
1045 parsed.absolute += signMultiplier * parsedValue;
1046 } // Match next occurrence
1047
1048
1049 ++idx;
1050 matchResult = cssRegex.exec(cssValue);
1051 } // None-matched
1052
1053
1054 if (idx === 0) {
1055 return null;
1056 }
1057
1058 return parsed;
1059 };
1060 var getDirection$1 = function (start, end) {
1061 if (start === end) return DIRECTION.NONE;
1062 return start < end ? DIRECTION.NEXT : DIRECTION.PREV;
1063 };
1064 var parseElement = function (element) {
1065 if (!Array.isArray(element)) {
1066 element = [element];
1067 }
1068
1069 var elements = [];
1070 element.forEach(function (el) {
1071 if (isString(el)) {
1072 var tempDiv = document.createElement("div");
1073 tempDiv.innerHTML = el;
1074 elements.push.apply(elements, __spreadArray([], __read$1(toArray$3(tempDiv.children))));
1075
1076 while (tempDiv.firstChild) {
1077 tempDiv.removeChild(tempDiv.firstChild);
1078 }
1079 } else if (el && el.nodeType === Node.ELEMENT_NODE) {
1080 elements.push(el);
1081 } else {
1082 throw new FlickingError(MESSAGE.WRONG_TYPE(el, ["HTMLElement", "string"]), CODE.WRONG_TYPE);
1083 }
1084 });
1085 return elements;
1086 };
1087 var getMinusCompensatedIndex = function (idx, max) {
1088 return idx < 0 ? clamp(idx + max, 0, max) : clamp(idx, 0, max);
1089 };
1090 var includes = function (array, target) {
1091 var e_1, _a;
1092
1093 try {
1094 for (var array_1 = __values$3(array), array_1_1 = array_1.next(); !array_1_1.done; array_1_1 = array_1.next()) {
1095 var val = array_1_1.value;
1096 if (val === target) return true;
1097 }
1098 } catch (e_1_1) {
1099 e_1 = {
1100 error: e_1_1
1101 };
1102 } finally {
1103 try {
1104 if (array_1_1 && !array_1_1.done && (_a = array_1.return)) _a.call(array_1);
1105 } finally {
1106 if (e_1) throw e_1.error;
1107 }
1108 }
1109
1110 return false;
1111 };
1112 var isString = function (val) {
1113 return typeof val === "string";
1114 };
1115 var circulatePosition = function (pos, min, max) {
1116 var size = max - min;
1117
1118 if (pos < min) {
1119 var offset = (min - pos) % size;
1120 pos = max - offset;
1121 } else if (pos > max) {
1122 var offset = (pos - max) % size;
1123 pos = min + offset;
1124 }
1125
1126 return pos;
1127 };
1128 var find$1 = function (array, checker) {
1129 var e_2, _a;
1130
1131 try {
1132 for (var array_2 = __values$3(array), array_2_1 = array_2.next(); !array_2_1.done; array_2_1 = array_2.next()) {
1133 var val = array_2_1.value;
1134
1135 if (checker(val)) {
1136 return val;
1137 }
1138 }
1139 } catch (e_2_1) {
1140 e_2 = {
1141 error: e_2_1
1142 };
1143 } finally {
1144 try {
1145 if (array_2_1 && !array_2_1.done && (_a = array_2.return)) _a.call(array_2);
1146 } finally {
1147 if (e_2) throw e_2.error;
1148 }
1149 }
1150
1151 return null;
1152 };
1153 var findIndex = function (array, checker) {
1154 for (var idx = 0; idx < array.length; idx++) {
1155 if (checker(array[idx])) {
1156 return idx;
1157 }
1158 }
1159
1160 return -1;
1161 };
1162 var getProgress = function (pos, prev, next) {
1163 return (pos - prev) / (next - prev);
1164 }; // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
1165
1166 var getStyle = function (el) {
1167 return window.getComputedStyle(el) || el.currentStyle;
1168 };
1169 var isBetween = function (val, min, max) {
1170 return val >= min && val <= max;
1171 };
1172 var circulateIndex = function (index, max) {
1173 if (index >= max) {
1174 return index % max;
1175 } else if (index < 0) {
1176 return getMinusCompensatedIndex((index + 1) % max - 1, max);
1177 } else {
1178 return index;
1179 }
1180 };
1181 var setPrototypeOf = Object.setPrototypeOf || function (obj, proto) {
1182 obj.__proto__ = proto;
1183 return obj;
1184 };
1185
1186 /*
1187 * Copyright (c) 2015 NAVER Corp.
1188 * egjs projects are licensed under the MIT license
1189 */
1190 /**
1191 * Special type of known error that {@link Flicking} throws.
1192 * @ko Flicking 내부에서 알려진 오류 발생시 throw되는 에러
1193 * @property {number} code Error code<ko>에러 코드</ko>
1194 * @property {string} message Error message<ko>에러 메시지</ko>
1195 * @see {@link Constants.ERROR_CODE ERROR_CODE}
1196 * @example
1197 * ```ts
1198 * import Flicking, { FlickingError, ERROR_CODES } from "@egjs/flicking";
1199 * try {
1200 * const flicking = new Flicking(".flicking-viewport")
1201 * } catch (e) {
1202 * if (e instanceof FlickingError && e.code === ERROR_CODES.ELEMENT_NOT_FOUND) {
1203 * console.error("Element not found")
1204 * }
1205 * }
1206 * ```
1207 */
1208
1209 var FlickingError = function (_super) {
1210 __extends$2(FlickingError, _super);
1211 /**
1212 * @param message Error message<ko>에러 메시지</ko>
1213 * @param code Error code<ko>에러 코드</ko>
1214 */
1215
1216
1217 function FlickingError(message, code) {
1218 var _this = _super.call(this, message) || this;
1219
1220 setPrototypeOf(_this, FlickingError.prototype);
1221 _this.name = "FlickingError";
1222 _this.code = code;
1223 return _this;
1224 }
1225
1226 return FlickingError;
1227 }(Error);
1228
1229 /*
1230 * Copyright (c) 2015 NAVER Corp.
1231 * egjs projects are licensed under the MIT license
1232 */
1233 /**
1234 * A component that manages viewport size
1235 * @ko 뷰포트 크기 정보를 담당하는 컴포넌트
1236 */
1237
1238 var Viewport = function () {
1239 /**
1240 * @param el A viewport element<ko>뷰포트 엘리먼트</ko>
1241 */
1242 function Viewport(el) {
1243 this._el = el;
1244 this._width = 0;
1245 this._height = 0;
1246 this._padding = {
1247 left: 0,
1248 right: 0,
1249 top: 0,
1250 bottom: 0
1251 };
1252 this._isBorderBoxSizing = false;
1253 }
1254
1255 var __proto = Viewport.prototype;
1256 Object.defineProperty(__proto, "element", {
1257 /**
1258 * A viewport(root) element
1259 * @ko 뷰포트(root) 엘리먼트
1260 * @type {HTMLElement}
1261 * @readonly
1262 */
1263 get: function () {
1264 return this._el;
1265 },
1266 enumerable: false,
1267 configurable: true
1268 });
1269 Object.defineProperty(__proto, "width", {
1270 /**
1271 * Viewport width, without paddings
1272 * @ko 뷰포트 너비
1273 * @type {number}
1274 * @readonly
1275 */
1276 get: function () {
1277 return this._width - this._padding.left - this._padding.right;
1278 },
1279 enumerable: false,
1280 configurable: true
1281 });
1282 Object.defineProperty(__proto, "height", {
1283 /**
1284 * Viewport height, without paddings
1285 * @ko 뷰포트 높이
1286 * @type {number}
1287 * @readonly
1288 */
1289 get: function () {
1290 return this._height - this._padding.top - this._padding.bottom;
1291 },
1292 enumerable: false,
1293 configurable: true
1294 });
1295 Object.defineProperty(__proto, "padding", {
1296 /**
1297 * Viewport paddings
1298 * @ko 뷰포트 CSS padding 값
1299 * @type {object}
1300 * @property {number} left CSS `padding-left`
1301 * @property {number} right CSS `padding-right`
1302 * @property {number} top CSS `padding-top`
1303 * @property {number} bottom CSS `padding-bottom`
1304 * @readonly
1305 */
1306 get: function () {
1307 return this._padding;
1308 },
1309 enumerable: false,
1310 configurable: true
1311 });
1312 /**
1313 * Change viewport's size.
1314 * This will change the actual size of `.flicking-viewport` element by changing its CSS width/height property
1315 * @ko 뷰포트 크기를 변경합니다.
1316 * `.flicking-viewport` 엘리먼트에 해당 크기의 CSS width/height를 적용합니다
1317 * @param {object} [size] New viewport size<ko>새 뷰포트 크기</ko>
1318 * @param {number|string} [size.width] CSS string or number(in px)<ko>CSS 문자열 또는 숫자(px)</ko>
1319 * @param {number|string} [size.height] CSS string or number(in px)<ko>CSS 문자열 또는 숫자(px)</ko>
1320 */
1321
1322 __proto.setSize = function (_a) {
1323 var width = _a.width,
1324 height = _a.height;
1325 var el = this._el;
1326 var padding = this._padding;
1327 var isBorderBoxSizing = this._isBorderBoxSizing;
1328
1329 if (width != null) {
1330 if (isString(width)) {
1331 el.style.width = width;
1332 } else {
1333 var newWidth = isBorderBoxSizing ? width + padding.left + padding.right : width;
1334 el.style.width = newWidth + "px";
1335 }
1336 }
1337
1338 if (height != null) {
1339 if (isString(height)) {
1340 el.style.height = height;
1341 } else {
1342 var newHeight = isBorderBoxSizing ? height + padding.top + padding.bottom : height;
1343 el.style.height = newHeight + "px";
1344 }
1345 }
1346
1347 this.resize();
1348 };
1349 /**
1350 * Update width/height to the current viewport element's size
1351 * @ko 현재 뷰포트 엘리먼트의 크기로 너비/높이를 업데이트합니다
1352 */
1353
1354
1355 __proto.resize = function () {
1356 var el = this._el;
1357 var elStyle = getStyle(el);
1358 this._width = el.clientWidth;
1359 this._height = el.clientHeight;
1360 this._padding = {
1361 left: parseFloat(elStyle.paddingLeft),
1362 right: parseFloat(elStyle.paddingRight),
1363 top: parseFloat(elStyle.paddingTop),
1364 bottom: parseFloat(elStyle.paddingBottom)
1365 };
1366 this._isBorderBoxSizing = elStyle.boxSizing === "border-box";
1367 };
1368
1369 return Viewport;
1370 }();
1371
1372 /*! Hammer.JS - v2.0.17-rc - 2019-12-16
1373 * http://naver.github.io/egjs
1374 *
1375 * Forked By Naver egjs
1376 * Copyright (c) hammerjs
1377 * Licensed under the MIT license */
1378 function _extends() {
1379 _extends = Object.assign || function (target) {
1380 for (var i = 1; i < arguments.length; i++) {
1381 var source = arguments[i];
1382
1383 for (var key in source) {
1384 if (Object.prototype.hasOwnProperty.call(source, key)) {
1385 target[key] = source[key];
1386 }
1387 }
1388 }
1389
1390 return target;
1391 };
1392
1393 return _extends.apply(this, arguments);
1394 }
1395
1396 function _inheritsLoose(subClass, superClass) {
1397 subClass.prototype = Object.create(superClass.prototype);
1398 subClass.prototype.constructor = subClass;
1399 subClass.__proto__ = superClass;
1400 }
1401
1402 function _assertThisInitialized(self) {
1403 if (self === void 0) {
1404 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
1405 }
1406
1407 return self;
1408 }
1409
1410 /**
1411 * @private
1412 * extend object.
1413 * means that properties in dest will be overwritten by the ones in src.
1414 * @param {Object} target
1415 * @param {...Object} objects_to_assign
1416 * @returns {Object} target
1417 */
1418 var assign;
1419
1420 if (typeof Object.assign !== 'function') {
1421 assign = function assign(target) {
1422 if (target === undefined || target === null) {
1423 throw new TypeError('Cannot convert undefined or null to object');
1424 }
1425
1426 var output = Object(target);
1427
1428 for (var index = 1; index < arguments.length; index++) {
1429 var source = arguments[index];
1430
1431 if (source !== undefined && source !== null) {
1432 for (var nextKey in source) {
1433 if (source.hasOwnProperty(nextKey)) {
1434 output[nextKey] = source[nextKey];
1435 }
1436 }
1437 }
1438 }
1439
1440 return output;
1441 };
1442 } else {
1443 assign = Object.assign;
1444 }
1445
1446 var assign$1 = assign;
1447
1448 var VENDOR_PREFIXES = ['', 'webkit', 'Moz', 'MS', 'ms', 'o'];
1449 var TEST_ELEMENT = typeof document === "undefined" ? {
1450 style: {}
1451 } : document.createElement('div');
1452 var TYPE_FUNCTION = 'function';
1453 var round = Math.round,
1454 abs = Math.abs;
1455 var now = Date.now;
1456
1457 /**
1458 * @private
1459 * get the prefixed property
1460 * @param {Object} obj
1461 * @param {String} property
1462 * @returns {String|Undefined} prefixed
1463 */
1464
1465 function prefixed(obj, property) {
1466 var prefix;
1467 var prop;
1468 var camelProp = property[0].toUpperCase() + property.slice(1);
1469 var i = 0;
1470
1471 while (i < VENDOR_PREFIXES.length) {
1472 prefix = VENDOR_PREFIXES[i];
1473 prop = prefix ? prefix + camelProp : property;
1474
1475 if (prop in obj) {
1476 return prop;
1477 }
1478
1479 i++;
1480 }
1481
1482 return undefined;
1483 }
1484
1485 /* eslint-disable no-new-func, no-nested-ternary */
1486 var win$1;
1487
1488 if (typeof window === "undefined") {
1489 // window is undefined in node.js
1490 win$1 = {};
1491 } else {
1492 win$1 = window;
1493 }
1494
1495 var PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction');
1496 var NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined;
1497 function getTouchActionProps() {
1498 if (!NATIVE_TOUCH_ACTION) {
1499 return false;
1500 }
1501
1502 var touchMap = {};
1503 var cssSupports = win$1.CSS && win$1.CSS.supports;
1504 ['auto', 'manipulation', 'pan-y', 'pan-x', 'pan-x pan-y', 'none'].forEach(function (val) {
1505 // If css.supports is not supported but there is native touch-action assume it supports
1506 // all values. This is the case for IE 10 and 11.
1507 return touchMap[val] = cssSupports ? win$1.CSS.supports('touch-action', val) : true;
1508 });
1509 return touchMap;
1510 }
1511
1512 var TOUCH_ACTION_COMPUTE = 'compute';
1513 var TOUCH_ACTION_AUTO = 'auto';
1514 var TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented
1515
1516 var TOUCH_ACTION_NONE = 'none';
1517 var TOUCH_ACTION_PAN_X = 'pan-x';
1518 var TOUCH_ACTION_PAN_Y = 'pan-y';
1519 var TOUCH_ACTION_MAP = getTouchActionProps();
1520
1521 var MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;
1522 var SUPPORT_TOUCH$1 = 'ontouchstart' in win$1;
1523 var SUPPORT_POINTER_EVENTS$1 = prefixed(win$1, 'PointerEvent') !== undefined;
1524 var SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH$1 && MOBILE_REGEX.test(navigator.userAgent);
1525 var INPUT_TYPE_TOUCH = 'touch';
1526 var INPUT_TYPE_PEN = 'pen';
1527 var INPUT_TYPE_MOUSE = 'mouse';
1528 var INPUT_TYPE_KINECT = 'kinect';
1529 var COMPUTE_INTERVAL = 25;
1530 var INPUT_START = 1;
1531 var INPUT_MOVE = 2;
1532 var INPUT_END = 4;
1533 var INPUT_CANCEL = 8;
1534 var DIRECTION_NONE = 1;
1535 var DIRECTION_LEFT = 2;
1536 var DIRECTION_RIGHT = 4;
1537 var DIRECTION_UP = 8;
1538 var DIRECTION_DOWN = 16;
1539 var DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT;
1540 var DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN;
1541 var DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL;
1542 var PROPS_XY = ['x', 'y'];
1543 var PROPS_CLIENT_XY = ['clientX', 'clientY'];
1544
1545 /**
1546 * @private
1547 * walk objects and arrays
1548 * @param {Object} obj
1549 * @param {Function} iterator
1550 * @param {Object} context
1551 */
1552 function each(obj, iterator, context) {
1553 var i;
1554
1555 if (!obj) {
1556 return;
1557 }
1558
1559 if (obj.forEach) {
1560 obj.forEach(iterator, context);
1561 } else if (obj.length !== undefined) {
1562 i = 0;
1563
1564 while (i < obj.length) {
1565 iterator.call(context, obj[i], i, obj);
1566 i++;
1567 }
1568 } else {
1569 for (i in obj) {
1570 obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj);
1571 }
1572 }
1573 }
1574
1575 /**
1576 * @private
1577 * let a boolean value also be a function that must return a boolean
1578 * this first item in args will be used as the context
1579 * @param {Boolean|Function} val
1580 * @param {Array} [args]
1581 * @returns {Boolean}
1582 */
1583
1584 function boolOrFn(val, args) {
1585 if (typeof val === TYPE_FUNCTION) {
1586 return val.apply(args ? args[0] || undefined : undefined, args);
1587 }
1588
1589 return val;
1590 }
1591
1592 /**
1593 * @private
1594 * small indexOf wrapper
1595 * @param {String} str
1596 * @param {String} find
1597 * @returns {Boolean} found
1598 */
1599 function inStr(str, find) {
1600 return str.indexOf(find) > -1;
1601 }
1602
1603 /**
1604 * @private
1605 * when the touchActions are collected they are not a valid value, so we need to clean things up. *
1606 * @param {String} actions
1607 * @returns {*}
1608 */
1609
1610 function cleanTouchActions(actions) {
1611 // none
1612 if (inStr(actions, TOUCH_ACTION_NONE)) {
1613 return TOUCH_ACTION_NONE;
1614 }
1615
1616 var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);
1617 var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y); // if both pan-x and pan-y are set (different recognizers
1618 // for different directions, e.g. horizontal pan but vertical swipe?)
1619 // we need none (as otherwise with pan-x pan-y combined none of these
1620 // recognizers will work, since the browser would handle all panning
1621
1622 if (hasPanX && hasPanY) {
1623 return TOUCH_ACTION_NONE;
1624 } // pan-x OR pan-y
1625
1626
1627 if (hasPanX || hasPanY) {
1628 return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y;
1629 } // manipulation
1630
1631
1632 if (inStr(actions, TOUCH_ACTION_MANIPULATION)) {
1633 return TOUCH_ACTION_MANIPULATION;
1634 }
1635
1636 return TOUCH_ACTION_AUTO;
1637 }
1638
1639 /**
1640 * @private
1641 * Touch Action
1642 * sets the touchAction property or uses the js alternative
1643 * @param {Manager} manager
1644 * @param {String} value
1645 * @constructor
1646 */
1647
1648 var TouchAction =
1649 /*#__PURE__*/
1650 function () {
1651 function TouchAction(manager, value) {
1652 this.manager = manager;
1653 this.set(value);
1654 }
1655 /**
1656 * @private
1657 * set the touchAction value on the element or enable the polyfill
1658 * @param {String} value
1659 */
1660
1661
1662 var _proto = TouchAction.prototype;
1663
1664 _proto.set = function set(value) {
1665 // find out the touch-action by the event handlers
1666 if (value === TOUCH_ACTION_COMPUTE) {
1667 value = this.compute();
1668 }
1669
1670 if (NATIVE_TOUCH_ACTION && this.manager.element.style && TOUCH_ACTION_MAP[value]) {
1671 this.manager.element.style[PREFIXED_TOUCH_ACTION] = value;
1672 }
1673
1674 this.actions = value.toLowerCase().trim();
1675 };
1676 /**
1677 * @private
1678 * just re-set the touchAction value
1679 */
1680
1681
1682 _proto.update = function update() {
1683 this.set(this.manager.options.touchAction);
1684 };
1685 /**
1686 * @private
1687 * compute the value for the touchAction property based on the recognizer's settings
1688 * @returns {String} value
1689 */
1690
1691
1692 _proto.compute = function compute() {
1693 var actions = [];
1694 each(this.manager.recognizers, function (recognizer) {
1695 if (boolOrFn(recognizer.options.enable, [recognizer])) {
1696 actions = actions.concat(recognizer.getTouchAction());
1697 }
1698 });
1699 return cleanTouchActions(actions.join(' '));
1700 };
1701 /**
1702 * @private
1703 * this method is called on each input cycle and provides the preventing of the browser behavior
1704 * @param {Object} input
1705 */
1706
1707
1708 _proto.preventDefaults = function preventDefaults(input) {
1709 var srcEvent = input.srcEvent;
1710 var direction = input.offsetDirection; // if the touch action did prevented once this session
1711
1712 if (this.manager.session.prevented) {
1713 srcEvent.preventDefault();
1714 return;
1715 }
1716
1717 var actions = this.actions;
1718 var hasNone = inStr(actions, TOUCH_ACTION_NONE) && !TOUCH_ACTION_MAP[TOUCH_ACTION_NONE];
1719 var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_Y];
1720 var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_X];
1721
1722 if (hasNone) {
1723 // do not prevent defaults if this is a tap gesture
1724 var isTapPointer = input.pointers.length === 1;
1725 var isTapMovement = input.distance < 2;
1726 var isTapTouchTime = input.deltaTime < 250;
1727
1728 if (isTapPointer && isTapMovement && isTapTouchTime) {
1729 return;
1730 }
1731 }
1732
1733 if (hasPanX && hasPanY) {
1734 // `pan-x pan-y` means browser handles all scrolling/panning, do not prevent
1735 return;
1736 }
1737
1738 if (hasNone || hasPanY && direction & DIRECTION_HORIZONTAL || hasPanX && direction & DIRECTION_VERTICAL) {
1739 return this.preventSrc(srcEvent);
1740 }
1741 };
1742 /**
1743 * @private
1744 * call preventDefault to prevent the browser's default behavior (scrolling in most cases)
1745 * @param {Object} srcEvent
1746 */
1747
1748
1749 _proto.preventSrc = function preventSrc(srcEvent) {
1750 this.manager.session.prevented = true;
1751 srcEvent.preventDefault();
1752 };
1753
1754 return TouchAction;
1755 }();
1756
1757 /**
1758 * @private
1759 * find if a node is in the given parent
1760 * @method hasParent
1761 * @param {HTMLElement} node
1762 * @param {HTMLElement} parent
1763 * @return {Boolean} found
1764 */
1765 function hasParent(node, parent) {
1766 while (node) {
1767 if (node === parent) {
1768 return true;
1769 }
1770
1771 node = node.parentNode;
1772 }
1773
1774 return false;
1775 }
1776
1777 /**
1778 * @private
1779 * get the center of all the pointers
1780 * @param {Array} pointers
1781 * @return {Object} center contains `x` and `y` properties
1782 */
1783
1784 function getCenter(pointers) {
1785 var pointersLength = pointers.length; // no need to loop when only one touch
1786
1787 if (pointersLength === 1) {
1788 return {
1789 x: round(pointers[0].clientX),
1790 y: round(pointers[0].clientY)
1791 };
1792 }
1793
1794 var x = 0;
1795 var y = 0;
1796 var i = 0;
1797
1798 while (i < pointersLength) {
1799 x += pointers[i].clientX;
1800 y += pointers[i].clientY;
1801 i++;
1802 }
1803
1804 return {
1805 x: round(x / pointersLength),
1806 y: round(y / pointersLength)
1807 };
1808 }
1809
1810 /**
1811 * @private
1812 * create a simple clone from the input used for storage of firstInput and firstMultiple
1813 * @param {Object} input
1814 * @returns {Object} clonedInputData
1815 */
1816
1817 function simpleCloneInputData(input) {
1818 // make a simple copy of the pointers because we will get a reference if we don't
1819 // we only need clientXY for the calculations
1820 var pointers = [];
1821 var i = 0;
1822
1823 while (i < input.pointers.length) {
1824 pointers[i] = {
1825 clientX: round(input.pointers[i].clientX),
1826 clientY: round(input.pointers[i].clientY)
1827 };
1828 i++;
1829 }
1830
1831 return {
1832 timeStamp: now(),
1833 pointers: pointers,
1834 center: getCenter(pointers),
1835 deltaX: input.deltaX,
1836 deltaY: input.deltaY
1837 };
1838 }
1839
1840 /**
1841 * @private
1842 * calculate the absolute distance between two points
1843 * @param {Object} p1 {x, y}
1844 * @param {Object} p2 {x, y}
1845 * @param {Array} [props] containing x and y keys
1846 * @return {Number} distance
1847 */
1848
1849 function getDistance(p1, p2, props) {
1850 if (!props) {
1851 props = PROPS_XY;
1852 }
1853
1854 var x = p2[props[0]] - p1[props[0]];
1855 var y = p2[props[1]] - p1[props[1]];
1856 return Math.sqrt(x * x + y * y);
1857 }
1858
1859 /**
1860 * @private
1861 * calculate the angle between two coordinates
1862 * @param {Object} p1
1863 * @param {Object} p2
1864 * @param {Array} [props] containing x and y keys
1865 * @return {Number} angle
1866 */
1867
1868 function getAngle(p1, p2, props) {
1869 if (!props) {
1870 props = PROPS_XY;
1871 }
1872
1873 var x = p2[props[0]] - p1[props[0]];
1874 var y = p2[props[1]] - p1[props[1]];
1875 return Math.atan2(y, x) * 180 / Math.PI;
1876 }
1877
1878 /**
1879 * @private
1880 * get the direction between two points
1881 * @param {Number} x
1882 * @param {Number} y
1883 * @return {Number} direction
1884 */
1885
1886 function getDirection(x, y) {
1887 if (x === y) {
1888 return DIRECTION_NONE;
1889 }
1890
1891 if (abs(x) >= abs(y)) {
1892 return x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
1893 }
1894
1895 return y < 0 ? DIRECTION_UP : DIRECTION_DOWN;
1896 }
1897
1898 function computeDeltaXY(session, input) {
1899 var center = input.center; // let { offsetDelta:offset = {}, prevDelta = {}, prevInput = {} } = session;
1900 // jscs throwing error on defalut destructured values and without defaults tests fail
1901
1902 var offset = session.offsetDelta || {};
1903 var prevDelta = session.prevDelta || {};
1904 var prevInput = session.prevInput || {};
1905
1906 if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) {
1907 prevDelta = session.prevDelta = {
1908 x: prevInput.deltaX || 0,
1909 y: prevInput.deltaY || 0
1910 };
1911 offset = session.offsetDelta = {
1912 x: center.x,
1913 y: center.y
1914 };
1915 }
1916
1917 input.deltaX = prevDelta.x + (center.x - offset.x);
1918 input.deltaY = prevDelta.y + (center.y - offset.y);
1919 }
1920
1921 /**
1922 * @private
1923 * calculate the velocity between two points. unit is in px per ms.
1924 * @param {Number} deltaTime
1925 * @param {Number} x
1926 * @param {Number} y
1927 * @return {Object} velocity `x` and `y`
1928 */
1929 function getVelocity(deltaTime, x, y) {
1930 return {
1931 x: x / deltaTime || 0,
1932 y: y / deltaTime || 0
1933 };
1934 }
1935
1936 /**
1937 * @private
1938 * calculate the scale factor between two pointersets
1939 * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out
1940 * @param {Array} start array of pointers
1941 * @param {Array} end array of pointers
1942 * @return {Number} scale
1943 */
1944
1945 function getScale(start, end) {
1946 return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY);
1947 }
1948
1949 /**
1950 * @private
1951 * calculate the rotation degrees between two pointersets
1952 * @param {Array} start array of pointers
1953 * @param {Array} end array of pointers
1954 * @return {Number} rotation
1955 */
1956
1957 function getRotation(start, end) {
1958 return getAngle(end[1], end[0], PROPS_CLIENT_XY) + getAngle(start[1], start[0], PROPS_CLIENT_XY);
1959 }
1960
1961 /**
1962 * @private
1963 * velocity is calculated every x ms
1964 * @param {Object} session
1965 * @param {Object} input
1966 */
1967
1968 function computeIntervalInputData(session, input) {
1969 var last = session.lastInterval || input;
1970 var deltaTime = input.timeStamp - last.timeStamp;
1971 var velocity;
1972 var velocityX;
1973 var velocityY;
1974 var direction;
1975
1976 if (input.eventType !== INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined)) {
1977 var deltaX = input.deltaX - last.deltaX;
1978 var deltaY = input.deltaY - last.deltaY;
1979 var v = getVelocity(deltaTime, deltaX, deltaY);
1980 velocityX = v.x;
1981 velocityY = v.y;
1982 velocity = abs(v.x) > abs(v.y) ? v.x : v.y;
1983 direction = getDirection(deltaX, deltaY);
1984 session.lastInterval = input;
1985 } else {
1986 // use latest velocity info if it doesn't overtake a minimum period
1987 velocity = last.velocity;
1988 velocityX = last.velocityX;
1989 velocityY = last.velocityY;
1990 direction = last.direction;
1991 }
1992
1993 input.velocity = velocity;
1994 input.velocityX = velocityX;
1995 input.velocityY = velocityY;
1996 input.direction = direction;
1997 }
1998
1999 /**
2000 * @private
2001 * extend the data with some usable properties like scale, rotate, velocity etc
2002 * @param {Object} manager
2003 * @param {Object} input
2004 */
2005
2006 function computeInputData(manager, input) {
2007 var session = manager.session;
2008 var pointers = input.pointers;
2009 var pointersLength = pointers.length; // store the first input to calculate the distance and direction
2010
2011 if (!session.firstInput) {
2012 session.firstInput = simpleCloneInputData(input);
2013 } // to compute scale and rotation we need to store the multiple touches
2014
2015
2016 if (pointersLength > 1 && !session.firstMultiple) {
2017 session.firstMultiple = simpleCloneInputData(input);
2018 } else if (pointersLength === 1) {
2019 session.firstMultiple = false;
2020 }
2021
2022 var firstInput = session.firstInput,
2023 firstMultiple = session.firstMultiple;
2024 var offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center;
2025 var center = input.center = getCenter(pointers);
2026 input.timeStamp = now();
2027 input.deltaTime = input.timeStamp - firstInput.timeStamp;
2028 input.angle = getAngle(offsetCenter, center);
2029 input.distance = getDistance(offsetCenter, center);
2030 computeDeltaXY(session, input);
2031 input.offsetDirection = getDirection(input.deltaX, input.deltaY);
2032 var overallVelocity = getVelocity(input.deltaTime, input.deltaX, input.deltaY);
2033 input.overallVelocityX = overallVelocity.x;
2034 input.overallVelocityY = overallVelocity.y;
2035 input.overallVelocity = abs(overallVelocity.x) > abs(overallVelocity.y) ? overallVelocity.x : overallVelocity.y;
2036 input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1;
2037 input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0;
2038 input.maxPointers = !session.prevInput ? input.pointers.length : input.pointers.length > session.prevInput.maxPointers ? input.pointers.length : session.prevInput.maxPointers;
2039 computeIntervalInputData(session, input); // find the correct target
2040
2041 var target = manager.element;
2042 var srcEvent = input.srcEvent;
2043 var srcEventTarget;
2044
2045 if (srcEvent.composedPath) {
2046 srcEventTarget = srcEvent.composedPath()[0];
2047 } else if (srcEvent.path) {
2048 srcEventTarget = srcEvent.path[0];
2049 } else {
2050 srcEventTarget = srcEvent.target;
2051 }
2052
2053 if (hasParent(srcEventTarget, target)) {
2054 target = srcEventTarget;
2055 }
2056
2057 input.target = target;
2058 }
2059
2060 /**
2061 * @private
2062 * handle input events
2063 * @param {Manager} manager
2064 * @param {String} eventType
2065 * @param {Object} input
2066 */
2067
2068 function inputHandler(manager, eventType, input) {
2069 var pointersLen = input.pointers.length;
2070 var changedPointersLen = input.changedPointers.length;
2071 var isFirst = eventType & INPUT_START && pointersLen - changedPointersLen === 0;
2072 var isFinal = eventType & (INPUT_END | INPUT_CANCEL) && pointersLen - changedPointersLen === 0;
2073 input.isFirst = !!isFirst;
2074 input.isFinal = !!isFinal;
2075
2076 if (isFirst) {
2077 manager.session = {};
2078 } // source event is the normalized value of the domEvents
2079 // like 'touchstart, mouseup, pointerdown'
2080
2081
2082 input.eventType = eventType; // compute scale, rotation etc
2083
2084 computeInputData(manager, input); // emit secret event
2085
2086 manager.emit('hammer.input', input);
2087 manager.recognize(input);
2088 manager.session.prevInput = input;
2089 }
2090
2091 /**
2092 * @private
2093 * split string on whitespace
2094 * @param {String} str
2095 * @returns {Array} words
2096 */
2097 function splitStr(str) {
2098 return str.trim().split(/\s+/g);
2099 }
2100
2101 /**
2102 * @private
2103 * addEventListener with multiple events at once
2104 * @param {EventTarget} target
2105 * @param {String} types
2106 * @param {Function} handler
2107 */
2108
2109 function addEventListeners(target, types, handler) {
2110 each(splitStr(types), function (type) {
2111 target.addEventListener(type, handler, false);
2112 });
2113 }
2114
2115 /**
2116 * @private
2117 * removeEventListener with multiple events at once
2118 * @param {EventTarget} target
2119 * @param {String} types
2120 * @param {Function} handler
2121 */
2122
2123 function removeEventListeners(target, types, handler) {
2124 each(splitStr(types), function (type) {
2125 target.removeEventListener(type, handler, false);
2126 });
2127 }
2128
2129 /**
2130 * @private
2131 * get the window object of an element
2132 * @param {HTMLElement} element
2133 * @returns {DocumentView|Window}
2134 */
2135 function getWindowForElement(element) {
2136 var doc = element.ownerDocument || element;
2137 return doc.defaultView || doc.parentWindow || window;
2138 }
2139
2140 /**
2141 * @private
2142 * create new input type manager
2143 * @param {Manager} manager
2144 * @param {Function} callback
2145 * @returns {Input}
2146 * @constructor
2147 */
2148
2149 var Input =
2150 /*#__PURE__*/
2151 function () {
2152 function Input(manager, callback) {
2153 var self = this;
2154 this.manager = manager;
2155 this.callback = callback;
2156 this.element = manager.element;
2157 this.target = manager.options.inputTarget; // smaller wrapper around the handler, for the scope and the enabled state of the manager,
2158 // so when disabled the input events are completely bypassed.
2159
2160 this.domHandler = function (ev) {
2161 if (boolOrFn(manager.options.enable, [manager])) {
2162 self.handler(ev);
2163 }
2164 };
2165
2166 this.init();
2167 }
2168 /**
2169 * @private
2170 * should handle the inputEvent data and trigger the callback
2171 * @virtual
2172 */
2173
2174
2175 var _proto = Input.prototype;
2176
2177 _proto.handler = function handler() {};
2178 /**
2179 * @private
2180 * bind the events
2181 */
2182
2183
2184 _proto.init = function init() {
2185 this.evEl && addEventListeners(this.element, this.evEl, this.domHandler);
2186 this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler);
2187 this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
2188 };
2189 /**
2190 * @private
2191 * unbind the events
2192 */
2193
2194
2195 _proto.destroy = function destroy() {
2196 this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler);
2197 this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler);
2198 this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
2199 };
2200
2201 return Input;
2202 }();
2203
2204 /**
2205 * @private
2206 * find if a array contains the object using indexOf or a simple polyFill
2207 * @param {Array} src
2208 * @param {String} find
2209 * @param {String} [findByKey]
2210 * @return {Boolean|Number} false when not found, or the index
2211 */
2212 function inArray(src, find, findByKey) {
2213 if (src.indexOf && !findByKey) {
2214 return src.indexOf(find);
2215 } else {
2216 var i = 0;
2217
2218 while (i < src.length) {
2219 if (findByKey && src[i][findByKey] == find || !findByKey && src[i] === find) {
2220 // do not use === here, test fails
2221 return i;
2222 }
2223
2224 i++;
2225 }
2226
2227 return -1;
2228 }
2229 }
2230
2231 var POINTER_INPUT_MAP = {
2232 pointerdown: INPUT_START,
2233 pointermove: INPUT_MOVE,
2234 pointerup: INPUT_END,
2235 pointercancel: INPUT_CANCEL,
2236 pointerout: INPUT_CANCEL
2237 }; // in IE10 the pointer types is defined as an enum
2238
2239 var IE10_POINTER_TYPE_ENUM = {
2240 2: INPUT_TYPE_TOUCH,
2241 3: INPUT_TYPE_PEN,
2242 4: INPUT_TYPE_MOUSE,
2243 5: INPUT_TYPE_KINECT // see https://twitter.com/jacobrossi/status/480596438489890816
2244
2245 };
2246 var POINTER_ELEMENT_EVENTS = 'pointerdown';
2247 var POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel'; // IE10 has prefixed support, and case-sensitive
2248
2249 if (win$1.MSPointerEvent && !win$1.PointerEvent) {
2250 POINTER_ELEMENT_EVENTS = 'MSPointerDown';
2251 POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel';
2252 }
2253 /**
2254 * @private
2255 * Pointer events input
2256 * @constructor
2257 * @extends Input
2258 */
2259
2260
2261 var PointerEventInput =
2262 /*#__PURE__*/
2263 function (_Input) {
2264 _inheritsLoose(PointerEventInput, _Input);
2265
2266 function PointerEventInput() {
2267 var _this;
2268
2269 var proto = PointerEventInput.prototype;
2270 proto.evEl = POINTER_ELEMENT_EVENTS;
2271 proto.evWin = POINTER_WINDOW_EVENTS;
2272 _this = _Input.apply(this, arguments) || this;
2273 _this.store = _this.manager.session.pointerEvents = [];
2274 return _this;
2275 }
2276 /**
2277 * @private
2278 * handle mouse events
2279 * @param {Object} ev
2280 */
2281
2282
2283 var _proto = PointerEventInput.prototype;
2284
2285 _proto.handler = function handler(ev) {
2286 var store = this.store;
2287 var removePointer = false;
2288 var eventTypeNormalized = ev.type.toLowerCase().replace('ms', '');
2289 var eventType = POINTER_INPUT_MAP[eventTypeNormalized];
2290 var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType;
2291 var isTouch = pointerType === INPUT_TYPE_TOUCH; // get index of the event in the store
2292
2293 var storeIndex = inArray(store, ev.pointerId, 'pointerId'); // start and mouse must be down
2294
2295 if (eventType & INPUT_START && (ev.button === 0 || isTouch)) {
2296 if (storeIndex < 0) {
2297 store.push(ev);
2298 storeIndex = store.length - 1;
2299 }
2300 } else if (eventType & (INPUT_END | INPUT_CANCEL)) {
2301 removePointer = true;
2302 } // it not found, so the pointer hasn't been down (so it's probably a hover)
2303
2304
2305 if (storeIndex < 0) {
2306 return;
2307 } // update the event in the store
2308
2309
2310 store[storeIndex] = ev;
2311 this.callback(this.manager, eventType, {
2312 pointers: store,
2313 changedPointers: [ev],
2314 pointerType: pointerType,
2315 srcEvent: ev
2316 });
2317
2318 if (removePointer) {
2319 // remove from the store
2320 store.splice(storeIndex, 1);
2321 }
2322 };
2323
2324 return PointerEventInput;
2325 }(Input);
2326
2327 /**
2328 * @private
2329 * convert array-like objects to real arrays
2330 * @param {Object} obj
2331 * @returns {Array}
2332 */
2333 function toArray$2(obj) {
2334 return Array.prototype.slice.call(obj, 0);
2335 }
2336
2337 /**
2338 * @private
2339 * unique array with objects based on a key (like 'id') or just by the array's value
2340 * @param {Array} src [{id:1},{id:2},{id:1}]
2341 * @param {String} [key]
2342 * @param {Boolean} [sort=False]
2343 * @returns {Array} [{id:1},{id:2}]
2344 */
2345
2346 function uniqueArray(src, key, sort) {
2347 var results = [];
2348 var values = [];
2349 var i = 0;
2350
2351 while (i < src.length) {
2352 var val = key ? src[i][key] : src[i];
2353
2354 if (inArray(values, val) < 0) {
2355 results.push(src[i]);
2356 }
2357
2358 values[i] = val;
2359 i++;
2360 }
2361
2362 if (sort) {
2363 if (!key) {
2364 results = results.sort();
2365 } else {
2366 results = results.sort(function (a, b) {
2367 return a[key] > b[key];
2368 });
2369 }
2370 }
2371
2372 return results;
2373 }
2374
2375 var TOUCH_INPUT_MAP = {
2376 touchstart: INPUT_START,
2377 touchmove: INPUT_MOVE,
2378 touchend: INPUT_END,
2379 touchcancel: INPUT_CANCEL
2380 };
2381 var TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel';
2382 /**
2383 * @private
2384 * Multi-user touch events input
2385 * @constructor
2386 * @extends Input
2387 */
2388
2389 var TouchInput =
2390 /*#__PURE__*/
2391 function (_Input) {
2392 _inheritsLoose(TouchInput, _Input);
2393
2394 function TouchInput() {
2395 var _this;
2396
2397 TouchInput.prototype.evTarget = TOUCH_TARGET_EVENTS;
2398 _this = _Input.apply(this, arguments) || this;
2399 _this.targetIds = {}; // this.evTarget = TOUCH_TARGET_EVENTS;
2400
2401 return _this;
2402 }
2403
2404 var _proto = TouchInput.prototype;
2405
2406 _proto.handler = function handler(ev) {
2407 var type = TOUCH_INPUT_MAP[ev.type];
2408 var touches = getTouches.call(this, ev, type);
2409
2410 if (!touches) {
2411 return;
2412 }
2413
2414 this.callback(this.manager, type, {
2415 pointers: touches[0],
2416 changedPointers: touches[1],
2417 pointerType: INPUT_TYPE_TOUCH,
2418 srcEvent: ev
2419 });
2420 };
2421
2422 return TouchInput;
2423 }(Input);
2424
2425 function getTouches(ev, type) {
2426 var allTouches = toArray$2(ev.touches);
2427 var targetIds = this.targetIds; // when there is only one touch, the process can be simplified
2428
2429 if (type & (INPUT_START | INPUT_MOVE) && allTouches.length === 1) {
2430 targetIds[allTouches[0].identifier] = true;
2431 return [allTouches, allTouches];
2432 }
2433
2434 var i;
2435 var targetTouches;
2436 var changedTouches = toArray$2(ev.changedTouches);
2437 var changedTargetTouches = [];
2438 var target = this.target; // get target touches from touches
2439
2440 targetTouches = allTouches.filter(function (touch) {
2441 return hasParent(touch.target, target);
2442 }); // collect touches
2443
2444 if (type === INPUT_START) {
2445 i = 0;
2446
2447 while (i < targetTouches.length) {
2448 targetIds[targetTouches[i].identifier] = true;
2449 i++;
2450 }
2451 } // filter changed touches to only contain touches that exist in the collected target ids
2452
2453
2454 i = 0;
2455
2456 while (i < changedTouches.length) {
2457 if (targetIds[changedTouches[i].identifier]) {
2458 changedTargetTouches.push(changedTouches[i]);
2459 } // cleanup removed touches
2460
2461
2462 if (type & (INPUT_END | INPUT_CANCEL)) {
2463 delete targetIds[changedTouches[i].identifier];
2464 }
2465
2466 i++;
2467 }
2468
2469 if (!changedTargetTouches.length) {
2470 return;
2471 }
2472
2473 return [// merge targetTouches with changedTargetTouches so it contains ALL touches, including 'end' and 'cancel'
2474 uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true), changedTargetTouches];
2475 }
2476
2477 var MOUSE_INPUT_MAP = {
2478 mousedown: INPUT_START,
2479 mousemove: INPUT_MOVE,
2480 mouseup: INPUT_END
2481 };
2482 var MOUSE_ELEMENT_EVENTS = 'mousedown';
2483 var MOUSE_WINDOW_EVENTS = 'mousemove mouseup';
2484 /**
2485 * @private
2486 * Mouse events input
2487 * @constructor
2488 * @extends Input
2489 */
2490
2491 var MouseInput =
2492 /*#__PURE__*/
2493 function (_Input) {
2494 _inheritsLoose(MouseInput, _Input);
2495
2496 function MouseInput() {
2497 var _this;
2498
2499 var proto = MouseInput.prototype;
2500 proto.evEl = MOUSE_ELEMENT_EVENTS;
2501 proto.evWin = MOUSE_WINDOW_EVENTS;
2502 _this = _Input.apply(this, arguments) || this;
2503 _this.pressed = false; // mousedown state
2504
2505 return _this;
2506 }
2507 /**
2508 * @private
2509 * handle mouse events
2510 * @param {Object} ev
2511 */
2512
2513
2514 var _proto = MouseInput.prototype;
2515
2516 _proto.handler = function handler(ev) {
2517 var eventType = MOUSE_INPUT_MAP[ev.type]; // on start we want to have the left mouse button down
2518
2519 if (eventType & INPUT_START && ev.button === 0) {
2520 this.pressed = true;
2521 }
2522
2523 if (eventType & INPUT_MOVE && ev.which !== 1) {
2524 eventType = INPUT_END;
2525 } // mouse must be down
2526
2527
2528 if (!this.pressed) {
2529 return;
2530 }
2531
2532 if (eventType & INPUT_END) {
2533 this.pressed = false;
2534 }
2535
2536 this.callback(this.manager, eventType, {
2537 pointers: [ev],
2538 changedPointers: [ev],
2539 pointerType: INPUT_TYPE_MOUSE,
2540 srcEvent: ev
2541 });
2542 };
2543
2544 return MouseInput;
2545 }(Input);
2546
2547 /**
2548 * @private
2549 * Combined touch and mouse input
2550 *
2551 * Touch has a higher priority then mouse, and while touching no mouse events are allowed.
2552 * This because touch devices also emit mouse events while doing a touch.
2553 *
2554 * @constructor
2555 * @extends Input
2556 */
2557
2558 var DEDUP_TIMEOUT = 2500;
2559 var DEDUP_DISTANCE = 25;
2560
2561 function setLastTouch(eventData) {
2562 var _eventData$changedPoi = eventData.changedPointers,
2563 touch = _eventData$changedPoi[0];
2564
2565 if (touch.identifier === this.primaryTouch) {
2566 var lastTouch = {
2567 x: touch.clientX,
2568 y: touch.clientY
2569 };
2570 var lts = this.lastTouches;
2571 this.lastTouches.push(lastTouch);
2572
2573 var removeLastTouch = function removeLastTouch() {
2574 var i = lts.indexOf(lastTouch);
2575
2576 if (i > -1) {
2577 lts.splice(i, 1);
2578 }
2579 };
2580
2581 setTimeout(removeLastTouch, DEDUP_TIMEOUT);
2582 }
2583 }
2584
2585 function recordTouches(eventType, eventData) {
2586 if (eventType & INPUT_START) {
2587 this.primaryTouch = eventData.changedPointers[0].identifier;
2588 setLastTouch.call(this, eventData);
2589 } else if (eventType & (INPUT_END | INPUT_CANCEL)) {
2590 setLastTouch.call(this, eventData);
2591 }
2592 }
2593
2594 function isSyntheticEvent(eventData) {
2595 var x = eventData.srcEvent.clientX;
2596 var y = eventData.srcEvent.clientY;
2597
2598 for (var i = 0; i < this.lastTouches.length; i++) {
2599 var t = this.lastTouches[i];
2600 var dx = Math.abs(x - t.x);
2601 var dy = Math.abs(y - t.y);
2602
2603 if (dx <= DEDUP_DISTANCE && dy <= DEDUP_DISTANCE) {
2604 return true;
2605 }
2606 }
2607
2608 return false;
2609 }
2610
2611 var TouchMouseInput =
2612 /*#__PURE__*/
2613 function () {
2614 var TouchMouseInput =
2615 /*#__PURE__*/
2616 function (_Input) {
2617 _inheritsLoose(TouchMouseInput, _Input);
2618
2619 function TouchMouseInput(_manager, callback) {
2620 var _this;
2621
2622 _this = _Input.call(this, _manager, callback) || this;
2623
2624 _this.handler = function (manager, inputEvent, inputData) {
2625 var isTouch = inputData.pointerType === INPUT_TYPE_TOUCH;
2626 var isMouse = inputData.pointerType === INPUT_TYPE_MOUSE;
2627
2628 if (isMouse && inputData.sourceCapabilities && inputData.sourceCapabilities.firesTouchEvents) {
2629 return;
2630 } // when we're in a touch event, record touches to de-dupe synthetic mouse event
2631
2632
2633 if (isTouch) {
2634 recordTouches.call(_assertThisInitialized(_assertThisInitialized(_this)), inputEvent, inputData);
2635 } else if (isMouse && isSyntheticEvent.call(_assertThisInitialized(_assertThisInitialized(_this)), inputData)) {
2636 return;
2637 }
2638
2639 _this.callback(manager, inputEvent, inputData);
2640 };
2641
2642 _this.touch = new TouchInput(_this.manager, _this.handler);
2643 _this.mouse = new MouseInput(_this.manager, _this.handler);
2644 _this.primaryTouch = null;
2645 _this.lastTouches = [];
2646 return _this;
2647 }
2648 /**
2649 * @private
2650 * handle mouse and touch events
2651 * @param {Hammer} manager
2652 * @param {String} inputEvent
2653 * @param {Object} inputData
2654 */
2655
2656
2657 var _proto = TouchMouseInput.prototype;
2658
2659 /**
2660 * @private
2661 * remove the event listeners
2662 */
2663 _proto.destroy = function destroy() {
2664 this.touch.destroy();
2665 this.mouse.destroy();
2666 };
2667
2668 return TouchMouseInput;
2669 }(Input);
2670
2671 return TouchMouseInput;
2672 }();
2673
2674 /**
2675 * @private
2676 * create new input type manager
2677 * called by the Manager constructor
2678 * @param {Hammer} manager
2679 * @returns {Input}
2680 */
2681
2682 function createInputInstance(manager) {
2683 var Type; // let inputClass = manager.options.inputClass;
2684
2685 var inputClass = manager.options.inputClass;
2686
2687 if (inputClass) {
2688 Type = inputClass;
2689 } else if (SUPPORT_POINTER_EVENTS$1) {
2690 Type = PointerEventInput;
2691 } else if (SUPPORT_ONLY_TOUCH) {
2692 Type = TouchInput;
2693 } else if (!SUPPORT_TOUCH$1) {
2694 Type = MouseInput;
2695 } else {
2696 Type = TouchMouseInput;
2697 }
2698
2699 return new Type(manager, inputHandler);
2700 }
2701
2702 /**
2703 * @private
2704 * if the argument is an array, we want to execute the fn on each entry
2705 * if it aint an array we don't want to do a thing.
2706 * this is used by all the methods that accept a single and array argument.
2707 * @param {*|Array} arg
2708 * @param {String} fn
2709 * @param {Object} [context]
2710 * @returns {Boolean}
2711 */
2712
2713 function invokeArrayArg(arg, fn, context) {
2714 if (Array.isArray(arg)) {
2715 each(arg, context[fn], context);
2716 return true;
2717 }
2718
2719 return false;
2720 }
2721
2722 var STATE_POSSIBLE = 1;
2723 var STATE_BEGAN = 2;
2724 var STATE_CHANGED = 4;
2725 var STATE_ENDED = 8;
2726 var STATE_RECOGNIZED = STATE_ENDED;
2727 var STATE_CANCELLED = 16;
2728 var STATE_FAILED = 32;
2729
2730 /**
2731 * @private
2732 * get a unique id
2733 * @returns {number} uniqueId
2734 */
2735 var _uniqueId = 1;
2736 function uniqueId() {
2737 return _uniqueId++;
2738 }
2739
2740 /**
2741 * @private
2742 * get a recognizer by name if it is bound to a manager
2743 * @param {Recognizer|String} otherRecognizer
2744 * @param {Recognizer} recognizer
2745 * @returns {Recognizer}
2746 */
2747 function getRecognizerByNameIfManager(otherRecognizer, recognizer) {
2748 var manager = recognizer.manager;
2749
2750 if (manager) {
2751 return manager.get(otherRecognizer);
2752 }
2753
2754 return otherRecognizer;
2755 }
2756
2757 /**
2758 * @private
2759 * get a usable string, used as event postfix
2760 * @param {constant} state
2761 * @returns {String} state
2762 */
2763
2764 function stateStr(state) {
2765 if (state & STATE_CANCELLED) {
2766 return 'cancel';
2767 } else if (state & STATE_ENDED) {
2768 return 'end';
2769 } else if (state & STATE_CHANGED) {
2770 return 'move';
2771 } else if (state & STATE_BEGAN) {
2772 return 'start';
2773 }
2774
2775 return '';
2776 }
2777
2778 /**
2779 * @private
2780 * Recognizer flow explained; *
2781 * All recognizers have the initial state of POSSIBLE when a input session starts.
2782 * The definition of a input session is from the first input until the last input, with all it's movement in it. *
2783 * Example session for mouse-input: mousedown -> mousemove -> mouseup
2784 *
2785 * On each recognizing cycle (see Manager.recognize) the .recognize() method is executed
2786 * which determines with state it should be.
2787 *
2788 * If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to
2789 * POSSIBLE to give it another change on the next cycle.
2790 *
2791 * Possible
2792 * |
2793 * +-----+---------------+
2794 * | |
2795 * +-----+-----+ |
2796 * | | |
2797 * Failed Cancelled |
2798 * +-------+------+
2799 * | |
2800 * Recognized Began
2801 * |
2802 * Changed
2803 * |
2804 * Ended/Recognized
2805 */
2806
2807 /**
2808 * @private
2809 * Recognizer
2810 * Every recognizer needs to extend from this class.
2811 * @constructor
2812 * @param {Object} options
2813 */
2814
2815 var Recognizer =
2816 /*#__PURE__*/
2817 function () {
2818 function Recognizer(options) {
2819 if (options === void 0) {
2820 options = {};
2821 }
2822
2823 this.options = _extends({
2824 enable: true
2825 }, options);
2826 this.id = uniqueId();
2827 this.manager = null; // default is enable true
2828
2829 this.state = STATE_POSSIBLE;
2830 this.simultaneous = {};
2831 this.requireFail = [];
2832 }
2833 /**
2834 * @private
2835 * set options
2836 * @param {Object} options
2837 * @return {Recognizer}
2838 */
2839
2840
2841 var _proto = Recognizer.prototype;
2842
2843 _proto.set = function set(options) {
2844 assign$1(this.options, options); // also update the touchAction, in case something changed about the directions/enabled state
2845
2846 this.manager && this.manager.touchAction.update();
2847 return this;
2848 };
2849 /**
2850 * @private
2851 * recognize simultaneous with an other recognizer.
2852 * @param {Recognizer} otherRecognizer
2853 * @returns {Recognizer} this
2854 */
2855
2856
2857 _proto.recognizeWith = function recognizeWith(otherRecognizer) {
2858 if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) {
2859 return this;
2860 }
2861
2862 var simultaneous = this.simultaneous;
2863 otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
2864
2865 if (!simultaneous[otherRecognizer.id]) {
2866 simultaneous[otherRecognizer.id] = otherRecognizer;
2867 otherRecognizer.recognizeWith(this);
2868 }
2869
2870 return this;
2871 };
2872 /**
2873 * @private
2874 * drop the simultaneous link. it doesnt remove the link on the other recognizer.
2875 * @param {Recognizer} otherRecognizer
2876 * @returns {Recognizer} this
2877 */
2878
2879
2880 _proto.dropRecognizeWith = function dropRecognizeWith(otherRecognizer) {
2881 if (invokeArrayArg(otherRecognizer, 'dropRecognizeWith', this)) {
2882 return this;
2883 }
2884
2885 otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
2886 delete this.simultaneous[otherRecognizer.id];
2887 return this;
2888 };
2889 /**
2890 * @private
2891 * recognizer can only run when an other is failing
2892 * @param {Recognizer} otherRecognizer
2893 * @returns {Recognizer} this
2894 */
2895
2896
2897 _proto.requireFailure = function requireFailure(otherRecognizer) {
2898 if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) {
2899 return this;
2900 }
2901
2902 var requireFail = this.requireFail;
2903 otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
2904
2905 if (inArray(requireFail, otherRecognizer) === -1) {
2906 requireFail.push(otherRecognizer);
2907 otherRecognizer.requireFailure(this);
2908 }
2909
2910 return this;
2911 };
2912 /**
2913 * @private
2914 * drop the requireFailure link. it does not remove the link on the other recognizer.
2915 * @param {Recognizer} otherRecognizer
2916 * @returns {Recognizer} this
2917 */
2918
2919
2920 _proto.dropRequireFailure = function dropRequireFailure(otherRecognizer) {
2921 if (invokeArrayArg(otherRecognizer, 'dropRequireFailure', this)) {
2922 return this;
2923 }
2924
2925 otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
2926 var index = inArray(this.requireFail, otherRecognizer);
2927
2928 if (index > -1) {
2929 this.requireFail.splice(index, 1);
2930 }
2931
2932 return this;
2933 };
2934 /**
2935 * @private
2936 * has require failures boolean
2937 * @returns {boolean}
2938 */
2939
2940
2941 _proto.hasRequireFailures = function hasRequireFailures() {
2942 return this.requireFail.length > 0;
2943 };
2944 /**
2945 * @private
2946 * if the recognizer can recognize simultaneous with an other recognizer
2947 * @param {Recognizer} otherRecognizer
2948 * @returns {Boolean}
2949 */
2950
2951
2952 _proto.canRecognizeWith = function canRecognizeWith(otherRecognizer) {
2953 return !!this.simultaneous[otherRecognizer.id];
2954 };
2955 /**
2956 * @private
2957 * You should use `tryEmit` instead of `emit` directly to check
2958 * that all the needed recognizers has failed before emitting.
2959 * @param {Object} input
2960 */
2961
2962
2963 _proto.emit = function emit(input) {
2964 var self = this;
2965 var state = this.state;
2966
2967 function emit(event) {
2968 self.manager.emit(event, input);
2969 } // 'panstart' and 'panmove'
2970
2971
2972 if (state < STATE_ENDED) {
2973 emit(self.options.event + stateStr(state));
2974 }
2975
2976 emit(self.options.event); // simple 'eventName' events
2977
2978 if (input.additionalEvent) {
2979 // additional event(panleft, panright, pinchin, pinchout...)
2980 emit(input.additionalEvent);
2981 } // panend and pancancel
2982
2983
2984 if (state >= STATE_ENDED) {
2985 emit(self.options.event + stateStr(state));
2986 }
2987 };
2988 /**
2989 * @private
2990 * Check that all the require failure recognizers has failed,
2991 * if true, it emits a gesture event,
2992 * otherwise, setup the state to FAILED.
2993 * @param {Object} input
2994 */
2995
2996
2997 _proto.tryEmit = function tryEmit(input) {
2998 if (this.canEmit()) {
2999 return this.emit(input);
3000 } // it's failing anyway
3001
3002
3003 this.state = STATE_FAILED;
3004 };
3005 /**
3006 * @private
3007 * can we emit?
3008 * @returns {boolean}
3009 */
3010
3011
3012 _proto.canEmit = function canEmit() {
3013 var i = 0;
3014
3015 while (i < this.requireFail.length) {
3016 if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) {
3017 return false;
3018 }
3019
3020 i++;
3021 }
3022
3023 return true;
3024 };
3025 /**
3026 * @private
3027 * update the recognizer
3028 * @param {Object} inputData
3029 */
3030
3031
3032 _proto.recognize = function recognize(inputData) {
3033 // make a new copy of the inputData
3034 // so we can change the inputData without messing up the other recognizers
3035 var inputDataClone = assign$1({}, inputData); // is is enabled and allow recognizing?
3036
3037 if (!boolOrFn(this.options.enable, [this, inputDataClone])) {
3038 this.reset();
3039 this.state = STATE_FAILED;
3040 return;
3041 } // reset when we've reached the end
3042
3043
3044 if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) {
3045 this.state = STATE_POSSIBLE;
3046 }
3047
3048 this.state = this.process(inputDataClone); // the recognizer has recognized a gesture
3049 // so trigger an event
3050
3051 if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) {
3052 this.tryEmit(inputDataClone);
3053 }
3054 };
3055 /**
3056 * @private
3057 * return the state of the recognizer
3058 * the actual recognizing happens in this method
3059 * @virtual
3060 * @param {Object} inputData
3061 * @returns {constant} STATE
3062 */
3063
3064 /* jshint ignore:start */
3065
3066
3067 _proto.process = function process(inputData) {};
3068 /* jshint ignore:end */
3069
3070 /**
3071 * @private
3072 * return the preferred touch-action
3073 * @virtual
3074 * @returns {Array}
3075 */
3076
3077
3078 _proto.getTouchAction = function getTouchAction() {};
3079 /**
3080 * @private
3081 * called when the gesture isn't allowed to recognize
3082 * like when another is being recognized or it is disabled
3083 * @virtual
3084 */
3085
3086
3087 _proto.reset = function reset() {};
3088
3089 return Recognizer;
3090 }();
3091
3092 /**
3093 * @private
3094 * A tap is recognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur
3095 * between the given interval and position. The delay option can be used to recognize multi-taps without firing
3096 * a single tap.
3097 *
3098 * The eventData from the emitted event contains the property `tapCount`, which contains the amount of
3099 * multi-taps being recognized.
3100 * @constructor
3101 * @extends Recognizer
3102 */
3103
3104 var TapRecognizer =
3105 /*#__PURE__*/
3106 function (_Recognizer) {
3107 _inheritsLoose(TapRecognizer, _Recognizer);
3108
3109 function TapRecognizer(options) {
3110 var _this;
3111
3112 if (options === void 0) {
3113 options = {};
3114 }
3115
3116 _this = _Recognizer.call(this, _extends({
3117 event: 'tap',
3118 pointers: 1,
3119 taps: 1,
3120 interval: 300,
3121 // max time between the multi-tap taps
3122 time: 250,
3123 // max time of the pointer to be down (like finger on the screen)
3124 threshold: 9,
3125 // a minimal movement is ok, but keep it low
3126 posThreshold: 10
3127 }, options)) || this; // previous time and center,
3128 // used for tap counting
3129
3130 _this.pTime = false;
3131 _this.pCenter = false;
3132 _this._timer = null;
3133 _this._input = null;
3134 _this.count = 0;
3135 return _this;
3136 }
3137
3138 var _proto = TapRecognizer.prototype;
3139
3140 _proto.getTouchAction = function getTouchAction() {
3141 return [TOUCH_ACTION_MANIPULATION];
3142 };
3143
3144 _proto.process = function process(input) {
3145 var _this2 = this;
3146
3147 var options = this.options;
3148 var validPointers = input.pointers.length === options.pointers;
3149 var validMovement = input.distance < options.threshold;
3150 var validTouchTime = input.deltaTime < options.time;
3151 this.reset();
3152
3153 if (input.eventType & INPUT_START && this.count === 0) {
3154 return this.failTimeout();
3155 } // we only allow little movement
3156 // and we've reached an end event, so a tap is possible
3157
3158
3159 if (validMovement && validTouchTime && validPointers) {
3160 if (input.eventType !== INPUT_END) {
3161 return this.failTimeout();
3162 }
3163
3164 var validInterval = this.pTime ? input.timeStamp - this.pTime < options.interval : true;
3165 var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold;
3166 this.pTime = input.timeStamp;
3167 this.pCenter = input.center;
3168
3169 if (!validMultiTap || !validInterval) {
3170 this.count = 1;
3171 } else {
3172 this.count += 1;
3173 }
3174
3175 this._input = input; // if tap count matches we have recognized it,
3176 // else it has began recognizing...
3177
3178 var tapCount = this.count % options.taps;
3179
3180 if (tapCount === 0) {
3181 // no failing requirements, immediately trigger the tap event
3182 // or wait as long as the multitap interval to trigger
3183 if (!this.hasRequireFailures()) {
3184 return STATE_RECOGNIZED;
3185 } else {
3186 this._timer = setTimeout(function () {
3187 _this2.state = STATE_RECOGNIZED;
3188
3189 _this2.tryEmit();
3190 }, options.interval);
3191 return STATE_BEGAN;
3192 }
3193 }
3194 }
3195
3196 return STATE_FAILED;
3197 };
3198
3199 _proto.failTimeout = function failTimeout() {
3200 var _this3 = this;
3201
3202 this._timer = setTimeout(function () {
3203 _this3.state = STATE_FAILED;
3204 }, this.options.interval);
3205 return STATE_FAILED;
3206 };
3207
3208 _proto.reset = function reset() {
3209 clearTimeout(this._timer);
3210 };
3211
3212 _proto.emit = function emit() {
3213 if (this.state === STATE_RECOGNIZED) {
3214 this._input.tapCount = this.count;
3215 this.manager.emit(this.options.event, this._input);
3216 }
3217 };
3218
3219 return TapRecognizer;
3220 }(Recognizer);
3221
3222 /**
3223 * @private
3224 * This recognizer is just used as a base for the simple attribute recognizers.
3225 * @constructor
3226 * @extends Recognizer
3227 */
3228
3229 var AttrRecognizer =
3230 /*#__PURE__*/
3231 function (_Recognizer) {
3232 _inheritsLoose(AttrRecognizer, _Recognizer);
3233
3234 function AttrRecognizer(options) {
3235 if (options === void 0) {
3236 options = {};
3237 }
3238
3239 return _Recognizer.call(this, _extends({
3240 pointers: 1
3241 }, options)) || this;
3242 }
3243 /**
3244 * @private
3245 * Used to check if it the recognizer receives valid input, like input.distance > 10.
3246 * @memberof AttrRecognizer
3247 * @param {Object} input
3248 * @returns {Boolean} recognized
3249 */
3250
3251
3252 var _proto = AttrRecognizer.prototype;
3253
3254 _proto.attrTest = function attrTest(input) {
3255 var optionPointers = this.options.pointers;
3256 return optionPointers === 0 || input.pointers.length === optionPointers;
3257 };
3258 /**
3259 * @private
3260 * Process the input and return the state for the recognizer
3261 * @memberof AttrRecognizer
3262 * @param {Object} input
3263 * @returns {*} State
3264 */
3265
3266
3267 _proto.process = function process(input) {
3268 var state = this.state;
3269 var eventType = input.eventType;
3270 var isRecognized = state & (STATE_BEGAN | STATE_CHANGED);
3271 var isValid = this.attrTest(input); // on cancel input and we've recognized before, return STATE_CANCELLED
3272
3273 if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) {
3274 return state | STATE_CANCELLED;
3275 } else if (isRecognized || isValid) {
3276 if (eventType & INPUT_END) {
3277 return state | STATE_ENDED;
3278 } else if (!(state & STATE_BEGAN)) {
3279 return STATE_BEGAN;
3280 }
3281
3282 return state | STATE_CHANGED;
3283 }
3284
3285 return STATE_FAILED;
3286 };
3287
3288 return AttrRecognizer;
3289 }(Recognizer);
3290
3291 /**
3292 * @private
3293 * direction cons to string
3294 * @param {constant} direction
3295 * @returns {String}
3296 */
3297
3298 function directionStr(direction) {
3299 if (direction === DIRECTION_DOWN) {
3300 return 'down';
3301 } else if (direction === DIRECTION_UP) {
3302 return 'up';
3303 } else if (direction === DIRECTION_LEFT) {
3304 return 'left';
3305 } else if (direction === DIRECTION_RIGHT) {
3306 return 'right';
3307 }
3308
3309 return '';
3310 }
3311
3312 /**
3313 * @private
3314 * Pan
3315 * Recognized when the pointer is down and moved in the allowed direction.
3316 * @constructor
3317 * @extends AttrRecognizer
3318 */
3319
3320 var PanRecognizer =
3321 /*#__PURE__*/
3322 function (_AttrRecognizer) {
3323 _inheritsLoose(PanRecognizer, _AttrRecognizer);
3324
3325 function PanRecognizer(options) {
3326 var _this;
3327
3328 if (options === void 0) {
3329 options = {};
3330 }
3331
3332 _this = _AttrRecognizer.call(this, _extends({
3333 event: 'pan',
3334 threshold: 10,
3335 pointers: 1,
3336 direction: DIRECTION_ALL
3337 }, options)) || this;
3338 _this.pX = null;
3339 _this.pY = null;
3340 return _this;
3341 }
3342
3343 var _proto = PanRecognizer.prototype;
3344
3345 _proto.getTouchAction = function getTouchAction() {
3346 var direction = this.options.direction;
3347 var actions = [];
3348
3349 if (direction & DIRECTION_HORIZONTAL) {
3350 actions.push(TOUCH_ACTION_PAN_Y);
3351 }
3352
3353 if (direction & DIRECTION_VERTICAL) {
3354 actions.push(TOUCH_ACTION_PAN_X);
3355 }
3356
3357 return actions;
3358 };
3359
3360 _proto.directionTest = function directionTest(input) {
3361 var options = this.options;
3362 var hasMoved = true;
3363 var distance = input.distance;
3364 var direction = input.direction;
3365 var x = input.deltaX;
3366 var y = input.deltaY; // lock to axis?
3367
3368 if (!(direction & options.direction)) {
3369 if (options.direction & DIRECTION_HORIZONTAL) {
3370 direction = x === 0 ? DIRECTION_NONE : x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
3371 hasMoved = x !== this.pX;
3372 distance = Math.abs(input.deltaX);
3373 } else {
3374 direction = y === 0 ? DIRECTION_NONE : y < 0 ? DIRECTION_UP : DIRECTION_DOWN;
3375 hasMoved = y !== this.pY;
3376 distance = Math.abs(input.deltaY);
3377 }
3378 }
3379
3380 input.direction = direction;
3381 return hasMoved && distance > options.threshold && direction & options.direction;
3382 };
3383
3384 _proto.attrTest = function attrTest(input) {
3385 return AttrRecognizer.prototype.attrTest.call(this, input) && ( // replace with a super call
3386 this.state & STATE_BEGAN || !(this.state & STATE_BEGAN) && this.directionTest(input));
3387 };
3388
3389 _proto.emit = function emit(input) {
3390 this.pX = input.deltaX;
3391 this.pY = input.deltaY;
3392 var direction = directionStr(input.direction);
3393
3394 if (direction) {
3395 input.additionalEvent = this.options.event + direction;
3396 }
3397
3398 _AttrRecognizer.prototype.emit.call(this, input);
3399 };
3400
3401 return PanRecognizer;
3402 }(AttrRecognizer);
3403
3404 /**
3405 * @private
3406 * Swipe
3407 * Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction.
3408 * @constructor
3409 * @extends AttrRecognizer
3410 */
3411
3412 var SwipeRecognizer =
3413 /*#__PURE__*/
3414 function (_AttrRecognizer) {
3415 _inheritsLoose(SwipeRecognizer, _AttrRecognizer);
3416
3417 function SwipeRecognizer(options) {
3418 if (options === void 0) {
3419 options = {};
3420 }
3421
3422 return _AttrRecognizer.call(this, _extends({
3423 event: 'swipe',
3424 threshold: 10,
3425 velocity: 0.3,
3426 direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL,
3427 pointers: 1
3428 }, options)) || this;
3429 }
3430
3431 var _proto = SwipeRecognizer.prototype;
3432
3433 _proto.getTouchAction = function getTouchAction() {
3434 return PanRecognizer.prototype.getTouchAction.call(this);
3435 };
3436
3437 _proto.attrTest = function attrTest(input) {
3438 var direction = this.options.direction;
3439 var velocity;
3440
3441 if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) {
3442 velocity = input.overallVelocity;
3443 } else if (direction & DIRECTION_HORIZONTAL) {
3444 velocity = input.overallVelocityX;
3445 } else if (direction & DIRECTION_VERTICAL) {
3446 velocity = input.overallVelocityY;
3447 }
3448
3449 return _AttrRecognizer.prototype.attrTest.call(this, input) && direction & input.offsetDirection && input.distance > this.options.threshold && input.maxPointers === this.options.pointers && abs(velocity) > this.options.velocity && input.eventType & INPUT_END;
3450 };
3451
3452 _proto.emit = function emit(input) {
3453 var direction = directionStr(input.offsetDirection);
3454
3455 if (direction) {
3456 this.manager.emit(this.options.event + direction, input);
3457 }
3458
3459 this.manager.emit(this.options.event, input);
3460 };
3461
3462 return SwipeRecognizer;
3463 }(AttrRecognizer);
3464
3465 /**
3466 * @private
3467 * Pinch
3468 * Recognized when two or more pointers are moving toward (zoom-in) or away from each other (zoom-out).
3469 * @constructor
3470 * @extends AttrRecognizer
3471 */
3472
3473 var PinchRecognizer =
3474 /*#__PURE__*/
3475 function (_AttrRecognizer) {
3476 _inheritsLoose(PinchRecognizer, _AttrRecognizer);
3477
3478 function PinchRecognizer(options) {
3479 if (options === void 0) {
3480 options = {};
3481 }
3482
3483 return _AttrRecognizer.call(this, _extends({
3484 event: 'pinch',
3485 threshold: 0,
3486 pointers: 2
3487 }, options)) || this;
3488 }
3489
3490 var _proto = PinchRecognizer.prototype;
3491
3492 _proto.getTouchAction = function getTouchAction() {
3493 return [TOUCH_ACTION_NONE];
3494 };
3495
3496 _proto.attrTest = function attrTest(input) {
3497 return _AttrRecognizer.prototype.attrTest.call(this, input) && (Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN);
3498 };
3499
3500 _proto.emit = function emit(input) {
3501 if (input.scale !== 1) {
3502 var inOut = input.scale < 1 ? 'in' : 'out';
3503 input.additionalEvent = this.options.event + inOut;
3504 }
3505
3506 _AttrRecognizer.prototype.emit.call(this, input);
3507 };
3508
3509 return PinchRecognizer;
3510 }(AttrRecognizer);
3511
3512 /**
3513 * @private
3514 * Rotate
3515 * Recognized when two or more pointer are moving in a circular motion.
3516 * @constructor
3517 * @extends AttrRecognizer
3518 */
3519
3520 var RotateRecognizer =
3521 /*#__PURE__*/
3522 function (_AttrRecognizer) {
3523 _inheritsLoose(RotateRecognizer, _AttrRecognizer);
3524
3525 function RotateRecognizer(options) {
3526 if (options === void 0) {
3527 options = {};
3528 }
3529
3530 return _AttrRecognizer.call(this, _extends({
3531 event: 'rotate',
3532 threshold: 0,
3533 pointers: 2
3534 }, options)) || this;
3535 }
3536
3537 var _proto = RotateRecognizer.prototype;
3538
3539 _proto.getTouchAction = function getTouchAction() {
3540 return [TOUCH_ACTION_NONE];
3541 };
3542
3543 _proto.attrTest = function attrTest(input) {
3544 return _AttrRecognizer.prototype.attrTest.call(this, input) && (Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN);
3545 };
3546
3547 return RotateRecognizer;
3548 }(AttrRecognizer);
3549
3550 /**
3551 * @private
3552 * Press
3553 * Recognized when the pointer is down for x ms without any movement.
3554 * @constructor
3555 * @extends Recognizer
3556 */
3557
3558 var PressRecognizer =
3559 /*#__PURE__*/
3560 function (_Recognizer) {
3561 _inheritsLoose(PressRecognizer, _Recognizer);
3562
3563 function PressRecognizer(options) {
3564 var _this;
3565
3566 if (options === void 0) {
3567 options = {};
3568 }
3569
3570 _this = _Recognizer.call(this, _extends({
3571 event: 'press',
3572 pointers: 1,
3573 time: 251,
3574 // minimal time of the pointer to be pressed
3575 threshold: 9
3576 }, options)) || this;
3577 _this._timer = null;
3578 _this._input = null;
3579 return _this;
3580 }
3581
3582 var _proto = PressRecognizer.prototype;
3583
3584 _proto.getTouchAction = function getTouchAction() {
3585 return [TOUCH_ACTION_AUTO];
3586 };
3587
3588 _proto.process = function process(input) {
3589 var _this2 = this;
3590
3591 var options = this.options;
3592 var validPointers = input.pointers.length === options.pointers;
3593 var validMovement = input.distance < options.threshold;
3594 var validTime = input.deltaTime > options.time;
3595 this._input = input; // we only allow little movement
3596 // and we've reached an end event, so a tap is possible
3597
3598 if (!validMovement || !validPointers || input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime) {
3599 this.reset();
3600 } else if (input.eventType & INPUT_START) {
3601 this.reset();
3602 this._timer = setTimeout(function () {
3603 _this2.state = STATE_RECOGNIZED;
3604
3605 _this2.tryEmit();
3606 }, options.time);
3607 } else if (input.eventType & INPUT_END) {
3608 return STATE_RECOGNIZED;
3609 }
3610
3611 return STATE_FAILED;
3612 };
3613
3614 _proto.reset = function reset() {
3615 clearTimeout(this._timer);
3616 };
3617
3618 _proto.emit = function emit(input) {
3619 if (this.state !== STATE_RECOGNIZED) {
3620 return;
3621 }
3622
3623 if (input && input.eventType & INPUT_END) {
3624 this.manager.emit(this.options.event + "up", input);
3625 } else {
3626 this._input.timeStamp = now();
3627 this.manager.emit(this.options.event, this._input);
3628 }
3629 };
3630
3631 return PressRecognizer;
3632 }(Recognizer);
3633
3634 var defaults = {
3635 /**
3636 * @private
3637 * set if DOM events are being triggered.
3638 * But this is slower and unused by simple implementations, so disabled by default.
3639 * @type {Boolean}
3640 * @default false
3641 */
3642 domEvents: false,
3643
3644 /**
3645 * @private
3646 * The value for the touchAction property/fallback.
3647 * When set to `compute` it will magically set the correct value based on the added recognizers.
3648 * @type {String}
3649 * @default compute
3650 */
3651 touchAction: TOUCH_ACTION_COMPUTE,
3652
3653 /**
3654 * @private
3655 * @type {Boolean}
3656 * @default true
3657 */
3658 enable: true,
3659
3660 /**
3661 * @private
3662 * EXPERIMENTAL FEATURE -- can be removed/changed
3663 * Change the parent input target element.
3664 * If Null, then it is being set the to main element.
3665 * @type {Null|EventTarget}
3666 * @default null
3667 */
3668 inputTarget: null,
3669
3670 /**
3671 * @private
3672 * force an input class
3673 * @type {Null|Function}
3674 * @default null
3675 */
3676 inputClass: null,
3677
3678 /**
3679 * @private
3680 * Some CSS properties can be used to improve the working of Hammer.
3681 * Add them to this method and they will be set when creating a new Manager.
3682 * @namespace
3683 */
3684 cssProps: {
3685 /**
3686 * @private
3687 * Disables text selection to improve the dragging gesture. Mainly for desktop browsers.
3688 * @type {String}
3689 * @default 'none'
3690 */
3691 userSelect: "none",
3692
3693 /**
3694 * @private
3695 * Disable the Windows Phone grippers when pressing an element.
3696 * @type {String}
3697 * @default 'none'
3698 */
3699 touchSelect: "none",
3700
3701 /**
3702 * @private
3703 * Disables the default callout shown when you touch and hold a touch target.
3704 * On iOS, when you touch and hold a touch target such as a link, Safari displays
3705 * a callout containing information about the link. This property allows you to disable that callout.
3706 * @type {String}
3707 * @default 'none'
3708 */
3709 touchCallout: "none",
3710
3711 /**
3712 * @private
3713 * Specifies whether zooming is enabled. Used by IE10>
3714 * @type {String}
3715 * @default 'none'
3716 */
3717 contentZooming: "none",
3718
3719 /**
3720 * @private
3721 * Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers.
3722 * @type {String}
3723 * @default 'none'
3724 */
3725 userDrag: "none",
3726
3727 /**
3728 * @private
3729 * Overrides the highlight color shown when the user taps a link or a JavaScript
3730 * clickable element in iOS. This property obeys the alpha value, if specified.
3731 * @type {String}
3732 * @default 'rgba(0,0,0,0)'
3733 */
3734 tapHighlightColor: "rgba(0,0,0,0)"
3735 }
3736 };
3737 /**
3738 * @private
3739 * Default recognizer setup when calling `Hammer()`
3740 * When creating a new Manager these will be skipped.
3741 * This is separated with other defaults because of tree-shaking.
3742 * @type {Array}
3743 */
3744
3745 var preset = [[RotateRecognizer, {
3746 enable: false
3747 }], [PinchRecognizer, {
3748 enable: false
3749 }, ['rotate']], [SwipeRecognizer, {
3750 direction: DIRECTION_HORIZONTAL
3751 }], [PanRecognizer, {
3752 direction: DIRECTION_HORIZONTAL
3753 }, ['swipe']], [TapRecognizer], [TapRecognizer, {
3754 event: 'doubletap',
3755 taps: 2
3756 }, ['tap']], [PressRecognizer]];
3757
3758 var STOP = 1;
3759 var FORCED_STOP = 2;
3760 /**
3761 * @private
3762 * add/remove the css properties as defined in manager.options.cssProps
3763 * @param {Manager} manager
3764 * @param {Boolean} add
3765 */
3766
3767 function toggleCssProps(manager, add) {
3768 var element = manager.element;
3769
3770 if (!element.style) {
3771 return;
3772 }
3773
3774 var prop;
3775 each(manager.options.cssProps, function (value, name) {
3776 prop = prefixed(element.style, name);
3777
3778 if (add) {
3779 manager.oldCssProps[prop] = element.style[prop];
3780 element.style[prop] = value;
3781 } else {
3782 element.style[prop] = manager.oldCssProps[prop] || "";
3783 }
3784 });
3785
3786 if (!add) {
3787 manager.oldCssProps = {};
3788 }
3789 }
3790 /**
3791 * @private
3792 * trigger dom event
3793 * @param {String} event
3794 * @param {Object} data
3795 */
3796
3797
3798 function triggerDomEvent(event, data) {
3799 var gestureEvent = document.createEvent("Event");
3800 gestureEvent.initEvent(event, true, true);
3801 gestureEvent.gesture = data;
3802 data.target.dispatchEvent(gestureEvent);
3803 }
3804 /**
3805 * @private
3806 * Manager
3807 * @param {HTMLElement} element
3808 * @param {Object} [options]
3809 * @constructor
3810 */
3811
3812
3813 var Manager =
3814 /*#__PURE__*/
3815 function () {
3816 function Manager(element, options) {
3817 var _this = this;
3818
3819 this.options = assign$1({}, defaults, options || {});
3820 this.options.inputTarget = this.options.inputTarget || element;
3821 this.handlers = {};
3822 this.session = {};
3823 this.recognizers = [];
3824 this.oldCssProps = {};
3825 this.element = element;
3826 this.input = createInputInstance(this);
3827 this.touchAction = new TouchAction(this, this.options.touchAction);
3828 toggleCssProps(this, true);
3829 each(this.options.recognizers, function (item) {
3830 var recognizer = _this.add(new item[0](item[1]));
3831
3832 item[2] && recognizer.recognizeWith(item[2]);
3833 item[3] && recognizer.requireFailure(item[3]);
3834 }, this);
3835 }
3836 /**
3837 * @private
3838 * set options
3839 * @param {Object} options
3840 * @returns {Manager}
3841 */
3842
3843
3844 var _proto = Manager.prototype;
3845
3846 _proto.set = function set(options) {
3847 assign$1(this.options, options); // Options that need a little more setup
3848
3849 if (options.touchAction) {
3850 this.touchAction.update();
3851 }
3852
3853 if (options.inputTarget) {
3854 // Clean up existing event listeners and reinitialize
3855 this.input.destroy();
3856 this.input.target = options.inputTarget;
3857 this.input.init();
3858 }
3859
3860 return this;
3861 };
3862 /**
3863 * @private
3864 * stop recognizing for this session.
3865 * This session will be discarded, when a new [input]start event is fired.
3866 * When forced, the recognizer cycle is stopped immediately.
3867 * @param {Boolean} [force]
3868 */
3869
3870
3871 _proto.stop = function stop(force) {
3872 this.session.stopped = force ? FORCED_STOP : STOP;
3873 };
3874 /**
3875 * @private
3876 * run the recognizers!
3877 * called by the inputHandler function on every movement of the pointers (touches)
3878 * it walks through all the recognizers and tries to detect the gesture that is being made
3879 * @param {Object} inputData
3880 */
3881
3882
3883 _proto.recognize = function recognize(inputData) {
3884 var session = this.session;
3885
3886 if (session.stopped) {
3887 return;
3888 } // run the touch-action polyfill
3889
3890
3891 this.touchAction.preventDefaults(inputData);
3892 var recognizer;
3893 var recognizers = this.recognizers; // this holds the recognizer that is being recognized.
3894 // so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED
3895 // if no recognizer is detecting a thing, it is set to `null`
3896
3897 var curRecognizer = session.curRecognizer; // reset when the last recognizer is recognized
3898 // or when we're in a new session
3899
3900 if (!curRecognizer || curRecognizer && curRecognizer.state & STATE_RECOGNIZED) {
3901 session.curRecognizer = null;
3902 curRecognizer = null;
3903 }
3904
3905 var i = 0;
3906
3907 while (i < recognizers.length) {
3908 recognizer = recognizers[i]; // find out if we are allowed try to recognize the input for this one.
3909 // 1. allow if the session is NOT forced stopped (see the .stop() method)
3910 // 2. allow if we still haven't recognized a gesture in this session, or the this recognizer is the one
3911 // that is being recognized.
3912 // 3. allow if the recognizer is allowed to run simultaneous with the current recognized recognizer.
3913 // this can be setup with the `recognizeWith()` method on the recognizer.
3914
3915 if (session.stopped !== FORCED_STOP && ( // 1
3916 !curRecognizer || recognizer === curRecognizer || // 2
3917 recognizer.canRecognizeWith(curRecognizer))) {
3918 // 3
3919 recognizer.recognize(inputData);
3920 } else {
3921 recognizer.reset();
3922 } // if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the
3923 // current active recognizer. but only if we don't already have an active recognizer
3924
3925
3926 if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) {
3927 session.curRecognizer = recognizer;
3928 curRecognizer = recognizer;
3929 }
3930
3931 i++;
3932 }
3933 };
3934 /**
3935 * @private
3936 * get a recognizer by its event name.
3937 * @param {Recognizer|String} recognizer
3938 * @returns {Recognizer|Null}
3939 */
3940
3941
3942 _proto.get = function get(recognizer) {
3943 if (recognizer instanceof Recognizer) {
3944 return recognizer;
3945 }
3946
3947 var recognizers = this.recognizers;
3948
3949 for (var i = 0; i < recognizers.length; i++) {
3950 if (recognizers[i].options.event === recognizer) {
3951 return recognizers[i];
3952 }
3953 }
3954
3955 return null;
3956 };
3957 /**
3958 * @private add a recognizer to the manager
3959 * existing recognizers with the same event name will be removed
3960 * @param {Recognizer} recognizer
3961 * @returns {Recognizer|Manager}
3962 */
3963
3964
3965 _proto.add = function add(recognizer) {
3966 if (invokeArrayArg(recognizer, "add", this)) {
3967 return this;
3968 } // remove existing
3969
3970
3971 var existing = this.get(recognizer.options.event);
3972
3973 if (existing) {
3974 this.remove(existing);
3975 }
3976
3977 this.recognizers.push(recognizer);
3978 recognizer.manager = this;
3979 this.touchAction.update();
3980 return recognizer;
3981 };
3982 /**
3983 * @private
3984 * remove a recognizer by name or instance
3985 * @param {Recognizer|String} recognizer
3986 * @returns {Manager}
3987 */
3988
3989
3990 _proto.remove = function remove(recognizer) {
3991 if (invokeArrayArg(recognizer, "remove", this)) {
3992 return this;
3993 }
3994
3995 var targetRecognizer = this.get(recognizer); // let's make sure this recognizer exists
3996
3997 if (recognizer) {
3998 var recognizers = this.recognizers;
3999 var index = inArray(recognizers, targetRecognizer);
4000
4001 if (index !== -1) {
4002 recognizers.splice(index, 1);
4003 this.touchAction.update();
4004 }
4005 }
4006
4007 return this;
4008 };
4009 /**
4010 * @private
4011 * bind event
4012 * @param {String} events
4013 * @param {Function} handler
4014 * @returns {EventEmitter} this
4015 */
4016
4017
4018 _proto.on = function on(events, handler) {
4019 if (events === undefined || handler === undefined) {
4020 return this;
4021 }
4022
4023 var handlers = this.handlers;
4024 each(splitStr(events), function (event) {
4025 handlers[event] = handlers[event] || [];
4026 handlers[event].push(handler);
4027 });
4028 return this;
4029 };
4030 /**
4031 * @private unbind event, leave emit blank to remove all handlers
4032 * @param {String} events
4033 * @param {Function} [handler]
4034 * @returns {EventEmitter} this
4035 */
4036
4037
4038 _proto.off = function off(events, handler) {
4039 if (events === undefined) {
4040 return this;
4041 }
4042
4043 var handlers = this.handlers;
4044 each(splitStr(events), function (event) {
4045 if (!handler) {
4046 delete handlers[event];
4047 } else {
4048 handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1);
4049 }
4050 });
4051 return this;
4052 };
4053 /**
4054 * @private emit event to the listeners
4055 * @param {String} event
4056 * @param {Object} data
4057 */
4058
4059
4060 _proto.emit = function emit(event, data) {
4061 // we also want to trigger dom events
4062 if (this.options.domEvents) {
4063 triggerDomEvent(event, data);
4064 } // no handlers, so skip it all
4065
4066
4067 var handlers = this.handlers[event] && this.handlers[event].slice();
4068
4069 if (!handlers || !handlers.length) {
4070 return;
4071 }
4072
4073 data.type = event;
4074
4075 data.preventDefault = function () {
4076 data.srcEvent.preventDefault();
4077 };
4078
4079 var i = 0;
4080
4081 while (i < handlers.length) {
4082 handlers[i](data);
4083 i++;
4084 }
4085 };
4086 /**
4087 * @private
4088 * destroy the manager and unbinds all events
4089 * it doesn't unbind dom events, that is the user own responsibility
4090 */
4091
4092
4093 _proto.destroy = function destroy() {
4094 this.element && toggleCssProps(this, false);
4095 this.handlers = {};
4096 this.session = {};
4097 this.input.destroy();
4098 this.element = null;
4099 };
4100
4101 return Manager;
4102 }();
4103
4104 var SINGLE_TOUCH_INPUT_MAP = {
4105 touchstart: INPUT_START,
4106 touchmove: INPUT_MOVE,
4107 touchend: INPUT_END,
4108 touchcancel: INPUT_CANCEL
4109 };
4110 var SINGLE_TOUCH_TARGET_EVENTS = 'touchstart';
4111 var SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel';
4112 /**
4113 * @private
4114 * Touch events input
4115 * @constructor
4116 * @extends Input
4117 */
4118
4119 var SingleTouchInput =
4120 /*#__PURE__*/
4121 function (_Input) {
4122 _inheritsLoose(SingleTouchInput, _Input);
4123
4124 function SingleTouchInput() {
4125 var _this;
4126
4127 var proto = SingleTouchInput.prototype;
4128 proto.evTarget = SINGLE_TOUCH_TARGET_EVENTS;
4129 proto.evWin = SINGLE_TOUCH_WINDOW_EVENTS;
4130 _this = _Input.apply(this, arguments) || this;
4131 _this.started = false;
4132 return _this;
4133 }
4134
4135 var _proto = SingleTouchInput.prototype;
4136
4137 _proto.handler = function handler(ev) {
4138 var type = SINGLE_TOUCH_INPUT_MAP[ev.type]; // should we handle the touch events?
4139
4140 if (type === INPUT_START) {
4141 this.started = true;
4142 }
4143
4144 if (!this.started) {
4145 return;
4146 }
4147
4148 var touches = normalizeSingleTouches.call(this, ev, type); // when done, reset the started state
4149
4150 if (type & (INPUT_END | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) {
4151 this.started = false;
4152 }
4153
4154 this.callback(this.manager, type, {
4155 pointers: touches[0],
4156 changedPointers: touches[1],
4157 pointerType: INPUT_TYPE_TOUCH,
4158 srcEvent: ev
4159 });
4160 };
4161
4162 return SingleTouchInput;
4163 }(Input);
4164
4165 function normalizeSingleTouches(ev, type) {
4166 var all = toArray$2(ev.touches);
4167 var changed = toArray$2(ev.changedTouches);
4168
4169 if (type & (INPUT_END | INPUT_CANCEL)) {
4170 all = uniqueArray(all.concat(changed), 'identifier', true);
4171 }
4172
4173 return [all, changed];
4174 }
4175
4176 /**
4177 * @private
4178 * wrap a method with a deprecation warning and stack trace
4179 * @param {Function} method
4180 * @param {String} name
4181 * @param {String} message
4182 * @returns {Function} A new function wrapping the supplied method.
4183 */
4184 function deprecate(method, name, message) {
4185 var deprecationMessage = "DEPRECATED METHOD: " + name + "\n" + message + " AT \n";
4186 return function () {
4187 var e = new Error('get-stack-trace');
4188 var stack = e && e.stack ? e.stack.replace(/^[^\(]+?[\n$]/gm, '').replace(/^\s+at\s+/gm, '').replace(/^Object.<anonymous>\s*\(/gm, '{anonymous}()@') : 'Unknown Stack Trace';
4189 var log = window.console && (window.console.warn || window.console.log);
4190
4191 if (log) {
4192 log.call(window.console, deprecationMessage, stack);
4193 }
4194
4195 return method.apply(this, arguments);
4196 };
4197 }
4198
4199 /**
4200 * @private
4201 * extend object.
4202 * means that properties in dest will be overwritten by the ones in src.
4203 * @param {Object} dest
4204 * @param {Object} src
4205 * @param {Boolean} [merge=false]
4206 * @returns {Object} dest
4207 */
4208
4209 var extend = deprecate(function (dest, src, merge) {
4210 var keys = Object.keys(src);
4211 var i = 0;
4212
4213 while (i < keys.length) {
4214 if (!merge || merge && dest[keys[i]] === undefined) {
4215 dest[keys[i]] = src[keys[i]];
4216 }
4217
4218 i++;
4219 }
4220
4221 return dest;
4222 }, 'extend', 'Use `assign`.');
4223
4224 /**
4225 * @private
4226 * merge the values from src in the dest.
4227 * means that properties that exist in dest will not be overwritten by src
4228 * @param {Object} dest
4229 * @param {Object} src
4230 * @returns {Object} dest
4231 */
4232
4233 var merge = deprecate(function (dest, src) {
4234 return extend(dest, src, true);
4235 }, 'merge', 'Use `assign`.');
4236
4237 /**
4238 * @private
4239 * simple class inheritance
4240 * @param {Function} child
4241 * @param {Function} base
4242 * @param {Object} [properties]
4243 */
4244
4245 function inherit(child, base, properties) {
4246 var baseP = base.prototype;
4247 var childP;
4248 childP = child.prototype = Object.create(baseP);
4249 childP.constructor = child;
4250 childP._super = baseP;
4251
4252 if (properties) {
4253 assign$1(childP, properties);
4254 }
4255 }
4256
4257 /**
4258 * @private
4259 * simple function bind
4260 * @param {Function} fn
4261 * @param {Object} context
4262 * @returns {Function}
4263 */
4264 function bindFn(fn, context) {
4265 return function boundFn() {
4266 return fn.apply(context, arguments);
4267 };
4268 }
4269
4270 /**
4271 * @private
4272 * Simple way to create a manager with a default set of recognizers.
4273 * @param {HTMLElement} element
4274 * @param {Object} [options]
4275 * @constructor
4276 */
4277
4278 var Hammer =
4279 /*#__PURE__*/
4280 function () {
4281 var Hammer =
4282 /**
4283 * @private
4284 * @const {string}
4285 */
4286 function Hammer(element, options) {
4287 if (options === void 0) {
4288 options = {};
4289 }
4290
4291 return new Manager(element, _extends({
4292 recognizers: preset.concat()
4293 }, options));
4294 };
4295
4296 Hammer.VERSION = "2.0.17-rc";
4297 Hammer.DIRECTION_ALL = DIRECTION_ALL;
4298 Hammer.DIRECTION_DOWN = DIRECTION_DOWN;
4299 Hammer.DIRECTION_LEFT = DIRECTION_LEFT;
4300 Hammer.DIRECTION_RIGHT = DIRECTION_RIGHT;
4301 Hammer.DIRECTION_UP = DIRECTION_UP;
4302 Hammer.DIRECTION_HORIZONTAL = DIRECTION_HORIZONTAL;
4303 Hammer.DIRECTION_VERTICAL = DIRECTION_VERTICAL;
4304 Hammer.DIRECTION_NONE = DIRECTION_NONE;
4305 Hammer.DIRECTION_DOWN = DIRECTION_DOWN;
4306 Hammer.INPUT_START = INPUT_START;
4307 Hammer.INPUT_MOVE = INPUT_MOVE;
4308 Hammer.INPUT_END = INPUT_END;
4309 Hammer.INPUT_CANCEL = INPUT_CANCEL;
4310 Hammer.STATE_POSSIBLE = STATE_POSSIBLE;
4311 Hammer.STATE_BEGAN = STATE_BEGAN;
4312 Hammer.STATE_CHANGED = STATE_CHANGED;
4313 Hammer.STATE_ENDED = STATE_ENDED;
4314 Hammer.STATE_RECOGNIZED = STATE_RECOGNIZED;
4315 Hammer.STATE_CANCELLED = STATE_CANCELLED;
4316 Hammer.STATE_FAILED = STATE_FAILED;
4317 Hammer.Manager = Manager;
4318 Hammer.Input = Input;
4319 Hammer.TouchAction = TouchAction;
4320 Hammer.TouchInput = TouchInput;
4321 Hammer.MouseInput = MouseInput;
4322 Hammer.PointerEventInput = PointerEventInput;
4323 Hammer.TouchMouseInput = TouchMouseInput;
4324 Hammer.SingleTouchInput = SingleTouchInput;
4325 Hammer.Recognizer = Recognizer;
4326 Hammer.AttrRecognizer = AttrRecognizer;
4327 Hammer.Tap = TapRecognizer;
4328 Hammer.Pan = PanRecognizer;
4329 Hammer.Swipe = SwipeRecognizer;
4330 Hammer.Pinch = PinchRecognizer;
4331 Hammer.Rotate = RotateRecognizer;
4332 Hammer.Press = PressRecognizer;
4333 Hammer.on = addEventListeners;
4334 Hammer.off = removeEventListeners;
4335 Hammer.each = each;
4336 Hammer.merge = merge;
4337 Hammer.extend = extend;
4338 Hammer.bindFn = bindFn;
4339 Hammer.assign = assign$1;
4340 Hammer.inherit = inherit;
4341 Hammer.bindFn = bindFn;
4342 Hammer.prefixed = prefixed;
4343 Hammer.toArray = toArray$2;
4344 Hammer.inArray = inArray;
4345 Hammer.uniqueArray = uniqueArray;
4346 Hammer.splitStr = splitStr;
4347 Hammer.boolOrFn = boolOrFn;
4348 Hammer.hasParent = hasParent;
4349 Hammer.addEventListeners = addEventListeners;
4350 Hammer.removeEventListeners = removeEventListeners;
4351 Hammer.defaults = assign$1({}, defaults, {
4352 preset: preset
4353 });
4354 return Hammer;
4355 }();
4356
4357 // style loader but by script tag, not by the loader.
4358
4359 Hammer.defaults;
4360
4361 /*
4362 Copyright (c) 2015 NAVER Corp.
4363 name: @egjs/agent
4364 license: MIT
4365 author: NAVER Corp.
4366 repository: git+https://github.com/naver/agent.git
4367 version: 2.3.0
4368 */
4369 function some(arr, callback) {
4370 var length = arr.length;
4371
4372 for (var i = 0; i < length; ++i) {
4373 if (callback(arr[i], i)) {
4374 return true;
4375 }
4376 }
4377
4378 return false;
4379 }
4380 function find(arr, callback) {
4381 var length = arr.length;
4382
4383 for (var i = 0; i < length; ++i) {
4384 if (callback(arr[i], i)) {
4385 return arr[i];
4386 }
4387 }
4388
4389 return null;
4390 }
4391 function getUserAgent(agent) {
4392 var userAgent = agent;
4393
4394 if (typeof userAgent === "undefined") {
4395 if (typeof navigator === "undefined" || !navigator) {
4396 return "";
4397 }
4398
4399 userAgent = navigator.userAgent || "";
4400 }
4401
4402 return userAgent.toLowerCase();
4403 }
4404 function execRegExp(pattern, text) {
4405 try {
4406 return new RegExp(pattern, "g").exec(text);
4407 } catch (e) {
4408 return null;
4409 }
4410 }
4411 function hasUserAgentData() {
4412 if (typeof navigator === "undefined" || !navigator || !navigator.userAgentData) {
4413 return false;
4414 }
4415
4416 var userAgentData = navigator.userAgentData;
4417 var brands = userAgentData.brands || userAgentData.uaList;
4418 return !!(brands && brands.length);
4419 }
4420 function findVersion(versionTest, userAgent) {
4421 var result = execRegExp("(" + versionTest + ")((?:\\/|\\s|:)([0-9|\\.|_]+))", userAgent);
4422 return result ? result[3] : "";
4423 }
4424 function convertVersion(text) {
4425 return text.replace(/_/g, ".");
4426 }
4427 function findPreset(presets, userAgent) {
4428 var userPreset = null;
4429 var version = "-1";
4430 some(presets, function (preset) {
4431 var result = execRegExp("(" + preset.test + ")((?:\\/|\\s|:)([0-9|\\.|_]+))?", userAgent);
4432
4433 if (!result || preset.brand) {
4434 return false;
4435 }
4436
4437 userPreset = preset;
4438 version = result[3] || "-1";
4439
4440 if (preset.versionAlias) {
4441 version = preset.versionAlias;
4442 } else if (preset.versionTest) {
4443 version = findVersion(preset.versionTest.toLowerCase(), userAgent) || version;
4444 }
4445
4446 version = convertVersion(version);
4447 return true;
4448 });
4449 return {
4450 preset: userPreset,
4451 version: version
4452 };
4453 }
4454 function findPresetBrand(presets, brands) {
4455 var brandInfo = {
4456 brand: "",
4457 version: "-1"
4458 };
4459 some(presets, function (preset) {
4460 var result = findBrand(brands, preset);
4461
4462 if (!result) {
4463 return false;
4464 }
4465
4466 brandInfo.brand = preset.id;
4467 brandInfo.version = preset.versionAlias || result.version;
4468 return brandInfo.version !== "-1";
4469 });
4470 return brandInfo;
4471 }
4472 function findBrand(brands, preset) {
4473 return find(brands, function (_a) {
4474 var brand = _a.brand;
4475 return execRegExp("" + preset.test, brand.toLowerCase());
4476 });
4477 }
4478
4479 var BROWSER_PRESETS = [{
4480 test: "phantomjs",
4481 id: "phantomjs"
4482 }, {
4483 test: "whale",
4484 id: "whale"
4485 }, {
4486 test: "edgios|edge|edg",
4487 id: "edge"
4488 }, {
4489 test: "msie|trident|windows phone",
4490 id: "ie",
4491 versionTest: "iemobile|msie|rv"
4492 }, {
4493 test: "miuibrowser",
4494 id: "miui browser"
4495 }, {
4496 test: "samsungbrowser",
4497 id: "samsung internet"
4498 }, {
4499 test: "samsung",
4500 id: "samsung internet",
4501 versionTest: "version"
4502 }, {
4503 test: "chrome|crios",
4504 id: "chrome"
4505 }, {
4506 test: "firefox|fxios",
4507 id: "firefox"
4508 }, {
4509 test: "android",
4510 id: "android browser",
4511 versionTest: "version"
4512 }, {
4513 test: "safari|iphone|ipad|ipod",
4514 id: "safari",
4515 versionTest: "version"
4516 }]; // chromium's engine(blink) is based on applewebkit 537.36.
4517
4518 var CHROMIUM_PRESETS = [{
4519 test: "(?=.*applewebkit/(53[0-7]|5[0-2]|[0-4]))(?=.*\\schrome)",
4520 id: "chrome",
4521 versionTest: "chrome"
4522 }, {
4523 test: "chromium",
4524 id: "chrome"
4525 }, {
4526 test: "whale",
4527 id: "chrome",
4528 versionAlias: "-1",
4529 brand: true
4530 }];
4531 var WEBKIT_PRESETS = [{
4532 test: "applewebkit",
4533 id: "webkit",
4534 versionTest: "applewebkit|safari"
4535 }];
4536 var WEBVIEW_PRESETS = [{
4537 test: "(?=(iphone|ipad))(?!(.*version))",
4538 id: "webview"
4539 }, {
4540 test: "(?=(android|iphone|ipad))(?=.*(naver|daum|; wv))",
4541 id: "webview"
4542 }, {
4543 // test webview
4544 test: "webview",
4545 id: "webview"
4546 }];
4547 var OS_PRESETS = [{
4548 test: "windows phone",
4549 id: "windows phone"
4550 }, {
4551 test: "windows 2000",
4552 id: "window",
4553 versionAlias: "5.0"
4554 }, {
4555 test: "windows nt",
4556 id: "window"
4557 }, {
4558 test: "iphone|ipad|ipod",
4559 id: "ios",
4560 versionTest: "iphone os|cpu os"
4561 }, {
4562 test: "mac os x",
4563 id: "mac"
4564 }, {
4565 test: "android",
4566 id: "android"
4567 }, {
4568 test: "tizen",
4569 id: "tizen"
4570 }, {
4571 test: "webos|web0s",
4572 id: "webos"
4573 }];
4574
4575 function parseUserAgentData(osData) {
4576 var userAgentData = navigator.userAgentData;
4577 var brands = (userAgentData.uaList || userAgentData.brands).slice();
4578 var isMobile = userAgentData.mobile || false;
4579 var firstBrand = brands[0];
4580 var browser = {
4581 name: firstBrand.brand,
4582 version: firstBrand.version,
4583 majorVersion: -1,
4584 webkit: false,
4585 webkitVersion: "-1",
4586 chromium: false,
4587 chromiumVersion: "-1",
4588 webview: !!findPresetBrand(WEBVIEW_PRESETS, brands).brand
4589 };
4590 var os = {
4591 name: "unknown",
4592 version: "-1",
4593 majorVersion: -1
4594 };
4595 browser.webkit = !browser.chromium && some(WEBKIT_PRESETS, function (preset) {
4596 return findBrand(brands, preset);
4597 });
4598 var chromiumBrand = findPresetBrand(CHROMIUM_PRESETS, brands);
4599 browser.chromium = !!chromiumBrand.brand;
4600 browser.chromiumVersion = chromiumBrand.version;
4601
4602 if (!browser.chromium) {
4603 var webkitBrand = findPresetBrand(WEBKIT_PRESETS, brands);
4604 browser.webkit = !!webkitBrand.brand;
4605 browser.webkitVersion = webkitBrand.version;
4606 }
4607
4608 if (osData) {
4609 var platform_1 = osData.platform.toLowerCase();
4610 var result = find(OS_PRESETS, function (preset) {
4611 return new RegExp("" + preset.test, "g").exec(platform_1);
4612 });
4613 os.name = result ? result.id : platform_1;
4614 os.version = osData.platformVersion;
4615 }
4616
4617 var browserBrand = findPresetBrand(BROWSER_PRESETS, brands);
4618
4619 if (browserBrand.brand) {
4620 browser.name = browserBrand.brand;
4621 browser.version = osData ? osData.uaFullVersion : browserBrand.version;
4622 }
4623
4624 if (navigator.platform === "Linux armv8l") {
4625 os.name = "android";
4626 } else if (browser.webkit) {
4627 os.name = isMobile ? "ios" : "mac";
4628 }
4629
4630 if (os.name === "ios" && browser.webview) {
4631 browser.version = "-1";
4632 }
4633
4634 os.version = convertVersion(os.version);
4635 browser.version = convertVersion(browser.version);
4636 os.majorVersion = parseInt(os.version, 10);
4637 browser.majorVersion = parseInt(browser.version, 10);
4638 return {
4639 browser: browser,
4640 os: os,
4641 isMobile: isMobile,
4642 isHints: true
4643 };
4644 }
4645
4646 function parseUserAgent(userAgent) {
4647 var nextAgent = getUserAgent(userAgent);
4648 var isMobile = !!/mobi/g.exec(nextAgent);
4649 var browser = {
4650 name: "unknown",
4651 version: "-1",
4652 majorVersion: -1,
4653 webview: !!findPreset(WEBVIEW_PRESETS, nextAgent).preset,
4654 chromium: false,
4655 chromiumVersion: "-1",
4656 webkit: false,
4657 webkitVersion: "-1"
4658 };
4659 var os = {
4660 name: "unknown",
4661 version: "-1",
4662 majorVersion: -1
4663 };
4664
4665 var _a = findPreset(BROWSER_PRESETS, nextAgent),
4666 browserPreset = _a.preset,
4667 browserVersion = _a.version;
4668
4669 var _b = findPreset(OS_PRESETS, nextAgent),
4670 osPreset = _b.preset,
4671 osVersion = _b.version;
4672
4673 var chromiumPreset = findPreset(CHROMIUM_PRESETS, nextAgent);
4674 browser.chromium = !!chromiumPreset.preset;
4675 browser.chromiumVersion = chromiumPreset.version;
4676
4677 if (!browser.chromium) {
4678 var webkitPreset = findPreset(WEBKIT_PRESETS, nextAgent);
4679 browser.webkit = !!webkitPreset.preset;
4680 browser.webkitVersion = webkitPreset.version;
4681 }
4682
4683 if (osPreset) {
4684 os.name = osPreset.id;
4685 os.version = osVersion;
4686 os.majorVersion = parseInt(osVersion, 10);
4687 }
4688
4689 if (browserPreset) {
4690 browser.name = browserPreset.id;
4691 browser.version = browserVersion;
4692
4693 if (browser.webview && os.name === "ios" && browser.name !== "safari") {
4694 browser.webview = false;
4695 }
4696 }
4697
4698 browser.majorVersion = parseInt(browser.version, 10);
4699 return {
4700 browser: browser,
4701 os: os,
4702 isMobile: isMobile,
4703 isHints: false
4704 };
4705 }
4706 /**
4707 * Extracts browser and operating system information from the user agent string.
4708 * @ko 유저 에이전트 문자열에서 브라우저와 운영체제 정보를 추출한다.
4709 * @function eg.agent#agent
4710 * @param - user agent string to parse <ko>파싱할 유저에이전트 문자열</ko>
4711 * @return - agent Info <ko> 에이전트 정보 </ko>
4712 * @example
4713 import agent from "@egjs/agent";
4714 // eg.agent();
4715 const { os, browser, isMobile } = agent();
4716 */
4717
4718 function agent(userAgent) {
4719 if (typeof userAgent === "undefined" && hasUserAgentData()) {
4720 return parseUserAgentData();
4721 } else {
4722 return parseUserAgent(userAgent);
4723 }
4724 }
4725
4726 /*
4727 Copyright (c) NAVER Corp.
4728 name: @egjs/component
4729 license: MIT
4730 author: NAVER Corp.
4731 repository: https://github.com/naver/egjs-component
4732 version: 2.2.2
4733 */
4734 /*! *****************************************************************************
4735 Copyright (c) Microsoft Corporation.
4736
4737 Permission to use, copy, modify, and/or distribute this software for any
4738 purpose with or without fee is hereby granted.
4739
4740 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
4741 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
4742 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
4743 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
4744 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
4745 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
4746 PERFORMANCE OF THIS SOFTWARE.
4747 ***************************************************************************** */
4748 function __values$1(o) {
4749 var s = typeof Symbol === "function" && Symbol.iterator,
4750 m = s && o[s],
4751 i = 0;
4752 if (m) return m.call(o);
4753 if (o && typeof o.length === "number") return {
4754 next: function () {
4755 if (o && i >= o.length) o = void 0;
4756 return {
4757 value: o && o[i++],
4758 done: !o
4759 };
4760 }
4761 };
4762 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
4763 }
4764
4765 /*
4766 * Copyright (c) 2015 NAVER Corp.
4767 * egjs projects are licensed under the MIT license
4768 */
4769
4770 function isUndefined$1(value) {
4771 return typeof value === "undefined";
4772 }
4773 /**
4774 * A class used to manage events in a component
4775 * @ko 컴포넌트의 이벤트을 관리할 수 있게 하는 클래스
4776 * @alias eg.Component
4777 */
4778
4779
4780 var Component$1 =
4781 /*#__PURE__*/
4782 function () {
4783 /**
4784 * @support {"ie": "7+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.1+ (except 3.x)"}
4785 */
4786 function Component() {
4787 /**
4788 * @deprecated
4789 * @private
4790 */
4791 this.options = {};
4792 this._eventHandler = {};
4793 }
4794 /**
4795 * Triggers a custom event.
4796 * @ko 커스텀 이벤트를 발생시킨다
4797 * @param {string} eventName The name of the custom event to be triggered <ko>발생할 커스텀 이벤트의 이름</ko>
4798 * @param {object} customEvent Event data to be sent when triggering a custom event <ko>커스텀 이벤트가 발생할 때 전달할 데이터</ko>
4799 * @param {any[]} restParam Additional parameters when triggering a custom event <ko>커스텀 이벤트가 발생할 때 필요시 추가적으로 전달할 데이터</ko>
4800 * @return Indicates whether the event has occurred. If the stop() method is called by a custom event handler, it will return false and prevent the event from occurring. <a href="https://github.com/naver/egjs-component/wiki/How-to-make-Component-event-design%3F">Ref</a> <ko>이벤트 발생 여부. 커스텀 이벤트 핸들러에서 stop() 메서드를 호출하면 'false'를 반환하고 이벤트 발생을 중단한다. <a href="https://github.com/naver/egjs-component/wiki/How-to-make-Component-event-design%3F">참고</a></ko>
4801 * @example
4802 * ```
4803 * class Some extends eg.Component {
4804 * some(){
4805 * if(this.trigger("beforeHi")){ // When event call to stop return false.
4806 * this.trigger("hi");// fire hi event.
4807 * }
4808 * }
4809 * }
4810 *
4811 * const some = new Some();
4812 * some.on("beforeHi", (e) => {
4813 * if(condition){
4814 * e.stop(); // When event call to stop, `hi` event not call.
4815 * }
4816 * });
4817 * some.on("hi", (e) => {
4818 * // `currentTarget` is component instance.
4819 * console.log(some === e.currentTarget); // true
4820 * });
4821 * // If you want to more know event design. You can see article.
4822 * // https://github.com/naver/egjs-component/wiki/How-to-make-Component-event-design%3F
4823 * ```
4824 */
4825
4826
4827 var __proto = Component.prototype;
4828
4829 __proto.trigger = function (eventName) {
4830 var _this = this;
4831
4832 var params = [];
4833
4834 for (var _i = 1; _i < arguments.length; _i++) {
4835 params[_i - 1] = arguments[_i];
4836 }
4837
4838 var handlerList = this._eventHandler[eventName] || [];
4839 var hasHandlerList = handlerList.length > 0;
4840
4841 if (!hasHandlerList) {
4842 return true;
4843 }
4844
4845 var customEvent = params[0] || {};
4846 var restParams = params.slice(1); // If detach method call in handler in first time then handler list calls.
4847
4848 handlerList = handlerList.concat();
4849 var isCanceled = false; // This should be done like this to pass previous tests
4850
4851 customEvent.eventType = eventName;
4852
4853 customEvent.stop = function () {
4854 isCanceled = true;
4855 };
4856
4857 customEvent.currentTarget = this;
4858 var arg = [customEvent];
4859
4860 if (restParams.length >= 1) {
4861 arg = arg.concat(restParams);
4862 }
4863
4864 handlerList.forEach(function (handler) {
4865 handler.apply(_this, arg);
4866 });
4867 return !isCanceled;
4868 };
4869 /**
4870 * Executed event just one time.
4871 * @ko 이벤트가 한번만 실행된다.
4872 * @param {string} eventName The name of the event to be attached <ko>등록할 이벤트의 이름</ko>
4873 * @param {function} handlerToAttach The handler function of the event to be attached <ko>등록할 이벤트의 핸들러 함수</ko>
4874 * @return An instance of a component itself<ko>컴포넌트 자신의 인스턴스</ko>
4875 * @example
4876 * ```
4877 * class Some extends eg.Component {
4878 * hi() {
4879 * alert("hi");
4880 * }
4881 * thing() {
4882 * this.once("hi", this.hi);
4883 * }
4884 *
4885 * var some = new Some();
4886 * some.thing();
4887 * some.trigger("hi");
4888 * // fire alert("hi");
4889 * some.trigger("hi");
4890 * // Nothing happens
4891 * ```
4892 */
4893
4894
4895 __proto.once = function (eventName, handlerToAttach) {
4896 var _this = this;
4897
4898 if (typeof eventName === "object" && isUndefined$1(handlerToAttach)) {
4899 var eventHash = eventName;
4900
4901 for (var key in eventHash) {
4902 this.once(key, eventHash[key]);
4903 }
4904
4905 return this;
4906 } else if (typeof eventName === "string" && typeof handlerToAttach === "function") {
4907 var listener_1 = function () {
4908 var args = [];
4909
4910 for (var _i = 0; _i < arguments.length; _i++) {
4911 args[_i] = arguments[_i];
4912 }
4913
4914 handlerToAttach.apply(_this, args);
4915
4916 _this.off(eventName, listener_1);
4917 };
4918
4919 this.on(eventName, listener_1);
4920 }
4921
4922 return this;
4923 };
4924 /**
4925 * Checks whether an event has been attached to a component.
4926 * @ko 컴포넌트에 이벤트가 등록됐는지 확인한다.
4927 * @param {string} eventName The name of the event to be attached <ko>등록 여부를 확인할 이벤트의 이름</ko>
4928 * @return {boolean} Indicates whether the event is attached. <ko>이벤트 등록 여부</ko>
4929 * @example
4930 * ```
4931 * class Some extends eg.Component {
4932 * some() {
4933 * this.hasOn("hi");// check hi event.
4934 * }
4935 * }
4936 * ```
4937 */
4938
4939
4940 __proto.hasOn = function (eventName) {
4941 return !!this._eventHandler[eventName];
4942 };
4943 /**
4944 * Attaches an event to a component.
4945 * @ko 컴포넌트에 이벤트를 등록한다.
4946 * @param {string} eventName The name of the event to be attached <ko>등록할 이벤트의 이름</ko>
4947 * @param {function} handlerToAttach The handler function of the event to be attached <ko>등록할 이벤트의 핸들러 함수</ko>
4948 * @return An instance of a component itself<ko>컴포넌트 자신의 인스턴스</ko>
4949 * @example
4950 * ```
4951 * class Some extends eg.Component {
4952 * hi() {
4953 * console.log("hi");
4954 * }
4955 * some() {
4956 * this.on("hi",this.hi); //attach event
4957 * }
4958 * }
4959 * ```
4960 */
4961
4962
4963 __proto.on = function (eventName, handlerToAttach) {
4964 if (typeof eventName === "object" && isUndefined$1(handlerToAttach)) {
4965 var eventHash = eventName;
4966
4967 for (var name in eventHash) {
4968 this.on(name, eventHash[name]);
4969 }
4970
4971 return this;
4972 } else if (typeof eventName === "string" && typeof handlerToAttach === "function") {
4973 var handlerList = this._eventHandler[eventName];
4974
4975 if (isUndefined$1(handlerList)) {
4976 this._eventHandler[eventName] = [];
4977 handlerList = this._eventHandler[eventName];
4978 }
4979
4980 handlerList.push(handlerToAttach);
4981 }
4982
4983 return this;
4984 };
4985 /**
4986 * Detaches an event from the component.
4987 * @ko 컴포넌트에 등록된 이벤트를 해제한다
4988 * @param {string} eventName The name of the event to be detached <ko>해제할 이벤트의 이름</ko>
4989 * @param {function} handlerToDetach The handler function of the event to be detached <ko>해제할 이벤트의 핸들러 함수</ko>
4990 * @return An instance of a component itself <ko>컴포넌트 자신의 인스턴스</ko>
4991 * @example
4992 * ```
4993 * class Some extends eg.Component {
4994 * hi() {
4995 * console.log("hi");
4996 * }
4997 * some() {
4998 * this.off("hi",this.hi); //detach event
4999 * }
5000 * }
5001 * ```
5002 */
5003
5004
5005 __proto.off = function (eventName, handlerToDetach) {
5006 var e_1, _a; // Detach all event handlers.
5007
5008
5009 if (isUndefined$1(eventName)) {
5010 this._eventHandler = {};
5011 return this;
5012 } // Detach all handlers for eventname or detach event handlers by object.
5013
5014
5015 if (isUndefined$1(handlerToDetach)) {
5016 if (typeof eventName === "string") {
5017 delete this._eventHandler[eventName];
5018 return this;
5019 } else {
5020 var eventHash = eventName;
5021
5022 for (var name in eventHash) {
5023 this.off(name, eventHash[name]);
5024 }
5025
5026 return this;
5027 }
5028 } // Detach single event handler
5029
5030
5031 var handlerList = this._eventHandler[eventName];
5032
5033 if (handlerList) {
5034 var idx = 0;
5035
5036 try {
5037 for (var handlerList_1 = __values$1(handlerList), handlerList_1_1 = handlerList_1.next(); !handlerList_1_1.done; handlerList_1_1 = handlerList_1.next()) {
5038 var handlerFunction = handlerList_1_1.value;
5039
5040 if (handlerFunction === handlerToDetach) {
5041 handlerList.splice(idx, 1);
5042 break;
5043 }
5044
5045 idx++;
5046 }
5047 } catch (e_1_1) {
5048 e_1 = {
5049 error: e_1_1
5050 };
5051 } finally {
5052 try {
5053 if (handlerList_1_1 && !handlerList_1_1.done && (_a = handlerList_1.return)) _a.call(handlerList_1);
5054 } finally {
5055 if (e_1) throw e_1.error;
5056 }
5057 }
5058 }
5059
5060 return this;
5061 };
5062 /**
5063 * Version info string
5064 * @ko 버전정보 문자열
5065 * @name VERSION
5066 * @static
5067 * @example
5068 * eg.Component.VERSION; // ex) 2.0.0
5069 * @memberof eg.Component
5070 */
5071
5072
5073 Component.VERSION = "2.2.2";
5074 return Component;
5075 }();
5076
5077 /*
5078 Copyright (c) 2015 NAVER Corp.
5079 name: @egjs/axes
5080 license: MIT
5081 author: NAVER Corp.
5082 repository: https://github.com/naver/egjs-axes
5083 version: 2.8.0
5084 */
5085
5086 /*! *****************************************************************************
5087 Copyright (c) Microsoft Corporation. All rights reserved.
5088 Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5089 this file except in compliance with the License. You may obtain a copy of the
5090 License at http://www.apache.org/licenses/LICENSE-2.0
5091
5092 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
5093 KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
5094 WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
5095 MERCHANTABLITY OR NON-INFRINGEMENT.
5096
5097 See the Apache Version 2.0 License for specific language governing permissions
5098 and limitations under the License.
5099 ***************************************************************************** */
5100
5101 /* global Reflect, Promise */
5102 var extendStatics$1 = function (d, b) {
5103 extendStatics$1 = Object.setPrototypeOf || {
5104 __proto__: []
5105 } instanceof Array && function (d, b) {
5106 d.__proto__ = b;
5107 } || function (d, b) {
5108 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
5109 };
5110
5111 return extendStatics$1(d, b);
5112 };
5113
5114 function __extends$1(d, b) {
5115 extendStatics$1(d, b);
5116
5117 function __() {
5118 this.constructor = d;
5119 }
5120
5121 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
5122 }
5123 var __assign$1 = function () {
5124 __assign$1 = Object.assign || function __assign(t) {
5125 for (var s, i = 1, n = arguments.length; i < n; i++) {
5126 s = arguments[i];
5127
5128 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
5129 }
5130
5131 return t;
5132 };
5133
5134 return __assign$1.apply(this, arguments);
5135 };
5136
5137 function getInsidePosition(destPos, range, circular, bounce) {
5138 var toDestPos = destPos;
5139 var targetRange = [circular[0] ? range[0] : bounce ? range[0] - bounce[0] : range[0], circular[1] ? range[1] : bounce ? range[1] + bounce[1] : range[1]];
5140 toDestPos = Math.max(targetRange[0], toDestPos);
5141 toDestPos = Math.min(targetRange[1], toDestPos);
5142 return toDestPos;
5143 } // determine outside
5144
5145 function isOutside(pos, range) {
5146 return pos < range[0] || pos > range[1];
5147 }
5148 function getDuration(distance, deceleration) {
5149 var duration = Math.sqrt(distance / deceleration * 2); // when duration is under 100, then value is zero
5150
5151 return duration < 100 ? 0 : duration;
5152 }
5153 function isCircularable(destPos, range, circular) {
5154 return circular[1] && destPos > range[1] || circular[0] && destPos < range[0];
5155 }
5156 function getCirculatedPos(pos, range, circular) {
5157 var toPos = pos;
5158 var min = range[0];
5159 var max = range[1];
5160 var length = max - min;
5161
5162 if (circular[1] && pos > max) {
5163 // right
5164 toPos = (toPos - max) % length + min;
5165 }
5166
5167 if (circular[0] && pos < min) {
5168 // left
5169 toPos = (toPos - min) % length + max;
5170 }
5171
5172 return toPos;
5173 }
5174
5175 /* eslint-disable no-new-func, no-nested-ternary */
5176 var win;
5177
5178 if (typeof window === "undefined") {
5179 // window is undefined in node.js
5180 win = {
5181 navigator: {
5182 userAgent: ""
5183 }
5184 };
5185 } else {
5186 win = window;
5187 }
5188
5189 function toArray$1(nodes) {
5190 // const el = Array.prototype.slice.call(nodes);
5191 // for IE8
5192 var el = [];
5193
5194 for (var i = 0, len = nodes.length; i < len; i++) {
5195 el.push(nodes[i]);
5196 }
5197
5198 return el;
5199 }
5200 function $(param, multi) {
5201 if (multi === void 0) {
5202 multi = false;
5203 }
5204
5205 var el;
5206
5207 if (typeof param === "string") {
5208 // String (HTML, Selector)
5209 // check if string is HTML tag format
5210 var match = param.match(/^<([a-z]+)\s*([^>]*)>/); // creating element
5211
5212 if (match) {
5213 // HTML
5214 var dummy = document.createElement("div");
5215 dummy.innerHTML = param;
5216 el = toArray$1(dummy.childNodes);
5217 } else {
5218 // Selector
5219 el = toArray$1(document.querySelectorAll(param));
5220 }
5221
5222 if (!multi) {
5223 el = el.length >= 1 ? el[0] : undefined;
5224 }
5225 } else if (param === win) {
5226 // window
5227 el = param;
5228 } else if (param.nodeName && (param.nodeType === 1 || param.nodeType === 9)) {
5229 // HTMLElement, Document
5230 el = param;
5231 } else if ("jQuery" in win && param instanceof jQuery || param.constructor.prototype.jquery) {
5232 // jQuery
5233 el = multi ? param.toArray() : param.get(0);
5234 } else if (Array.isArray(param)) {
5235 el = param.map(function (v) {
5236 return $(v);
5237 });
5238
5239 if (!multi) {
5240 el = el.length >= 1 ? el[0] : undefined;
5241 }
5242 }
5243
5244 return el;
5245 }
5246 var raf = win.requestAnimationFrame || win.webkitRequestAnimationFrame;
5247 var caf = win.cancelAnimationFrame || win.webkitCancelAnimationFrame;
5248
5249 if (raf && !caf) {
5250 var keyInfo_1 = {};
5251 var oldraf_1 = raf;
5252
5253 raf = function (callback) {
5254 function wrapCallback(timestamp) {
5255 if (keyInfo_1[key]) {
5256 callback(timestamp);
5257 }
5258 }
5259
5260 var key = oldraf_1(wrapCallback);
5261 keyInfo_1[key] = true;
5262 return key;
5263 };
5264
5265 caf = function (key) {
5266 delete keyInfo_1[key];
5267 };
5268 } else if (!(raf && caf)) {
5269 raf = function (callback) {
5270 return win.setTimeout(function () {
5271 callback(win.performance && win.performance.now && win.performance.now() || new Date().getTime());
5272 }, 16);
5273 };
5274
5275 caf = win.clearTimeout;
5276 }
5277 /**
5278 * A polyfill for the window.requestAnimationFrame() method.
5279 * @see https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame
5280 * @private
5281 */
5282
5283
5284 function requestAnimationFrame(fp) {
5285 return raf(fp);
5286 }
5287 /**
5288 * A polyfill for the window.cancelAnimationFrame() method. It cancels an animation executed through a call to the requestAnimationFrame() method.
5289 * @param {Number} key − The ID value returned through a call to the requestAnimationFrame() method. <ko>requestAnimationFrame() 메서드가 반환한 아이디 값</ko>
5290 * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/cancelAnimationFrame
5291 * @private
5292 */
5293
5294 function cancelAnimationFrame(key) {
5295 caf(key);
5296 }
5297 function map(obj, callback) {
5298 var tranformed = {};
5299
5300 for (var k in obj) {
5301 k && (tranformed[k] = callback(obj[k], k));
5302 }
5303
5304 return tranformed;
5305 }
5306 function filter(obj, callback) {
5307 var filtered = {};
5308
5309 for (var k in obj) {
5310 k && callback(obj[k], k) && (filtered[k] = obj[k]);
5311 }
5312
5313 return filtered;
5314 }
5315 function every(obj, callback) {
5316 for (var k in obj) {
5317 if (k && !callback(obj[k], k)) {
5318 return false;
5319 }
5320 }
5321
5322 return true;
5323 }
5324 function equal(target, base) {
5325 return every(target, function (v, k) {
5326 return v === base[k];
5327 });
5328 }
5329 var roundNumFunc = {};
5330 function roundNumber(num, roundUnit) {
5331 // Cache for performance
5332 if (!roundNumFunc[roundUnit]) {
5333 roundNumFunc[roundUnit] = getRoundFunc(roundUnit);
5334 }
5335
5336 return roundNumFunc[roundUnit](num);
5337 }
5338 function roundNumbers(num, roundUnit) {
5339 if (!num || !roundUnit) {
5340 return num;
5341 }
5342
5343 var isNumber = typeof roundUnit === "number";
5344 return map(num, function (value, key) {
5345 return roundNumber(value, isNumber ? roundUnit : roundUnit[key]);
5346 });
5347 }
5348 function getDecimalPlace(val) {
5349 if (!isFinite(val)) {
5350 return 0;
5351 }
5352
5353 var v = val + "";
5354
5355 if (v.indexOf("e") >= 0) {
5356 // Exponential Format
5357 // 1e-10, 1e-12
5358 var p = 0;
5359 var e = 1;
5360
5361 while (Math.round(val * e) / e !== val) {
5362 e *= 10;
5363 p++;
5364 }
5365
5366 return p;
5367 } // In general, following has performance benefit.
5368 // https://jsperf.com/precision-calculation
5369
5370
5371 return v.indexOf(".") >= 0 ? v.length - v.indexOf(".") - 1 : 0;
5372 }
5373 function inversePow(n) {
5374 // replace Math.pow(10, -n) to solve floating point issue.
5375 // eg. Math.pow(10, -4) => 0.00009999999999999999
5376 return 1 / Math.pow(10, n);
5377 }
5378 function getRoundFunc(v) {
5379 var p = v < 1 ? Math.pow(10, getDecimalPlace(v)) : 1;
5380 return function (n) {
5381 if (v === 0) {
5382 return 0;
5383 }
5384
5385 return Math.round(Math.round(n / v) * v * p) / p;
5386 };
5387 }
5388
5389 function minMax(value, min, max) {
5390 return Math.max(Math.min(value, max), min);
5391 }
5392
5393 var AnimationManager =
5394 /*#__PURE__*/
5395 function () {
5396 function AnimationManager(_a) {
5397 var options = _a.options,
5398 itm = _a.itm,
5399 em = _a.em,
5400 axm = _a.axm;
5401 this.options = options;
5402 this.itm = itm;
5403 this.em = em;
5404 this.axm = axm;
5405 this.animationEnd = this.animationEnd.bind(this);
5406 }
5407
5408 var __proto = AnimationManager.prototype;
5409
5410 __proto.getDuration = function (depaPos, destPos, wishDuration) {
5411 var _this = this;
5412
5413 var duration;
5414
5415 if (typeof wishDuration !== "undefined") {
5416 duration = wishDuration;
5417 } else {
5418 var durations_1 = map(destPos, function (v, k) {
5419 return getDuration(Math.abs(v - depaPos[k]), _this.options.deceleration);
5420 });
5421 duration = Object.keys(durations_1).reduce(function (max, v) {
5422 return Math.max(max, durations_1[v]);
5423 }, -Infinity);
5424 }
5425
5426 return minMax(duration, this.options.minimumDuration, this.options.maximumDuration);
5427 };
5428
5429 __proto.createAnimationParam = function (pos, duration, option) {
5430 var depaPos = this.axm.get();
5431 var destPos = pos;
5432 var inputEvent = option && option.event || null;
5433 return {
5434 depaPos: depaPos,
5435 destPos: destPos,
5436 duration: minMax(duration, this.options.minimumDuration, this.options.maximumDuration),
5437 delta: this.axm.getDelta(depaPos, destPos),
5438 inputEvent: inputEvent,
5439 input: option && option.input || null,
5440 isTrusted: !!inputEvent,
5441 done: this.animationEnd
5442 };
5443 };
5444
5445 __proto.grab = function (axes, option) {
5446 if (this._animateParam && axes.length) {
5447 var orgPos_1 = this.axm.get(axes);
5448 var pos = this.axm.map(orgPos_1, function (v, opt) {
5449 return getCirculatedPos(v, opt.range, opt.circular);
5450 });
5451
5452 if (!every(pos, function (v, k) {
5453 return orgPos_1[k] === v;
5454 })) {
5455 this.em.triggerChange(pos, false, orgPos_1, option, !!option);
5456 }
5457
5458 this._animateParam = null;
5459 this._raf && cancelAnimationFrame(this._raf);
5460 this._raf = null;
5461 this.em.triggerAnimationEnd(!!(option && option.event));
5462 }
5463 };
5464
5465 __proto.getEventInfo = function () {
5466 if (this._animateParam && this._animateParam.input && this._animateParam.inputEvent) {
5467 return {
5468 input: this._animateParam.input,
5469 event: this._animateParam.inputEvent
5470 };
5471 } else {
5472 return null;
5473 }
5474 };
5475
5476 __proto.restore = function (option) {
5477 var pos = this.axm.get();
5478 var destPos = this.axm.map(pos, function (v, opt) {
5479 return Math.min(opt.range[1], Math.max(opt.range[0], v));
5480 });
5481 this.animateTo(destPos, this.getDuration(pos, destPos), option);
5482 };
5483
5484 __proto.animationEnd = function () {
5485 var beforeParam = this.getEventInfo();
5486 this._animateParam = null; // for Circular
5487
5488 var circularTargets = this.axm.filter(this.axm.get(), function (v, opt) {
5489 return isCircularable(v, opt.range, opt.circular);
5490 });
5491 Object.keys(circularTargets).length > 0 && this.setTo(this.axm.map(circularTargets, function (v, opt) {
5492 return getCirculatedPos(v, opt.range, opt.circular);
5493 }));
5494 this.itm.setInterrupt(false);
5495 this.em.triggerAnimationEnd(!!beforeParam);
5496
5497 if (this.axm.isOutside()) {
5498 this.restore(beforeParam);
5499 } else {
5500 this.finish(!!beforeParam);
5501 }
5502 };
5503
5504 __proto.finish = function (isTrusted) {
5505 this._animateParam = null;
5506 this.itm.setInterrupt(false);
5507 this.em.triggerFinish(isTrusted);
5508 };
5509
5510 __proto.animateLoop = function (param, complete) {
5511 if (param.duration) {
5512 this._animateParam = __assign$1({}, param);
5513 var info_1 = this._animateParam;
5514 var self_1 = this;
5515 var destPos_1 = info_1.destPos;
5516 var prevPos_1 = info_1.depaPos;
5517 var prevEasingPer_1 = 0;
5518 var directions_1 = map(prevPos_1, function (value, key) {
5519 return value <= destPos_1[key] ? 1 : -1;
5520 });
5521 var originalIntendedPos_1 = map(destPos_1, function (v) {
5522 return v;
5523 });
5524 var prevTime_1 = new Date().getTime();
5525 info_1.startTime = prevTime_1;
5526
5527 (function loop() {
5528 self_1._raf = null;
5529 var currentTime = new Date().getTime();
5530 var ratio = (currentTime - info_1.startTime) / param.duration;
5531 var easingPer = self_1.easing(ratio);
5532 var toPos = self_1.axm.map(prevPos_1, function (pos, options, key) {
5533 var nextPos = ratio >= 1 ? destPos_1[key] : pos + info_1.delta[key] * (easingPer - prevEasingPer_1); // Subtract distance from distance already moved.
5534 // Recalculate the remaining distance.
5535 // Fix the bouncing phenomenon by changing the range.
5536
5537 var circulatedPos = getCirculatedPos(nextPos, options.range, options.circular);
5538
5539 if (nextPos !== circulatedPos) {
5540 // circular
5541 var rangeOffset = directions_1[key] * (options.range[1] - options.range[0]);
5542 destPos_1[key] -= rangeOffset;
5543 prevPos_1[key] -= rangeOffset;
5544 }
5545
5546 return circulatedPos;
5547 });
5548 var isCanceled = !self_1.em.triggerChange(toPos, false, prevPos_1);
5549 prevPos_1 = toPos;
5550 prevTime_1 = currentTime;
5551 prevEasingPer_1 = easingPer;
5552
5553 if (easingPer >= 1) {
5554 destPos_1 = self_1.getFinalPos(destPos_1, originalIntendedPos_1);
5555
5556 if (!equal(destPos_1, self_1.axm.get(Object.keys(destPos_1)))) {
5557 self_1.em.triggerChange(destPos_1, true, prevPos_1);
5558 }
5559
5560 complete();
5561 return;
5562 } else if (isCanceled) {
5563 self_1.finish(false);
5564 } else {
5565 // animationEnd
5566 self_1._raf = requestAnimationFrame(loop);
5567 }
5568 })();
5569 } else {
5570 this.em.triggerChange(param.destPos, true);
5571 complete();
5572 }
5573 };
5574 /**
5575 * Get estimated final value.
5576 *
5577 * If destPos is within the 'error range' of the original intended position, the initial intended position is returned.
5578 * - eg. original intended pos: 100, destPos: 100.0000000004 ==> return 100;
5579 * If dest Pos is outside the 'range of error' compared to the originally intended pos, it is returned rounded based on the originally intended pos.
5580 * - eg. original intended pos: 100.123 destPos: 50.12345 => return 50.123
5581 *
5582 * @param originalIntendedPos
5583 * @param destPos
5584 */
5585
5586
5587 __proto.getFinalPos = function (destPos, originalIntendedPos) {
5588 var _this = this; // compare destPos and originalIntendedPos
5589
5590
5591 var ERROR_LIMIT = 0.000001;
5592 var finalPos = map(destPos, function (value, key) {
5593 if (value >= originalIntendedPos[key] - ERROR_LIMIT && value <= originalIntendedPos[key] + ERROR_LIMIT) {
5594 // In error range, return original intended
5595 return originalIntendedPos[key];
5596 } else {
5597 // Out of error range, return rounded pos.
5598 var roundUnit = _this.getRoundUnit(value, key);
5599
5600 var result = roundNumber(value, roundUnit);
5601 return result;
5602 }
5603 });
5604 return finalPos;
5605 };
5606
5607 __proto.getRoundUnit = function (val, key) {
5608 var roundUnit = this.options.round; // manual mode
5609
5610 var minRoundUnit = null; // auto mode
5611 // auto mode
5612
5613 if (!roundUnit) {
5614 // Get minimum round unit
5615 var options = this.axm.getAxisOptions(key);
5616 minRoundUnit = inversePow(Math.max(getDecimalPlace(options.range[0]), getDecimalPlace(options.range[1]), getDecimalPlace(val)));
5617 }
5618
5619 return minRoundUnit || roundUnit;
5620 };
5621
5622 __proto.getUserControll = function (param) {
5623 var userWish = param.setTo();
5624 userWish.destPos = this.axm.get(userWish.destPos);
5625 userWish.duration = minMax(userWish.duration, this.options.minimumDuration, this.options.maximumDuration);
5626 return userWish;
5627 };
5628
5629 __proto.animateTo = function (destPos, duration, option) {
5630 var _this = this;
5631
5632 var param = this.createAnimationParam(destPos, duration, option);
5633
5634 var depaPos = __assign$1({}, param.depaPos);
5635
5636 var retTrigger = this.em.triggerAnimationStart(param); // to control
5637
5638 var userWish = this.getUserControll(param); // You can't stop the 'animationStart' event when 'circular' is true.
5639
5640 if (!retTrigger && this.axm.every(userWish.destPos, function (v, opt) {
5641 return isCircularable(v, opt.range, opt.circular);
5642 })) {
5643 console.warn("You can't stop the 'animation' event when 'circular' is true.");
5644 }
5645
5646 if (retTrigger && !equal(userWish.destPos, depaPos)) {
5647 var inputEvent = option && option.event || null;
5648 this.animateLoop({
5649 depaPos: depaPos,
5650 destPos: userWish.destPos,
5651 duration: userWish.duration,
5652 delta: this.axm.getDelta(depaPos, userWish.destPos),
5653 isTrusted: !!inputEvent,
5654 inputEvent: inputEvent,
5655 input: option && option.input || null
5656 }, function () {
5657 return _this.animationEnd();
5658 });
5659 }
5660 };
5661
5662 __proto.easing = function (p) {
5663 return p > 1 ? 1 : this.options.easing(p);
5664 };
5665
5666 __proto.setTo = function (pos, duration) {
5667 if (duration === void 0) {
5668 duration = 0;
5669 }
5670
5671 var axes = Object.keys(pos);
5672 this.grab(axes);
5673 var orgPos = this.axm.get(axes);
5674
5675 if (equal(pos, orgPos)) {
5676 return this;
5677 }
5678
5679 this.itm.setInterrupt(true);
5680 var movedPos = filter(pos, function (v, k) {
5681 return orgPos[k] !== v;
5682 });
5683
5684 if (!Object.keys(movedPos).length) {
5685 return this;
5686 }
5687
5688 movedPos = this.axm.map(movedPos, function (v, opt) {
5689 var range = opt.range,
5690 circular = opt.circular;
5691
5692 if (circular && (circular[0] || circular[1])) {
5693 return v;
5694 } else {
5695 return getInsidePosition(v, range, circular);
5696 }
5697 });
5698
5699 if (equal(movedPos, orgPos)) {
5700 return this;
5701 }
5702
5703 if (duration > 0) {
5704 this.animateTo(movedPos, duration);
5705 } else {
5706 this.em.triggerChange(movedPos);
5707 this.finish(false);
5708 }
5709
5710 return this;
5711 };
5712
5713 __proto.setBy = function (pos, duration) {
5714 if (duration === void 0) {
5715 duration = 0;
5716 }
5717
5718 return this.setTo(map(this.axm.get(Object.keys(pos)), function (v, k) {
5719 return v + pos[k];
5720 }), duration);
5721 };
5722
5723 return AnimationManager;
5724 }();
5725
5726 var EventManager =
5727 /*#__PURE__*/
5728 function () {
5729 function EventManager(axes) {
5730 this.axes = axes;
5731 }
5732 /**
5733 * This event is fired when a user holds an element on the screen of the device.
5734 * @ko 사용자가 기기의 화면에 손을 대고 있을 때 발생하는 이벤트
5735 * @name eg.Axes#hold
5736 * @event
5737 * @type {object}
5738 * @property {Object.<string, number>} pos coordinate <ko>좌표 정보</ko>
5739 * @property {Object} input The instance of inputType where the event occurred<ko>이벤트가 발생한 inputType 인스턴스</ko>
5740 * @property {Object} inputEvent The event object received from inputType <ko>inputType으로 부터 받은 이벤트 객체</ko>
5741 * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call <ko>사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다.</ko>
5742 *
5743 * @example
5744 * const axes = new eg.Axes({
5745 * "x": {
5746 * range: [0, 100]
5747 * },
5748 * "zoom": {
5749 * range: [50, 30]
5750 * }
5751 * }).on("hold", function(event) {
5752 * // event.pos
5753 * // event.input
5754 * // event.inputEvent
5755 * // isTrusted
5756 * });
5757 */
5758
5759
5760 var __proto = EventManager.prototype;
5761
5762 __proto.triggerHold = function (pos, option) {
5763 var roundPos = this.getRoundPos(pos).roundPos;
5764 this.axes.trigger("hold", {
5765 pos: roundPos,
5766 input: option.input || null,
5767 inputEvent: option.event || null,
5768 isTrusted: true
5769 });
5770 };
5771 /**
5772 * Specifies the coordinates to move after the 'change' event. It works when the holding value of the change event is true.
5773 * @ko 'change' 이벤트 이후 이동할 좌표를 지정한다. change이벤트의 holding 값이 true일 경우에 동작한다
5774 * @name set
5775 * @function
5776 * @param {Object.<string, number>} pos The coordinate to move to <ko>이동할 좌표</ko>
5777 * @example
5778 * const axes = new eg.Axes({
5779 * "x": {
5780 * range: [0, 100]
5781 * },
5782 * "zoom": {
5783 * range: [50, 30]
5784 * }
5785 * }).on("change", function(event) {
5786 * event.holding && event.set({x: 10});
5787 * });
5788 */
5789
5790 /** Specifies the animation coordinates to move after the 'release' or 'animationStart' events.
5791 * @ko 'release' 또는 'animationStart' 이벤트 이후 이동할 좌표를 지정한다.
5792 * @name setTo
5793 * @function
5794 * @param {Object.<string, number>} pos The coordinate to move to <ko>이동할 좌표</ko>
5795 * @param {Number} [duration] Duration of the animation (unit: ms) <ko>애니메이션 진행 시간(단위: ms)</ko>
5796 * @example
5797 * const axes = new eg.Axes({
5798 * "x": {
5799 * range: [0, 100]
5800 * },
5801 * "zoom": {
5802 * range: [50, 30]
5803 * }
5804 * }).on("animationStart", function(event) {
5805 * event.setTo({x: 10}, 2000);
5806 * });
5807 */
5808
5809 /**
5810 * This event is fired when a user release an element on the screen of the device.
5811 * @ko 사용자가 기기의 화면에서 손을 뗐을 때 발생하는 이벤트
5812 * @name eg.Axes#release
5813 * @event
5814 * @type {object}
5815 * @property {Object.<string, number>} depaPos The coordinates when releasing an element<ko>손을 뗐을 때의 좌표 </ko>
5816 * @property {Object.<string, number>} destPos The coordinates to move to after releasing an element<ko>손을 뗀 뒤에 이동할 좌표</ko>
5817 * @property {Object.<string, number>} delta The movement variation of coordinate <ko>좌표의 변화량</ko>
5818 * @property {Object} inputEvent The event object received from inputType <ko>inputType으로 부터 받은 이벤트 객체</ko>
5819 * @property {Object} input The instance of inputType where the event occurred<ko>이벤트가 발생한 inputType 인스턴스</ko>
5820 * @property {setTo} setTo Specifies the animation coordinates to move after the event <ko>이벤트 이후 이동할 애니메이션 좌표를 지정한다</ko>
5821 * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call <ko>사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다.</ko>
5822 *
5823 * @example
5824 * const axes = new eg.Axes({
5825 * "x": {
5826 * range: [0, 100]
5827 * },
5828 * "zoom": {
5829 * range: [50, 30]
5830 * }
5831 * }).on("release", function(event) {
5832 * // event.depaPos
5833 * // event.destPos
5834 * // event.delta
5835 * // event.input
5836 * // event.inputEvent
5837 * // event.setTo
5838 * // event.isTrusted
5839 *
5840 * // if you want to change the animation coordinates to move after the 'release' event.
5841 * event.setTo({x: 10}, 2000);
5842 * });
5843 */
5844
5845
5846 __proto.triggerRelease = function (param) {
5847 var _a = this.getRoundPos(param.destPos, param.depaPos),
5848 roundPos = _a.roundPos,
5849 roundDepa = _a.roundDepa;
5850
5851 param.destPos = roundPos;
5852 param.depaPos = roundDepa;
5853 param.setTo = this.createUserControll(param.destPos, param.duration);
5854 this.axes.trigger("release", param);
5855 };
5856 /**
5857 * This event is fired when coordinate changes.
5858 * @ko 좌표가 변경됐을 때 발생하는 이벤트
5859 * @name eg.Axes#change
5860 * @event
5861 * @type {object}
5862 * @property {Object.<string, number>} pos The coordinate <ko>좌표</ko>
5863 * @property {Object.<string, number>} delta The movement variation of coordinate <ko>좌표의 변화량</ko>
5864 * @property {Boolean} holding Indicates whether a user holds an element on the screen of the device.<ko>사용자가 기기의 화면을 누르고 있는지 여부</ko>
5865 * @property {Object} input The instance of inputType where the event occurred. If the value is changed by animation, it returns 'null'.<ko>이벤트가 발생한 inputType 인스턴스. 애니메이션에 의해 값이 변경될 경우에는 'null'을 반환한다.</ko>
5866 * @property {Object} inputEvent The event object received from inputType. If the value is changed by animation, it returns 'null'.<ko>inputType으로 부터 받은 이벤트 객체. 애니메이션에 의해 값이 변경될 경우에는 'null'을 반환한다.</ko>
5867 * @property {set} set Specifies the coordinates to move after the event. It works when the holding value is true <ko>이벤트 이후 이동할 좌표를 지정한다. holding 값이 true일 경우에 동작한다.</ko>
5868 * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call <ko>사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다.</ko>
5869 *
5870 * @example
5871 * const axes = new eg.Axes({
5872 * "x": {
5873 * range: [0, 100]
5874 * },
5875 * "zoom": {
5876 * range: [50, 30]
5877 * }
5878 * }).on("change", function(event) {
5879 * // event.pos
5880 * // event.delta
5881 * // event.input
5882 * // event.inputEvent
5883 * // event.holding
5884 * // event.set
5885 * // event.isTrusted
5886 *
5887 * // if you want to change the coordinates to move after the 'change' event.
5888 * // it works when the holding value of the change event is true.
5889 * event.holding && event.set({x: 10});
5890 * });
5891 */
5892
5893
5894 __proto.triggerChange = function (pos, isAccurate, depaPos, option, holding) {
5895 if (holding === void 0) {
5896 holding = false;
5897 }
5898
5899 var am = this.am;
5900 var axm = am.axm;
5901 var eventInfo = am.getEventInfo();
5902
5903 var _a = this.getRoundPos(pos, depaPos),
5904 roundPos = _a.roundPos,
5905 roundDepa = _a.roundDepa;
5906
5907 var moveTo = axm.moveTo(roundPos, roundDepa);
5908 var inputEvent = option && option.event || eventInfo && eventInfo.event || null;
5909 var param = {
5910 pos: moveTo.pos,
5911 delta: moveTo.delta,
5912 holding: holding,
5913 inputEvent: inputEvent,
5914 isTrusted: !!inputEvent,
5915 input: option && option.input || eventInfo && eventInfo.input || null,
5916 set: inputEvent ? this.createUserControll(moveTo.pos) : function () {}
5917 };
5918 var result = this.axes.trigger("change", param);
5919 inputEvent && axm.set(param.set()["destPos"]);
5920 return result;
5921 };
5922 /**
5923 * This event is fired when animation starts.
5924 * @ko 에니메이션이 시작할 때 발생한다.
5925 * @name eg.Axes#animationStart
5926 * @event
5927 * @type {object}
5928 * @property {Object.<string, number>} depaPos The coordinates when animation starts<ko>애니메이션이 시작 되었을 때의 좌표 </ko>
5929 * @property {Object.<string, number>} destPos The coordinates to move to. If you change this value, you can run the animation<ko>이동할 좌표. 이값을 변경하여 애니메이션을 동작시킬수 있다</ko>
5930 * @property {Object.<string, number>} delta The movement variation of coordinate <ko>좌표의 변화량</ko>
5931 * @property {Number} duration Duration of the animation (unit: ms). If you change this value, you can control the animation duration time.<ko>애니메이션 진행 시간(단위: ms). 이값을 변경하여 애니메이션의 이동시간을 조절할 수 있다.</ko>
5932 * @property {Object} input The instance of inputType where the event occurred. If the value is changed by animation, it returns 'null'.<ko>이벤트가 발생한 inputType 인스턴스. 애니메이션에 의해 값이 변경될 경우에는 'null'을 반환한다.</ko>
5933 * @property {Object} inputEvent The event object received from inputType <ko>inputType으로 부터 받은 이벤트 객체</ko>
5934 * @property {setTo} setTo Specifies the animation coordinates to move after the event <ko>이벤트 이후 이동할 애니메이션 좌표를 지정한다</ko>
5935 * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call <ko>사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다.</ko>
5936 *
5937 * @example
5938 * const axes = new eg.Axes({
5939 * "x": {
5940 * range: [0, 100]
5941 * },
5942 * "zoom": {
5943 * range: [50, 30]
5944 * }
5945 * }).on("release", function(event) {
5946 * // event.depaPos
5947 * // event.destPos
5948 * // event.delta
5949 * // event.input
5950 * // event.inputEvent
5951 * // event.setTo
5952 * // event.isTrusted
5953 *
5954 * // if you want to change the animation coordinates to move after the 'animationStart' event.
5955 * event.setTo({x: 10}, 2000);
5956 * });
5957 */
5958
5959
5960 __proto.triggerAnimationStart = function (param) {
5961 var _a = this.getRoundPos(param.destPos, param.depaPos),
5962 roundPos = _a.roundPos,
5963 roundDepa = _a.roundDepa;
5964
5965 param.destPos = roundPos;
5966 param.depaPos = roundDepa;
5967 param.setTo = this.createUserControll(param.destPos, param.duration);
5968 return this.axes.trigger("animationStart", param);
5969 };
5970 /**
5971 * This event is fired when animation ends.
5972 * @ko 에니메이션이 끝났을 때 발생한다.
5973 * @name eg.Axes#animationEnd
5974 * @event
5975 * @type {object}
5976 * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call <ko>사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다.</ko>
5977 *
5978 * @example
5979 * const axes = new eg.Axes({
5980 * "x": {
5981 * range: [0, 100]
5982 * },
5983 * "zoom": {
5984 * range: [50, 30]
5985 * }
5986 * }).on("animationEnd", function(event) {
5987 * // event.isTrusted
5988 * });
5989 */
5990
5991
5992 __proto.triggerAnimationEnd = function (isTrusted) {
5993 if (isTrusted === void 0) {
5994 isTrusted = false;
5995 }
5996
5997 this.axes.trigger("animationEnd", {
5998 isTrusted: isTrusted
5999 });
6000 };
6001 /**
6002 * This event is fired when all actions have been completed.
6003 * @ko 에니메이션이 끝났을 때 발생한다.
6004 * @name eg.Axes#finish
6005 * @event
6006 * @type {object}
6007 * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call <ko>사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다.</ko>
6008 *
6009 * @example
6010 * const axes = new eg.Axes({
6011 * "x": {
6012 * range: [0, 100]
6013 * },
6014 * "zoom": {
6015 * range: [50, 30]
6016 * }
6017 * }).on("finish", function(event) {
6018 * // event.isTrusted
6019 * });
6020 */
6021
6022
6023 __proto.triggerFinish = function (isTrusted) {
6024 if (isTrusted === void 0) {
6025 isTrusted = false;
6026 }
6027
6028 this.axes.trigger("finish", {
6029 isTrusted: isTrusted
6030 });
6031 };
6032
6033 __proto.createUserControll = function (pos, duration) {
6034 if (duration === void 0) {
6035 duration = 0;
6036 } // to controll
6037
6038
6039 var userControl = {
6040 destPos: __assign$1({}, pos),
6041 duration: duration
6042 };
6043 return function (toPos, userDuration) {
6044 toPos && (userControl.destPos = __assign$1({}, toPos));
6045 userDuration !== undefined && (userControl.duration = userDuration);
6046 return userControl;
6047 };
6048 };
6049
6050 __proto.setAnimationManager = function (am) {
6051 this.am = am;
6052 };
6053
6054 __proto.destroy = function () {
6055 this.axes.off();
6056 };
6057
6058 __proto.getRoundPos = function (pos, depaPos) {
6059 // round value if round exist
6060 var roundUnit = this.axes.options.round; // if (round == null) {
6061 // return {pos, depaPos}; // undefined, undefined
6062 // }
6063
6064 return {
6065 roundPos: roundNumbers(pos, roundUnit),
6066 roundDepa: roundNumbers(depaPos, roundUnit)
6067 };
6068 };
6069
6070 return EventManager;
6071 }();
6072
6073 var InterruptManager =
6074 /*#__PURE__*/
6075 function () {
6076 function InterruptManager(options) {
6077 this.options = options;
6078 this._prevented = false; // check whether the animation event was prevented
6079 }
6080
6081 var __proto = InterruptManager.prototype;
6082
6083 __proto.isInterrupting = function () {
6084 // when interruptable is 'true', return value is always 'true'.
6085 return this.options.interruptable || this._prevented;
6086 };
6087
6088 __proto.isInterrupted = function () {
6089 return !this.options.interruptable && this._prevented;
6090 };
6091
6092 __proto.setInterrupt = function (prevented) {
6093 !this.options.interruptable && (this._prevented = prevented);
6094 };
6095
6096 return InterruptManager;
6097 }();
6098
6099 var AxisManager =
6100 /*#__PURE__*/
6101 function () {
6102 function AxisManager(axis, options) {
6103 var _this = this;
6104
6105 this.axis = axis;
6106 this.options = options;
6107
6108 this._complementOptions();
6109
6110 this._pos = Object.keys(this.axis).reduce(function (acc, v) {
6111 acc[v] = _this.axis[v].range[0];
6112 return acc;
6113 }, {});
6114 }
6115 /**
6116 * set up 'css' expression
6117 * @private
6118 */
6119
6120
6121 var __proto = AxisManager.prototype;
6122
6123 __proto._complementOptions = function () {
6124 var _this = this;
6125
6126 Object.keys(this.axis).forEach(function (axis) {
6127 _this.axis[axis] = __assign$1({
6128 range: [0, 100],
6129 bounce: [0, 0],
6130 circular: [false, false]
6131 }, _this.axis[axis]);
6132 ["bounce", "circular"].forEach(function (v) {
6133 var axisOption = _this.axis;
6134 var key = axisOption[axis][v];
6135
6136 if (/string|number|boolean/.test(typeof key)) {
6137 axisOption[axis][v] = [key, key];
6138 }
6139 });
6140 });
6141 };
6142
6143 __proto.getDelta = function (depaPos, destPos) {
6144 var fullDepaPos = this.get(depaPos);
6145 return map(this.get(destPos), function (v, k) {
6146 return v - fullDepaPos[k];
6147 });
6148 };
6149
6150 __proto.get = function (axes) {
6151 var _this = this;
6152
6153 if (axes && Array.isArray(axes)) {
6154 return axes.reduce(function (acc, v) {
6155 if (v && v in _this._pos) {
6156 acc[v] = _this._pos[v];
6157 }
6158
6159 return acc;
6160 }, {});
6161 } else {
6162 return __assign$1(__assign$1({}, this._pos), axes || {});
6163 }
6164 };
6165
6166 __proto.moveTo = function (pos, depaPos) {
6167 if (depaPos === void 0) {
6168 depaPos = this._pos;
6169 }
6170
6171 var delta = map(this._pos, function (v, key) {
6172 return key in pos && key in depaPos ? pos[key] - depaPos[key] : 0;
6173 });
6174 this.set(this.map(pos, function (v, opt) {
6175 return opt ? getCirculatedPos(v, opt.range, opt.circular) : 0;
6176 }));
6177 return {
6178 pos: __assign$1({}, this._pos),
6179 delta: delta
6180 };
6181 };
6182
6183 __proto.set = function (pos) {
6184 for (var k in pos) {
6185 if (k && k in this._pos) {
6186 this._pos[k] = pos[k];
6187 }
6188 }
6189 };
6190
6191 __proto.every = function (pos, callback) {
6192 var axisOptions = this.axis;
6193 return every(pos, function (value, key) {
6194 return callback(value, axisOptions[key], key);
6195 });
6196 };
6197
6198 __proto.filter = function (pos, callback) {
6199 var axisOptions = this.axis;
6200 return filter(pos, function (value, key) {
6201 return callback(value, axisOptions[key], key);
6202 });
6203 };
6204
6205 __proto.map = function (pos, callback) {
6206 var axisOptions = this.axis;
6207 return map(pos, function (value, key) {
6208 return callback(value, axisOptions[key], key);
6209 });
6210 };
6211
6212 __proto.isOutside = function (axes) {
6213 return !this.every(axes ? this.get(axes) : this._pos, function (v, opt) {
6214 return !isOutside(v, opt.range);
6215 });
6216 };
6217
6218 __proto.getAxisOptions = function (key) {
6219 return this.axis[key];
6220 };
6221
6222 return AxisManager;
6223 }();
6224
6225 var InputObserver =
6226 /*#__PURE__*/
6227 function () {
6228 function InputObserver(_a) {
6229 var options = _a.options,
6230 itm = _a.itm,
6231 em = _a.em,
6232 axm = _a.axm,
6233 am = _a.am;
6234 this.isOutside = false;
6235 this.moveDistance = null;
6236 this.isStopped = false;
6237 this.options = options;
6238 this.itm = itm;
6239 this.em = em;
6240 this.axm = axm;
6241 this.am = am;
6242 } // when move pointer is held in outside
6243
6244
6245 var __proto = InputObserver.prototype;
6246
6247 __proto.atOutside = function (pos) {
6248 var _this = this;
6249
6250 if (this.isOutside) {
6251 return this.axm.map(pos, function (v, opt) {
6252 var tn = opt.range[0] - opt.bounce[0];
6253 var tx = opt.range[1] + opt.bounce[1];
6254 return v > tx ? tx : v < tn ? tn : v;
6255 });
6256 } else {
6257 // when start pointer is held in inside
6258 // get a initialization slope value to prevent smooth animation.
6259 var initSlope_1 = this.am.easing(0.00001) / 0.00001;
6260 return this.axm.map(pos, function (v, opt) {
6261 var min = opt.range[0];
6262 var max = opt.range[1];
6263 var out = opt.bounce;
6264 var circular = opt.circular;
6265
6266 if (circular && (circular[0] || circular[1])) {
6267 return v;
6268 } else if (v < min) {
6269 // left
6270 return min - _this.am.easing((min - v) / (out[0] * initSlope_1)) * out[0];
6271 } else if (v > max) {
6272 // right
6273 return max + _this.am.easing((v - max) / (out[1] * initSlope_1)) * out[1];
6274 }
6275
6276 return v;
6277 });
6278 }
6279 };
6280
6281 __proto.get = function (input) {
6282 return this.axm.get(input.axes);
6283 };
6284
6285 __proto.hold = function (input, event) {
6286 if (this.itm.isInterrupted() || !input.axes.length) {
6287 return;
6288 }
6289
6290 var changeOption = {
6291 input: input,
6292 event: event
6293 };
6294 this.isStopped = false;
6295 this.itm.setInterrupt(true);
6296 this.am.grab(input.axes, changeOption);
6297 !this.moveDistance && this.em.triggerHold(this.axm.get(), changeOption);
6298 this.isOutside = this.axm.isOutside(input.axes);
6299 this.moveDistance = this.axm.get(input.axes);
6300 };
6301
6302 __proto.change = function (input, event, offset) {
6303 if (this.isStopped || !this.itm.isInterrupting() || this.axm.every(offset, function (v) {
6304 return v === 0;
6305 })) {
6306 return;
6307 }
6308
6309 var depaPos = this.moveDistance || this.axm.get(input.axes);
6310 var destPos; // for outside logic
6311
6312 destPos = map(depaPos, function (v, k) {
6313 return v + (offset[k] || 0);
6314 });
6315 this.moveDistance && (this.moveDistance = destPos); // from outside to inside
6316
6317 if (this.isOutside && this.axm.every(depaPos, function (v, opt) {
6318 return !isOutside(v, opt.range);
6319 })) {
6320 this.isOutside = false;
6321 }
6322
6323 depaPos = this.atOutside(depaPos);
6324 destPos = this.atOutside(destPos);
6325 var isCanceled = !this.em.triggerChange(destPos, false, depaPos, {
6326 input: input,
6327 event: event
6328 }, true);
6329
6330 if (isCanceled) {
6331 this.isStopped = true;
6332 this.moveDistance = null;
6333 this.am.finish(false);
6334 }
6335 };
6336
6337 __proto.release = function (input, event, offset, inputDuration) {
6338 if (this.isStopped || !this.itm.isInterrupting() || !this.moveDistance) {
6339 return;
6340 }
6341
6342 var pos = this.axm.get(input.axes);
6343 var depaPos = this.axm.get();
6344 var destPos = this.axm.get(this.axm.map(offset, function (v, opt, k) {
6345 if (opt.circular && (opt.circular[0] || opt.circular[1])) {
6346 return pos[k] + v;
6347 } else {
6348 return getInsidePosition(pos[k] + v, opt.range, opt.circular, opt.bounce);
6349 }
6350 }));
6351 var duration = this.am.getDuration(destPos, pos, inputDuration);
6352
6353 if (duration === 0) {
6354 destPos = __assign$1({}, depaPos);
6355 } // prepare params
6356
6357
6358 var param = {
6359 depaPos: depaPos,
6360 destPos: destPos,
6361 duration: duration,
6362 delta: this.axm.getDelta(depaPos, destPos),
6363 inputEvent: event,
6364 input: input,
6365 isTrusted: true
6366 };
6367 this.em.triggerRelease(param);
6368 this.moveDistance = null; // to contol
6369
6370 var userWish = this.am.getUserControll(param);
6371 var isEqual = equal(userWish.destPos, depaPos);
6372 var changeOption = {
6373 input: input,
6374 event: event
6375 };
6376
6377 if (isEqual || userWish.duration === 0) {
6378 !isEqual && this.em.triggerChange(userWish.destPos, false, depaPos, changeOption, true);
6379 this.itm.setInterrupt(false);
6380
6381 if (this.axm.isOutside()) {
6382 this.am.restore(changeOption);
6383 } else {
6384 this.em.triggerFinish(true);
6385 }
6386 } else {
6387 this.am.animateTo(userWish.destPos, userWish.duration, changeOption);
6388 }
6389 };
6390
6391 return InputObserver;
6392 }();
6393
6394 // export const DIRECTION_NONE = 1;
6395 var IOS_EDGE_THRESHOLD = 30;
6396 var IS_IOS_SAFARI = "ontouchstart" in win && agent().browser.name === "safari";
6397 var TRANSFORM = function () {
6398 if (typeof document === "undefined") {
6399 return "";
6400 }
6401
6402 var bodyStyle = (document.head || document.getElementsByTagName("head")[0]).style;
6403 var target = ["transform", "webkitTransform", "msTransform", "mozTransform"];
6404
6405 for (var i = 0, len = target.length; i < len; i++) {
6406 if (target[i] in bodyStyle) {
6407 return target[i];
6408 }
6409 }
6410
6411 return "";
6412 }();
6413
6414 /**
6415 * @typedef {Object} AxisOption The Axis information. The key of the axis specifies the name to use as the logical virtual coordinate system.
6416 * @ko 축 정보. 축의 키는 논리적인 가상 좌표계로 사용할 이름을 지정한다.
6417 * @property {Number[]} [range] The coordinate of range <ko>좌표 범위</ko>
6418 * @property {Number} [range.0=0] The coordinate of the minimum <ko>최소 좌표</ko>
6419 * @property {Number} [range.1=0] The coordinate of the maximum <ko>최대 좌표</ko>
6420 * @property {Number[]} [bounce] The size of bouncing area. The coordinates can exceed the coordinate area as much as the bouncing area based on user action. If the coordinates does not exceed the bouncing area when an element is dragged, the coordinates where bouncing effects are applied are retuned back into the coordinate area<ko>바운스 영역의 크기. 사용자의 동작에 따라 좌표가 좌표 영역을 넘어 바운스 영역의 크기만큼 더 이동할 수 있다. 사용자가 끌어다 놓는 동작을 했을 때 좌표가 바운스 영역에 있으면, 바운스 효과가 적용된 좌표가 다시 좌표 영역 안으로 들어온다</ko>
6421 * @property {Number} [bounce.0=0] The size of coordinate of the minimum area <ko>최소 좌표 바운스 영역의 크기</ko>
6422 * @property {Number} [bounce.1=0] The size of coordinate of the maximum area <ko>최대 좌표 바운스 영역의 크기</ko>
6423 * @property {Boolean[]} [circular] Indicates whether a circular element is available. If it is set to "true" and an element is dragged outside the coordinate area, the element will appear on the other side.<ko>순환 여부. 'true'로 설정한 방향의 좌표 영역 밖으로 엘리먼트가 이동하면 반대 방향에서 엘리먼트가 나타난다</ko>
6424 * @property {Boolean} [circular.0=false] Indicates whether to circulate to the coordinate of the minimum <ko>최소 좌표 방향의 순환 여부</ko>
6425 * @property {Boolean} [circular.1=false] Indicates whether to circulate to the coordinate of the maximum <ko>최대 좌표 방향의 순환 여부</ko>
6426 **/
6427
6428 /**
6429 * @typedef {Object} AxesOption The option object of the eg.Axes module
6430 * @ko eg.Axes 모듈의 옵션 객체
6431 * @property {Function} [easing=easing.easeOutCubic] The easing function to apply to an animation <ko>애니메이션에 적용할 easing 함수</ko>
6432 * @property {Number} [maximumDuration=Infinity] Maximum duration of the animation <ko>가속도에 의해 애니메이션이 동작할 때의 최대 좌표 이동 시간</ko>
6433 * @property {Number} [minimumDuration=0] Minimum duration of the animation <ko>가속도에 의해 애니메이션이 동작할 때의 최소 좌표 이동 시간</ko>
6434 * @property {Number} [deceleration=0.0006] Deceleration of the animation where acceleration is manually enabled by user. A higher value indicates shorter running time. <ko>사용자의 동작으로 가속도가 적용된 애니메이션의 감속도. 값이 높을수록 애니메이션 실행 시간이 짧아진다</ko>
6435 * @property {Boolean} [interruptable=true] Indicates whether an animation is interruptible.<br>- true: It can be paused or stopped by user action or the API.<br>- false: It cannot be paused or stopped by user action or the API while it is running.<ko>진행 중인 애니메이션 중지 가능 여부.<br>- true: 사용자의 동작이나 API로 애니메이션을 중지할 수 있다.<br>- false: 애니메이션이 진행 중일 때는 사용자의 동작이나 API가 적용되지 않는다</ko>
6436 * @property {Number} [round = null] Rounding unit. For example, 0.1 rounds to 0.1 decimal point(6.1234 => 6.1), 5 rounds to 5 (93 => 95) <br>[Details](https://github.com/naver/egjs-axes/wiki/round-option)<ko>반올림 단위. 예를 들어 0.1 은 소숫점 0.1 까지 반올림(6.1234 => 6.1), 5 는 5 단위로 반올림(93 => 95).<br>[상세내용](https://github.com/naver/egjs-axes/wiki/round-option)</ko>
6437 **/
6438
6439 /**
6440 * @class eg.Axes
6441 * @classdesc A module used to change the information of user action entered by various input devices such as touch screen or mouse into the logical virtual coordinates. You can easily create a UI that responds to user actions.
6442 * @ko 터치 입력 장치나 마우스와 같은 다양한 입력 장치를 통해 전달 받은 사용자의 동작을 논리적인 가상 좌표로 변경하는 모듈이다. 사용자 동작에 반응하는 UI를 손쉽게 만들수 있다.
6443 * @extends eg.Component
6444 *
6445 * @param {Object.<string, AxisOption>} axis Axis information managed by eg.Axes. The key of the axis specifies the name to use as the logical virtual coordinate system. <ko>eg.Axes가 관리하는 축 정보. 축의 키는 논리적인 가상 좌표계로 사용할 이름을 지정한다.</ko>
6446 * @param {AxesOption} [options] The option object of the eg.Axes module<ko>eg.Axes 모듈의 옵션 객체</ko>
6447 * @param {Object.<string, number>} [startPos] The coordinates to be moved when creating an instance. not triggering change event.<ko>인스턴스 생성시 이동할 좌표, change 이벤트는 발생하지 않음.</ko>
6448 *
6449 * @support {"ie": "10+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.3+ (except 3.x)"}
6450 * @example
6451 *
6452 * // 1. Initialize eg.Axes
6453 * const axes = new eg.Axes({
6454 * something1: {
6455 * range: [0, 150],
6456 * bounce: 50
6457 * },
6458 * something2: {
6459 * range: [0, 200],
6460 * bounce: 100
6461 * },
6462 * somethingN: {
6463 * range: [1, 10],
6464 * }
6465 * }, {
6466 * deceleration : 0.0024
6467 * });
6468 *
6469 * // 2. attach event handler
6470 * axes.on({
6471 * "hold" : function(evt) {
6472 * },
6473 * "release" : function(evt) {
6474 * },
6475 * "animationStart" : function(evt) {
6476 * },
6477 * "animationEnd" : function(evt) {
6478 * },
6479 * "change" : function(evt) {
6480 * }
6481 * });
6482 *
6483 * // 3. Initialize inputTypes
6484 * const panInputArea = new eg.Axes.PanInput("#area", {
6485 * scale: [0.5, 1]
6486 * });
6487 * const panInputHmove = new eg.Axes.PanInput("#hmove");
6488 * const panInputVmove = new eg.Axes.PanInput("#vmove");
6489 * const pinchInputArea = new eg.Axes.PinchInput("#area", {
6490 * scale: 1.5
6491 * });
6492 *
6493 * // 4. Connect eg.Axes and InputTypes
6494 * // [PanInput] When the mouse or touchscreen is down and moved.
6495 * // Connect the 'something2' axis to the mouse or touchscreen x position and
6496 * // connect the 'somethingN' axis to the mouse or touchscreen y position.
6497 * axes.connect(["something2", "somethingN"], panInputArea); // or axes.connect("something2 somethingN", panInputArea);
6498 *
6499 * // Connect only one 'something1' axis to the mouse or touchscreen x position.
6500 * axes.connect(["something1"], panInputHmove); // or axes.connect("something1", panInputHmove);
6501 *
6502 * // Connect only one 'something2' axis to the mouse or touchscreen y position.
6503 * axes.connect(["", "something2"], panInputVmove); // or axes.connect(" something2", panInputVmove);
6504 *
6505 * // [PinchInput] Connect 'something2' axis when two pointers are moving toward (zoom-in) or away from each other (zoom-out).
6506 * axes.connect("something2", pinchInputArea);
6507 */
6508
6509 var Axes =
6510 /*#__PURE__*/
6511 function (_super) {
6512 __extends$1(Axes, _super);
6513
6514 function Axes(axis, options, startPos) {
6515 if (axis === void 0) {
6516 axis = {};
6517 }
6518
6519 if (options === void 0) {
6520 options = {};
6521 }
6522
6523 var _this = _super.call(this) || this;
6524
6525 _this.axis = axis;
6526 _this._inputs = [];
6527 _this.options = __assign$1({
6528 easing: function easeOutCubic(x) {
6529 return 1 - Math.pow(1 - x, 3);
6530 },
6531 interruptable: true,
6532 maximumDuration: Infinity,
6533 minimumDuration: 0,
6534 deceleration: 0.0006,
6535 round: null
6536 }, options);
6537 _this.itm = new InterruptManager(_this.options);
6538 _this.axm = new AxisManager(_this.axis, _this.options);
6539 _this.em = new EventManager(_this);
6540 _this.am = new AnimationManager(_this);
6541 _this.io = new InputObserver(_this);
6542
6543 _this.em.setAnimationManager(_this.am);
6544
6545 startPos && _this.em.triggerChange(startPos);
6546 return _this;
6547 }
6548 /**
6549 * Connect the axis of eg.Axes to the inputType.
6550 * @ko eg.Axes의 축과 inputType을 연결한다
6551 * @method eg.Axes#connect
6552 * @param {(String[]|String)} axes The name of the axis to associate with inputType <ko>inputType과 연결할 축의 이름</ko>
6553 * @param {Object} inputType The inputType instance to associate with the axis of eg.Axes <ko>eg.Axes의 축과 연결할 inputType 인스턴스<ko>
6554 * @return {eg.Axes} An instance of a module itself <ko>모듈 자신의 인스턴스</ko>
6555 * @example
6556 * const axes = new eg.Axes({
6557 * "x": {
6558 * range: [0, 100]
6559 * },
6560 * "xOther": {
6561 * range: [-100, 100]
6562 * }
6563 * });
6564 *
6565 * axes.connect("x", new eg.Axes.PanInput("#area1"))
6566 * .connect("x xOther", new eg.Axes.PanInput("#area2"))
6567 * .connect(" xOther", new eg.Axes.PanInput("#area3"))
6568 * .connect(["x"], new eg.Axes.PanInput("#area4"))
6569 * .connect(["xOther", "x"], new eg.Axes.PanInput("#area5"))
6570 * .connect(["", "xOther"], new eg.Axes.PanInput("#area6"));
6571 */
6572
6573
6574 var __proto = Axes.prototype;
6575
6576 __proto.connect = function (axes, inputType) {
6577 var mapped;
6578
6579 if (typeof axes === "string") {
6580 mapped = axes.split(" ");
6581 } else {
6582 mapped = axes.concat();
6583 } // check same instance
6584
6585
6586 if (~this._inputs.indexOf(inputType)) {
6587 this.disconnect(inputType);
6588 } // check same element in hammer type for share
6589
6590
6591 if ("hammer" in inputType) {
6592 var targets = this._inputs.filter(function (v) {
6593 return v.hammer && v.element === inputType.element;
6594 });
6595
6596 if (targets.length) {
6597 inputType.hammer = targets[0].hammer;
6598 }
6599 }
6600
6601 inputType.mapAxes(mapped);
6602 inputType.connect(this.io);
6603
6604 this._inputs.push(inputType);
6605
6606 return this;
6607 };
6608 /**
6609 * Disconnect the axis of eg.Axes from the inputType.
6610 * @ko eg.Axes의 축과 inputType의 연결을 끊는다.
6611 * @method eg.Axes#disconnect
6612 * @param {Object} [inputType] An inputType instance associated with the axis of eg.Axes <ko>eg.Axes의 축과 연결한 inputType 인스턴스<ko>
6613 * @return {eg.Axes} An instance of a module itself <ko>모듈 자신의 인스턴스</ko>
6614 * @example
6615 * const axes = new eg.Axes({
6616 * "x": {
6617 * range: [0, 100]
6618 * },
6619 * "xOther": {
6620 * range: [-100, 100]
6621 * }
6622 * });
6623 *
6624 * const input1 = new eg.Axes.PanInput("#area1");
6625 * const input2 = new eg.Axes.PanInput("#area2");
6626 * const input3 = new eg.Axes.PanInput("#area3");
6627 *
6628 * axes.connect("x", input1);
6629 * .connect("x xOther", input2)
6630 * .connect(["xOther", "x"], input3);
6631 *
6632 * axes.disconnect(input1); // disconnects input1
6633 * axes.disconnect(); // disconnects all of them
6634 */
6635
6636
6637 __proto.disconnect = function (inputType) {
6638 if (inputType) {
6639 var index = this._inputs.indexOf(inputType);
6640
6641 if (index >= 0) {
6642 this._inputs[index].disconnect();
6643
6644 this._inputs.splice(index, 1);
6645 }
6646 } else {
6647 this._inputs.forEach(function (v) {
6648 return v.disconnect();
6649 });
6650
6651 this._inputs = [];
6652 }
6653
6654 return this;
6655 };
6656 /**
6657 * Returns the current position of the coordinates.
6658 * @ko 좌표의 현재 위치를 반환한다
6659 * @method eg.Axes#get
6660 * @param {Object} [axes] The names of the axis <ko>축 이름들</ko>
6661 * @return {Object.<string, number>} Axis coordinate information <ko>축 좌표 정보</ko>
6662 * @example
6663 * const axes = new eg.Axes({
6664 * "x": {
6665 * range: [0, 100]
6666 * },
6667 * "xOther": {
6668 * range: [-100, 100]
6669 * },
6670 * "zoom": {
6671 * range: [50, 30]
6672 * }
6673 * });
6674 *
6675 * axes.get(); // {"x": 0, "xOther": -100, "zoom": 50}
6676 * axes.get(["x", "zoom"]); // {"x": 0, "zoom": 50}
6677 */
6678
6679
6680 __proto.get = function (axes) {
6681 return this.axm.get(axes);
6682 };
6683 /**
6684 * Moves an axis to specific coordinates.
6685 * @ko 좌표를 이동한다.
6686 * @method eg.Axes#setTo
6687 * @param {Object.<string, number>} pos The coordinate to move to <ko>이동할 좌표</ko>
6688 * @param {Number} [duration=0] Duration of the animation (unit: ms) <ko>애니메이션 진행 시간(단위: ms)</ko>
6689 * @return {eg.Axes} An instance of a module itself <ko>모듈 자신의 인스턴스</ko>
6690 * @example
6691 * const axes = new eg.Axes({
6692 * "x": {
6693 * range: [0, 100]
6694 * },
6695 * "xOther": {
6696 * range: [-100, 100]
6697 * },
6698 * "zoom": {
6699 * range: [50, 30]
6700 * }
6701 * });
6702 *
6703 * axes.setTo({"x": 30, "zoom": 60});
6704 * axes.get(); // {"x": 30, "xOther": -100, "zoom": 60}
6705 *
6706 * axes.setTo({"x": 100, "xOther": 60}, 1000); // animatation
6707 *
6708 * // after 1000 ms
6709 * axes.get(); // {"x": 100, "xOther": 60, "zoom": 60}
6710 */
6711
6712
6713 __proto.setTo = function (pos, duration) {
6714 if (duration === void 0) {
6715 duration = 0;
6716 }
6717
6718 this.am.setTo(pos, duration);
6719 return this;
6720 };
6721 /**
6722 * Moves an axis from the current coordinates to specific coordinates.
6723 * @ko 현재 좌표를 기준으로 좌표를 이동한다.
6724 * @method eg.Axes#setBy
6725 * @param {Object.<string, number>} pos The coordinate to move to <ko>이동할 좌표</ko>
6726 * @param {Number} [duration=0] Duration of the animation (unit: ms) <ko>애니메이션 진행 시간(단위: ms)</ko>
6727 * @return {eg.Axes} An instance of a module itself <ko>모듈 자신의 인스턴스</ko>
6728 * @example
6729 * const axes = new eg.Axes({
6730 * "x": {
6731 * range: [0, 100]
6732 * },
6733 * "xOther": {
6734 * range: [-100, 100]
6735 * },
6736 * "zoom": {
6737 * range: [50, 30]
6738 * }
6739 * });
6740 *
6741 * axes.setBy({"x": 30, "zoom": 10});
6742 * axes.get(); // {"x": 30, "xOther": -100, "zoom": 60}
6743 *
6744 * axes.setBy({"x": 70, "xOther": 60}, 1000); // animatation
6745 *
6746 * // after 1000 ms
6747 * axes.get(); // {"x": 100, "xOther": -40, "zoom": 60}
6748 */
6749
6750
6751 __proto.setBy = function (pos, duration) {
6752 if (duration === void 0) {
6753 duration = 0;
6754 }
6755
6756 this.am.setBy(pos, duration);
6757 return this;
6758 };
6759 /**
6760 * Returns whether there is a coordinate in the bounce area of ​​the target axis.
6761 * @ko 대상 축 중 bounce영역에 좌표가 존재하는지를 반환한다
6762 * @method eg.Axes#isBounceArea
6763 * @param {Object} [axes] The names of the axis <ko>축 이름들</ko>
6764 * @return {Boolen} Whether the bounce area exists. <ko>bounce 영역 존재 여부</ko>
6765 * @example
6766 * const axes = new eg.Axes({
6767 * "x": {
6768 * range: [0, 100]
6769 * },
6770 * "xOther": {
6771 * range: [-100, 100]
6772 * },
6773 * "zoom": {
6774 * range: [50, 30]
6775 * }
6776 * });
6777 *
6778 * axes.isBounceArea(["x"]);
6779 * axes.isBounceArea(["x", "zoom"]);
6780 * axes.isBounceArea();
6781 */
6782
6783
6784 __proto.isBounceArea = function (axes) {
6785 return this.axm.isOutside(axes);
6786 };
6787 /**
6788 * Destroys properties, and events used in a module and disconnect all connections to inputTypes.
6789 * @ko 모듈에 사용한 속성, 이벤트를 해제한다. 모든 inputType과의 연결을 끊는다.
6790 * @method eg.Axes#destroy
6791 */
6792
6793
6794 __proto.destroy = function () {
6795 this.disconnect();
6796 this.em.destroy();
6797 };
6798 /**
6799 * Version info string
6800 * @ko 버전정보 문자열
6801 * @name VERSION
6802 * @static
6803 * @type {String}
6804 * @example
6805 * eg.Axes.VERSION; // ex) 3.3.3
6806 * @memberof eg.Axes
6807 */
6808
6809
6810 Axes.VERSION = "2.8.0";
6811 /**
6812 * @name eg.Axes.TRANSFORM
6813 * @desc Returns the transform attribute with CSS vendor prefixes.
6814 * @ko CSS vendor prefixes를 붙인 transform 속성을 반환한다.
6815 *
6816 * @constant
6817 * @type {String}
6818 * @example
6819 * eg.Axes.TRANSFORM; // "transform" or "webkitTransform"
6820 */
6821
6822 Axes.TRANSFORM = TRANSFORM;
6823 /**
6824 * @name eg.Axes.DIRECTION_NONE
6825 * @constant
6826 * @type {Number}
6827 */
6828
6829 Axes.DIRECTION_NONE = DIRECTION_NONE;
6830 /**
6831 * @name eg.Axes.DIRECTION_LEFT
6832 * @constant
6833 * @type {Number}
6834 */
6835
6836 Axes.DIRECTION_LEFT = DIRECTION_LEFT;
6837 /**
6838 * @name eg.Axes.DIRECTION_RIGHT
6839 * @constant
6840 * @type {Number}
6841 */
6842
6843 Axes.DIRECTION_RIGHT = DIRECTION_RIGHT;
6844 /**
6845 * @name eg.Axes.DIRECTION_UP
6846 * @constant
6847 * @type {Number}
6848 */
6849
6850 Axes.DIRECTION_UP = DIRECTION_UP;
6851 /**
6852 * @name eg.Axes.DIRECTION_DOWN
6853 * @constant
6854 * @type {Number}
6855 */
6856
6857 Axes.DIRECTION_DOWN = DIRECTION_DOWN;
6858 /**
6859 * @name eg.Axes.DIRECTION_HORIZONTAL
6860 * @constant
6861 * @type {Number}
6862 */
6863
6864 Axes.DIRECTION_HORIZONTAL = DIRECTION_HORIZONTAL;
6865 /**
6866 * @name eg.Axes.DIRECTION_VERTICAL
6867 * @constant
6868 * @type {Number}
6869 */
6870
6871 Axes.DIRECTION_VERTICAL = DIRECTION_VERTICAL;
6872 /**
6873 * @name eg.Axes.DIRECTION_ALL
6874 * @constant
6875 * @type {Number}
6876 */
6877
6878 Axes.DIRECTION_ALL = DIRECTION_ALL;
6879 return Axes;
6880 }(Component$1);
6881
6882 var SUPPORT_POINTER_EVENTS = "PointerEvent" in win || "MSPointerEvent" in win;
6883 var SUPPORT_TOUCH = ("ontouchstart" in win);
6884 var UNIQUEKEY = "_EGJS_AXES_INPUTTYPE_";
6885 function toAxis(source, offset) {
6886 return offset.reduce(function (acc, v, i) {
6887 if (source[i]) {
6888 acc[source[i]] = v;
6889 }
6890
6891 return acc;
6892 }, {});
6893 }
6894 function createHammer(element, options) {
6895 try {
6896 // create Hammer
6897 return new Manager(element, __assign$1({}, options));
6898 } catch (e) {
6899 return null;
6900 }
6901 }
6902 function convertInputType(inputType) {
6903 if (inputType === void 0) {
6904 inputType = [];
6905 }
6906
6907 var hasTouch = false;
6908 var hasMouse = false;
6909 var hasPointer = false;
6910 inputType.forEach(function (v) {
6911 switch (v) {
6912 case "mouse":
6913 hasMouse = true;
6914 break;
6915
6916 case "touch":
6917 hasTouch = SUPPORT_TOUCH;
6918 break;
6919
6920 case "pointer":
6921 hasPointer = SUPPORT_POINTER_EVENTS;
6922 // no default
6923 }
6924 });
6925
6926 if (hasPointer) {
6927 return PointerEventInput;
6928 } else if (hasTouch && hasMouse) {
6929 return TouchMouseInput;
6930 } else if (hasTouch) {
6931 return TouchInput;
6932 } else if (hasMouse) {
6933 return MouseInput;
6934 }
6935
6936 return null;
6937 }
6938
6939 function getDirectionByAngle(angle, thresholdAngle) {
6940 if (thresholdAngle < 0 || thresholdAngle > 90) {
6941 return DIRECTION_NONE;
6942 }
6943
6944 var toAngle = Math.abs(angle);
6945 return toAngle > thresholdAngle && toAngle < 180 - thresholdAngle ? DIRECTION_VERTICAL : DIRECTION_HORIZONTAL;
6946 }
6947 function getNextOffset(speeds, deceleration) {
6948 var normalSpeed = Math.sqrt(speeds[0] * speeds[0] + speeds[1] * speeds[1]);
6949 var duration = Math.abs(normalSpeed / -deceleration);
6950 return [speeds[0] / 2 * duration, speeds[1] / 2 * duration];
6951 }
6952 function useDirection(checkType, direction, userDirection) {
6953 if (userDirection) {
6954 return !!(direction === DIRECTION_ALL || direction & checkType && userDirection & checkType);
6955 } else {
6956 return !!(direction & checkType);
6957 }
6958 }
6959 /**
6960 * @typedef {Object} PanInputOption The option object of the eg.Axes.PanInput module.
6961 * @ko eg.Axes.PanInput 모듈의 옵션 객체
6962 * @property {String[]} [inputType=["touch","mouse", "pointer"]] Types of input devices.<br>- touch: Touch screen<br>- mouse: Mouse <ko>입력 장치 종류.<br>- touch: 터치 입력 장치<br>- mouse: 마우스</ko>
6963 * @property {Number[]} [scale] Coordinate scale that a user can move<ko>사용자의 동작으로 이동하는 좌표의 배율</ko>
6964 * @property {Number} [scale.0=1] horizontal axis scale <ko>수평축 배율</ko>
6965 * @property {Number} [scale.1=1] vertical axis scale <ko>수직축 배율</ko>
6966 * @property {Number} [thresholdAngle=45] The threshold value that determines whether user action is horizontal or vertical (0~90) <ko>사용자의 동작이 가로 방향인지 세로 방향인지 판단하는 기준 각도(0~90)</ko>
6967 * @property {Number} [threshold=0] Minimal pan distance required before recognizing <ko>사용자의 Pan 동작을 인식하기 위해산 최소한의 거리</ko>
6968 * @property {Number} [iOSEdgeSwipeThreshold=30] Area (px) that can go to the next page when swiping the right edge in iOS safari <ko>iOS Safari에서 오른쪽 엣지를 스와이프 하는 경우 다음 페이지로 넘어갈 수 있는 영역(px)</ko>
6969 * @property {Object} [hammerManagerOptions={cssProps: {userSelect: "none",touchSelect: "none",touchCallout: "none",userDrag: "none"}] Options of Hammer.Manager <ko>Hammer.Manager의 옵션</ko>
6970 **/
6971
6972 /**
6973 * @class eg.Axes.PanInput
6974 * @classdesc A module that passes the amount of change to eg.Axes when the mouse or touchscreen is down and moved. use less than two axes.
6975 * @ko 마우스나 터치 스크린을 누르고 움직일때의 변화량을 eg.Axes에 전달하는 모듈. 두개 이하의 축을 사용한다.
6976 *
6977 * @example
6978 * const pan = new eg.Axes.PanInput("#area", {
6979 * inputType: ["touch"],
6980 * scale: [1, 1.3],
6981 * });
6982 *
6983 * // Connect the 'something2' axis to the mouse or touchscreen x position when the mouse or touchscreen is down and moved.
6984 * // Connect the 'somethingN' axis to the mouse or touchscreen y position when the mouse or touchscreen is down and moved.
6985 * axes.connect(["something2", "somethingN"], pan); // or axes.connect("something2 somethingN", pan);
6986 *
6987 * // Connect only one 'something1' axis to the mouse or touchscreen x position when the mouse or touchscreen is down and moved.
6988 * axes.connect(["something1"], pan); // or axes.connect("something1", pan);
6989 *
6990 * // Connect only one 'something2' axis to the mouse or touchscreen y position when the mouse or touchscreen is down and moved.
6991 * axes.connect(["", "something2"], pan); // or axes.connect(" something2", pan);
6992 *
6993 * @param {HTMLElement|String|jQuery} element An element to use the eg.Axes.PanInput module <ko>eg.Axes.PanInput 모듈을 사용할 엘리먼트</ko>
6994 * @param {PanInputOption} [options] The option object of the eg.Axes.PanInput module<ko>eg.Axes.PanInput 모듈의 옵션 객체</ko>
6995 */
6996
6997 var PanInput =
6998 /*#__PURE__*/
6999 function () {
7000 function PanInput(el, options) {
7001 this.axes = [];
7002 this.hammer = null;
7003 this.element = null;
7004 this.panRecognizer = null;
7005 this.isRightEdge = false;
7006 this.rightEdgeTimer = 0;
7007 this.panFlag = false;
7008 /**
7009 * Hammer helps you add support for touch gestures to your page
7010 *
7011 * @external Hammer
7012 * @see {@link http://hammerjs.github.io|Hammer.JS}
7013 * @see {@link http://hammerjs.github.io/jsdoc/Hammer.html|Hammer.JS API documents}
7014 * @see Hammer.JS applies specific CSS properties by {@link http://hammerjs.github.io/jsdoc/Hammer.defaults.cssProps.html|default} when creating an instance. The eg.Axes module removes all default CSS properties provided by Hammer.JS
7015 */
7016
7017 if (typeof Manager === "undefined") {
7018 throw new Error("The Hammerjs must be loaded before eg.Axes.PanInput.\nhttp://hammerjs.github.io/");
7019 }
7020
7021 this.element = $(el);
7022 this.options = __assign$1({
7023 inputType: ["touch", "mouse", "pointer"],
7024 scale: [1, 1],
7025 thresholdAngle: 45,
7026 threshold: 0,
7027 iOSEdgeSwipeThreshold: IOS_EDGE_THRESHOLD,
7028 releaseOnScroll: false,
7029 hammerManagerOptions: {
7030 // css properties were removed due to usablility issue
7031 // http://hammerjs.github.io/jsdoc/Hammer.defaults.cssProps.html
7032 cssProps: {
7033 userSelect: "none",
7034 touchSelect: "none",
7035 touchCallout: "none",
7036 userDrag: "none"
7037 }
7038 }
7039 }, options);
7040 this.onHammerInput = this.onHammerInput.bind(this);
7041 this.onPanmove = this.onPanmove.bind(this);
7042 this.onPanend = this.onPanend.bind(this);
7043 }
7044
7045 var __proto = PanInput.prototype;
7046
7047 __proto.mapAxes = function (axes) {
7048 var useHorizontal = !!axes[0];
7049 var useVertical = !!axes[1];
7050
7051 if (useHorizontal && useVertical) {
7052 this._direction = DIRECTION_ALL;
7053 } else if (useHorizontal) {
7054 this._direction = DIRECTION_HORIZONTAL;
7055 } else if (useVertical) {
7056 this._direction = DIRECTION_VERTICAL;
7057 } else {
7058 this._direction = DIRECTION_NONE;
7059 }
7060
7061 this.axes = axes;
7062 };
7063
7064 __proto.connect = function (observer) {
7065 var hammerOption = {
7066 direction: this._direction,
7067 threshold: this.options.threshold
7068 };
7069
7070 if (this.hammer) {
7071 // for sharing hammer instance.
7072 // hammer remove previous PanRecognizer.
7073 this.removeRecognizer();
7074 this.dettachEvent();
7075 } else {
7076 var keyValue = this.element[UNIQUEKEY];
7077
7078 if (!keyValue) {
7079 keyValue = String(Math.round(Math.random() * new Date().getTime()));
7080 }
7081
7082 var inputClass = convertInputType(this.options.inputType);
7083
7084 if (!inputClass) {
7085 throw new Error("Wrong inputType parameter!");
7086 }
7087
7088 this.hammer = createHammer(this.element, __assign$1({
7089 inputClass: inputClass
7090 }, this.options.hammerManagerOptions));
7091 this.element[UNIQUEKEY] = keyValue;
7092 }
7093
7094 this.panRecognizer = new PanRecognizer(hammerOption);
7095 this.hammer.add(this.panRecognizer);
7096 this.attachEvent(observer);
7097 return this;
7098 };
7099
7100 __proto.disconnect = function () {
7101 this.removeRecognizer();
7102
7103 if (this.hammer) {
7104 this.dettachEvent();
7105 }
7106
7107 this._direction = DIRECTION_NONE;
7108 return this;
7109 };
7110 /**
7111 * Destroys elements, properties, and events used in a module.
7112 * @ko 모듈에 사용한 엘리먼트와 속성, 이벤트를 해제한다.
7113 * @method eg.Axes.PanInput#destroy
7114 */
7115
7116
7117 __proto.destroy = function () {
7118 this.disconnect();
7119
7120 if (this.hammer && this.hammer.recognizers.length === 0) {
7121 this.hammer.destroy();
7122 }
7123
7124 delete this.element[UNIQUEKEY];
7125 this.element = null;
7126 this.hammer = null;
7127 };
7128 /**
7129 * Enables input devices
7130 * @ko 입력 장치를 사용할 수 있게 한다
7131 * @method eg.Axes.PanInput#enable
7132 * @return {eg.Axes.PanInput} An instance of a module itself <ko>모듈 자신의 인스턴스</ko>
7133 */
7134
7135
7136 __proto.enable = function () {
7137 this.hammer && (this.hammer.get("pan").options.enable = true);
7138 return this;
7139 };
7140 /**
7141 * Disables input devices
7142 * @ko 입력 장치를 사용할 수 없게 한다.
7143 * @method eg.Axes.PanInput#disable
7144 * @return {eg.Axes.PanInput} An instance of a module itself <ko>모듈 자신의 인스턴스</ko>
7145 */
7146
7147
7148 __proto.disable = function () {
7149 this.hammer && (this.hammer.get("pan").options.enable = false);
7150 return this;
7151 };
7152 /**
7153 * Returns whether to use an input device
7154 * @ko 입력 장치를 사용 여부를 반환한다.
7155 * @method eg.Axes.PanInput#isEnable
7156 * @return {Boolean} Whether to use an input device <ko>입력장치 사용여부</ko>
7157 */
7158
7159
7160 __proto.isEnable = function () {
7161 return !!(this.hammer && this.hammer.get("pan").options.enable);
7162 };
7163
7164 __proto.removeRecognizer = function () {
7165 if (this.hammer && this.panRecognizer) {
7166 this.hammer.remove(this.panRecognizer);
7167 this.panRecognizer = null;
7168 }
7169 };
7170
7171 __proto.onHammerInput = function (event) {
7172 if (this.isEnable()) {
7173 if (event.isFirst) {
7174 this.panFlag = false;
7175
7176 if (event.srcEvent.cancelable !== false) {
7177 var edgeThreshold = this.options.iOSEdgeSwipeThreshold;
7178 this.observer.hold(this, event);
7179 this.isRightEdge = IS_IOS_SAFARI && event.center.x > window.innerWidth - edgeThreshold;
7180 this.panFlag = true;
7181 }
7182 } else if (event.isFinal) {
7183 this.onPanend(event);
7184 }
7185 }
7186 };
7187
7188 __proto.onPanmove = function (event) {
7189 var _this = this;
7190
7191 if (!this.panFlag) {
7192 return;
7193 }
7194
7195 var _a = this.options,
7196 iOSEdgeSwipeThreshold = _a.iOSEdgeSwipeThreshold,
7197 releaseOnScroll = _a.releaseOnScroll;
7198 var userDirection = getDirectionByAngle(event.angle, this.options.thresholdAngle); // not support offset properties in Hammerjs - start
7199
7200 var prevInput = this.hammer.session.prevInput;
7201
7202 if (releaseOnScroll && !event.srcEvent.cancelable) {
7203 this.onPanend(__assign$1(__assign$1({}, event), {
7204 velocityX: 0,
7205 velocityY: 0,
7206 offsetX: 0,
7207 offsetY: 0
7208 }));
7209 return;
7210 }
7211
7212 if (prevInput && IS_IOS_SAFARI) {
7213 var swipeLeftToRight = event.center.x < 0;
7214
7215 if (swipeLeftToRight) {
7216 // iOS swipe left => right
7217 this.onPanend(__assign$1(__assign$1({}, prevInput), {
7218 velocityX: 0,
7219 velocityY: 0,
7220 offsetX: 0,
7221 offsetY: 0
7222 }));
7223 return;
7224 } else if (this.isRightEdge) {
7225 clearTimeout(this.rightEdgeTimer); // - is right to left
7226
7227 var swipeRightToLeft = event.deltaX < -iOSEdgeSwipeThreshold;
7228
7229 if (swipeRightToLeft) {
7230 this.isRightEdge = false;
7231 } else {
7232 // iOS swipe right => left
7233 this.rightEdgeTimer = window.setTimeout(function () {
7234 _this.onPanend(__assign$1(__assign$1({}, prevInput), {
7235 velocityX: 0,
7236 velocityY: 0,
7237 offsetX: 0,
7238 offsetY: 0
7239 }));
7240 }, 100);
7241 }
7242 }
7243 }
7244 /* eslint-disable no-param-reassign */
7245
7246
7247 if (prevInput) {
7248 event.offsetX = event.deltaX - prevInput.deltaX;
7249 event.offsetY = event.deltaY - prevInput.deltaY;
7250 } else {
7251 event.offsetX = 0;
7252 event.offsetY = 0;
7253 }
7254
7255 var offset = this.getOffset([event.offsetX, event.offsetY], [useDirection(DIRECTION_HORIZONTAL, this._direction, userDirection), useDirection(DIRECTION_VERTICAL, this._direction, userDirection)]);
7256 var prevent = offset.some(function (v) {
7257 return v !== 0;
7258 });
7259
7260 if (prevent) {
7261 var srcEvent = event.srcEvent;
7262
7263 if (srcEvent.cancelable !== false) {
7264 srcEvent.preventDefault();
7265 }
7266
7267 srcEvent.stopPropagation();
7268 }
7269
7270 event.preventSystemEvent = prevent;
7271 prevent && this.observer.change(this, event, toAxis(this.axes, offset));
7272 };
7273
7274 __proto.onPanend = function (event) {
7275 if (!this.panFlag) {
7276 return;
7277 }
7278
7279 clearTimeout(this.rightEdgeTimer);
7280 this.panFlag = false;
7281 var offset = this.getOffset([Math.abs(event.velocityX) * (event.deltaX < 0 ? -1 : 1), Math.abs(event.velocityY) * (event.deltaY < 0 ? -1 : 1)], [useDirection(DIRECTION_HORIZONTAL, this._direction), useDirection(DIRECTION_VERTICAL, this._direction)]);
7282 offset = getNextOffset(offset, this.observer.options.deceleration);
7283 this.observer.release(this, event, toAxis(this.axes, offset));
7284 };
7285
7286 __proto.attachEvent = function (observer) {
7287 this.observer = observer;
7288 this.hammer.on("hammer.input", this.onHammerInput).on("panstart panmove", this.onPanmove);
7289 };
7290
7291 __proto.dettachEvent = function () {
7292 this.hammer.off("hammer.input", this.onHammerInput).off("panstart panmove", this.onPanmove);
7293 this.observer = null;
7294 };
7295
7296 __proto.getOffset = function (properties, direction) {
7297 var offset = [0, 0];
7298 var scale = this.options.scale;
7299
7300 if (direction[0]) {
7301 offset[0] = properties[0] * scale[0];
7302 }
7303
7304 if (direction[1]) {
7305 offset[1] = properties[1] * scale[1];
7306 }
7307
7308 return offset;
7309 };
7310
7311 return PanInput;
7312 }();
7313
7314 var Axes$1 = Axes;
7315
7316 /**
7317 * All possible @egjs/axes event keys
7318 * @internal
7319 */
7320 var EVENT = {
7321 HOLD: "hold",
7322 CHANGE: "change",
7323 RELEASE: "release",
7324 ANIMATION_END: "animationEnd",
7325 FINISH: "finish"
7326 };
7327 /**
7328 * An Axis key that Flicking uses
7329 * @internal
7330 */
7331
7332 var POSITION_KEY = "flick";
7333
7334 var STATE_TYPE;
7335
7336 (function (STATE_TYPE) {
7337 STATE_TYPE[STATE_TYPE["IDLE"] = 0] = "IDLE";
7338 STATE_TYPE[STATE_TYPE["HOLDING"] = 1] = "HOLDING";
7339 STATE_TYPE[STATE_TYPE["DRAGGING"] = 2] = "DRAGGING";
7340 STATE_TYPE[STATE_TYPE["ANIMATING"] = 3] = "ANIMATING";
7341 STATE_TYPE[STATE_TYPE["DISABLED"] = 4] = "DISABLED";
7342 })(STATE_TYPE || (STATE_TYPE = {}));
7343 /**
7344 * A component that shows the current status of the user input or the animation
7345 * @ko 현재 사용자 입력 또는 애니메이션 상태를 나타내는 컴포넌트
7346 * @internal
7347 */
7348
7349
7350 var State = function () {
7351 function State() {
7352 this._delta = 0;
7353 this._targetPanel = null;
7354 }
7355
7356 var __proto = State.prototype;
7357 Object.defineProperty(__proto, "delta", {
7358 /**
7359 * A sum of delta values of change events from the last hold event of Axes
7360 * @ko 이전 hold이벤트부터 change에 의해 발생한 이동 delta값의 합산
7361 * @type {number}
7362 * @readonly
7363 */
7364 get: function () {
7365 return this._delta;
7366 },
7367 enumerable: false,
7368 configurable: true
7369 });
7370 Object.defineProperty(__proto, "targetPanel", {
7371 /**
7372 * A panel to set as {@link Control#activePanel} after the animation is finished
7373 * @ko 애니메이션 종료시 {@link Control#activePanel}로 설정할 패널
7374 * @type {number}
7375 * @readonly
7376 */
7377 get: function () {
7378 return this._targetPanel;
7379 },
7380 set: function (val) {
7381 this._targetPanel = val;
7382 },
7383 enumerable: false,
7384 configurable: true
7385 });
7386 /**
7387 * An callback which is called when state has changed to this state
7388 * @ko 현재 상태로 돌입했을때 호출되는 콜백 함수
7389 * @param {State} prevState An previous state<ko>이전 상태값</ko>
7390 * @return {void}
7391 */
7392
7393 __proto.onEnter = function (prevState) {
7394 this._delta = prevState._delta;
7395 this._targetPanel = prevState._targetPanel;
7396 };
7397 /**
7398 * An event handler for Axes's {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:hold hold} event
7399 * @ko Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:hold hold} 이벤트 핸들러
7400 * @param {object} [ctx] Event context<ko>이벤트 콘텍스트</ko>
7401 * @param {Flicking} [ctx.flicking] An instance of Flicking<ko>Flicking 인스턴스</ko>
7402 * @param {object} [ctx.axesEvent] A {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:hold hold} event of Axes
7403 * <ko>Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:hold hold} 이벤트</ko>
7404 * @param {function} [ctx.transitTo] A function for changing current state to other state<ko>다른 상태로 변경하기 위한 함수</ko>
7405 * @return {void}
7406 */
7407
7408
7409 __proto.onHold = function (ctx) {// DO NOTHING
7410 };
7411 /**
7412 * An event handler for Axes's {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:change change} event
7413 * @ko Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:change change} 이벤트 핸들러
7414 * @param {object} [ctx] Event context<ko>이벤트 콘텍스트</ko>
7415 * @param {Flicking} [ctx.flicking] An instance of Flicking<ko>Flicking 인스턴스</ko>
7416 * @param {object} [ctx.axesEvent] A {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:change change} event of Axes
7417 * <ko>Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:change change} 이벤트</ko>
7418 * @param {function} [ctx.transitTo] A function for changing current state to other state<ko>다른 상태로 변경하기 위한 함수</ko>
7419 * @return {void}
7420 */
7421
7422
7423 __proto.onChange = function (ctx) {// DO NOTHING
7424 };
7425 /**
7426 * An event handler for Axes's {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} event
7427 * @ko Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} 이벤트 핸들러
7428 * @param {object} [ctx] Event context<ko>이벤트 콘텍스트</ko>
7429 * @param {Flicking} [ctx.flicking] An instance of Flicking<ko>Flicking 인스턴스</ko>
7430 * @param {object} [ctx.axesEvent] A {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} event of Axes
7431 * <ko>Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} 이벤트</ko>
7432 * @param {function} [ctx.transitTo] A function for changing current state to other state<ko>다른 상태로 변경하기 위한 함수</ko>
7433 * @return {void}
7434 */
7435
7436
7437 __proto.onRelease = function (ctx) {// DO NOTHING
7438 };
7439 /**
7440 * An event handler for Axes's {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:animationEnd animationEnd} event
7441 * @ko Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:animationEnd animationEnd} 이벤트 핸들러
7442 * @param {object} [ctx] Event context<ko>이벤트 콘텍스트</ko>
7443 * @param {Flicking} [ctx.flicking] An instance of Flicking<ko>Flicking 인스턴스</ko>
7444 * @param {object} [ctx.axesEvent] A {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:animationEnd animationEnd} event of Axes
7445 * <ko>Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:animationEnd animationEnd} 이벤트</ko>
7446 * @param {function} [ctx.transitTo] A function for changing current state to other state<ko>다른 상태로 변경하기 위한 함수</ko>
7447 * @return {void}
7448 */
7449
7450
7451 __proto.onAnimationEnd = function (ctx) {// DO NOTHING
7452 };
7453 /**
7454 * An event handler for Axes's {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:finish finish} event
7455 * @ko Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:finish finish} 이벤트 핸들러
7456 * @param {object} [ctx] Event context<ko>이벤트 콘텍스트</ko>
7457 * @param {Flicking} [ctx.flicking] An instance of Flicking<ko>Flicking 인스턴스</ko>
7458 * @param {object} [ctx.axesEvent] A {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:finish finish} event of Axes<ko>Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:finish finish} 이벤트</ko>
7459 * @param {function} [ctx.transitTo] A function for changing current state to other state<ko>다른 상태로 변경하기 위한 함수</ko>
7460 * @return {void}
7461 */
7462
7463
7464 __proto.onFinish = function (ctx) {// DO NOTHING
7465 };
7466
7467 __proto._moveToChangedPosition = function (ctx) {
7468 var flicking = ctx.flicking,
7469 axesEvent = ctx.axesEvent,
7470 transitTo = ctx.transitTo;
7471 var delta = axesEvent.delta[POSITION_KEY];
7472
7473 if (!delta) {
7474 return;
7475 }
7476
7477 this._delta += delta;
7478 var camera = flicking.camera;
7479 var prevPosition = camera.position;
7480 var position = axesEvent.pos[POSITION_KEY];
7481 var newPosition = flicking.circularEnabled ? circulatePosition(position, camera.range.min, camera.range.max) : position;
7482 camera.lookAt(newPosition);
7483 var moveEvent = new ComponentEvent$1(EVENTS.MOVE, {
7484 isTrusted: axesEvent.isTrusted,
7485 holding: this.holding,
7486 direction: getDirection$1(0, axesEvent.delta[POSITION_KEY]),
7487 axesEvent: axesEvent
7488 });
7489 flicking.trigger(moveEvent);
7490
7491 if (moveEvent.isCanceled()) {
7492 // Return to previous position
7493 camera.lookAt(prevPosition);
7494 transitTo(STATE_TYPE.DISABLED);
7495 }
7496 };
7497
7498 return State;
7499 }();
7500
7501 /**
7502 * A default state when there's no user input and no animation's playing
7503 * @ko 사용자의 입력이 없고, 애니메이션이 동작하고있지 않은 기본 상태
7504 * @internal
7505 */
7506
7507 var IdleState = function (_super) {
7508 __extends$2(IdleState, _super);
7509
7510 function IdleState() {
7511 var _this = _super !== null && _super.apply(this, arguments) || this;
7512 /**
7513 * Whether user is clicking or touching
7514 * @ko 현재 사용자가 클릭/터치중인지 여부
7515 * @type {false}
7516 * @readonly
7517 */
7518
7519
7520 _this.holding = false;
7521 /**
7522 * Whether Flicking's animating
7523 * @ko 현재 애니메이션 동작 여부
7524 * @type {false}
7525 * @readonly
7526 */
7527
7528 _this.animating = false;
7529 return _this;
7530 }
7531
7532 var __proto = IdleState.prototype;
7533
7534 __proto.onEnter = function () {
7535 this._delta = 0;
7536 this._targetPanel = null;
7537 };
7538
7539 __proto.onHold = function (ctx) {
7540 // Shouldn't do any action until any panels on flicking area
7541 var flicking = ctx.flicking,
7542 axesEvent = ctx.axesEvent,
7543 transitTo = ctx.transitTo;
7544
7545 if (flicking.renderer.panelCount <= 0) {
7546 transitTo(STATE_TYPE.DISABLED);
7547 return;
7548 }
7549
7550 var holdStartEvent = new ComponentEvent$1(EVENTS.HOLD_START, {
7551 axesEvent: axesEvent
7552 });
7553 flicking.trigger(holdStartEvent);
7554
7555 if (holdStartEvent.isCanceled()) {
7556 transitTo(STATE_TYPE.DISABLED);
7557 } else {
7558 transitTo(STATE_TYPE.HOLDING);
7559 }
7560 }; // By methods call
7561
7562
7563 __proto.onChange = function (ctx) {
7564 var flicking = ctx.flicking,
7565 axesEvent = ctx.axesEvent,
7566 transitTo = ctx.transitTo;
7567 var controller = flicking.control.controller;
7568 var animatingContext = controller.animatingContext;
7569 var moveStartEvent = new ComponentEvent$1(EVENTS.MOVE_START, {
7570 isTrusted: axesEvent.isTrusted,
7571 holding: this.holding,
7572 direction: getDirection$1(animatingContext.start, animatingContext.end),
7573 axesEvent: axesEvent
7574 });
7575 flicking.trigger(moveStartEvent);
7576
7577 if (moveStartEvent.isCanceled()) {
7578 transitTo(STATE_TYPE.DISABLED);
7579 } else {
7580 // Trigger AnimatingState's onChange, to trigger "move" event immediately
7581 transitTo(STATE_TYPE.ANIMATING).onChange(ctx);
7582 }
7583 };
7584
7585 return IdleState;
7586 }(State);
7587
7588 /**
7589 * A state that activates when user's holding the Flicking area, but not moved a single pixel yet
7590 * @ko 사용자의 입력이 시작되었으나, 아직 움직이지는 않은 상태
7591 * @internal
7592 */
7593
7594 var HoldingState = function (_super) {
7595 __extends$2(HoldingState, _super);
7596
7597 function HoldingState() {
7598 var _this = _super !== null && _super.apply(this, arguments) || this;
7599 /**
7600 * Whether user is clicking or touching
7601 * @ko 현재 사용자가 클릭/터치중인지 여부
7602 * @type {true}
7603 * @readonly
7604 */
7605
7606
7607 _this.holding = true;
7608 /**
7609 * Whether Flicking's animating
7610 * @ko 현재 애니메이션 동작 여부
7611 * @type {false}
7612 * @readonly
7613 */
7614
7615 _this.animating = false;
7616 _this._releaseEvent = null;
7617 return _this;
7618 }
7619
7620 var __proto = HoldingState.prototype;
7621
7622 __proto.onChange = function (ctx) {
7623 var flicking = ctx.flicking,
7624 axesEvent = ctx.axesEvent,
7625 transitTo = ctx.transitTo;
7626 var inputEvent = axesEvent.inputEvent;
7627 var offset = flicking.horizontal ? inputEvent.offsetX : inputEvent.offsetY;
7628 var moveStartEvent = new ComponentEvent$1(EVENTS.MOVE_START, {
7629 isTrusted: axesEvent.isTrusted,
7630 holding: this.holding,
7631 direction: getDirection$1(0, -offset),
7632 axesEvent: axesEvent
7633 });
7634 flicking.trigger(moveStartEvent);
7635
7636 if (moveStartEvent.isCanceled()) {
7637 transitTo(STATE_TYPE.DISABLED);
7638 } else {
7639 // Trigger DraggingState's onChange, to trigger "move" event immediately
7640 transitTo(STATE_TYPE.DRAGGING).onChange(ctx);
7641 }
7642 };
7643
7644 __proto.onRelease = function (ctx) {
7645 var flicking = ctx.flicking,
7646 axesEvent = ctx.axesEvent,
7647 transitTo = ctx.transitTo;
7648 flicking.trigger(new ComponentEvent$1(EVENTS.HOLD_END, {
7649 axesEvent: axesEvent
7650 }));
7651
7652 if (axesEvent.delta.flick !== 0) {
7653 // Sometimes "release" event on axes triggered before "change" event
7654 // Especially if user flicked panel fast in really short amount of time
7655 // if delta is not zero, that means above case happened.
7656 // Event flow should be HOLD_START -> MOVE_START -> MOVE -> HOLD_END
7657 // At least one move event should be included between holdStart and holdEnd
7658 axesEvent.setTo({
7659 flick: flicking.camera.position
7660 }, 0);
7661 transitTo(STATE_TYPE.IDLE);
7662 return;
7663 } // Can't handle select event here,
7664 // As "finish" axes event happens
7665
7666
7667 this._releaseEvent = axesEvent;
7668 };
7669
7670 __proto.onFinish = function (ctx) {
7671 var e_1, _a;
7672
7673 var flicking = ctx.flicking,
7674 transitTo = ctx.transitTo; // Should transite to IDLE state before select event
7675 // As user expects hold is already finished
7676
7677 transitTo(STATE_TYPE.IDLE);
7678
7679 if (!this._releaseEvent) {
7680 return;
7681 } // Handle release event here
7682 // To prevent finish event called twice
7683
7684
7685 var releaseEvent = this._releaseEvent; // Static click
7686
7687 /* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access */
7688
7689 var srcEvent = releaseEvent.inputEvent.srcEvent;
7690 var clickedElement;
7691
7692 if (srcEvent.type === "touchend") {
7693 var touchEvent = srcEvent;
7694 var touch = touchEvent.changedTouches[0];
7695 clickedElement = document.elementFromPoint(touch.clientX, touch.clientY);
7696 } else {
7697 clickedElement = srcEvent.target;
7698 }
7699 /* eslint-enable */
7700
7701
7702 var panels = flicking.renderer.panels;
7703 var clickedPanel = null;
7704
7705 try {
7706 for (var panels_1 = __values$3(panels), panels_1_1 = panels_1.next(); !panels_1_1.done; panels_1_1 = panels_1.next()) {
7707 var panel = panels_1_1.value;
7708
7709 if (panel.contains(clickedElement)) {
7710 clickedPanel = panel;
7711 break;
7712 }
7713 }
7714 } catch (e_1_1) {
7715 e_1 = {
7716 error: e_1_1
7717 };
7718 } finally {
7719 try {
7720 if (panels_1_1 && !panels_1_1.done && (_a = panels_1.return)) _a.call(panels_1);
7721 } finally {
7722 if (e_1) throw e_1.error;
7723 }
7724 }
7725
7726 if (clickedPanel) {
7727 var cameraPosition = flicking.camera.position;
7728 var clickedPanelPosition = clickedPanel.position;
7729 flicking.trigger(new ComponentEvent$1(EVENTS.SELECT, {
7730 index: clickedPanel.index,
7731 panel: clickedPanel,
7732 // Direction to the clicked panel
7733 direction: getDirection$1(cameraPosition, clickedPanelPosition)
7734 }));
7735 }
7736 };
7737
7738 return HoldingState;
7739 }(State);
7740
7741 /**
7742 * A state that activates when user's dragging the Flicking area
7743 * @ko 사용자가 드래깅중인 상태
7744 * @internal
7745 */
7746
7747 var DraggingState = function (_super) {
7748 __extends$2(DraggingState, _super);
7749
7750 function DraggingState() {
7751 var _this = _super !== null && _super.apply(this, arguments) || this;
7752 /**
7753 * Whether user is clicking or touching
7754 * @ko 현재 사용자가 클릭/터치중인지 여부
7755 * @type {true}
7756 * @readonly
7757 */
7758
7759
7760 _this.holding = true;
7761 /**
7762 * Whether Flicking's animating
7763 * @ko 현재 애니메이션 동작 여부
7764 * @type {true}
7765 * @readonly
7766 */
7767
7768 _this.animating = true;
7769 return _this;
7770 }
7771
7772 var __proto = DraggingState.prototype;
7773
7774 __proto.onChange = function (ctx) {
7775 this._moveToChangedPosition(ctx);
7776 };
7777
7778 __proto.onRelease = function (ctx) {
7779 var flicking = ctx.flicking,
7780 axesEvent = ctx.axesEvent,
7781 transitTo = ctx.transitTo; // Update last position to cope with Axes's animating behavior
7782 // Axes uses start position when animation start
7783
7784 flicking.trigger(new ComponentEvent$1(EVENTS.HOLD_END, {
7785 axesEvent: axesEvent
7786 }));
7787
7788 if (flicking.renderer.panelCount <= 0) {
7789 // There're no panels
7790 transitTo(STATE_TYPE.IDLE);
7791 return;
7792 }
7793
7794 transitTo(STATE_TYPE.ANIMATING);
7795 var control = flicking.control;
7796 var position = axesEvent.destPos[POSITION_KEY];
7797 var duration = Math.max(axesEvent.duration, flicking.duration);
7798 void control.moveToPosition(position, duration, axesEvent);
7799 };
7800
7801 return DraggingState;
7802 }(State);
7803
7804 /**
7805 * A state that activates when Flicking's animating by user input or method call
7806 * @ko 사용자 입력이나 메소드 호출에 의해 Flicking의 애니메이션이 동작중인 상태
7807 * @internal
7808 */
7809
7810 var AnimatingState = function (_super) {
7811 __extends$2(AnimatingState, _super);
7812
7813 function AnimatingState() {
7814 var _this = _super !== null && _super.apply(this, arguments) || this;
7815 /**
7816 * Whether user is clicking or touching
7817 * @ko 현재 사용자가 클릭/터치중인지 여부
7818 * @type {false}
7819 * @readonly
7820 */
7821
7822
7823 _this.holding = false;
7824 /**
7825 * Whether Flicking's animating
7826 * @ko 현재 애니메이션 동작 여부
7827 * @type {true}
7828 * @readonly
7829 */
7830
7831 _this.animating = true;
7832 return _this;
7833 }
7834
7835 var __proto = AnimatingState.prototype;
7836
7837 __proto.onHold = function (ctx) {
7838 var flicking = ctx.flicking,
7839 axesEvent = ctx.axesEvent,
7840 transitTo = ctx.transitTo;
7841 this._delta = 0;
7842 flicking.control.updateInput();
7843 var holdStartEvent = new ComponentEvent$1(EVENTS.HOLD_START, {
7844 axesEvent: axesEvent
7845 });
7846 flicking.trigger(holdStartEvent);
7847
7848 if (holdStartEvent.isCanceled()) {
7849 transitTo(STATE_TYPE.DISABLED);
7850 } else {
7851 transitTo(STATE_TYPE.DRAGGING);
7852 }
7853 };
7854
7855 __proto.onChange = function (ctx) {
7856 this._moveToChangedPosition(ctx);
7857 };
7858
7859 __proto.onFinish = function (ctx) {
7860 var flicking = ctx.flicking,
7861 axesEvent = ctx.axesEvent,
7862 transitTo = ctx.transitTo;
7863 var control = flicking.control;
7864 var controller = control.controller;
7865 var animatingContext = controller.animatingContext;
7866 transitTo(STATE_TYPE.IDLE);
7867 flicking.trigger(new ComponentEvent$1(EVENTS.MOVE_END, {
7868 isTrusted: axesEvent.isTrusted,
7869 direction: getDirection$1(animatingContext.start, animatingContext.end),
7870 axesEvent: axesEvent
7871 }));
7872 control.setActive(this._targetPanel, control.activePanel, axesEvent.isTrusted);
7873 };
7874
7875 return AnimatingState;
7876 }(State);
7877
7878 /**
7879 * A state that activates when Flicking is stopped by event's `stop` method
7880 * @ko 이벤트의 `stop`호출에 의해 Flicking이 정지된 상태
7881 * @internal
7882 */
7883
7884 var DisabledState = function (_super) {
7885 __extends$2(DisabledState, _super);
7886
7887 function DisabledState() {
7888 var _this = _super !== null && _super.apply(this, arguments) || this;
7889 /**
7890 * Whether user is clicking or touching
7891 * @ko 현재 사용자가 클릭/터치중인지 여부
7892 * @type {false}
7893 * @readonly
7894 */
7895
7896
7897 _this.holding = false;
7898 /**
7899 * Whether Flicking's animating
7900 * @ko 현재 애니메이션 동작 여부
7901 * @type {true}
7902 * @readonly
7903 */
7904
7905 _this.animating = true;
7906 return _this;
7907 }
7908
7909 var __proto = DisabledState.prototype;
7910
7911 __proto.onAnimationEnd = function (ctx) {
7912 var transitTo = ctx.transitTo;
7913 transitTo(STATE_TYPE.IDLE);
7914 };
7915
7916 __proto.onChange = function (ctx) {
7917 var axesEvent = ctx.axesEvent,
7918 transitTo = ctx.transitTo; // Can stop Axes's change event
7919
7920 axesEvent.stop();
7921 transitTo(STATE_TYPE.IDLE);
7922 };
7923
7924 __proto.onRelease = function (ctx) {
7925 var axesEvent = ctx.axesEvent,
7926 transitTo = ctx.transitTo; // This is needed when stopped hold start event
7927
7928 if (axesEvent.delta.flick === 0) {
7929 transitTo(STATE_TYPE.IDLE);
7930 }
7931 };
7932
7933 return DisabledState;
7934 }(State);
7935
7936 /**
7937 * @internal
7938 */
7939
7940 var StateMachine = function () {
7941 function StateMachine() {
7942 var _this = this;
7943
7944 this.transitTo = function (nextStateType) {
7945 var nextState;
7946
7947 switch (nextStateType) {
7948 case STATE_TYPE.IDLE:
7949 nextState = new IdleState();
7950 break;
7951
7952 case STATE_TYPE.HOLDING:
7953 nextState = new HoldingState();
7954 break;
7955
7956 case STATE_TYPE.DRAGGING:
7957 nextState = new DraggingState();
7958 break;
7959
7960 case STATE_TYPE.ANIMATING:
7961 nextState = new AnimatingState();
7962 break;
7963
7964 case STATE_TYPE.DISABLED:
7965 nextState = new DisabledState();
7966 break;
7967 }
7968
7969 nextState.onEnter(_this._state);
7970 _this._state = nextState;
7971 return _this._state;
7972 };
7973
7974 this._state = new IdleState();
7975 }
7976
7977 var __proto = StateMachine.prototype;
7978 Object.defineProperty(__proto, "state", {
7979 get: function () {
7980 return this._state;
7981 },
7982 enumerable: false,
7983 configurable: true
7984 });
7985
7986 __proto.fire = function (eventType, externalCtx) {
7987 var currentState = this._state;
7988
7989 var ctx = __assign$2(__assign$2({}, externalCtx), {
7990 transitTo: this.transitTo
7991 });
7992
7993 switch (eventType) {
7994 case EVENT.HOLD:
7995 currentState.onHold(ctx);
7996 break;
7997
7998 case EVENT.CHANGE:
7999 currentState.onChange(ctx);
8000 break;
8001
8002 case EVENT.RELEASE:
8003 currentState.onRelease(ctx);
8004 break;
8005
8006 case EVENT.ANIMATION_END:
8007 currentState.onAnimationEnd(ctx);
8008 break;
8009
8010 case EVENT.FINISH:
8011 currentState.onFinish(ctx);
8012 break;
8013 }
8014 };
8015
8016 return StateMachine;
8017 }();
8018
8019 /*
8020 * Copyright (c) 2015 NAVER Corp.
8021 * egjs projects are licensed under the MIT license
8022 */
8023 /**
8024 * A controller that handles the {@link https://naver.github.io/egjs-axes/ @egjs/axes} events
8025 * @ko {@link https://naver.github.io/egjs-axes/ @egjs/axes}의 이벤트를 처리하는 컨트롤러 컴포넌트
8026 * @internal
8027 */
8028
8029 var AxesController = function () {
8030 /** */
8031 function AxesController() {
8032 var _this = this;
8033
8034 this._onAxesHold = function () {
8035 _this._dragged = false;
8036 };
8037
8038 this._onAxesChange = function () {
8039 _this._dragged = true;
8040 };
8041
8042 this._preventClickWhenDragged = function (e) {
8043 if (_this._dragged) {
8044 e.preventDefault();
8045 e.stopPropagation();
8046 }
8047
8048 _this._dragged = false;
8049 };
8050
8051 this._resetInternalValues();
8052
8053 this._stateMachine = new StateMachine();
8054 }
8055
8056 var __proto = AxesController.prototype;
8057 Object.defineProperty(__proto, "axes", {
8058 /**
8059 * An {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html Axes} instance
8060 * @ko {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html Axes}의 인스턴스
8061 * @type {Axes}
8062 * @see https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html
8063 * @readonly
8064 */
8065 get: function () {
8066 return this._axes;
8067 },
8068 enumerable: false,
8069 configurable: true
8070 });
8071 Object.defineProperty(__proto, "stateMachine", {
8072 /**
8073 * @internal
8074 */
8075 get: function () {
8076 return this._stateMachine;
8077 },
8078 enumerable: false,
8079 configurable: true
8080 });
8081 Object.defineProperty(__proto, "state", {
8082 /**
8083 * A activated {@link State} that shows the current status of the user input or the animation
8084 * @ko 현재 활성화된 {@link State} 인스턴스로 사용자 입력 또는 애니메이션 상태를 나타냅니다
8085 * @type {State}
8086 */
8087 get: function () {
8088 return this._stateMachine.state;
8089 },
8090 enumerable: false,
8091 configurable: true
8092 });
8093 Object.defineProperty(__proto, "animatingContext", {
8094 /**
8095 * A context of the current animation playing
8096 * @ko 현재 재생중인 애니메이션 정보
8097 * @type {object}
8098 * @property {number} start A start position of the animation<ko>애니메이션 시작 지점</ko>
8099 * @property {number} end A end position of the animation<ko>애니메이션 끝 지점</ko>
8100 * @property {number} offset camera offset<ko>카메라 오프셋</ko>
8101 * @readonly
8102 */
8103 get: function () {
8104 return this._animatingContext;
8105 },
8106 enumerable: false,
8107 configurable: true
8108 });
8109 Object.defineProperty(__proto, "controlParams", {
8110 /**
8111 * A current control parameters of the Axes instance
8112 * @ko 활성화된 현재 Axes 패러미터들
8113 * @type {ControlParams}
8114 */
8115 get: function () {
8116 var axes = this._axes;
8117
8118 if (!axes) {
8119 return {
8120 range: {
8121 min: 0,
8122 max: 0
8123 },
8124 position: 0,
8125 circular: false
8126 };
8127 }
8128
8129 var axis = axes.axis[POSITION_KEY];
8130 return {
8131 range: {
8132 min: axis.range[0],
8133 max: axis.range[1]
8134 },
8135 circular: axis.circular[0],
8136 position: this.position
8137 };
8138 },
8139 enumerable: false,
8140 configurable: true
8141 });
8142 Object.defineProperty(__proto, "enabled", {
8143 /**
8144 * A Boolean indicating whether the user input is enabled
8145 * @ko 현재 사용자 입력이 활성화되었는지를 나타내는 값
8146 * @type {boolean}
8147 * @readonly
8148 */
8149 get: function () {
8150 var _a, _b;
8151
8152 return (_b = (_a = this._panInput) === null || _a === void 0 ? void 0 : _a.isEnable()) !== null && _b !== void 0 ? _b : false;
8153 },
8154 enumerable: false,
8155 configurable: true
8156 });
8157 Object.defineProperty(__proto, "position", {
8158 /**
8159 * Current position value in {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html Axes} instance
8160 * @ko {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html Axes} 인스턴스 내부의 현재 좌표 값
8161 * @type {number}
8162 * @readonly
8163 */
8164 get: function () {
8165 var _a, _b;
8166
8167 return (_b = (_a = this._axes) === null || _a === void 0 ? void 0 : _a.get([POSITION_KEY])[POSITION_KEY]) !== null && _b !== void 0 ? _b : 0;
8168 },
8169 enumerable: false,
8170 configurable: true
8171 });
8172 Object.defineProperty(__proto, "range", {
8173 /**
8174 * Current range value in {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html Axes} instance
8175 * @ko {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html Axes} 인스턴스 내부의 현재 이동 범위 값
8176 * @type {number[]}
8177 * @readonly
8178 */
8179 get: function () {
8180 var _a, _b;
8181
8182 return (_b = (_a = this._axes) === null || _a === void 0 ? void 0 : _a.axis[POSITION_KEY].range) !== null && _b !== void 0 ? _b : [0, 0];
8183 },
8184 enumerable: false,
8185 configurable: true
8186 });
8187 Object.defineProperty(__proto, "bounce", {
8188 /**
8189 * Actual bounce size(px)
8190 * @ko 적용된 bounce 크기(px 단위)
8191 * @type {number[]}
8192 * @readonly
8193 */
8194 get: function () {
8195 var _a;
8196
8197 return (_a = this._axes) === null || _a === void 0 ? void 0 : _a.axis[POSITION_KEY].bounce;
8198 },
8199 enumerable: false,
8200 configurable: true
8201 });
8202 /**
8203 * Initialize AxesController
8204 * @ko AxesController를 초기화합니다
8205 * @param {Flicking} flicking An instance of Flicking
8206 * @chainable
8207 * @return {this}
8208 */
8209
8210 __proto.init = function (flicking) {
8211 var _a;
8212
8213 var _this = this;
8214
8215 this._flicking = flicking;
8216 this._axes = new Axes$1((_a = {}, _a[POSITION_KEY] = {
8217 range: [0, 0],
8218 circular: false,
8219 bounce: [0, 0]
8220 }, _a), {
8221 deceleration: flicking.deceleration,
8222 interruptable: flicking.interruptable,
8223 easing: flicking.easing
8224 });
8225 this._panInput = new PanInput(flicking.viewport.element, {
8226 inputType: flicking.inputType,
8227 iOSEdgeSwipeThreshold: flicking.iOSEdgeSwipeThreshold,
8228 scale: flicking.horizontal ? [-1, 0] : [0, -1],
8229 releaseOnScroll: true
8230 });
8231 var axes = this._axes;
8232 axes.connect(flicking.horizontal ? [POSITION_KEY, ""] : ["", POSITION_KEY], this._panInput);
8233
8234 var _loop_1 = function (key) {
8235 var eventType = EVENT[key];
8236 axes.on(eventType, function (e) {
8237 _this._stateMachine.fire(eventType, {
8238 flicking: flicking,
8239 axesEvent: e
8240 });
8241 });
8242 };
8243
8244 for (var key in EVENT) {
8245 _loop_1(key);
8246 }
8247
8248 return this;
8249 };
8250 /**
8251 * Destroy AxesController and return to initial state
8252 * @ko AxesController를 초기 상태로 되돌립니다
8253 * @return {void}
8254 */
8255
8256
8257 __proto.destroy = function () {
8258 var _a;
8259
8260 if (this._axes) {
8261 this.removePreventClickHandler();
8262
8263 this._axes.destroy();
8264 }
8265
8266 (_a = this._panInput) === null || _a === void 0 ? void 0 : _a.destroy();
8267
8268 this._resetInternalValues();
8269 };
8270 /**
8271 * Enable input from the user (mouse/touch)
8272 * @ko 사용자의 입력(마우스/터치)를 활성화합니다
8273 * @chainable
8274 * @return {this}
8275 */
8276
8277
8278 __proto.enable = function () {
8279 var _a;
8280
8281 (_a = this._panInput) === null || _a === void 0 ? void 0 : _a.enable();
8282 return this;
8283 };
8284 /**
8285 * Disable input from the user (mouse/touch)
8286 * @ko 사용자의 입력(마우스/터치)를 막습니다
8287 * @chainable
8288 * @return {this}
8289 */
8290
8291
8292 __proto.disable = function () {
8293 var _a;
8294
8295 (_a = this._panInput) === null || _a === void 0 ? void 0 : _a.disable();
8296 return this;
8297 };
8298 /**
8299 * Update {@link https://naver.github.io/egjs-axes/ @egjs/axes}'s state
8300 * @ko {@link https://naver.github.io/egjs-axes/ @egjs/axes}의 상태를 갱신합니다
8301 * @chainable
8302 * @throws {FlickingError}
8303 * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link AxesController#init init} is not called before
8304 * <ko>{@link AxesController#init init}이 이전에 호출되지 않은 경우</ko>
8305 * @return {this}
8306 */
8307
8308
8309 __proto.update = function (controlParams) {
8310 var _a;
8311
8312 var flicking = getFlickingAttached(this._flicking, "Control");
8313 var camera = flicking.camera;
8314 var axes = this._axes;
8315 var axis = axes.axis[POSITION_KEY];
8316 axis.circular = [controlParams.circular, controlParams.circular];
8317 axis.range = [controlParams.range.min, controlParams.range.max];
8318 axis.bounce = parseBounce(flicking.bounce, camera.size);
8319 axes.axm.set((_a = {}, _a[POSITION_KEY] = controlParams.position, _a));
8320 return this;
8321 };
8322 /**
8323 * Attach a handler to the camera element to prevent click events during animation
8324 * @ko 카메라 엘리먼트에 애니메이션 도중에 클릭 이벤트를 방지하는 핸들러를 부착합니다
8325 * @return {this}
8326 */
8327
8328
8329 __proto.addPreventClickHandler = function () {
8330 var flicking = getFlickingAttached(this._flicking, "Control");
8331 var axes = this._axes;
8332 var cameraEl = flicking.camera.element;
8333 axes.on(EVENT.HOLD, this._onAxesHold);
8334 axes.on(EVENT.CHANGE, this._onAxesChange);
8335 cameraEl.addEventListener("click", this._preventClickWhenDragged, true);
8336 return this;
8337 };
8338 /**
8339 * Detach a handler to the camera element to prevent click events during animation
8340 * @ko 카메라 엘리먼트에 애니메이션 도중에 클릭 이벤트를 방지하는 핸들러를 탈착합니다
8341 * @return {this}
8342 */
8343
8344
8345 __proto.removePreventClickHandler = function () {
8346 var flicking = getFlickingAttached(this._flicking, "Control");
8347 var axes = this._axes;
8348 var cameraEl = flicking.camera.element;
8349 axes.off(EVENT.HOLD, this._onAxesHold);
8350 axes.off(EVENT.CHANGE, this._onAxesChange);
8351 cameraEl.removeEventListener("click", this._preventClickWhenDragged, true);
8352 return this;
8353 };
8354 /**
8355 * Run Axes's {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#setTo setTo} using the given position
8356 * @ko Axes의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#setTo setTo} 메소드를 주어진 좌표를 이용하여 수행합니다
8357 * @param {number} position A position to move<ko>이동할 좌표</ko>
8358 * @param {number} duration Duration of the animation (unit: ms)<ko>애니메이션 진행 시간 (단위: ms)</ko>
8359 * @param {number} [axesEvent] If provided, it'll use its {@link https://naver#github#io/egjs-axes/release/latest/doc/eg#Axes#html#setTo setTo} method instead<ko>이 값이 주어졌을 경우, 해당 이벤트의 {@link https://naver#github#io/egjs-axes/release/latest/doc/eg#Axes#html#setTo setTo} 메소드를 대신해서 사용합니다.</ko>
8360 * @throws {FlickingError}
8361 * |code|condition|
8362 * |---|---|
8363 * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|When {@link Control#init init} is not called before|
8364 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|
8365 * <ko>
8366 *
8367 * |code|condition|
8368 * |---|---|
8369 * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|{@link Control#init init}이 이전에 호출되지 않은 경우|
8370 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|
8371 *
8372 * </ko>
8373 * @return {Promise<void>} A Promise which will be resolved after reaching the target position<ko>해당 좌표 도달시에 resolve되는 Promise</ko>
8374 */
8375
8376
8377 __proto.animateTo = function (position, duration, axesEvent) {
8378 var _a;
8379
8380 var _this = this;
8381
8382 var axes = this._axes;
8383
8384 if (!axes) {
8385 return Promise.reject(new FlickingError(MESSAGE.NOT_ATTACHED_TO_FLICKING("Control"), CODE.NOT_ATTACHED_TO_FLICKING));
8386 }
8387
8388 var startPos = axes.get([POSITION_KEY])[POSITION_KEY];
8389
8390 if (startPos === position) {
8391 var flicking = getFlickingAttached(this._flicking, "Control");
8392 flicking.camera.lookAt(position);
8393 return Promise.resolve();
8394 }
8395
8396 this._animatingContext = {
8397 start: startPos,
8398 end: position,
8399 offset: 0
8400 };
8401
8402 var animate = function () {
8403 var _a, _b;
8404
8405 var resetContext = function () {
8406 _this._animatingContext = {
8407 start: 0,
8408 end: 0,
8409 offset: 0
8410 };
8411 };
8412
8413 axes.once(EVENT.FINISH, resetContext);
8414
8415 if (axesEvent) {
8416 axesEvent.setTo((_a = {}, _a[POSITION_KEY] = position, _a), duration);
8417 } else {
8418 axes.setTo((_b = {}, _b[POSITION_KEY] = position, _b), duration);
8419 }
8420 };
8421
8422 if (duration === 0) {
8423 var flicking = getFlickingAttached(this._flicking, "Control");
8424 var camera = flicking.camera;
8425 animate();
8426 var newPos = flicking.circularEnabled ? circulatePosition(position, camera.range.min, camera.range.max) : position;
8427 axes.axm.set((_a = {}, _a[POSITION_KEY] = newPos, _a));
8428 return Promise.resolve();
8429 } else {
8430 return new Promise(function (resolve, reject) {
8431 var animationFinishHandler = function () {
8432 axes.off(EVENT.HOLD, interruptionHandler);
8433 resolve();
8434 };
8435
8436 var interruptionHandler = function () {
8437 axes.off(EVENT.FINISH, animationFinishHandler);
8438 reject(new FlickingError(MESSAGE.ANIMATION_INTERRUPTED, CODE.ANIMATION_INTERRUPTED));
8439 };
8440
8441 axes.once(EVENT.FINISH, animationFinishHandler);
8442 axes.once(EVENT.HOLD, interruptionHandler);
8443 animate();
8444 });
8445 }
8446 };
8447
8448 __proto._resetInternalValues = function () {
8449 this._flicking = null;
8450 this._axes = null;
8451 this._panInput = null;
8452 this._animatingContext = {
8453 start: 0,
8454 end: 0,
8455 offset: 0
8456 };
8457 this._dragged = false;
8458 };
8459
8460 return AxesController;
8461 }();
8462
8463 /**
8464 * A component that manages inputs and animation of Flicking
8465 * @ko Flicking의 입력 장치 & 애니메이션을 담당하는 컴포넌트
8466 */
8467
8468 var Control$1 = function () {
8469 /** */
8470 function Control() {
8471 this._flicking = null;
8472 this._controller = new AxesController();
8473 this._activePanel = null;
8474 }
8475
8476 var __proto = Control.prototype;
8477 Object.defineProperty(__proto, "controller", {
8478 /**
8479 * A controller that handles the {@link https://naver.github.io/egjs-axes/ @egjs/axes} events
8480 * @ko {@link https://naver.github.io/egjs-axes/ @egjs/axes}의 이벤트를 처리하는 컨트롤러 컴포넌트
8481 * @type {AxesController}
8482 * @readonly
8483 */
8484 get: function () {
8485 return this._controller;
8486 },
8487 enumerable: false,
8488 configurable: true
8489 });
8490 Object.defineProperty(__proto, "activeIndex", {
8491 /**
8492 * Index number of the {@link Flicking#currentPanel currentPanel}
8493 * @ko {@link Flicking#currentPanel currentPanel}의 인덱스 번호
8494 * @type {number}
8495 * @default 0
8496 * @readonly
8497 */
8498 get: function () {
8499 var _a, _b;
8500
8501 return (_b = (_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.index) !== null && _b !== void 0 ? _b : -1;
8502 },
8503 enumerable: false,
8504 configurable: true
8505 });
8506 Object.defineProperty(__proto, "activePanel", {
8507 /**
8508 * An active panel
8509 * @ko 현재 선택된 패널
8510 * @type {Panel | null}
8511 * @readonly
8512 */
8513 get: function () {
8514 return this._activePanel;
8515 },
8516 enumerable: false,
8517 configurable: true
8518 });
8519 Object.defineProperty(__proto, "animating", {
8520 /**
8521 * Whether Flicking's animating
8522 * @ko 현재 애니메이션 동작 여부
8523 * @type {boolean}
8524 * @readonly
8525 */
8526 get: function () {
8527 return this._controller.state.animating;
8528 },
8529 enumerable: false,
8530 configurable: true
8531 });
8532 Object.defineProperty(__proto, "holding", {
8533 /**
8534 * Whether user is clicking or touching
8535 * @ko 현재 사용자가 클릭/터치중인지 여부
8536 * @type {boolean}
8537 * @readonly
8538 */
8539 get: function () {
8540 return this._controller.state.holding;
8541 },
8542 enumerable: false,
8543 configurable: true
8544 });
8545 /**
8546 * Initialize Control
8547 * @ko Control을 초기화합니다
8548 * @param {Flicking} flicking An instance of {@link Flicking}<ko>Flicking의 인스턴스</ko>
8549 * @chainable
8550 * @return {this}
8551 */
8552
8553 __proto.init = function (flicking) {
8554 this._flicking = flicking;
8555
8556 this._controller.init(flicking);
8557
8558 return this;
8559 };
8560 /**
8561 * Destroy Control and return to initial state
8562 * @ko Control을 초기 상태로 되돌립니다
8563 * @return {void}
8564 */
8565
8566
8567 __proto.destroy = function () {
8568 this._controller.destroy();
8569
8570 this._flicking = null;
8571 this._activePanel = null;
8572 };
8573 /**
8574 * Enable input from the user (mouse/touch)
8575 * @ko 사용자의 입력(마우스/터치)를 활성화합니다
8576 * @chainable
8577 * @return {this}
8578 */
8579
8580
8581 __proto.enable = function () {
8582 this._controller.enable();
8583
8584 return this;
8585 };
8586 /**
8587 * Disable input from the user (mouse/touch)
8588 * @ko 사용자의 입력(마우스/터치)를 막습니다
8589 * @chainable
8590 * @return {this}
8591 */
8592
8593
8594 __proto.disable = function () {
8595 this._controller.disable();
8596
8597 return this;
8598 };
8599 /**
8600 * Update position after resizing
8601 * @ko resize 이후에 position을 업데이트합니다
8602 * @param {number} progressInPanel Previous camera's progress in active panel before resize<ko>Resize 이전 현재 선택된 패널 내에서의 카메라 progress 값</ko>
8603 * @throws {FlickingError}
8604 * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
8605 * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>
8606 * @chainable
8607 * @return {Promise<void>}
8608 */
8609
8610
8611 __proto.updatePosition = function (_progressInPanel) {
8612 var flicking = getFlickingAttached(this._flicking, "Control");
8613 var camera = flicking.camera;
8614 var activePanel = this._activePanel;
8615
8616 if (activePanel) {
8617 camera.lookAt(camera.clampToReachablePosition(activePanel.position));
8618 }
8619 };
8620 /**
8621 * Update {@link Control#controller controller}'s state
8622 * @ko {@link Control#controller controller}의 내부 상태를 갱신합니다
8623 * @chainable
8624 * @return {this}
8625 */
8626
8627
8628 __proto.updateInput = function () {
8629 var flicking = getFlickingAttached(this._flicking, "Control");
8630 var camera = flicking.camera;
8631
8632 this._controller.update(camera.controlParams);
8633
8634 return this;
8635 };
8636 /**
8637 * Reset {@link Control#activePanel activePanel} to `null`
8638 * @ko {@link Control#activePanel activePanel}을 `null`로 초기화합니다
8639 * @chainable
8640 * @return {this}
8641 */
8642
8643
8644 __proto.resetActive = function () {
8645 this._activePanel = null;
8646 return this;
8647 };
8648 /**
8649 * Move {@link Camera} to the given panel
8650 * @ko {@link Camera}를 해당 패널 위로 이동합니다
8651 * @param {Panel} panel The target panel to move<ko>이동할 패널</ko>
8652 * @param {object} options An options object<ko>옵션 오브젝트</ko>
8653 * @param {number} duration Duration of the animation (unit: ms)<ko>애니메이션 진행 시간 (단위: ms)</ko>
8654 * @param {object} [axesEvent] {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} event of {@link https://naver.github.io/egjs-axes/ Axes}
8655 * <ko>{@link https://naver.github.io/egjs-axes/ Axes}의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} 이벤트</ko>
8656 * @param {DIRECTION} [direction=DIRECTION.NONE] Direction to move, only available in the {@link Flicking#circular circular} mode<ko>이동할 방향. {@link Flicking#circular circular} 옵션 활성화시에만 사용 가능합니다</ko>
8657 * @fires Flicking#moveStart
8658 * @fires Flicking#move
8659 * @fires Flicking#moveEnd
8660 * @fires Flicking#willChange
8661 * @fires Flicking#changed
8662 * @fires Flicking#willRestore
8663 * @fires Flicking#restored
8664 * @fires Flicking#needPanel
8665 * @fires Flicking#visibleChange
8666 * @fires Flicking#reachEdge
8667 * @throws {FlickingError}
8668 * |code|condition|
8669 * |---|---|
8670 * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|When the given panel is already removed or not in the Camera's {@link Camera#range range}|
8671 * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|When {@link Control#init init} is not called before|
8672 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|
8673 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the animation is interrupted by user input|
8674 * <ko>
8675 *
8676 * |code|condition|
8677 * |---|---|
8678 * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|주어진 패널이 제거되었거나, Camera의 {@link Camera#range range} 밖에 있을 경우|
8679 * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|{@link Control#init init}이 이전에 호출되지 않은 경우|
8680 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|
8681 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|
8682 *
8683 * </ko>
8684 * @return {Promise<void>} A Promise which will be resolved after reaching the target panel<ko>해당 패널 도달시에 resolve되는 Promise</ko>
8685 */
8686
8687
8688 __proto.moveToPanel = function (panel, _a) {
8689 var duration = _a.duration,
8690 _b = _a.direction,
8691 direction = _b === void 0 ? DIRECTION.NONE : _b,
8692 axesEvent = _a.axesEvent;
8693 return __awaiter(this, void 0, void 0, function () {
8694 var flicking, camera, position, nearestAnchor, camPos_1, camRangeDiff, possiblePositions;
8695 return __generator(this, function (_c) {
8696 flicking = getFlickingAttached(this._flicking, "Control");
8697 camera = flicking.camera;
8698 position = panel.position;
8699 nearestAnchor = camera.findNearestAnchor(position);
8700
8701 if (panel.removed || !nearestAnchor) {
8702 return [2
8703 /*return*/
8704 , Promise.reject(new FlickingError(MESSAGE.POSITION_NOT_REACHABLE(panel.position), CODE.POSITION_NOT_REACHABLE))];
8705 }
8706
8707 if (!camera.canReach(panel)) {
8708 // Override position & panel if that panel is not reachable
8709 position = nearestAnchor.position;
8710 panel = nearestAnchor.panel;
8711 } else if (flicking.circularEnabled) {
8712 camPos_1 = this._controller.position;
8713 camRangeDiff = camera.rangeDiff;
8714 possiblePositions = [position, position + camRangeDiff, position - camRangeDiff].filter(function (pos) {
8715 if (direction === DIRECTION.NONE) return true;
8716 return direction === DIRECTION.PREV ? pos <= camPos_1 : pos >= camPos_1;
8717 });
8718 position = possiblePositions.reduce(function (nearestPosition, pos) {
8719 if (Math.abs(camPos_1 - pos) < Math.abs(camPos_1 - nearestPosition)) {
8720 return pos;
8721 } else {
8722 return nearestPosition;
8723 }
8724 }, Infinity);
8725 }
8726
8727 this._triggerIndexChangeEvent(panel, panel.position, axesEvent);
8728
8729 return [2
8730 /*return*/
8731 , this._animateToPosition({
8732 position: position,
8733 duration: duration,
8734 newActivePanel: panel,
8735 axesEvent: axesEvent
8736 })];
8737 });
8738 });
8739 };
8740 /**
8741 * @internal
8742 */
8743
8744
8745 __proto.setActive = function (newActivePanel, prevActivePanel, isTrusted) {
8746 var _a;
8747
8748 var flicking = getFlickingAttached(this._flicking, "Control");
8749 this._activePanel = newActivePanel;
8750 flicking.camera.updateAdaptiveHeight();
8751
8752 if (newActivePanel !== prevActivePanel) {
8753 flicking.trigger(new ComponentEvent$1(EVENTS.CHANGED, {
8754 index: newActivePanel.index,
8755 panel: newActivePanel,
8756 prevIndex: (_a = prevActivePanel === null || prevActivePanel === void 0 ? void 0 : prevActivePanel.index) !== null && _a !== void 0 ? _a : -1,
8757 prevPanel: prevActivePanel,
8758 isTrusted: isTrusted,
8759 direction: prevActivePanel ? getDirection$1(prevActivePanel.position, newActivePanel.position) : DIRECTION.NONE
8760 }));
8761 } else {
8762 flicking.trigger(new ComponentEvent$1(EVENTS.RESTORED, {
8763 isTrusted: isTrusted
8764 }));
8765 }
8766 };
8767
8768 __proto._triggerIndexChangeEvent = function (panel, position, axesEvent) {
8769 var _a;
8770
8771 var flicking = getFlickingAttached(this._flicking, "Control");
8772 var triggeringEvent = panel !== this._activePanel ? EVENTS.WILL_CHANGE : EVENTS.WILL_RESTORE;
8773 var camera = flicking.camera;
8774 var activePanel = this._activePanel;
8775 var event = new ComponentEvent$1(triggeringEvent, {
8776 index: panel.index,
8777 panel: panel,
8778 isTrusted: (axesEvent === null || axesEvent === void 0 ? void 0 : axesEvent.isTrusted) || false,
8779 direction: getDirection$1((_a = activePanel === null || activePanel === void 0 ? void 0 : activePanel.position) !== null && _a !== void 0 ? _a : camera.position, position)
8780 });
8781 flicking.trigger(event);
8782
8783 if (event.isCanceled()) {
8784 throw new FlickingError(MESSAGE.STOP_CALLED_BY_USER, CODE.STOP_CALLED_BY_USER);
8785 }
8786 };
8787
8788 __proto._animateToPosition = function (_a) {
8789 var position = _a.position,
8790 duration = _a.duration,
8791 newActivePanel = _a.newActivePanel,
8792 axesEvent = _a.axesEvent;
8793 return __awaiter(this, void 0, void 0, function () {
8794 var flicking, animate, state;
8795
8796 var _this = this;
8797
8798 return __generator(this, function (_b) {
8799 flicking = getFlickingAttached(this._flicking, "Control");
8800
8801 animate = function () {
8802 return _this._controller.animateTo(position, duration, axesEvent);
8803 };
8804
8805 state = this._controller.state;
8806 state.targetPanel = newActivePanel;
8807
8808 if (duration <= 0) {
8809 return [2
8810 /*return*/
8811 , animate()];
8812 } else {
8813 return [2
8814 /*return*/
8815 , animate().then(function () {
8816 return __awaiter(_this, void 0, void 0, function () {
8817 return __generator(this, function (_a) {
8818 switch (_a.label) {
8819 case 0:
8820 return [4
8821 /*yield*/
8822 , flicking.renderer.render()];
8823
8824 case 1:
8825 _a.sent();
8826
8827 return [2
8828 /*return*/
8829 ];
8830 }
8831 });
8832 });
8833 }).catch(function (err) {
8834 if (axesEvent && err instanceof FlickingError && err.code === CODE.ANIMATION_INTERRUPTED) return;
8835 throw err;
8836 })];
8837 }
8838 });
8839 });
8840 };
8841
8842 return Control;
8843 }();
8844
8845 /**
8846 * A data component that has actual position where the camera should be stopped at
8847 * @ko 카메라가 정지해야하는 실제 위치를 담고 있는 데이터 컴포넌트
8848 */
8849 var AnchorPoint = function () {
8850 /**
8851 * @param {object} options An options object<ko>옵션 객체</ko>
8852 * @param {number} [options.index] Index of AnchorPoint<ko>AnchorPoint의 인덱스</ko>
8853 * @param {number} [options.position] Position of AnchorPoint<ko>AnchorPoint의 좌표</ko>
8854 * @param {Panel} [options.panel] A {@link Panel} instance AnchorPoint is referencing to<ko>AnchorPoint가 참조하고 있는 {@link Panel}</ko>
8855 */
8856 function AnchorPoint(_a) {
8857 var index = _a.index,
8858 position = _a.position,
8859 panel = _a.panel;
8860 this._index = index;
8861 this._pos = position;
8862 this._panel = panel;
8863 }
8864
8865 var __proto = AnchorPoint.prototype;
8866 Object.defineProperty(__proto, "index", {
8867 /**
8868 * Index of AnchorPoint
8869 * @ko AnchorPoint의 인덱스
8870 * @type {number}
8871 * @readonly
8872 */
8873 get: function () {
8874 return this._index;
8875 },
8876 enumerable: false,
8877 configurable: true
8878 });
8879 Object.defineProperty(__proto, "position", {
8880 /**
8881 * Position of AnchorPoint
8882 * @ko AnchorPoint의 좌표
8883 * @type {number}
8884 * @readonly
8885 */
8886 get: function () {
8887 return this._pos;
8888 },
8889 enumerable: false,
8890 configurable: true
8891 });
8892 Object.defineProperty(__proto, "panel", {
8893 /**
8894 * A {@link Panel} instance AnchorPoint is referencing to
8895 * @ko AnchorPoint가 참조하고 있는 {@link Panel}
8896 * @type {Panel}
8897 * @readonly
8898 */
8899 get: function () {
8900 return this._panel;
8901 },
8902 enumerable: false,
8903 configurable: true
8904 });
8905 return AnchorPoint;
8906 }();
8907
8908 /**
8909 * A {@link Control} that uses a release momentum to choose destination panel
8910 * @ko 입력을 중단한 시점의 가속도에 영향받아 도달할 패널을 계산하는 이동 방식을 사용하는 {@link Control}
8911 */
8912
8913 var SnapControl = function (_super) {
8914 __extends$2(SnapControl, _super);
8915 /** */
8916
8917
8918 function SnapControl(_a) {
8919 var _b = _a === void 0 ? {} : _a,
8920 _c = _b.count,
8921 count = _c === void 0 ? Infinity : _c;
8922
8923 var _this = _super.call(this) || this;
8924
8925 _this._count = count;
8926 return _this;
8927 }
8928
8929 var __proto = SnapControl.prototype;
8930 Object.defineProperty(__proto, "count", {
8931 /**
8932 * Maximum number of panels can go after release
8933 * @ko 입력 중단 이후 통과하여 이동할 수 있는 패널의 최대 갯수
8934 * @type {number}
8935 * @default Infinity
8936 */
8937 get: function () {
8938 return this._count;
8939 },
8940 set: function (val) {
8941 this._count = val;
8942 },
8943 enumerable: false,
8944 configurable: true
8945 });
8946 /**
8947 * Move {@link Camera} to the given position
8948 * @ko {@link Camera}를 주어진 좌표로 이동합니다
8949 * @param {number} position The target position to move<ko>이동할 좌표</ko>
8950 * @param {number} duration Duration of the panel movement animation (unit: ms).<ko>패널 이동 애니메이션 진행 시간 (단위: ms)</ko>
8951 * @param {object} [axesEvent] {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} event of {@link https://naver.github.io/egjs-axes/ Axes}
8952 * <ko>{@link https://naver.github.io/egjs-axes/ Axes}의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} 이벤트</ko>
8953 * @fires Flicking#moveStart
8954 * @fires Flicking#move
8955 * @fires Flicking#moveEnd
8956 * @fires Flicking#willChange
8957 * @fires Flicking#changed
8958 * @fires Flicking#willRestore
8959 * @fires Flicking#restored
8960 * @fires Flicking#needPanel
8961 * @fires Flicking#visibleChange
8962 * @fires Flicking#reachEdge
8963 * @throws {FlickingError}
8964 * |code|condition|
8965 * |---|---|
8966 * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|When the given panel is already removed or not in the Camera's {@link Camera#range range}|
8967 * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|When {@link Control#init init} is not called before|
8968 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|
8969 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the animation is interrupted by user input|
8970 * <ko>
8971 *
8972 * |code|condition|
8973 * |---|---|
8974 * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|주어진 패널이 제거되었거나, Camera의 {@link Camera#range range} 밖에 있을 경우|
8975 * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|{@link Control#init init}이 이전에 호출되지 않은 경우|
8976 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|
8977 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|
8978 *
8979 * </ko>
8980 * @return {Promise<void>} A Promise which will be resolved after reaching the target position<ko>해당 좌표 도달시에 resolve되는 Promise</ko>
8981 */
8982
8983 __proto.moveToPosition = function (position, duration, axesEvent) {
8984 return __awaiter(this, void 0, void 0, function () {
8985 var flicking, camera, activeAnchor, anchorAtCamera, state, snapThreshold, posDelta, absPosDelta, snapDelta, targetAnchor;
8986 return __generator(this, function (_a) {
8987 flicking = getFlickingAttached(this._flicking, "Control");
8988 camera = flicking.camera;
8989 activeAnchor = camera.findActiveAnchor();
8990 anchorAtCamera = camera.findNearestAnchor(camera.position);
8991 state = flicking.control.controller.state;
8992
8993 if (!activeAnchor || !anchorAtCamera) {
8994 return [2
8995 /*return*/
8996 , Promise.reject(new FlickingError(MESSAGE.POSITION_NOT_REACHABLE(position), CODE.POSITION_NOT_REACHABLE))];
8997 }
8998
8999 snapThreshold = this._calcSnapThreshold(position, activeAnchor);
9000 posDelta = flicking.animating ? state.delta : position - camera.position;
9001 absPosDelta = Math.abs(posDelta);
9002 snapDelta = axesEvent && axesEvent.delta[POSITION_KEY] !== 0 ? Math.abs(axesEvent.delta[POSITION_KEY]) : absPosDelta;
9003
9004 if (snapDelta >= snapThreshold && snapDelta > 0) {
9005 // Move to anchor at position
9006 targetAnchor = this._findSnappedAnchor(position, anchorAtCamera);
9007 } else if (absPosDelta >= flicking.threshold && absPosDelta > 0) {
9008 // Move to the adjacent panel
9009 targetAnchor = this._findAdjacentAnchor(posDelta, anchorAtCamera);
9010 } else {
9011 // Restore to active panel
9012 targetAnchor = anchorAtCamera;
9013 }
9014
9015 this._triggerIndexChangeEvent(targetAnchor.panel, position, axesEvent);
9016
9017 return [2
9018 /*return*/
9019 , this._animateToPosition({
9020 position: camera.clampToReachablePosition(targetAnchor.position),
9021 duration: duration,
9022 newActivePanel: targetAnchor.panel,
9023 axesEvent: axesEvent
9024 })];
9025 });
9026 });
9027 };
9028
9029 __proto._findSnappedAnchor = function (position, anchorAtCamera) {
9030 var flicking = getFlickingAttached(this._flicking, "Control");
9031 var camera = flicking.camera;
9032 var count = this._count;
9033 var currentPos = camera.position;
9034 var clampedPosition = camera.clampToReachablePosition(position);
9035 var anchorAtPosition = camera.findAnchorIncludePosition(clampedPosition);
9036
9037 if (!anchorAtCamera || !anchorAtPosition) {
9038 throw new FlickingError(MESSAGE.POSITION_NOT_REACHABLE(position), CODE.POSITION_NOT_REACHABLE);
9039 }
9040
9041 if (!isFinite(count)) {
9042 return anchorAtPosition;
9043 }
9044
9045 var panelCount = flicking.panelCount;
9046 var anchors = camera.anchorPoints;
9047 var loopCount = Math.sign(position - currentPos) * Math.floor(Math.abs(position - currentPos) / camera.rangeDiff);
9048
9049 if (position > currentPos && anchorAtPosition.index < anchorAtCamera.index || anchorAtPosition.position > anchorAtCamera.position && anchorAtPosition.index === anchorAtCamera.index) {
9050 loopCount += 1;
9051 } else if (position < currentPos && anchorAtPosition.index > anchorAtCamera.index || anchorAtPosition.position < anchorAtCamera.position && anchorAtPosition.index === anchorAtCamera.index) {
9052 loopCount -= 1;
9053 }
9054
9055 var circularIndexOffset = loopCount * panelCount;
9056 var anchorAtPositionIndex = anchorAtPosition.index + circularIndexOffset;
9057
9058 if (Math.abs(anchorAtPositionIndex - anchorAtCamera.index) <= count) {
9059 var anchor = anchors[anchorAtPosition.index];
9060 return new AnchorPoint({
9061 index: anchor.index,
9062 position: anchor.position + loopCount * camera.rangeDiff,
9063 panel: anchor.panel
9064 });
9065 }
9066
9067 if (flicking.circularEnabled) {
9068 var targetAnchor = anchors[circulateIndex(anchorAtCamera.index + Math.sign(position - currentPos) * count, panelCount)];
9069 var loop = Math.floor(count / panelCount);
9070
9071 if (position > currentPos && targetAnchor.index < anchorAtCamera.index) {
9072 loop += 1;
9073 } else if (position < currentPos && targetAnchor.index > anchorAtCamera.index) {
9074 loop -= 1;
9075 }
9076
9077 return new AnchorPoint({
9078 index: targetAnchor.index,
9079 position: targetAnchor.position + loop * camera.rangeDiff,
9080 panel: targetAnchor.panel
9081 });
9082 } else {
9083 return anchors[clamp(anchorAtCamera.index + Math.sign(position - currentPos) * count, 0, anchors.length - 1)];
9084 }
9085 };
9086
9087 __proto._findAdjacentAnchor = function (posDelta, anchorAtCamera) {
9088 var _a;
9089
9090 var flicking = getFlickingAttached(this._flicking, "Control");
9091 var camera = flicking.camera;
9092 var adjacentAnchor = (_a = posDelta > 0 ? camera.getNextAnchor(anchorAtCamera) : camera.getPrevAnchor(anchorAtCamera)) !== null && _a !== void 0 ? _a : anchorAtCamera;
9093 return adjacentAnchor;
9094 };
9095
9096 __proto._calcSnapThreshold = function (position, activeAnchor) {
9097 var isNextDirection = position > activeAnchor.position;
9098 var panel = activeAnchor.panel;
9099 var panelSize = panel.size;
9100 var alignPos = panel.alignPosition; // Minimum distance needed to decide prev/next panel as nearest
9101
9102 /*
9103 * | Prev | Next |
9104 * |<------>|<------------>|
9105 * [ |<-Anchor ]
9106 */
9107
9108 return isNextDirection ? panelSize - alignPos + panel.margin.next : alignPos + panel.margin.prev;
9109 };
9110
9111 return SnapControl;
9112 }(Control$1);
9113
9114 /**
9115 * A {@link Control} that can be scrolled freely without alignment
9116 * @ko 패널이 정해진 지점에 정렬되지 않고, 자유롭게 스크롤할 수 있는 이동 방식을 사용하는 {@link Control}
9117 */
9118
9119 var FreeControl = function (_super) {
9120 __extends$2(FreeControl, _super);
9121 /** */
9122
9123
9124 function FreeControl(_a) {
9125 var _b = _a === void 0 ? {} : _a,
9126 _c = _b.stopAtEdge,
9127 stopAtEdge = _c === void 0 ? true : _c;
9128
9129 var _this = _super.call(this) || this;
9130
9131 _this._stopAtEdge = stopAtEdge;
9132 return _this;
9133 }
9134
9135 var __proto = FreeControl.prototype;
9136 Object.defineProperty(__proto, "stopAtEdge", {
9137 /**
9138 * Make scroll animation to stop at the start/end of the scroll area, not going out the bounce area
9139 * @ko 스크롤 애니메이션을 스크롤 영역의 시작과 끝부분에서 멈추도록 하여, 바운스 영역을 넘어가지 않도록 합니다
9140 * @type {boolean}
9141 * @default true
9142 */
9143 get: function () {
9144 return this._stopAtEdge;
9145 },
9146 set: function (val) {
9147 this._stopAtEdge = val;
9148 },
9149 enumerable: false,
9150 configurable: true
9151 });
9152 /**
9153 * Update position after resizing
9154 * @ko resize 이후에 position을 업데이트합니다
9155 * @param {number} progressInPanel Previous camera's progress in active panel before resize<ko>Resize 이전 현재 선택된 패널 내에서의 카메라 progress 값</ko>
9156 * @throws {FlickingError}
9157 * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
9158 * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>
9159 * @chainable
9160 * @return {Promise<void>}
9161 */
9162
9163 __proto.updatePosition = function (progressInPanel) {
9164 var flicking = getFlickingAttached(this._flicking, "Control");
9165 var camera = flicking.camera;
9166 var activePanel = this._activePanel;
9167
9168 if (activePanel) {
9169 var panelRange = activePanel.range;
9170 var newPosition = panelRange.min + (panelRange.max - panelRange.min) * progressInPanel;
9171 camera.lookAt(camera.clampToReachablePosition(newPosition));
9172 }
9173 };
9174 /**
9175 * Move {@link Camera} to the given position
9176 * @ko {@link Camera}를 주어진 좌표로 이동합니다
9177 * @param {number} position The target position to move<ko>이동할 좌표</ko>
9178 * @param {number} duration Duration of the panel movement animation (unit: ms).<ko>패널 이동 애니메이션 진행 시간 (단위: ms)</ko>
9179 * @param {object} [axesEvent] {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} event of {@link https://naver.github.io/egjs-axes/ Axes}
9180 * <ko>{@link https://naver.github.io/egjs-axes/ Axes}의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} 이벤트</ko>
9181 * @fires Flicking#moveStart
9182 * @fires Flicking#move
9183 * @fires Flicking#moveEnd
9184 * @fires Flicking#willChange
9185 * @fires Flicking#changed
9186 * @fires Flicking#willRestore
9187 * @fires Flicking#restored
9188 * @fires Flicking#needPanel
9189 * @fires Flicking#visibleChange
9190 * @fires Flicking#reachEdge
9191 * @throws {FlickingError}
9192 * |code|condition|
9193 * |---|---|
9194 * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|When the given panel is already removed or not in the Camera's {@link Camera#range range}|
9195 * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|When {@link Control#init init} is not called before|
9196 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|
9197 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the animation is interrupted by user input|
9198 * <ko>
9199 *
9200 * |code|condition|
9201 * |---|---|
9202 * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|주어진 패널이 제거되었거나, Camera의 {@link Camera#range range} 밖에 있을 경우|
9203 * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|{@link Control#init init}이 이전에 호출되지 않은 경우|
9204 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|
9205 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|
9206 *
9207 * </ko>
9208 * @return {Promise<void>} A Promise which will be resolved after reaching the target position<ko>해당 좌표 도달시에 resolve되는 Promise</ko>
9209 */
9210
9211
9212 __proto.moveToPosition = function (position, duration, axesEvent) {
9213 return __awaiter(this, void 0, void 0, function () {
9214 var flicking, camera, targetPos, anchorAtPosition, targetPanel;
9215 return __generator(this, function (_a) {
9216 flicking = getFlickingAttached(this._flicking, "Control");
9217 camera = flicking.camera;
9218 targetPos = camera.clampToReachablePosition(position);
9219 anchorAtPosition = camera.findAnchorIncludePosition(targetPos);
9220
9221 if (!anchorAtPosition) {
9222 return [2
9223 /*return*/
9224 , Promise.reject(new FlickingError(MESSAGE.POSITION_NOT_REACHABLE(position), CODE.POSITION_NOT_REACHABLE))];
9225 }
9226
9227 targetPanel = anchorAtPosition.panel; // Trigger only change event
9228
9229 if (targetPanel !== this._activePanel) {
9230 this._triggerIndexChangeEvent(targetPanel, position, axesEvent);
9231 }
9232
9233 return [2
9234 /*return*/
9235 , this._animateToPosition({
9236 position: this._stopAtEdge ? targetPos : position,
9237 duration: duration,
9238 newActivePanel: targetPanel,
9239 axesEvent: axesEvent
9240 })];
9241 });
9242 });
9243 };
9244
9245 return FreeControl;
9246 }(Control$1);
9247
9248 /**
9249 * A {@link Control} that allow you to select the maximum number of panels to move at a time
9250 * @ko 한번에 최대로 이동할 패널의 개수를 선택 가능한 {@link Control}
9251 */
9252
9253 var StrictControl = function (_super) {
9254 __extends$2(StrictControl, _super);
9255 /** */
9256
9257
9258 function StrictControl(_a) {
9259 var _b = _a === void 0 ? {} : _a,
9260 _c = _b.count,
9261 count = _c === void 0 ? 1 : _c;
9262
9263 var _this = _super.call(this) || this;
9264
9265 _this.setActive = function (newActivePanel, prevActivePanel, isTrusted) {
9266 _super.prototype.setActive.call(_this, newActivePanel, prevActivePanel, isTrusted);
9267
9268 _this.updateInput();
9269 };
9270
9271 _this._count = count;
9272
9273 _this._resetIndexRange();
9274
9275 return _this;
9276 }
9277
9278 var __proto = StrictControl.prototype;
9279 Object.defineProperty(__proto, "count", {
9280 /**
9281 * Maximum number of panels that can be moved at a time
9282 * @ko 최대로 움직일 수 있는 패널의 개수
9283 * @type {number}
9284 * @default 1
9285 */
9286 get: function () {
9287 return this._count;
9288 },
9289 set: function (val) {
9290 this._count = val;
9291 },
9292 enumerable: false,
9293 configurable: true
9294 });
9295 /**
9296 * Destroy Control and return to initial state
9297 * @ko Control을 초기 상태로 되돌립니다
9298 * @return {void}
9299 */
9300
9301 __proto.destroy = function () {
9302 _super.prototype.destroy.call(this);
9303
9304 this._resetIndexRange();
9305 };
9306 /**
9307 * Update {@link Control#controller controller}'s state
9308 * @ko {@link Control#controller controller}의 내부 상태를 갱신합니다
9309 * @chainable
9310 * @return {this}
9311 */
9312
9313
9314 __proto.updateInput = function () {
9315 var _a;
9316
9317 var flicking = getFlickingAttached(this._flicking, "Control");
9318 var camera = flicking.camera;
9319 var renderer = flicking.renderer;
9320 var controller = this._controller;
9321 var controlParams = camera.controlParams;
9322 var count = this._count;
9323 var activePanel = controller.state.animating ? (_a = camera.findNearestAnchor(camera.position)) === null || _a === void 0 ? void 0 : _a.panel : this._activePanel;
9324
9325 if (!activePanel) {
9326 controller.update(controlParams);
9327
9328 this._resetIndexRange();
9329
9330 return this;
9331 }
9332
9333 var cameraRange = controlParams.range;
9334 var currentPos = activePanel.position;
9335 var currentIndex = activePanel.index;
9336 var panelCount = renderer.panelCount;
9337 var prevPanelIndex = currentIndex - count;
9338 var nextPanelIndex = currentIndex + count;
9339
9340 if (prevPanelIndex < 0) {
9341 prevPanelIndex = flicking.circularEnabled ? getMinusCompensatedIndex((prevPanelIndex + 1) % panelCount - 1, panelCount) : clamp(prevPanelIndex, 0, panelCount - 1);
9342 }
9343
9344 if (nextPanelIndex >= panelCount) {
9345 nextPanelIndex = flicking.circularEnabled ? nextPanelIndex % panelCount : clamp(nextPanelIndex, 0, panelCount - 1);
9346 }
9347
9348 var prevPanel = renderer.panels[prevPanelIndex];
9349 var nextPanel = renderer.panels[nextPanelIndex];
9350 var prevPos = Math.max(prevPanel.position, cameraRange.min);
9351 var nextPos = Math.min(nextPanel.position, cameraRange.max);
9352
9353 if (prevPos > currentPos) {
9354 prevPos -= camera.rangeDiff;
9355 }
9356
9357 if (nextPos < currentPos) {
9358 nextPos += camera.rangeDiff;
9359 }
9360
9361 controlParams.range = {
9362 min: prevPos,
9363 max: nextPos
9364 };
9365
9366 if (controlParams.circular) {
9367 if (controlParams.position < prevPos) {
9368 controlParams.position += camera.rangeDiff;
9369 }
9370
9371 if (controlParams.position > nextPos) {
9372 controlParams.position -= camera.rangeDiff;
9373 }
9374 }
9375
9376 controlParams.circular = false;
9377 controller.update(controlParams);
9378 this._indexRange = {
9379 min: prevPanel.index,
9380 max: nextPanel.index
9381 };
9382 return this;
9383 };
9384 /**
9385 * Move {@link Camera} to the given position
9386 * @ko {@link Camera}를 주어진 좌표로 이동합니다
9387 * @param {number} position The target position to move<ko>이동할 좌표</ko>
9388 * @param {number} duration Duration of the panel movement animation (unit: ms).<ko>패널 이동 애니메이션 진행 시간 (단위: ms)</ko>
9389 * @param {object} [axesEvent] {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} event of {@link https://naver.github.io/egjs-axes/ Axes}
9390 * <ko>{@link https://naver.github.io/egjs-axes/ Axes}의 {@link https://naver.github.io/egjs-axes/release/latest/doc/eg.Axes.html#event:release release} 이벤트</ko>
9391 * @fires Flicking#moveStart
9392 * @fires Flicking#move
9393 * @fires Flicking#moveEnd
9394 * @fires Flicking#willChange
9395 * @fires Flicking#changed
9396 * @fires Flicking#willRestore
9397 * @fires Flicking#restored
9398 * @fires Flicking#needPanel
9399 * @fires Flicking#visibleChange
9400 * @fires Flicking#reachEdge
9401 * @throws {FlickingError}
9402 * |code|condition|
9403 * |---|---|
9404 * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|When the given panel is already removed or not in the Camera's {@link Camera#range range}|
9405 * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|When {@link Control#init init} is not called before|
9406 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|
9407 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the animation is interrupted by user input|
9408 * <ko>
9409 *
9410 * |code|condition|
9411 * |---|---|
9412 * |{@link ERROR_CODE POSITION_NOT_REACHABLE}|주어진 패널이 제거되었거나, Camera의 {@link Camera#range range} 밖에 있을 경우|
9413 * |{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING}|{@link Control#init init}이 이전에 호출되지 않은 경우|
9414 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|
9415 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|
9416 *
9417 * </ko>
9418 * @return {Promise<void>} A Promise which will be resolved after reaching the target position<ko>해당 좌표 도달시에 resolve되는 Promise</ko>
9419 */
9420
9421
9422 __proto.moveToPosition = function (position, duration, axesEvent) {
9423 return __awaiter(this, void 0, void 0, function () {
9424 var flicking, camera, activePanel, axesRange, indexRange, cameraRange, clampedPosition, anchorAtPosition, prevPos, isOverThreshold, adjacentAnchor, targetPos, targetPanel, anchors, firstAnchor, lastAnchor, shouldBounceToFirst, shouldBounceToLast, targetAnchor;
9425 return __generator(this, function (_a) {
9426 flicking = getFlickingAttached(this._flicking, "Control");
9427 camera = flicking.camera;
9428 activePanel = this._activePanel;
9429 axesRange = this._controller.range;
9430 indexRange = this._indexRange;
9431 cameraRange = camera.range;
9432 clampedPosition = clamp(camera.clampToReachablePosition(position), axesRange[0], axesRange[1]);
9433 anchorAtPosition = camera.findAnchorIncludePosition(clampedPosition);
9434
9435 if (!anchorAtPosition || !activePanel) {
9436 return [2
9437 /*return*/
9438 , Promise.reject(new FlickingError(MESSAGE.POSITION_NOT_REACHABLE(position), CODE.POSITION_NOT_REACHABLE))];
9439 }
9440
9441 prevPos = activePanel.position;
9442 isOverThreshold = Math.abs(position - prevPos) >= flicking.threshold;
9443 adjacentAnchor = position > prevPos ? camera.getNextAnchor(anchorAtPosition) : camera.getPrevAnchor(anchorAtPosition);
9444 anchors = camera.anchorPoints;
9445 firstAnchor = anchors[0];
9446 lastAnchor = anchors[anchors.length - 1];
9447 shouldBounceToFirst = position <= cameraRange.min && isBetween(firstAnchor.panel.index, indexRange.min, indexRange.max);
9448 shouldBounceToLast = position >= cameraRange.max && isBetween(lastAnchor.panel.index, indexRange.min, indexRange.max);
9449
9450 if (shouldBounceToFirst || shouldBounceToLast) {
9451 targetAnchor = position < cameraRange.min ? firstAnchor : lastAnchor;
9452 targetPanel = targetAnchor.panel;
9453 targetPos = targetAnchor.position;
9454 } else if (isOverThreshold && anchorAtPosition.position !== activePanel.position) {
9455 // Move to anchor at position
9456 targetPanel = anchorAtPosition.panel;
9457 targetPos = anchorAtPosition.position;
9458 } else if (isOverThreshold && adjacentAnchor && isBetween(adjacentAnchor.index, indexRange.min, indexRange.max)) {
9459 // Move to adjacent anchor
9460 targetPanel = adjacentAnchor.panel;
9461 targetPos = adjacentAnchor.position;
9462 } else {
9463 // Restore to active panel
9464 targetPos = camera.clampToReachablePosition(activePanel.position);
9465 targetPanel = activePanel;
9466 }
9467
9468 this._triggerIndexChangeEvent(targetPanel, position, axesEvent);
9469
9470 return [2
9471 /*return*/
9472 , this._animateToPosition({
9473 position: targetPos,
9474 duration: duration,
9475 newActivePanel: targetPanel,
9476 axesEvent: axesEvent
9477 })];
9478 });
9479 });
9480 };
9481
9482 __proto._resetIndexRange = function () {
9483 this._indexRange = {
9484 min: 0,
9485 max: 0
9486 };
9487 };
9488
9489 return StrictControl;
9490 }(Control$1);
9491
9492 /*
9493 * Copyright (c) 2015 NAVER Corp.
9494 * egjs projects are licensed under the MIT license
9495 */
9496
9497 var Control = {
9498 __proto__: null,
9499 Control: Control$1,
9500 SnapControl: SnapControl,
9501 FreeControl: FreeControl,
9502 StrictControl: StrictControl,
9503 AxesController: AxesController,
9504 State: State,
9505 IdleState: IdleState,
9506 HoldingState: HoldingState,
9507 DraggingState: DraggingState,
9508 AnimatingState: AnimatingState,
9509 DisabledState: DisabledState,
9510 StateMachine: StateMachine
9511 };
9512
9513 /**
9514 * A component that manages actual movement inside the viewport
9515 * @ko 뷰포트 내에서의 실제 움직임을 담당하는 컴포넌트
9516 */
9517
9518 var Camera$1 = function () {
9519 /** */
9520 function Camera(_a) {
9521 var _this = this;
9522
9523 var _b = _a === void 0 ? {} : _a,
9524 _c = _b.align,
9525 align = _c === void 0 ? ALIGN.CENTER : _c;
9526
9527 this._checkTranslateSupport = function () {
9528 var e_1, _a;
9529
9530 var transforms = ["webkitTransform", "msTransform", "MozTransform", "OTransform", "transform"];
9531 var supportedStyle = document.documentElement.style;
9532 var transformName = "";
9533
9534 try {
9535 for (var transforms_1 = __values$3(transforms), transforms_1_1 = transforms_1.next(); !transforms_1_1.done; transforms_1_1 = transforms_1.next()) {
9536 var prefixedTransform = transforms_1_1.value;
9537
9538 if (prefixedTransform in supportedStyle) {
9539 transformName = prefixedTransform;
9540 }
9541 }
9542 } catch (e_1_1) {
9543 e_1 = {
9544 error: e_1_1
9545 };
9546 } finally {
9547 try {
9548 if (transforms_1_1 && !transforms_1_1.done && (_a = transforms_1.return)) _a.call(transforms_1);
9549 } finally {
9550 if (e_1) throw e_1.error;
9551 }
9552 }
9553
9554 if (!transformName) {
9555 throw new FlickingError(MESSAGE.TRANSFORM_NOT_SUPPORTED, CODE.TRANSFORM_NOT_SUPPORTED);
9556 }
9557
9558 _this._transform = transformName;
9559 };
9560
9561 this._flicking = null;
9562
9563 this._resetInternalValues(); // Options
9564
9565
9566 this._align = align;
9567 }
9568
9569 var __proto = Camera.prototype;
9570 Object.defineProperty(__proto, "element", {
9571 // Internal states getter
9572
9573 /**
9574 * The camera(`.flicking-camera`) element
9575 * @ko 카메라(`.flicking-camera`) 엘리먼트
9576 * @type {HTMLElement}
9577 * @readonly
9578 */
9579 get: function () {
9580 return this._el;
9581 },
9582 enumerable: false,
9583 configurable: true
9584 });
9585 Object.defineProperty(__proto, "position", {
9586 /**
9587 * Current position of the camera
9588 * @ko Camera의 현재 좌표
9589 * @type {number}
9590 * @readonly
9591 */
9592 get: function () {
9593 return this._position;
9594 },
9595 enumerable: false,
9596 configurable: true
9597 });
9598 Object.defineProperty(__proto, "alignPosition", {
9599 /**
9600 * Align position inside the viewport where {@link Panel}'s {@link Panel#alignPosition alignPosition} should be located at
9601 * @ko 패널의 정렬 기준 위치. 뷰포트 내에서 {@link Panel}의 {@link Panel#alignPosition alignPosition}이 위치해야 하는 곳입니다
9602 * @type {number}
9603 * @readonly
9604 */
9605 get: function () {
9606 return this._alignPos;
9607 },
9608 enumerable: false,
9609 configurable: true
9610 });
9611 Object.defineProperty(__proto, "offset", {
9612 /**
9613 * Position offset, used for the {@link Flicking#renderOnlyVisible renderOnlyVisible} option
9614 * @ko Camera의 좌표 오프셋. {@link Flicking#renderOnlyVisible renderOnlyVisible} 옵션을 위해 사용됩니다.
9615 * @type {number}
9616 * @default 0
9617 * @readonly
9618 */
9619 get: function () {
9620 return this._offset;
9621 },
9622 enumerable: false,
9623 configurable: true
9624 });
9625 Object.defineProperty(__proto, "range", {
9626 /**
9627 * A range that Camera's {@link Camera#position position} can reach
9628 * @ko Camera의 {@link Camera#position position}이 도달 가능한 범위
9629 * @type {object}
9630 * @property {number} min A minimum position<ko>최소 위치</ko>
9631 * @property {number} min A maximum position<ko>최대 위치</ko>
9632 * @readonly
9633 */
9634 get: function () {
9635 return this._range;
9636 },
9637 enumerable: false,
9638 configurable: true
9639 });
9640 Object.defineProperty(__proto, "rangeDiff", {
9641 /**
9642 * A difference between Camera's minimum and maximum position that can reach
9643 * @ko Camera가 도달 가능한 최소/최대 좌표의 차이
9644 * @type {number}
9645 * @readonly
9646 */
9647 get: function () {
9648 return this._range.max - this._range.min;
9649 },
9650 enumerable: false,
9651 configurable: true
9652 });
9653 Object.defineProperty(__proto, "visiblePanels", {
9654 /**
9655 * An array of visible panels from the current position
9656 * @ko 현재 보이는 패널들의 배열
9657 * @type {Panel[]}
9658 * @readonly
9659 */
9660 get: function () {
9661 return this._visiblePanels;
9662 },
9663 enumerable: false,
9664 configurable: true
9665 });
9666 Object.defineProperty(__proto, "visibleRange", {
9667 /**
9668 * A range of the visible area from the current position
9669 * @ko 현재 위치에서 보이는 범위
9670 * @type {object}
9671 * @property {number} min A minimum position<ko>최소 위치</ko>
9672 * @property {number} min A maximum position<ko>최대 위치</ko>
9673 * @readonly
9674 */
9675 get: function () {
9676 return {
9677 min: this._position - this._alignPos,
9678 max: this._position - this._alignPos + this.size
9679 };
9680 },
9681 enumerable: false,
9682 configurable: true
9683 });
9684 Object.defineProperty(__proto, "anchorPoints", {
9685 /**
9686 * An array of {@link AnchorPoint}s that Camera can be stopped at
9687 * @ko 카메라가 도달 가능한 {@link AnchorPoint}의 목록
9688 * @type {AnchorPoint[]}
9689 * @readonly
9690 */
9691 get: function () {
9692 return this._anchors;
9693 },
9694 enumerable: false,
9695 configurable: true
9696 });
9697 Object.defineProperty(__proto, "controlParams", {
9698 /**
9699 * A current parameters of the Camera for updating {@link AxesController}
9700 * @ko {@link AxesController}를 업데이트하기 위한 현재 Camera 패러미터들
9701 * @type {ControlParams}
9702 * @readonly
9703 */
9704 get: function () {
9705 return {
9706 range: this._range,
9707 position: this._position,
9708 circular: false
9709 };
9710 },
9711 enumerable: false,
9712 configurable: true
9713 });
9714 Object.defineProperty(__proto, "atEdge", {
9715 /**
9716 * A Boolean value indicating whether Camera's over the minimum or maximum position reachable
9717 * @ko 현재 카메라가 도달 가능한 범위의 최소 혹은 최대점을 넘어섰는지를 나타냅니다
9718 * @type {boolean}
9719 * @readonly
9720 */
9721 get: function () {
9722 return this._position <= this._range.min || this._position >= this._range.max;
9723 },
9724 enumerable: false,
9725 configurable: true
9726 });
9727 Object.defineProperty(__proto, "size", {
9728 /**
9729 * Return the size of the viewport
9730 * @ko 뷰포트 크기를 반환합니다
9731 * @type {number}
9732 * @readonly
9733 */
9734 get: function () {
9735 var flicking = this._flicking;
9736 return flicking ? flicking.horizontal ? flicking.viewport.width : flicking.viewport.height : 0;
9737 },
9738 enumerable: false,
9739 configurable: true
9740 });
9741 Object.defineProperty(__proto, "progress", {
9742 /**
9743 * Return the camera's position progress from the first panel to last panel
9744 * Range is from 0 to last panel's index
9745 * @ko 첫번째 패널로부터 마지막 패널까지의 카메라 위치의 진행도를 반환합니다
9746 * 범위는 0부터 마지막 패널의 인덱스까지입니다
9747 * @type {number}
9748 * @readonly
9749 */
9750 get: function () {
9751 var flicking = this._flicking;
9752 var position = this._position + this._offset;
9753 var nearestAnchor = this.findNearestAnchor(this._position);
9754
9755 if (!flicking || !nearestAnchor) {
9756 return NaN;
9757 }
9758
9759 var nearestPanel = nearestAnchor.panel;
9760 var panelPos = nearestPanel.position + nearestPanel.offset;
9761 var bounceSize = flicking.control.controller.bounce;
9762 var _a = this.range,
9763 prevRange = _a.min,
9764 nextRange = _a.max;
9765 var rangeDiff = this.rangeDiff;
9766
9767 if (position === panelPos) {
9768 return nearestPanel.index;
9769 }
9770
9771 if (position < panelPos) {
9772 var prevPanel = nearestPanel.prev();
9773 var prevPosition = prevPanel ? prevPanel.position + prevPanel.offset : prevRange - bounceSize[0]; // Looped
9774
9775 if (prevPosition > panelPos) {
9776 prevPosition -= rangeDiff;
9777 }
9778
9779 return nearestPanel.index - 1 + getProgress(position, prevPosition, panelPos);
9780 } else {
9781 var nextPanel = nearestPanel.next();
9782 var nextPosition = nextPanel ? nextPanel.position + nextPanel.offset : nextRange + bounceSize[1]; // Looped
9783
9784 if (nextPosition < panelPos) {
9785 nextPosition += rangeDiff;
9786 }
9787
9788 return nearestPanel.index + getProgress(position, panelPos, nextPosition);
9789 }
9790 },
9791 enumerable: false,
9792 configurable: true
9793 });
9794 Object.defineProperty(__proto, "align", {
9795 // Options Getter
9796
9797 /**
9798 * A value indicating where the {@link Camera#alignPosition alignPosition} should be located at inside the viewport element
9799 * @ko {@link Camera#alignPosition alignPosition}이 뷰포트 엘리먼트 내의 어디에 위치해야 하는지를 나타내는 값
9800 * @type {ALIGN | string | number}
9801 */
9802 get: function () {
9803 return this._align;
9804 },
9805 // Options Setter
9806 set: function (val) {
9807 this._align = val;
9808 },
9809 enumerable: false,
9810 configurable: true
9811 });
9812 /**
9813 * Initialize Camera
9814 * @ko Camera를 초기화합니다
9815 * @param {Flicking} flicking An instance of {@link Flicking}<ko>Flicking의 인스턴스</ko>
9816 * @chainable
9817 * @throws {FlickingError}
9818 * {@link ERROR_CODE VAL_MUST_NOT_NULL} If the camera element(`.flicking-camera`) does not exist inside viewport element
9819 * <ko>{@link ERROR_CODE VAL_MUST_NOT_NULL} 뷰포트 엘리먼트 내부에 카메라 엘리먼트(`.flicking-camera`)가 존재하지 않을 경우</ko>
9820 * @return {this}
9821 */
9822
9823 __proto.init = function (flicking) {
9824 this._flicking = flicking;
9825 var viewportEl = flicking.viewport.element;
9826 checkExistence(viewportEl.firstElementChild, "First element child of the viewport element");
9827 this._el = viewportEl.firstElementChild;
9828
9829 this._checkTranslateSupport();
9830
9831 return this;
9832 };
9833 /**
9834 * Destroy Camera and return to initial state
9835 * @ko Camera를 초기 상태로 되돌립니다
9836 * @return {void}
9837 */
9838
9839
9840 __proto.destroy = function () {
9841 this._flicking = null;
9842
9843 this._resetInternalValues();
9844
9845 return this;
9846 };
9847 /**
9848 * Move to the given position and apply CSS transform
9849 * @ko 해당 좌표로 이동하고, CSS transform을 적용합니다
9850 * @param {number} pos A new position<ko>움직일 위치</ko>
9851 * @throws {FlickingError}
9852 * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
9853 * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>
9854 * @return {this}
9855 */
9856
9857
9858 __proto.lookAt = function (pos) {
9859 var prevPos = this._position;
9860 this._position = pos;
9861
9862 this._refreshVisiblePanels();
9863
9864 this._checkNeedPanel();
9865
9866 this._checkReachEnd(prevPos, pos);
9867
9868 this._applyTransform();
9869 };
9870 /**
9871 * Return a previous {@link AnchorPoint} of given {@link AnchorPoint}
9872 * If it does not exist, return `null` instead
9873 * @ko 주어진 {@link AnchorPoint}의 이전 {@link AnchorPoint}를 반환합니다
9874 * 존재하지 않을 경우 `null`을 반환합니다
9875 * @param {AnchorPoint} anchor A reference {@link AnchorPoint}<ko>기준 {@link AnchorPoint}</ko>
9876 * @return {AnchorPoint | null} The previous {@link AnchorPoint}<ko>이전 {@link AnchorPoint}</ko>
9877 */
9878
9879
9880 __proto.getPrevAnchor = function (anchor) {
9881 return this._anchors[anchor.index - 1] || null;
9882 };
9883 /**
9884 * Return a next {@link AnchorPoint} of given {@link AnchorPoint}
9885 * If it does not exist, return `null` instead
9886 * @ko 주어진 {@link AnchorPoint}의 다음 {@link AnchorPoint}를 반환합니다
9887 * 존재하지 않을 경우 `null`을 반환합니다
9888 * @param {AnchorPoint} anchor A reference {@link AnchorPoint}<ko>기준 {@link AnchorPoint}</ko>
9889 * @return {AnchorPoint | null} The next {@link AnchorPoint}<ko>다음 {@link AnchorPoint}</ko>
9890 */
9891
9892
9893 __proto.getNextAnchor = function (anchor) {
9894 return this._anchors[anchor.index + 1] || null;
9895 };
9896 /**
9897 * Return the camera's position progress in the panel below
9898 * Value is from 0 to 1 when the camera's inside panel
9899 * Value can be lower than 0 or bigger than 1 when it's in the margin area
9900 * @ko 현재 카메라 아래 패널에서의 위치 진행도를 반환합니다
9901 * 반환값은 카메라가 패널 내부에 있을 경우 0부터 1까지의 값을 갖습니다
9902 * 패널의 margin 영역에 있을 경우 0보다 작거나 1보다 큰 값을 반환할 수 있습니다
9903 */
9904
9905
9906 __proto.getProgressInPanel = function (panel) {
9907 var panelRange = panel.range;
9908 return (this._position - panelRange.min) / (panelRange.max - panelRange.min);
9909 };
9910 /**
9911 * Return {@link AnchorPoint} that includes given position
9912 * If there's no {@link AnchorPoint} that includes the given position, return `null` instead
9913 * @ko 주어진 좌표를 포함하는 {@link AnchorPoint}를 반환합니다
9914 * 주어진 좌표를 포함하는 {@link AnchorPoint}가 없을 경우 `null`을 반환합니다
9915 * @param {number} position A position to check<ko>확인할 좌표</ko>
9916 * @return {AnchorPoint | null} The {@link AnchorPoint} that includes the given position<ko>해당 좌표를 포함하는 {@link AnchorPoint}</ko>
9917 */
9918
9919
9920 __proto.findAnchorIncludePosition = function (position) {
9921 var anchors = this._anchors;
9922 var anchorsIncludingPosition = anchors.filter(function (anchor) {
9923 return anchor.panel.includePosition(position, true);
9924 });
9925 return anchorsIncludingPosition.reduce(function (nearest, anchor) {
9926 if (!nearest) return anchor;
9927 return Math.abs(nearest.position - position) < Math.abs(anchor.position - position) ? nearest : anchor;
9928 }, null);
9929 };
9930 /**
9931 * Return {@link AnchorPoint} nearest to given position
9932 * If there're no {@link AnchorPoint}s, return `null` instead
9933 * @ko 해당 좌표에서 가장 가까운 {@link AnchorPoint}를 반환합니다
9934 * {@link AnchorPoint}가 하나도 없을 경우 `null`을 반환합니다
9935 * @param {number} position A position to check<ko>확인할 좌표</ko>
9936 * @return {AnchorPoint | null} The {@link AnchorPoint} nearest to the given position<ko>해당 좌표에 가장 인접한 {@link AnchorPoint}</ko>
9937 */
9938
9939
9940 __proto.findNearestAnchor = function (position) {
9941 var anchors = this._anchors;
9942 if (anchors.length <= 0) return null;
9943 var prevDist = Infinity;
9944
9945 for (var anchorIdx = 0; anchorIdx < anchors.length; anchorIdx++) {
9946 var anchor = anchors[anchorIdx];
9947 var dist = Math.abs(anchor.position - position);
9948
9949 if (dist > prevDist) {
9950 // Return previous anchor
9951 return anchors[anchorIdx - 1];
9952 }
9953
9954 prevDist = dist;
9955 } // Return last anchor
9956
9957
9958 return anchors[anchors.length - 1];
9959 };
9960 /**
9961 * Return {@link AnchorPoint} that matches {@link Flicking#currentPanel}
9962 * @ko 현재 {@link Flicking#currentPanel}에 해당하는 {@link AnchorPoint}를 반환합니다
9963 * @return {AnchorPoint | null}
9964 */
9965
9966
9967 __proto.findActiveAnchor = function () {
9968 var flicking = getFlickingAttached(this._flicking, "Camera");
9969 var activeIndex = flicking.control.activeIndex;
9970 return find$1(this._anchors, function (anchor) {
9971 return anchor.panel.index === activeIndex;
9972 });
9973 };
9974 /**
9975 * Clamp the given position between camera's range
9976 * @ko 주어진 좌표를 Camera가 도달 가능한 범위 사이의 값으로 만듭니다
9977 * @param {number} position A position to clamp<ko>범위를 제한할 좌표</ko>
9978 * @return {number} A clamped position<ko>범위 제한된 좌표</ko>
9979 */
9980
9981
9982 __proto.clampToReachablePosition = function (position) {
9983 var range = this._range;
9984 return clamp(position, range.min, range.max);
9985 };
9986 /**
9987 * Check whether the given panel is inside of the Camera's range
9988 * @ko 해당 {@link Panel}이 Camera가 도달 가능한 범위 내에 있는지를 반환합니다
9989 * @param panel An instance of {@link Panel} to check<ko>확인할 {@link Panel}의 인스턴스</ko>
9990 * @return {boolean} Whether the panel's inside Camera's range<ko>도달 가능한 범위 내에 해당 패널이 존재하는지 여부</ko>
9991 */
9992
9993
9994 __proto.canReach = function (panel) {
9995 var range = this._range;
9996 if (panel.removed) return false;
9997 var panelPos = panel.position;
9998 return panelPos >= range.min && panelPos <= range.max;
9999 };
10000 /**
10001 * Check whether the given panel element is visible at the current position
10002 * @ko 현재 좌표에서 해당 패널 엘리먼트를 볼 수 있는지 여부를 반환합니다
10003 * @param panel An instance of {@link Panel} to check<ko>확인할 {@link Panel}의 인스턴스</ko>
10004 * @return Whether the panel element is visible at the current position<ko>현재 위치에서 해당 패널 엘리먼트가 보이는지 여부</ko>
10005 */
10006
10007
10008 __proto.canSee = function (panel) {
10009 var visibleRange = this.visibleRange; // Should not include margin, as we don't declare what the margin is visible as what the panel is visible.
10010
10011 return panel.includeRange(visibleRange.min, visibleRange.max, false);
10012 };
10013 /**
10014 * Update Camera's {@link Camera#alignPosition alignPosition}
10015 * @ko Camera의 {@link Camera#alignPosition alignPosition}을 업데이트합니다
10016 * @chainable
10017 * @return {this}
10018 */
10019
10020
10021 __proto.updateAlignPos = function () {
10022 var align = this._align;
10023 var alignVal = typeof align === "object" ? align.camera : align;
10024 this._alignPos = parseAlign$1(alignVal, this.size);
10025 return this;
10026 };
10027 /**
10028 * Update Camera's {@link Camera#anchorPoints anchorPoints}
10029 * @ko Camera의 {@link Camera#anchorPoints anchorPoints}를 업데이트합니다
10030 * @throws {FlickingError}
10031 * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
10032 * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>
10033 * @chainable
10034 * @return {this}
10035 */
10036
10037
10038 __proto.updateAnchors = function () {
10039 var flicking = getFlickingAttached(this._flicking, "Camera");
10040 var panels = flicking.renderer.panels;
10041 this._anchors = panels.map(function (panel, index) {
10042 return new AnchorPoint({
10043 index: index,
10044 position: panel.position,
10045 panel: panel
10046 });
10047 });
10048 return this;
10049 };
10050 /**
10051 * Update Viewport's height to active panel's height
10052 * @ko 현재 선택된 패널의 높이와 동일하도록 뷰포트의 높이를 업데이트합니다
10053 * @throws {FlickingError}
10054 * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
10055 * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>
10056 * @chainable
10057 * @return {this}
10058 */
10059
10060
10061 __proto.updateAdaptiveHeight = function () {
10062 var flicking = getFlickingAttached(this._flicking, "Camera");
10063 var activePanel = flicking.control.activePanel;
10064 if (!flicking.horizontal || !flicking.adaptive || !activePanel) return;
10065 flicking.viewport.setSize({
10066 height: activePanel.height
10067 });
10068 };
10069
10070 __proto.updateOffset = function () {
10071 var flicking = getFlickingAttached(this._flicking, "Camera");
10072 var unRenderedPanels = flicking.panels.filter(function (panel) {
10073 return !panel.rendered;
10074 });
10075 var position = this._position;
10076 this._offset = unRenderedPanels.filter(function (panel) {
10077 return panel.position + panel.offset < position;
10078 }).reduce(function (offset, panel) {
10079 return offset + panel.sizeIncludingMargin;
10080 }, 0);
10081
10082 this._applyTransform();
10083 };
10084 /**
10085 * Reset the history of {@link Flicking#event:needPanel needPanel} events so it can be triggered again
10086 * @ko 발생한 {@link Flicking#event:needPanel needPanel} 이벤트들을 초기화하여 다시 발생할 수 있도록 합니다
10087 * @chainable
10088 * @return {this}
10089 */
10090
10091
10092 __proto.resetNeedPanelHistory = function () {
10093 this._needPanelTriggered = {
10094 prev: false,
10095 next: false
10096 };
10097 return this;
10098 };
10099
10100 __proto._resetInternalValues = function () {
10101 this._position = 0;
10102 this._alignPos = 0;
10103 this._offset = 0;
10104 this._range = {
10105 min: 0,
10106 max: 0
10107 };
10108 this._visiblePanels = [];
10109 this._anchors = [];
10110 this._needPanelTriggered = {
10111 prev: false,
10112 next: false
10113 };
10114 };
10115
10116 __proto._refreshVisiblePanels = function () {
10117 var _this = this;
10118
10119 var flicking = getFlickingAttached(this._flicking, "Camera");
10120 var panels = flicking.renderer.panels;
10121 var newVisiblePanels = panels.filter(function (panel) {
10122 return _this.canSee(panel);
10123 });
10124 var prevVisiblePanels = this._visiblePanels;
10125 this._visiblePanels = newVisiblePanels;
10126 var added = newVisiblePanels.filter(function (panel) {
10127 return !includes(prevVisiblePanels, panel);
10128 });
10129 var removed = prevVisiblePanels.filter(function (panel) {
10130 return !includes(newVisiblePanels, panel);
10131 });
10132
10133 if (added.length > 0 || removed.length > 0) {
10134 void flicking.renderer.render().then(function () {
10135 flicking.trigger(new ComponentEvent$1(EVENTS.VISIBLE_CHANGE, {
10136 added: added,
10137 removed: removed,
10138 visiblePanels: newVisiblePanels
10139 }));
10140 });
10141 }
10142 };
10143
10144 __proto._checkNeedPanel = function () {
10145 var needPanelTriggered = this._needPanelTriggered;
10146 if (needPanelTriggered.prev && needPanelTriggered.next) return;
10147 var flicking = getFlickingAttached(this._flicking, "Camera");
10148 var panels = flicking.renderer.panels;
10149
10150 if (panels.length <= 0) {
10151 if (!needPanelTriggered.prev) {
10152 flicking.trigger(new ComponentEvent$1(EVENTS.NEED_PANEL, {
10153 direction: DIRECTION.PREV
10154 }));
10155 needPanelTriggered.prev = true;
10156 }
10157
10158 if (!needPanelTriggered.next) {
10159 flicking.trigger(new ComponentEvent$1(EVENTS.NEED_PANEL, {
10160 direction: DIRECTION.NEXT
10161 }));
10162 needPanelTriggered.next = true;
10163 }
10164
10165 return;
10166 }
10167
10168 var cameraPosition = this._position;
10169 var cameraSize = this.size;
10170 var cameraRange = this._range;
10171 var needPanelThreshold = flicking.needPanelThreshold;
10172 var cameraPrev = cameraPosition - this._alignPos;
10173 var cameraNext = cameraPrev + cameraSize;
10174 var firstPanel = panels[0];
10175 var lastPanel = panels[panels.length - 1];
10176
10177 if (!needPanelTriggered.prev) {
10178 var firstPanelPrev = firstPanel.range.min;
10179
10180 if (cameraPrev <= firstPanelPrev + needPanelThreshold || cameraPosition <= cameraRange.min + needPanelThreshold) {
10181 flicking.trigger(new ComponentEvent$1(EVENTS.NEED_PANEL, {
10182 direction: DIRECTION.PREV
10183 }));
10184 needPanelTriggered.prev = true;
10185 }
10186 }
10187
10188 if (!needPanelTriggered.next) {
10189 var lastPanelNext = lastPanel.range.max;
10190
10191 if (cameraNext >= lastPanelNext - needPanelThreshold || cameraPosition >= cameraRange.max - needPanelThreshold) {
10192 flicking.trigger(new ComponentEvent$1(EVENTS.NEED_PANEL, {
10193 direction: DIRECTION.NEXT
10194 }));
10195 needPanelTriggered.next = true;
10196 }
10197 }
10198 };
10199
10200 __proto._checkReachEnd = function (prevPos, newPos) {
10201 var flicking = getFlickingAttached(this._flicking, "Camera");
10202 var range = this._range;
10203 var wasBetweenRange = prevPos > range.min && prevPos < range.max;
10204 var isBetweenRange = newPos > range.min && newPos < range.max;
10205 if (!wasBetweenRange || isBetweenRange) return;
10206 var direction = newPos <= range.min ? DIRECTION.PREV : DIRECTION.NEXT;
10207 flicking.trigger(new ComponentEvent$1(EVENTS.REACH_EDGE, {
10208 direction: direction
10209 }));
10210 };
10211
10212 __proto._applyTransform = function () {
10213 var el = this._el;
10214 var flicking = getFlickingAttached(this._flicking, "Camera");
10215 var actualPosition = this._position - this._alignPos - this._offset;
10216 el.style[this._transform] = flicking.horizontal ? "translate(" + -actualPosition + "px)" : "translate(0, " + -actualPosition + "px)";
10217 };
10218
10219 return Camera;
10220 }();
10221
10222 /**
10223 * A {@link Camera} that can move from the position of the first panel to the position of the last panel
10224 * @ko 첫번째 패널의 좌표로부터 마지막 패널의 좌표로까지 이동할 수 있는 종류의 {@link Camera}
10225 */
10226
10227 var LinearCamera = function (_super) {
10228 __extends$2(LinearCamera, _super);
10229
10230 function LinearCamera() {
10231 return _super !== null && _super.apply(this, arguments) || this;
10232 }
10233 /**
10234 * Update {@link Camera#range range} of Camera
10235 * @ko Camera의 {@link Camera#range range}를 업데이트합니다
10236 * @chainable
10237 * @throws {FlickingError}
10238 * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
10239 * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>
10240 * @return {this}
10241 */
10242
10243
10244 var __proto = LinearCamera.prototype;
10245
10246 __proto.updateRange = function () {
10247 var _a, _b;
10248
10249 var flicking = getFlickingAttached(this._flicking, "Camera");
10250 var renderer = flicking.renderer;
10251 var firstPanel = renderer.getPanel(0);
10252 var lastPanel = renderer.getPanel(renderer.panelCount - 1);
10253 this._range = {
10254 min: (_a = firstPanel === null || firstPanel === void 0 ? void 0 : firstPanel.position) !== null && _a !== void 0 ? _a : 0,
10255 max: (_b = lastPanel === null || lastPanel === void 0 ? void 0 : lastPanel.position) !== null && _b !== void 0 ? _b : 0
10256 };
10257 return this;
10258 };
10259
10260 return LinearCamera;
10261 }(Camera$1);
10262
10263 /**
10264 * A {@link Camera} that connects the last panel and the first panel, enabling continuous loop
10265 * @ko 첫번째 패널과 마지막 패널이 이어진 상태로, 무한히 회전할 수 있는 종류의 {@link Camera}
10266 */
10267
10268 var CircularCamera = function (_super) {
10269 __extends$2(CircularCamera, _super);
10270
10271 function CircularCamera() {
10272 var _this = _super !== null && _super.apply(this, arguments) || this;
10273
10274 _this._circularOffset = 0;
10275 _this._circularEnabled = false;
10276 return _this;
10277 }
10278
10279 var __proto = CircularCamera.prototype;
10280 Object.defineProperty(__proto, "offset", {
10281 get: function () {
10282 return this._offset - this._circularOffset;
10283 },
10284 enumerable: false,
10285 configurable: true
10286 });
10287 Object.defineProperty(__proto, "controlParams", {
10288 get: function () {
10289 return {
10290 range: this._range,
10291 position: this._position,
10292 circular: this._circularEnabled
10293 };
10294 },
10295 enumerable: false,
10296 configurable: true
10297 });
10298
10299 __proto.getPrevAnchor = function (anchor) {
10300 if (!this._circularEnabled || anchor.index !== 0) return _super.prototype.getPrevAnchor.call(this, anchor);
10301 var anchors = this._anchors;
10302 var rangeDiff = this.rangeDiff;
10303 var lastAnchor = anchors[anchors.length - 1];
10304 return new AnchorPoint({
10305 index: lastAnchor.index,
10306 position: lastAnchor.position - rangeDiff,
10307 panel: lastAnchor.panel
10308 });
10309 };
10310
10311 __proto.getNextAnchor = function (anchor) {
10312 var anchors = this._anchors;
10313 if (!this._circularEnabled || anchor.index !== anchors.length - 1) return _super.prototype.getNextAnchor.call(this, anchor);
10314 var rangeDiff = this.rangeDiff;
10315 var firstAnchor = anchors[0];
10316 return new AnchorPoint({
10317 index: firstAnchor.index,
10318 position: firstAnchor.position + rangeDiff,
10319 panel: firstAnchor.panel
10320 });
10321 };
10322
10323 __proto.findAnchorIncludePosition = function (position) {
10324 if (!this._circularEnabled) return _super.prototype.findAnchorIncludePosition.call(this, position);
10325 var range = this._range;
10326 var positionInRange = circulatePosition(position, range.min, range.max);
10327
10328 var anchorInRange = _super.prototype.findAnchorIncludePosition.call(this, positionInRange);
10329
10330 if (!anchorInRange) return null;
10331 var rangeDiff = this.rangeDiff;
10332
10333 if (position < range.min) {
10334 var loopCount = -Math.floor((range.min - position) / rangeDiff) - 1;
10335 return new AnchorPoint({
10336 index: anchorInRange.index,
10337 position: anchorInRange.position + rangeDiff * loopCount,
10338 panel: anchorInRange.panel
10339 });
10340 } else if (position > range.max) {
10341 var loopCount = Math.floor((position - range.max) / rangeDiff) + 1;
10342 return new AnchorPoint({
10343 index: anchorInRange.index,
10344 position: anchorInRange.position + rangeDiff * loopCount,
10345 panel: anchorInRange.panel
10346 });
10347 }
10348
10349 return anchorInRange;
10350 };
10351
10352 __proto.clampToReachablePosition = function (position) {
10353 // Basically all position is reachable for circular camera
10354 return this._circularEnabled ? position : _super.prototype.clampToReachablePosition.call(this, position);
10355 };
10356
10357 __proto.canReach = function (panel) {
10358 if (panel.removed) return false;
10359 return this._circularEnabled // Always reachable on circular mode
10360 ? true : _super.prototype.canReach.call(this, panel);
10361 };
10362
10363 __proto.canSee = function (panel) {
10364 var range = this._range;
10365 var rangeDiff = this.rangeDiff;
10366 var visibleRange = this.visibleRange;
10367
10368 var visibleInCurrentRange = _super.prototype.canSee.call(this, panel);
10369
10370 if (!this._circularEnabled) {
10371 return visibleInCurrentRange;
10372 } // Check looped visible area for circular case
10373
10374
10375 if (visibleRange.min < range.min) {
10376 return visibleInCurrentRange || panel.includeRange(visibleRange.min + rangeDiff, visibleRange.max + rangeDiff, false);
10377 } else if (visibleRange.max > range.max) {
10378 return visibleInCurrentRange || panel.includeRange(visibleRange.min - rangeDiff, visibleRange.max - rangeDiff, false);
10379 }
10380
10381 return visibleInCurrentRange;
10382 };
10383 /**
10384 * Update {@link Camera#range range} of Camera
10385 * @ko Camera의 {@link Camera#range range}를 업데이트합니다
10386 * @chainable
10387 * @throws {FlickingError}
10388 * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
10389 * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>
10390 * @return {this}
10391 */
10392
10393
10394 __proto.updateRange = function () {
10395 var flicking = getFlickingAttached(this._flicking, "Camera");
10396 var renderer = flicking.renderer;
10397 var panels = renderer.panels;
10398
10399 if (panels.length <= 0) {
10400 this._resetInternalValues();
10401
10402 return this;
10403 }
10404
10405 var firstPanel = panels[0];
10406 var lastPanel = panels[panels.length - 1];
10407 var firstPanelPrev = firstPanel.range.min - firstPanel.margin.prev;
10408 var lastPanelNext = lastPanel.range.max + lastPanel.margin.next;
10409 var visibleSize = this.size;
10410 var panelSizeSum = lastPanelNext - firstPanelPrev;
10411 var canSetCircularMode = panels.every(function (panel) {
10412 return panelSizeSum - panel.size >= visibleSize;
10413 });
10414 this._circularEnabled = canSetCircularMode;
10415
10416 if (canSetCircularMode) {
10417 this._range = {
10418 min: firstPanelPrev,
10419 max: lastPanelNext
10420 };
10421 panels.forEach(function (panel) {
10422 return panel.updateCircularToggleDirection();
10423 });
10424 } else {
10425 this._range = {
10426 min: firstPanel.position,
10427 max: lastPanel.position
10428 };
10429 }
10430
10431 this._updateCircularOffset();
10432
10433 return this;
10434 };
10435
10436 __proto.lookAt = function (pos) {
10437 var flicking = getFlickingAttached(this._flicking, "Camera");
10438 var prevPos = this._position;
10439 if (pos === prevPos) return _super.prototype.lookAt.call(this, pos);
10440 var panels = flicking.renderer.panels;
10441 var toggled = panels.map(function (panel) {
10442 return panel.toggle(prevPos, pos);
10443 });
10444 this._position = pos;
10445
10446 if (toggled.some(function (isToggled) {
10447 return isToggled;
10448 })) {
10449 this._updateCircularOffset();
10450
10451 void flicking.renderer.render();
10452 }
10453
10454 return _super.prototype.lookAt.call(this, pos);
10455 };
10456
10457 __proto._applyTransform = function () {
10458 var el = this._el;
10459 var flicking = getFlickingAttached(this._flicking, "Camera");
10460 var actualPosition = this._position - this._alignPos - this._offset + this._circularOffset;
10461 el.style[this._transform] = flicking.horizontal ? "translate(" + -actualPosition + "px)" : "translate(0, " + -actualPosition + "px)";
10462 };
10463
10464 __proto._resetInternalValues = function () {
10465 _super.prototype._resetInternalValues.call(this);
10466
10467 this._circularOffset = 0;
10468 this._circularEnabled = false;
10469 };
10470
10471 __proto._calcPanelAreaSum = function (panels) {
10472 return panels.reduce(function (sum, panel) {
10473 return sum + panel.sizeIncludingMargin;
10474 }, 0);
10475 };
10476
10477 __proto._updateCircularOffset = function () {
10478 if (!this._circularEnabled) {
10479 this._circularOffset = 0;
10480 return;
10481 }
10482
10483 var flicking = getFlickingAttached(this._flicking, "Camera");
10484 var toggledPrev = [];
10485 var toggledNext = [];
10486 flicking.panels.filter(function (panel) {
10487 return panel.toggled;
10488 }).forEach(function (panel) {
10489 if (panel.toggleDirection === DIRECTION.PREV) {
10490 toggledPrev.push(panel);
10491 } else {
10492 toggledNext.push(panel);
10493 }
10494 });
10495 this._circularOffset = this._calcPanelAreaSum(toggledPrev) - this._calcPanelAreaSum(toggledNext);
10496 };
10497
10498 return CircularCamera;
10499 }(Camera$1);
10500
10501 /**
10502 * A {@link Camera} that set range not to go out of the first/last panel, so it won't show empty spaces before/after the first/last panel
10503 * @ko 첫번째와 마지막 패널 밖으로 넘어가지 못하도록 범위를 설정하여, 첫번째/마지막 패널 전/후의 빈 공간을 보이지 않도록 하는 종류의 {@link Camera}
10504 */
10505
10506 var BoundCamera = function (_super) {
10507 __extends$2(BoundCamera, _super);
10508
10509 function BoundCamera() {
10510 return _super !== null && _super.apply(this, arguments) || this;
10511 }
10512 /**
10513 * Update {@link Camera#range range} of Camera
10514 * @ko Camera의 {@link Camera#range range}를 업데이트합니다
10515 * @chainable
10516 * @throws {FlickingError}
10517 * {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
10518 * <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>
10519 * @return {this}
10520 */
10521
10522
10523 var __proto = BoundCamera.prototype;
10524
10525 __proto.updateRange = function () {
10526 var flicking = getFlickingAttached(this._flicking, "Camera");
10527 var renderer = flicking.renderer;
10528 var alignPos = this._alignPos;
10529 var firstPanel = renderer.getPanel(0);
10530 var lastPanel = renderer.getPanel(renderer.panelCount - 1);
10531
10532 if (!firstPanel || !lastPanel) {
10533 this._range = {
10534 min: 0,
10535 max: 0
10536 };
10537 return this;
10538 }
10539
10540 var viewportSize = this.size;
10541 var firstPanelPrev = firstPanel.range.min;
10542 var lastPanelNext = lastPanel.range.max;
10543 var panelAreaSize = lastPanelNext - firstPanelPrev;
10544 var isBiggerThanViewport = viewportSize < panelAreaSize;
10545 var firstPos = firstPanelPrev + alignPos;
10546 var lastPos = lastPanelNext - viewportSize + alignPos;
10547
10548 if (isBiggerThanViewport) {
10549 this._range = {
10550 min: firstPos,
10551 max: lastPos
10552 };
10553 } else {
10554 var align = this._align;
10555 var alignVal = typeof align === "object" ? align.camera : align;
10556 var pos = firstPos + parseAlign$1(alignVal, lastPos - firstPos);
10557 this._range = {
10558 min: pos,
10559 max: pos
10560 };
10561 }
10562
10563 return this;
10564 };
10565
10566 __proto.updateAnchors = function () {
10567 var _this = this;
10568
10569 var flicking = getFlickingAttached(this._flicking, "Camera");
10570 var panels = flicking.renderer.panels;
10571
10572 if (panels.length <= 0) {
10573 this._anchors = [];
10574 return this;
10575 }
10576
10577 var range = this._range;
10578 var reachablePanels = panels.filter(function (panel) {
10579 return _this.canReach(panel);
10580 });
10581
10582 if (reachablePanels.length > 0) {
10583 var shouldPrependBoundAnchor = reachablePanels[0].position !== range.min;
10584 var shouldAppendBoundAnchor = reachablePanels[reachablePanels.length - 1].position !== range.max;
10585 var indexOffset_1 = shouldPrependBoundAnchor ? 1 : 0;
10586 var newAnchors = reachablePanels.map(function (panel, idx) {
10587 return new AnchorPoint({
10588 index: idx + indexOffset_1,
10589 position: panel.position,
10590 panel: panel
10591 });
10592 });
10593
10594 if (shouldPrependBoundAnchor) {
10595 newAnchors.splice(0, 0, new AnchorPoint({
10596 index: 0,
10597 position: range.min,
10598 panel: panels[reachablePanels[0].index - 1]
10599 }));
10600 }
10601
10602 if (shouldAppendBoundAnchor) {
10603 newAnchors.push(new AnchorPoint({
10604 index: newAnchors.length,
10605 position: range.max,
10606 panel: panels[reachablePanels[reachablePanels.length - 1].index + 1]
10607 }));
10608 }
10609
10610 this._anchors = newAnchors;
10611 } else if (range.min !== range.max) {
10612 // There're more than 2 panels
10613 var nearestPanelAtMin = this._findNearestPanel(range.min, panels);
10614
10615 var panelAtMin = nearestPanelAtMin.index === panels.length - 1 ? nearestPanelAtMin.prev() : nearestPanelAtMin;
10616 var panelAtMax = panelAtMin.next();
10617 this._anchors = [new AnchorPoint({
10618 index: 0,
10619 position: range.min,
10620 panel: panelAtMin
10621 }), new AnchorPoint({
10622 index: 1,
10623 position: range.max,
10624 panel: panelAtMax
10625 })];
10626 } else {
10627 this._anchors = [new AnchorPoint({
10628 index: 0,
10629 position: range.min,
10630 panel: this._findNearestPanel(range.min, panels)
10631 })];
10632 }
10633
10634 return this;
10635 };
10636
10637 __proto.findAnchorIncludePosition = function (position) {
10638 var range = this._range;
10639 var anchors = this._anchors;
10640 if (anchors.length <= 0) return null;
10641
10642 if (position <= range.min) {
10643 return anchors[0];
10644 } else if (position >= range.max) {
10645 return anchors[anchors.length - 1];
10646 } else {
10647 return _super.prototype.findAnchorIncludePosition.call(this, position);
10648 }
10649 };
10650
10651 __proto._findNearestPanel = function (pos, panels) {
10652 var prevDist = Infinity;
10653
10654 for (var panelIdx = 0; panelIdx < panels.length; panelIdx++) {
10655 var panel = panels[panelIdx];
10656 var dist = Math.abs(panel.position - pos);
10657
10658 if (dist > prevDist) {
10659 // Return previous anchor
10660 return panels[panelIdx - 1];
10661 }
10662
10663 prevDist = dist;
10664 } // Return last anchor
10665
10666
10667 return panels[panels.length - 1];
10668 };
10669
10670 return BoundCamera;
10671 }(Camera$1);
10672
10673 /*
10674 * Copyright (c) 2015 NAVER Corp.
10675 * egjs projects are licensed under the MIT license
10676 */
10677
10678 var Camera = {
10679 __proto__: null,
10680 Camera: Camera$1,
10681 LinearCamera: LinearCamera,
10682 CircularCamera: CircularCamera,
10683 BoundCamera: BoundCamera
10684 };
10685
10686 /*
10687 Copyright (c) NAVER Corp.
10688 name: @egjs/component
10689 license: MIT
10690 author: NAVER Corp.
10691 repository: https://github.com/naver/egjs-component
10692 version: 2.2.2
10693 */
10694 /*! *****************************************************************************
10695 Copyright (c) Microsoft Corporation.
10696
10697 Permission to use, copy, modify, and/or distribute this software for any
10698 purpose with or without fee is hereby granted.
10699
10700 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10701 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10702 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
10703 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
10704 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
10705 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
10706 PERFORMANCE OF THIS SOFTWARE.
10707 ***************************************************************************** */
10708 function __values(o) {
10709 var s = typeof Symbol === "function" && Symbol.iterator,
10710 m = s && o[s],
10711 i = 0;
10712 if (m) return m.call(o);
10713 if (o && typeof o.length === "number") return {
10714 next: function () {
10715 if (o && i >= o.length) o = void 0;
10716 return {
10717 value: o && o[i++],
10718 done: !o
10719 };
10720 }
10721 };
10722 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
10723 }
10724
10725 /*
10726 * Copyright (c) 2015 NAVER Corp.
10727 * egjs projects are licensed under the MIT license
10728 */
10729
10730 function isUndefined(value) {
10731 return typeof value === "undefined";
10732 }
10733 /**
10734 * A class used to manage events in a component
10735 * @ko 컴포넌트의 이벤트을 관리할 수 있게 하는 클래스
10736 * @alias eg.Component
10737 */
10738
10739
10740 var Component =
10741 /*#__PURE__*/
10742 function () {
10743 /**
10744 * @support {"ie": "7+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.1+ (except 3.x)"}
10745 */
10746 function Component() {
10747 /**
10748 * @deprecated
10749 * @private
10750 */
10751 this.options = {};
10752 this._eventHandler = {};
10753 }
10754 /**
10755 * Triggers a custom event.
10756 * @ko 커스텀 이벤트를 발생시킨다
10757 * @param {string} eventName The name of the custom event to be triggered <ko>발생할 커스텀 이벤트의 이름</ko>
10758 * @param {object} customEvent Event data to be sent when triggering a custom event <ko>커스텀 이벤트가 발생할 때 전달할 데이터</ko>
10759 * @param {any[]} restParam Additional parameters when triggering a custom event <ko>커스텀 이벤트가 발생할 때 필요시 추가적으로 전달할 데이터</ko>
10760 * @return Indicates whether the event has occurred. If the stop() method is called by a custom event handler, it will return false and prevent the event from occurring. <a href="https://github.com/naver/egjs-component/wiki/How-to-make-Component-event-design%3F">Ref</a> <ko>이벤트 발생 여부. 커스텀 이벤트 핸들러에서 stop() 메서드를 호출하면 'false'를 반환하고 이벤트 발생을 중단한다. <a href="https://github.com/naver/egjs-component/wiki/How-to-make-Component-event-design%3F">참고</a></ko>
10761 * @example
10762 * ```
10763 * class Some extends eg.Component {
10764 * some(){
10765 * if(this.trigger("beforeHi")){ // When event call to stop return false.
10766 * this.trigger("hi");// fire hi event.
10767 * }
10768 * }
10769 * }
10770 *
10771 * const some = new Some();
10772 * some.on("beforeHi", (e) => {
10773 * if(condition){
10774 * e.stop(); // When event call to stop, `hi` event not call.
10775 * }
10776 * });
10777 * some.on("hi", (e) => {
10778 * // `currentTarget` is component instance.
10779 * console.log(some === e.currentTarget); // true
10780 * });
10781 * // If you want to more know event design. You can see article.
10782 * // https://github.com/naver/egjs-component/wiki/How-to-make-Component-event-design%3F
10783 * ```
10784 */
10785
10786
10787 var __proto = Component.prototype;
10788
10789 __proto.trigger = function (eventName) {
10790 var _this = this;
10791
10792 var params = [];
10793
10794 for (var _i = 1; _i < arguments.length; _i++) {
10795 params[_i - 1] = arguments[_i];
10796 }
10797
10798 var handlerList = this._eventHandler[eventName] || [];
10799 var hasHandlerList = handlerList.length > 0;
10800
10801 if (!hasHandlerList) {
10802 return true;
10803 }
10804
10805 var customEvent = params[0] || {};
10806 var restParams = params.slice(1); // If detach method call in handler in first time then handler list calls.
10807
10808 handlerList = handlerList.concat();
10809 var isCanceled = false; // This should be done like this to pass previous tests
10810
10811 customEvent.eventType = eventName;
10812
10813 customEvent.stop = function () {
10814 isCanceled = true;
10815 };
10816
10817 customEvent.currentTarget = this;
10818 var arg = [customEvent];
10819
10820 if (restParams.length >= 1) {
10821 arg = arg.concat(restParams);
10822 }
10823
10824 handlerList.forEach(function (handler) {
10825 handler.apply(_this, arg);
10826 });
10827 return !isCanceled;
10828 };
10829 /**
10830 * Executed event just one time.
10831 * @ko 이벤트가 한번만 실행된다.
10832 * @param {string} eventName The name of the event to be attached <ko>등록할 이벤트의 이름</ko>
10833 * @param {function} handlerToAttach The handler function of the event to be attached <ko>등록할 이벤트의 핸들러 함수</ko>
10834 * @return An instance of a component itself<ko>컴포넌트 자신의 인스턴스</ko>
10835 * @example
10836 * ```
10837 * class Some extends eg.Component {
10838 * hi() {
10839 * alert("hi");
10840 * }
10841 * thing() {
10842 * this.once("hi", this.hi);
10843 * }
10844 *
10845 * var some = new Some();
10846 * some.thing();
10847 * some.trigger("hi");
10848 * // fire alert("hi");
10849 * some.trigger("hi");
10850 * // Nothing happens
10851 * ```
10852 */
10853
10854
10855 __proto.once = function (eventName, handlerToAttach) {
10856 var _this = this;
10857
10858 if (typeof eventName === "object" && isUndefined(handlerToAttach)) {
10859 var eventHash = eventName;
10860
10861 for (var key in eventHash) {
10862 this.once(key, eventHash[key]);
10863 }
10864
10865 return this;
10866 } else if (typeof eventName === "string" && typeof handlerToAttach === "function") {
10867 var listener_1 = function () {
10868 var args = [];
10869
10870 for (var _i = 0; _i < arguments.length; _i++) {
10871 args[_i] = arguments[_i];
10872 }
10873
10874 handlerToAttach.apply(_this, args);
10875
10876 _this.off(eventName, listener_1);
10877 };
10878
10879 this.on(eventName, listener_1);
10880 }
10881
10882 return this;
10883 };
10884 /**
10885 * Checks whether an event has been attached to a component.
10886 * @ko 컴포넌트에 이벤트가 등록됐는지 확인한다.
10887 * @param {string} eventName The name of the event to be attached <ko>등록 여부를 확인할 이벤트의 이름</ko>
10888 * @return {boolean} Indicates whether the event is attached. <ko>이벤트 등록 여부</ko>
10889 * @example
10890 * ```
10891 * class Some extends eg.Component {
10892 * some() {
10893 * this.hasOn("hi");// check hi event.
10894 * }
10895 * }
10896 * ```
10897 */
10898
10899
10900 __proto.hasOn = function (eventName) {
10901 return !!this._eventHandler[eventName];
10902 };
10903 /**
10904 * Attaches an event to a component.
10905 * @ko 컴포넌트에 이벤트를 등록한다.
10906 * @param {string} eventName The name of the event to be attached <ko>등록할 이벤트의 이름</ko>
10907 * @param {function} handlerToAttach The handler function of the event to be attached <ko>등록할 이벤트의 핸들러 함수</ko>
10908 * @return An instance of a component itself<ko>컴포넌트 자신의 인스턴스</ko>
10909 * @example
10910 * ```
10911 * class Some extends eg.Component {
10912 * hi() {
10913 * console.log("hi");
10914 * }
10915 * some() {
10916 * this.on("hi",this.hi); //attach event
10917 * }
10918 * }
10919 * ```
10920 */
10921
10922
10923 __proto.on = function (eventName, handlerToAttach) {
10924 if (typeof eventName === "object" && isUndefined(handlerToAttach)) {
10925 var eventHash = eventName;
10926
10927 for (var name in eventHash) {
10928 this.on(name, eventHash[name]);
10929 }
10930
10931 return this;
10932 } else if (typeof eventName === "string" && typeof handlerToAttach === "function") {
10933 var handlerList = this._eventHandler[eventName];
10934
10935 if (isUndefined(handlerList)) {
10936 this._eventHandler[eventName] = [];
10937 handlerList = this._eventHandler[eventName];
10938 }
10939
10940 handlerList.push(handlerToAttach);
10941 }
10942
10943 return this;
10944 };
10945 /**
10946 * Detaches an event from the component.
10947 * @ko 컴포넌트에 등록된 이벤트를 해제한다
10948 * @param {string} eventName The name of the event to be detached <ko>해제할 이벤트의 이름</ko>
10949 * @param {function} handlerToDetach The handler function of the event to be detached <ko>해제할 이벤트의 핸들러 함수</ko>
10950 * @return An instance of a component itself <ko>컴포넌트 자신의 인스턴스</ko>
10951 * @example
10952 * ```
10953 * class Some extends eg.Component {
10954 * hi() {
10955 * console.log("hi");
10956 * }
10957 * some() {
10958 * this.off("hi",this.hi); //detach event
10959 * }
10960 * }
10961 * ```
10962 */
10963
10964
10965 __proto.off = function (eventName, handlerToDetach) {
10966 var e_1, _a; // Detach all event handlers.
10967
10968
10969 if (isUndefined(eventName)) {
10970 this._eventHandler = {};
10971 return this;
10972 } // Detach all handlers for eventname or detach event handlers by object.
10973
10974
10975 if (isUndefined(handlerToDetach)) {
10976 if (typeof eventName === "string") {
10977 delete this._eventHandler[eventName];
10978 return this;
10979 } else {
10980 var eventHash = eventName;
10981
10982 for (var name in eventHash) {
10983 this.off(name, eventHash[name]);
10984 }
10985
10986 return this;
10987 }
10988 } // Detach single event handler
10989
10990
10991 var handlerList = this._eventHandler[eventName];
10992
10993 if (handlerList) {
10994 var idx = 0;
10995
10996 try {
10997 for (var handlerList_1 = __values(handlerList), handlerList_1_1 = handlerList_1.next(); !handlerList_1_1.done; handlerList_1_1 = handlerList_1.next()) {
10998 var handlerFunction = handlerList_1_1.value;
10999
11000 if (handlerFunction === handlerToDetach) {
11001 handlerList.splice(idx, 1);
11002 break;
11003 }
11004
11005 idx++;
11006 }
11007 } catch (e_1_1) {
11008 e_1 = {
11009 error: e_1_1
11010 };
11011 } finally {
11012 try {
11013 if (handlerList_1_1 && !handlerList_1_1.done && (_a = handlerList_1.return)) _a.call(handlerList_1);
11014 } finally {
11015 if (e_1) throw e_1.error;
11016 }
11017 }
11018 }
11019
11020 return this;
11021 };
11022 /**
11023 * Version info string
11024 * @ko 버전정보 문자열
11025 * @name VERSION
11026 * @static
11027 * @example
11028 * eg.Component.VERSION; // ex) 2.0.0
11029 * @memberof eg.Component
11030 */
11031
11032
11033 Component.VERSION = "2.2.2";
11034 return Component;
11035 }();
11036
11037 /*
11038 Copyright (c) 2020-present NAVER Corp.
11039 name: @egjs/imready
11040 license: MIT
11041 author: NAVER Corp.
11042 repository: https://github.com/naver/egjs-imready
11043 version: 1.1.3
11044 */
11045
11046 /*! *****************************************************************************
11047 Copyright (c) Microsoft Corporation.
11048
11049 Permission to use, copy, modify, and/or distribute this software for any
11050 purpose with or without fee is hereby granted.
11051
11052 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
11053 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11054 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11055 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11056 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
11057 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
11058 PERFORMANCE OF THIS SOFTWARE.
11059 ***************************************************************************** */
11060
11061 /* global Reflect, Promise */
11062 var extendStatics = function (d, b) {
11063 extendStatics = Object.setPrototypeOf || {
11064 __proto__: []
11065 } instanceof Array && function (d, b) {
11066 d.__proto__ = b;
11067 } || function (d, b) {
11068 for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];
11069 };
11070
11071 return extendStatics(d, b);
11072 };
11073
11074 function __extends(d, b) {
11075 extendStatics(d, b);
11076
11077 function __() {
11078 this.constructor = d;
11079 }
11080
11081 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
11082 }
11083 var __assign = function () {
11084 __assign = Object.assign || function __assign(t) {
11085 for (var s, i = 1, n = arguments.length; i < n; i++) {
11086 s = arguments[i];
11087
11088 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
11089 }
11090
11091 return t;
11092 };
11093
11094 return __assign.apply(this, arguments);
11095 };
11096 function __spreadArrays() {
11097 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
11098
11099 for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j];
11100
11101 return r;
11102 }
11103
11104 /*
11105 egjs-imready
11106 Copyright (c) 2020-present NAVER Corp.
11107 MIT license
11108 */
11109 var isWindow = typeof window !== "undefined";
11110 var ua = isWindow ? window.navigator.userAgent : "";
11111 var SUPPORT_COMPUTEDSTYLE = isWindow ? !!("getComputedStyle" in window) : false;
11112 var IS_IE = /MSIE|Trident|Windows Phone|Edge/.test(ua);
11113 var SUPPORT_ADDEVENTLISTENER = isWindow ? !!("addEventListener" in document) : false;
11114 var WIDTH = "width";
11115 var HEIGHT = "height";
11116
11117 function getAttribute(el, name) {
11118 return el.getAttribute(name) || "";
11119 }
11120 function toArray(arr) {
11121 return [].slice.call(arr);
11122 }
11123 function hasSizeAttribute(target, prefix) {
11124 if (prefix === void 0) {
11125 prefix = "data-";
11126 }
11127
11128 return !!target.getAttribute(prefix + "width");
11129 }
11130 function hasLoadingAttribute(target) {
11131 return "loading" in target && target.getAttribute("loading") === "lazy";
11132 }
11133 function hasSkipAttribute(target, prefix) {
11134 if (prefix === void 0) {
11135 prefix = "data-";
11136 }
11137
11138 return !!target.getAttribute(prefix + "skip");
11139 }
11140 function addEvent(element, type, handler) {
11141 if (SUPPORT_ADDEVENTLISTENER) {
11142 element.addEventListener(type, handler, false);
11143 } else if (element.attachEvent) {
11144 element.attachEvent("on" + type, handler);
11145 } else {
11146 element["on" + type] = handler;
11147 }
11148 }
11149 function removeEvent(element, type, handler) {
11150 if (element.removeEventListener) {
11151 element.removeEventListener(type, handler, false);
11152 } else if (element.detachEvent) {
11153 element.detachEvent("on" + type, handler);
11154 } else {
11155 element["on" + type] = null;
11156 }
11157 }
11158 function innerWidth(el) {
11159 return getSize(el, "Width");
11160 }
11161 function innerHeight(el) {
11162 return getSize(el, "Height");
11163 }
11164 function getStyles(el) {
11165 return (SUPPORT_COMPUTEDSTYLE ? window.getComputedStyle(el) : el.currentStyle) || {};
11166 }
11167
11168 function getSize(el, name) {
11169 var size = el["client" + name] || el["offset" + name];
11170 return parseFloat(size || getStyles(el)[name.toLowerCase()]) || 0;
11171 }
11172
11173 function getContentElements(element, tags, prefix) {
11174 var skipElements = toArray(element.querySelectorAll(__spreadArrays(["[" + prefix + "skip] [" + prefix + "width]"], tags.map(function (tag) {
11175 return ["[" + prefix + "skip] " + tag, tag + "[" + prefix + "skip]", "[" + prefix + "width] " + tag].join(", ");
11176 })).join(", ")));
11177 return toArray(element.querySelectorAll("[" + prefix + "width], " + tags.join(", "))).filter(function (el) {
11178 return skipElements.indexOf(el) === -1;
11179 });
11180 }
11181
11182 /*
11183 egjs-imready
11184 Copyright (c) 2020-present NAVER Corp.
11185 MIT license
11186 */
11187 var elements = [];
11188 function addAutoSizer(element, prefix) {
11189 !elements.length && addEvent(window, "resize", resizeAllAutoSizers);
11190 element.__PREFIX__ = prefix;
11191 elements.push(element);
11192 resize(element);
11193 }
11194 function removeAutoSizer(element, prefix) {
11195 var index = elements.indexOf(element);
11196
11197 if (index < 0) {
11198 return;
11199 }
11200
11201 var fixed = getAttribute(element, prefix + "fixed");
11202 delete element.__PREFIX__;
11203 element.style[fixed === HEIGHT ? WIDTH : HEIGHT] = "";
11204 elements.splice(index, 1);
11205 !elements.length && removeEvent(window, "resize", resizeAllAutoSizers);
11206 }
11207
11208 function resize(element, prefix) {
11209 if (prefix === void 0) {
11210 prefix = "data-";
11211 }
11212
11213 var elementPrefix = element.__PREFIX__ || prefix;
11214 var dataWidth = parseInt(getAttribute(element, "" + elementPrefix + WIDTH), 10) || 0;
11215 var dataHeight = parseInt(getAttribute(element, "" + elementPrefix + HEIGHT), 10) || 0;
11216 var fixed = getAttribute(element, elementPrefix + "fixed");
11217
11218 if (fixed === HEIGHT) {
11219 var size = innerHeight(element) || dataHeight;
11220 element.style[WIDTH] = dataWidth / dataHeight * size + "px";
11221 } else {
11222 var size = innerWidth(element) || dataWidth;
11223 element.style[HEIGHT] = dataHeight / dataWidth * size + "px";
11224 }
11225 }
11226
11227 function resizeAllAutoSizers() {
11228 elements.forEach(function (element) {
11229 resize(element);
11230 });
11231 }
11232
11233 var Loader =
11234 /*#__PURE__*/
11235 function (_super) {
11236 __extends(Loader, _super);
11237
11238 function Loader(element, options) {
11239 if (options === void 0) {
11240 options = {};
11241 }
11242
11243 var _this = _super.call(this) || this;
11244
11245 _this.isReady = false;
11246 _this.isPreReady = false;
11247 _this.hasDataSize = false;
11248 _this.hasLoading = false;
11249 _this.isSkip = false;
11250
11251 _this.onCheck = function (e) {
11252 _this.clear();
11253
11254 if (e && e.type === "error") {
11255 _this.onError(_this.element);
11256 } // I'm pre-ready and ready!
11257
11258
11259 var withPreReady = !_this.hasDataSize && !_this.hasLoading;
11260
11261 _this.onReady(withPreReady);
11262 };
11263
11264 _this.options = __assign({
11265 prefix: "data-"
11266 }, options);
11267 _this.element = element;
11268 _this.hasDataSize = hasSizeAttribute(element, _this.options.prefix);
11269 _this.hasLoading = hasLoadingAttribute(element);
11270 _this.isSkip = hasSkipAttribute(_this.element);
11271 return _this;
11272 }
11273
11274 var __proto = Loader.prototype;
11275
11276 __proto.check = function () {
11277 if (this.isSkip || !this.checkElement()) {
11278 // I'm Ready
11279 this.onAlreadyReady(true);
11280 return false;
11281 }
11282
11283 if (this.hasDataSize) {
11284 addAutoSizer(this.element, this.options.prefix);
11285 }
11286
11287 if (this.hasDataSize || this.hasLoading) {
11288 // I'm Pre Ready
11289 this.onAlreadyPreReady();
11290 } // Wati Pre Ready, Ready
11291
11292
11293 return true;
11294 };
11295
11296 __proto.addEvents = function () {
11297 var _this = this;
11298
11299 var element = this.element;
11300 this.constructor.EVENTS.forEach(function (name) {
11301 addEvent(element, name, _this.onCheck);
11302 });
11303 };
11304
11305 __proto.clear = function () {
11306 var _this = this;
11307
11308 var element = this.element;
11309 this.constructor.EVENTS.forEach(function (name) {
11310 removeEvent(element, name, _this.onCheck);
11311 });
11312 this.removeAutoSizer();
11313 };
11314
11315 __proto.destroy = function () {
11316 this.clear();
11317 this.off();
11318 };
11319
11320 __proto.removeAutoSizer = function () {
11321 if (this.hasDataSize) {
11322 // I'm already ready.
11323 var prefix = this.options.prefix;
11324 removeAutoSizer(this.element, prefix);
11325 }
11326 };
11327
11328 __proto.onError = function (target) {
11329 this.trigger("error", {
11330 element: this.element,
11331 target: target
11332 });
11333 };
11334
11335 __proto.onPreReady = function () {
11336 if (this.isPreReady) {
11337 return;
11338 }
11339
11340 this.isPreReady = true;
11341 this.trigger("preReady", {
11342 element: this.element,
11343 hasLoading: this.hasLoading,
11344 isSkip: this.isSkip
11345 });
11346 };
11347
11348 __proto.onReady = function (withPreReady) {
11349 if (this.isReady) {
11350 return;
11351 }
11352
11353 withPreReady = !this.isPreReady && withPreReady;
11354
11355 if (withPreReady) {
11356 this.isPreReady = true;
11357 }
11358
11359 this.removeAutoSizer();
11360 this.isReady = true;
11361 this.trigger("ready", {
11362 element: this.element,
11363 withPreReady: withPreReady,
11364 hasLoading: this.hasLoading,
11365 isSkip: this.isSkip
11366 });
11367 };
11368
11369 __proto.onAlreadyError = function (target) {
11370 var _this = this;
11371
11372 setTimeout(function () {
11373 _this.onError(target);
11374 });
11375 };
11376
11377 __proto.onAlreadyPreReady = function () {
11378 var _this = this;
11379
11380 setTimeout(function () {
11381 _this.onPreReady();
11382 });
11383 };
11384
11385 __proto.onAlreadyReady = function (withPreReady) {
11386 var _this = this;
11387
11388 setTimeout(function () {
11389 _this.onReady(withPreReady);
11390 });
11391 };
11392
11393 Loader.EVENTS = [];
11394 return Loader;
11395 }(Component);
11396
11397 var ElementLoader =
11398 /*#__PURE__*/
11399 function (_super) {
11400 __extends(ElementLoader, _super);
11401
11402 function ElementLoader() {
11403 return _super !== null && _super.apply(this, arguments) || this;
11404 }
11405
11406 var __proto = ElementLoader.prototype;
11407
11408 __proto.setHasLoading = function (hasLoading) {
11409 this.hasLoading = hasLoading;
11410 };
11411
11412 __proto.check = function () {
11413 if (this.isSkip) {
11414 // I'm Ready
11415 this.onAlreadyReady(true);
11416 return false;
11417 }
11418
11419 if (this.hasDataSize) {
11420 addAutoSizer(this.element, this.options.prefix);
11421 this.onAlreadyPreReady();
11422 } else {
11423 // has not data size
11424 this.trigger("requestChildren");
11425 }
11426
11427 return true;
11428 };
11429
11430 __proto.checkElement = function () {
11431 return true;
11432 };
11433
11434 __proto.destroy = function () {
11435 this.clear();
11436 this.trigger("requestDestroy");
11437 this.off();
11438 };
11439
11440 __proto.onAlreadyPreReady = function () {
11441 // has data size
11442 _super.prototype.onAlreadyPreReady.call(this);
11443
11444 this.trigger("reqeustReadyChildren");
11445 };
11446
11447 ElementLoader.EVENTS = [];
11448 return ElementLoader;
11449 }(Loader);
11450
11451 /**
11452 * @alias eg.ImReady
11453 * @extends eg.Component
11454 */
11455
11456 var ImReadyManager =
11457 /*#__PURE__*/
11458 function (_super) {
11459 __extends(ImReadyManager, _super);
11460 /**
11461 * @param - ImReady's options
11462 */
11463
11464
11465 function ImReadyManager(options) {
11466 if (options === void 0) {
11467 options = {};
11468 }
11469
11470 var _this = _super.call(this) || this;
11471
11472 _this.readyCount = 0;
11473 _this.preReadyCount = 0;
11474 _this.totalCount = 0;
11475 _this.totalErrorCount = 0;
11476 _this.isPreReadyOver = true;
11477 _this.elementInfos = [];
11478 _this.options = __assign({
11479 loaders: {},
11480 prefix: "data-"
11481 }, options);
11482 return _this;
11483 }
11484 /**
11485 * Checks whether elements are in the ready state.
11486 * @ko 엘리먼트가 준비 상태인지 체크한다.
11487 * @elements - Elements to check ready status. <ko> 준비 상태를 체크할 엘리먼트들.</ko>
11488 * @example
11489 * ```html
11490 * <div>
11491 * <img src="./1.jpg" data-width="1280" data-height="853" style="width:100%"/>
11492 * <img src="./2.jpg" data-width="1280" data-height="853"/>
11493 * <img src="ERR" data-width="1280" data-height="853"/>
11494 * </div>
11495 * ```
11496 * ## Javascript
11497 * ```js
11498 * import ImReady from "@egjs/imready";
11499 *
11500 * const im = new ImReady(); // umd: eg.ImReady
11501 * im.check(document.querySelectorAll("img")).on({
11502 * preReadyElement: e => {
11503 * // 1, 3
11504 * // 2, 3
11505 * // 3, 3
11506 * console.log(e.preReadyCount, e.totalCount),
11507 * },
11508 * });
11509 * ```
11510 */
11511
11512
11513 var __proto = ImReadyManager.prototype;
11514
11515 __proto.check = function (elements) {
11516 var _this = this;
11517
11518 var prefix = this.options.prefix;
11519 this.clear();
11520 this.elementInfos = toArray(elements).map(function (element, index) {
11521 var loader = _this.getLoader(element, {
11522 prefix: prefix
11523 });
11524
11525 loader.check();
11526 loader.on("error", function (e) {
11527 _this.onError(index, e.target);
11528 }).on("preReady", function (e) {
11529 var info = _this.elementInfos[index];
11530 info.hasLoading = e.hasLoading;
11531 info.isSkip = e.isSkip;
11532
11533 var isPreReady = _this.checkPreReady(index);
11534
11535 _this.onPreReadyElement(index);
11536
11537 isPreReady && _this.onPreReady();
11538 }).on("ready", function (_a) {
11539 var withPreReady = _a.withPreReady,
11540 hasLoading = _a.hasLoading,
11541 isSkip = _a.isSkip;
11542 var info = _this.elementInfos[index];
11543 info.hasLoading = hasLoading;
11544 info.isSkip = isSkip;
11545
11546 var isPreReady = withPreReady && _this.checkPreReady(index);
11547
11548 var isReady = _this.checkReady(index); // Pre-ready and ready occur simultaneously
11549
11550
11551 withPreReady && _this.onPreReadyElement(index);
11552
11553 _this.onReadyElement(index);
11554
11555 isPreReady && _this.onPreReady();
11556 isReady && _this.onReady();
11557 });
11558 return {
11559 loader: loader,
11560 element: element,
11561 hasLoading: false,
11562 hasError: false,
11563 isPreReady: false,
11564 isReady: false,
11565 isSkip: false
11566 };
11567 });
11568 var length = this.elementInfos.length;
11569 this.totalCount = length;
11570
11571 if (!length) {
11572 setTimeout(function () {
11573 _this.onPreReady();
11574
11575 _this.onReady();
11576 });
11577 }
11578
11579 return this;
11580 };
11581 /**
11582 * Gets the total count of elements to be checked.
11583 * @ko 체크하는 element의 총 개수를 가져온다.
11584 */
11585
11586
11587 __proto.getTotalCount = function () {
11588 return this.totalCount;
11589 };
11590 /**
11591 * Whether the elements are all pre-ready. (all sizes are known)
11592 * @ko 엘리먼트들이 모두 사전 준비가 됐는지 (사이즈를 전부 알 수 있는지) 여부.
11593 */
11594
11595
11596 __proto.isPreReady = function () {
11597 return this.elementInfos.every(function (info) {
11598 return info.isPreReady;
11599 });
11600 };
11601 /**
11602 * Whether the elements are all ready.
11603 * @ko 엘리먼트들이 모두 준비가 됐는지 여부.
11604 */
11605
11606
11607 __proto.isReady = function () {
11608 return this.elementInfos.every(function (info) {
11609 return info.isReady;
11610 });
11611 };
11612 /**
11613 * Whether an error has occurred in the elements in the current state.
11614 * @ko 현재 상태에서 엘리먼트들이 에러가 발생했는지 여부.
11615 */
11616
11617
11618 __proto.hasError = function () {
11619 return this.totalErrorCount > 0;
11620 };
11621 /**
11622 * Clears events of elements being checked.
11623 * @ko 체크 중인 엘리먼트들의 이벤트를 해제 한다.
11624 */
11625
11626
11627 __proto.clear = function () {
11628 this.isPreReadyOver = false;
11629 this.totalCount = 0;
11630 this.preReadyCount = 0;
11631 this.readyCount = 0;
11632 this.totalErrorCount = 0;
11633 this.elementInfos.forEach(function (info) {
11634 if (!info.isReady && info.loader) {
11635 info.loader.destroy();
11636 }
11637 });
11638 this.elementInfos = [];
11639 };
11640 /**
11641 * Destory all events.
11642 * @ko 모든 이벤트를 해제 한다.
11643 */
11644
11645
11646 __proto.destroy = function () {
11647 this.clear();
11648 this.off();
11649 };
11650
11651 __proto.getLoader = function (element, options) {
11652 var _this = this;
11653
11654 var tagName = element.tagName.toLowerCase();
11655 var loaders = this.options.loaders;
11656 var tags = Object.keys(loaders);
11657
11658 if (loaders[tagName]) {
11659 return new loaders[tagName](element, options);
11660 }
11661
11662 var loader = new ElementLoader(element, options);
11663 var children = toArray(element.querySelectorAll(tags.join(", ")));
11664 loader.setHasLoading(children.some(function (el) {
11665 return hasLoadingAttribute(el);
11666 }));
11667 var withPreReady = false;
11668 var childrenImReady = this.clone().on("error", function (e) {
11669 loader.onError(e.target);
11670 }).on("ready", function () {
11671 loader.onReady(withPreReady);
11672 });
11673 loader.on("requestChildren", function () {
11674 // has not data size
11675 var contentElements = getContentElements(element, tags, _this.options.prefix);
11676 childrenImReady.check(contentElements).on("preReady", function (e) {
11677 withPreReady = e.isReady;
11678
11679 if (!withPreReady) {
11680 loader.onPreReady();
11681 }
11682 });
11683 }).on("reqeustReadyChildren", function () {
11684 // has data size
11685 // loader call preReady
11686 // check only video, image elements
11687 childrenImReady.check(children);
11688 }).on("requestDestroy", function () {
11689 childrenImReady.destroy();
11690 });
11691 return loader;
11692 };
11693
11694 __proto.clone = function () {
11695 return new ImReadyManager(__assign({}, this.options));
11696 };
11697
11698 __proto.checkPreReady = function (index) {
11699 this.elementInfos[index].isPreReady = true;
11700 ++this.preReadyCount;
11701
11702 if (this.preReadyCount < this.totalCount) {
11703 return false;
11704 }
11705
11706 return true;
11707 };
11708
11709 __proto.checkReady = function (index) {
11710 this.elementInfos[index].isReady = true;
11711 ++this.readyCount;
11712
11713 if (this.readyCount < this.totalCount) {
11714 return false;
11715 }
11716
11717 return true;
11718 };
11719
11720 __proto.onError = function (index, target) {
11721 var info = this.elementInfos[index];
11722 info.hasError = true;
11723 /**
11724 * An event occurs if the image, video fails to load.
11725 * @ko 이미지, 비디오가 로딩에 실패하면 이벤트가 발생한다.
11726 * @event eg.ImReady#error
11727 * @param {eg.ImReady.OnError} e - The object of data to be sent to an event <ko>이벤트에 전달되는 데이터 객체</ko>
11728 * @param {HTMLElement} [e.element] - The element with error images.<ko>오류난 이미지가 있는 엘리먼트</ko>
11729 * @param {number} [e.index] - The item's index with error images. <ko>오류난 이미지가 있는 엘리먼트의 인덱스</ko>
11730 * @param {HTMLElement} [e.target] - Error image target in element <ko>엘리먼트의 오류난 이미지 타겟</ko>
11731 * @param {number} [e.errorCount] - The number of elements with errors <ko>에러가 있는 엘리먼트들의 개수</ko>
11732 * @param {number} [e.totalErrorCount] - The total number of targets with errors <ko>에러가 있는 타겟들의 총 개수</ko>
11733 * @example
11734 * ```html
11735 * <div>
11736 * <img src="./1.jpg" data-width="1280" data-height="853" style="width:100%"/>
11737 * <img src="./2.jpg"/>
11738 * <img src="ERR"/>
11739 * </div>
11740 * ```
11741 * ## Javascript
11742 * ```js
11743 * import ImReady from "@egjs/imready";
11744 *
11745 * const im = new ImReady(); // umd: eg.ImReady
11746 * im.check([document.querySelector("div")]).on({
11747 * error: e => {
11748 * // <div>...</div>, 0, <img src="ERR"/>
11749 * console.log(e.element, e.index, e.target),
11750 * },
11751 * });
11752 * ```
11753 */
11754
11755 this.trigger("error", {
11756 element: info.element,
11757 index: index,
11758 target: target,
11759 errorCount: this.getErrorCount(),
11760 totalErrorCount: ++this.totalErrorCount
11761 });
11762 };
11763
11764 __proto.onPreReadyElement = function (index) {
11765 var info = this.elementInfos[index];
11766 /**
11767 * An event occurs when the element is pre-ready (when the loading attribute is applied or the size is known)
11768 * @ko 해당 엘리먼트가 사전 준비되었을 때(loading 속성이 적용되었거나 사이즈를 알 수 있을 때) 이벤트가 발생한다.
11769 * @event eg.ImReady#preReadyElement
11770 * @param {eg.ImReady.OnPreReadyElement} e - The object of data to be sent to an event <ko>이벤트에 전달되는 데이터 객체</ko>
11771 * @param {HTMLElement} [e.element] - The pre-ready element.<ko>사전 준비된 엘리먼트</ko>
11772 * @param {number} [e.index] - The index of the pre-ready element. <ko>사전 준비된 엘리먼트의 인덱스</ko>
11773 * @param {number} [e.preReadyCount] - Number of elements pre-ready <ko>사전 준비된 엘리먼트들의 개수</ko>
11774 * @param {number} [e.readyCount] - Number of elements ready <ko>준비된 엘리먼트들의 개수</ko>
11775 * @param {number} [e.totalCount] - Total number of elements <ko>엘리먼트들의 총 개수</ko>
11776 * @param {boolean} [e.isPreReady] - Whether all elements are pre-ready <ko>모든 엘리먼트가 사전 준비가 끝났는지 여부</ko>
11777 * @param {boolean} [e.isReady] - Whether all elements are ready <ko>모든 엘리먼트가 준비가 끝났는지 여부</ko>
11778 * @param {boolean} [e.hasLoading] - Whether the loading attribute has been applied <ko>loading 속성이 적용되었는지 여부</ko>
11779 * @param {boolean} [e.isSkip] - Whether the check is omitted due to skip attribute <ko>skip 속성으로 인하여 체크가 생략됐는지 여부</ko>
11780 * @example
11781 * ```html
11782 * <div>
11783 * <img src="./1.jpg" data-width="1280" data-height="853" style="width:100%"/>
11784 * <img src="./2.jpg" data-width="1280" data-height="853"/>
11785 * <img src="ERR" data-width="1280" data-height="853"/>
11786 * </div>
11787 * ```
11788 * ## Javascript
11789 * ```js
11790 * import ImReady from "@egjs/imready";
11791 *
11792 * const im = new ImReady(); // umd: eg.ImReady
11793 * im.check(document.querySelectorAll("img")).on({
11794 * preReadyElement: e => {
11795 * // 1, 3
11796 * // 2, 3
11797 * // 3, 3
11798 * console.log(e.preReadyCount, e.totalCount),
11799 * },
11800 * });
11801 * ```
11802 */
11803
11804 this.trigger("preReadyElement", {
11805 element: info.element,
11806 index: index,
11807 preReadyCount: this.preReadyCount,
11808 readyCount: this.readyCount,
11809 totalCount: this.totalCount,
11810 isPreReady: this.isPreReady(),
11811 isReady: this.isReady(),
11812 hasLoading: info.hasLoading,
11813 isSkip: info.isSkip
11814 });
11815 };
11816
11817 __proto.onPreReady = function () {
11818 this.isPreReadyOver = true;
11819 /**
11820 * An event occurs when all element are pre-ready (When all elements have the loading attribute applied or the size is known)
11821 * @ko 모든 엘리먼트들이 사전 준비된 경우 (모든 엘리먼트들이 loading 속성이 적용되었거나 사이즈를 알 수 있는 경우) 이벤트가 발생한다.
11822 * @event eg.ImReady#preReady
11823 * @param {eg.ImReady.OnPreReady} e - The object of data to be sent to an event <ko>이벤트에 전달되는 데이터 객체</ko>
11824 * @param {number} [e.readyCount] - Number of elements ready <ko>준비된 엘리먼트들의 개수</ko>
11825 * @param {number} [e.totalCount] - Total number of elements <ko>엘리먼트들의 총 개수</ko>
11826 * @param {boolean} [e.isReady] - Whether all elements are ready <ko>모든 엘리먼트가 준비가 끝났는지 여부</ko>
11827 * @param {boolean} [e.hasLoading] - Whether the loading attribute has been applied <ko>loading 속성이 적용되었는지 여부</ko>
11828 * @example
11829 * ```html
11830 * <div>
11831 * <img src="./1.jpg" data-width="1280" data-height="853" style="width:100%"/>
11832 * <img src="./2.jpg" data-width="1280" data-height="853"/>
11833 * <img src="ERR" data-width="1280" data-height="853"/>
11834 * </div>
11835 * ```
11836 * ## Javascript
11837 * ```js
11838 * import ImReady from "@egjs/imready";
11839 *
11840 * const im = new ImReady(); // umd: eg.ImReady
11841 * im.check(document.querySelectorAll("img")).on({
11842 * preReady: e => {
11843 * // 0, 3
11844 * console.log(e.readyCount, e.totalCount),
11845 * },
11846 * });
11847 * ```
11848 */
11849
11850 this.trigger("preReady", {
11851 readyCount: this.readyCount,
11852 totalCount: this.totalCount,
11853 isReady: this.isReady(),
11854 hasLoading: this.hasLoading()
11855 });
11856 };
11857
11858 __proto.onReadyElement = function (index) {
11859 var info = this.elementInfos[index];
11860 /**
11861 * An event occurs when the element is ready
11862 * @ko 해당 엘리먼트가 준비가 되었을 때 이벤트가 발생한다.
11863 * @event eg.ImReady#readyElement
11864 * @param {eg.ImReady.OnReadyElement} e - The object of data to be sent to an event <ko>이벤트에 전달되는 데이터 객체</ko>
11865 * @param {HTMLElement} [e.element] - The ready element.<ko>준비된 엘리먼트</ko>
11866 * @param {number} [e.index] - The index of the ready element. <ko>준비된 엘리먼트의 인덱스</ko>
11867 * @param {boolean} [e.hasError] - Whether there is an error in the element <ko>해당 엘리먼트에 에러가 있는지 여부</ko>
11868 * @param {number} [e.errorCount] - The number of elements with errors <ko>에러가 있는 엘리먼트들의 개수</ko>
11869 * @param {number} [e.totalErrorCount] - The total number of targets with errors <ko>에러가 있는 타겟들의 총 개수</ko>
11870 * @param {number} [e.preReadyCount] - Number of elements pre-ready <ko>사전 준비된 엘리먼트들의 개수</ko>
11871 * @param {number} [e.readyCount] - Number of elements ready <ko>준비된 엘리먼트들의 개수</ko>
11872 * @param {number} [e.totalCount] - Total number of elements <ko>엘리먼트들의 총 개수</ko>
11873 * @param {boolean} [e.isPreReady] - Whether all elements are pre-ready <ko>모든 엘리먼트가 사전 준비가 끝났는지 여부</ko>
11874 * @param {boolean} [e.isReady] - Whether all elements are ready <ko>모든 엘리먼트가 준비가 끝났는지 여부</ko>
11875 * @param {boolean} [e.hasLoading] - Whether the loading attribute has been applied <ko>loading 속성이 적용되었는지 여부</ko>
11876 * @param {boolean} [e.isPreReadyOver] - Whether pre-ready is over <ko>사전 준비가 끝났는지 여부</ko>
11877 * @param {boolean} [e.isSkip] - Whether the check is omitted due to skip attribute <ko>skip 속성으로 인하여 체크가 생략됐는지 여부</ko>
11878 * @example
11879 * ```html
11880 * <div>
11881 * <img src="./1.jpg" data-width="1280" data-height="853" style="width:100%"/>
11882 * <img src="./2.jpg" data-width="1280" data-height="853"/>
11883 * <img src="ERR" data-width="1280" data-height="853"/>
11884 * </div>
11885 * ```
11886 * ## Javascript
11887 * ```js
11888 * import ImReady from "@egjs/imready";
11889 *
11890 * const im = new ImReady(); // umd: eg.ImReady
11891 * im.check(document.querySelectorAll("img")).on({
11892 * readyElement: e => {
11893 * // 1, 0, false, 3
11894 * // 2, 1, false, 3
11895 * // 3, 2, true, 3
11896 * console.log(e.readyCount, e.index, e.hasError, e.totalCount),
11897 * },
11898 * });
11899 * ```
11900 */
11901
11902 this.trigger("readyElement", {
11903 index: index,
11904 element: info.element,
11905 hasError: info.hasError,
11906 errorCount: this.getErrorCount(),
11907 totalErrorCount: this.totalErrorCount,
11908 preReadyCount: this.preReadyCount,
11909 readyCount: this.readyCount,
11910 totalCount: this.totalCount,
11911 isPreReady: this.isPreReady(),
11912 isReady: this.isReady(),
11913 hasLoading: info.hasLoading,
11914 isPreReadyOver: this.isPreReadyOver,
11915 isSkip: info.isSkip
11916 });
11917 };
11918
11919 __proto.onReady = function () {
11920 /**
11921 * An event occurs when all element are ready
11922 * @ko 모든 엘리먼트들이 준비된 경우 이벤트가 발생한다.
11923 * @event eg.ImReady#ready
11924 * @param {eg.ImReady.OnReady} e - The object of data to be sent to an event <ko>이벤트에 전달되는 데이터 객체</ko>
11925 * @param {number} [e.errorCount] - The number of elements with errors <ko>에러가 있는 엘리먼트들의 개수</ko>
11926 * @param {number} [e.totalErrorCount] - The total number of targets with errors <ko>에러가 있는 타겟들의 총 개수</ko>
11927 * @param {number} [e.totalCount] - Total number of elements <ko>엘리먼트들의 총 개수</ko>
11928 * @example
11929 * ```html
11930 * <div>
11931 * <img src="./1.jpg" data-width="1280" data-height="853" style="width:100%"/>
11932 * <img src="./2.jpg" data-width="1280" data-height="853"/>
11933 * <img src="ERR" data-width="1280" data-height="853"/>
11934 * </div>
11935 * ```
11936 * ## Javascript
11937 * ```js
11938 * import ImReady from "@egjs/imready";
11939 *
11940 * const im = new ImReady(); // umd: eg.ImReady
11941 * im.check(document.querySelectorAll("img")).on({
11942 * preReady: e => {
11943 * // 0, 3
11944 * console.log(e.readyCount, e.totalCount),
11945 * },
11946 * ready: e => {
11947 * // 1, 3
11948 * console.log(e.errorCount, e.totalCount),
11949 * },
11950 * });
11951 * ```
11952 */
11953 this.trigger("ready", {
11954 errorCount: this.getErrorCount(),
11955 totalErrorCount: this.totalErrorCount,
11956 totalCount: this.totalCount
11957 });
11958 };
11959
11960 __proto.getErrorCount = function () {
11961 return this.elementInfos.filter(function (info) {
11962 return info.hasError;
11963 }).length;
11964 };
11965
11966 __proto.hasLoading = function () {
11967 return this.elementInfos.some(function (info) {
11968 return info.hasLoading;
11969 });
11970 };
11971
11972 return ImReadyManager;
11973 }(Component);
11974
11975 var ImageLoader =
11976 /*#__PURE__*/
11977 function (_super) {
11978 __extends(ImageLoader, _super);
11979
11980 function ImageLoader() {
11981 return _super !== null && _super.apply(this, arguments) || this;
11982 }
11983
11984 var __proto = ImageLoader.prototype;
11985
11986 __proto.checkElement = function () {
11987 var element = this.element;
11988 var src = element.getAttribute("src");
11989
11990 if (element.complete) {
11991 if (src) {
11992 // complete
11993 if (!element.naturalWidth) {
11994 this.onAlreadyError(element);
11995 }
11996
11997 return false;
11998 } else {
11999 // Using an external lazy loading module
12000 this.onAlreadyPreReady();
12001 }
12002 }
12003
12004 this.addEvents();
12005 IS_IE && element.setAttribute("src", src);
12006 return true;
12007 };
12008
12009 ImageLoader.EVENTS = ["load", "error"];
12010 return ImageLoader;
12011 }(Loader);
12012
12013 var VideoLoader =
12014 /*#__PURE__*/
12015 function (_super) {
12016 __extends(VideoLoader, _super);
12017
12018 function VideoLoader() {
12019 return _super !== null && _super.apply(this, arguments) || this;
12020 }
12021
12022 var __proto = VideoLoader.prototype;
12023
12024 __proto.checkElement = function () {
12025 var element = this.element; // HAVE_NOTHING: 0, no information whether or not the audio/video is ready
12026 // HAVE_METADATA: 1, HAVE_METADATA - metadata for the audio/video is ready
12027 // HAVE_CURRENT_DATA: 2, data for the current playback position is available, but not enough data to play next frame/millisecond
12028 // HAVE_FUTURE_DATA: 3, data for the current and at least the next frame is available
12029 // HAVE_ENOUGH_DATA: 4, enough data available to start playing
12030
12031 if (element.readyState >= 1) {
12032 return false;
12033 }
12034
12035 if (element.error) {
12036 this.onAlreadyError(element);
12037 return false;
12038 }
12039
12040 this.addEvents();
12041 return true;
12042 };
12043
12044 VideoLoader.EVENTS = ["loadedmetadata", "error"];
12045 return VideoLoader;
12046 }(Loader);
12047
12048 var ImReady =
12049 /*#__PURE__*/
12050 function (_super) {
12051 __extends(ImReady, _super);
12052
12053 function ImReady(options) {
12054 if (options === void 0) {
12055 options = {};
12056 }
12057
12058 return _super.call(this, __assign({
12059 loaders: {
12060 img: ImageLoader,
12061 video: VideoLoader
12062 }
12063 }, options)) || this;
12064 }
12065
12066 return ImReady;
12067 }(ImReadyManager);
12068
12069 /*
12070 egjs-imready
12071 Copyright (c) 2020-present NAVER Corp.
12072 MIT license
12073 */
12074
12075 var ImReady$1 = ImReady;
12076
12077 /**
12078 * A component that manages {@link Panel} and its elements
12079 * @ko {@link Panel}과 그 엘리먼트들을 관리하는 컴포넌트
12080 */
12081
12082 var Renderer$1 = function () {
12083 /**
12084 * @param {object} options An options object<ko>옵션 오브젝트</ko>
12085 * @param {Constants.ALIGN | string | number} [options.align] An {@link Flicking#align align} value that will be applied to all panels<ko>전체 패널에 적용될 {@link Flicking#align align} 값</ko>
12086 */
12087 function Renderer(_a) {
12088 var _b = _a === void 0 ? {} : _a,
12089 _c = _b.align,
12090 align = _c === void 0 ? ALIGN.CENTER : _c;
12091
12092 this._flicking = null;
12093 this._panels = []; // Bind options
12094
12095 this._align = align;
12096 }
12097
12098 var __proto = Renderer.prototype;
12099 Object.defineProperty(__proto, "panels", {
12100 // Internal states Getter
12101
12102 /**
12103 * Array of panels
12104 * @ko 전체 패널들의 배열
12105 * @type {Panel[]}
12106 * @readonly
12107 * @see Panel
12108 */
12109 get: function () {
12110 return this._panels;
12111 },
12112 enumerable: false,
12113 configurable: true
12114 });
12115 Object.defineProperty(__proto, "panelCount", {
12116 /**
12117 * Count of panels
12118 * @ko 전체 패널의 개수
12119 * @type {number}
12120 * @readonly
12121 */
12122 get: function () {
12123 return this._panels.length;
12124 },
12125 enumerable: false,
12126 configurable: true
12127 });
12128 Object.defineProperty(__proto, "align", {
12129 // Options Getter
12130
12131 /**
12132 * A {@link Panel}'s {@link Panel#align align} value that applied to all panels
12133 * @ko {@link Panel}에 공통적으로 적용할 {@link Panel#align align} 값
12134 * @type {Constants.ALIGN | string | number}
12135 */
12136 get: function () {
12137 return this._align;
12138 },
12139 // Options Setter
12140 set: function (val) {
12141 this._align = val;
12142
12143 var panelAlign = this._getPanelAlign();
12144
12145 this._panels.forEach(function (panel) {
12146 panel.align = panelAlign;
12147 });
12148 },
12149 enumerable: false,
12150 configurable: true
12151 });
12152 /**
12153 * Initialize Renderer
12154 * @ko Renderer를 초기화합니다
12155 * @param {Flicking} flicking An instance of {@link Flicking}<ko>Flicking의 인스턴스</ko>
12156 * @chainable
12157 * @return {this}
12158 */
12159
12160 __proto.init = function (flicking) {
12161 this._flicking = flicking;
12162
12163 this._collectPanels();
12164
12165 return this;
12166 };
12167 /**
12168 * Destroy Renderer and return to initial state
12169 * @ko Renderer를 초기 상태로 되돌립니다
12170 * @return {void}
12171 */
12172
12173
12174 __proto.destroy = function () {
12175 this._flicking = null;
12176 this._panels = [];
12177 };
12178 /**
12179 * Return the {@link Panel} at the given index. `null` if it doesn't exists.
12180 * @ko 주어진 인덱스에 해당하는 {@link Panel}을 반환합니다. 주어진 인덱스에 해당하는 패널이 존재하지 않을 경우 `null`을 반환합니다.
12181 * @return {Panel | null} Panel at the given index<ko>주어진 인덱스에 해당하는 패널</ko>
12182 * @see Panel
12183 */
12184
12185
12186 __proto.getPanel = function (index) {
12187 return this._panels[index] || null;
12188 };
12189 /**
12190 * Update all panel sizes
12191 * @ko 모든 패널의 크기를 업데이트합니다
12192 * @chainable
12193 * @return {this}
12194 */
12195
12196
12197 __proto.updatePanelSize = function () {
12198 var flicking = getFlickingAttached(this._flicking, "Renderer");
12199
12200 if (flicking.panelsPerView > 0) {
12201 this._updatePanelSizeByGrid(flicking);
12202 } else {
12203 flicking.panels.forEach(function (panel) {
12204 return panel.resize();
12205 });
12206 }
12207
12208 return this;
12209 };
12210 /**
12211 * Insert new panels at given index
12212 * This will increase index of panels after by the number of panels added
12213 * @ko 주어진 인덱스에 새로운 패널들을 추가합니다
12214 * 해당 인덱스보다 같거나 큰 인덱스를 가진 기존 패널들은 추가한 패널의 개수만큼 인덱스가 증가합니다.
12215 * @param {number} index Index to insert new panels at<ko>새로 패널들을 추가할 인덱스</ko>
12216 * @param {any[]} elements An array of element or framework component with element in it<ko>엘리먼트의 배열 혹은 프레임워크에서 엘리먼트를 포함한 컴포넌트들의 배열</ko>
12217 * @return {Panel[]} An array of prepended panels<ko>추가된 패널들의 배열</ko>
12218 */
12219
12220
12221 __proto.batchInsert = function () {
12222 var _this = this;
12223
12224 var items = [];
12225
12226 for (var _i = 0; _i < arguments.length; _i++) {
12227 items[_i] = arguments[_i];
12228 }
12229
12230 var panels = this._panels;
12231 var flicking = getFlickingAttached(this._flicking, "Renderer");
12232 var control = flicking.control;
12233
12234 var align = this._getPanelAlign();
12235
12236 var allPanelsInserted = items.reduce(function (addedPanels, item) {
12237 var _a;
12238
12239 var insertingIdx = getMinusCompensatedIndex(item.index, panels.length);
12240 var panelsPushed = panels.slice(insertingIdx);
12241 var panelsInserted = item.elements.map(function (el, idx) {
12242 return _this._createPanel(el, {
12243 index: insertingIdx + idx,
12244 align: align,
12245 flicking: flicking
12246 });
12247 });
12248 panels.splice.apply(panels, __spreadArray([insertingIdx, 0], __read$1(panelsInserted))); // Insert the actual elements as camera element's children
12249
12250 _this._insertPanelElements(panelsInserted, (_a = panelsPushed[0]) !== null && _a !== void 0 ? _a : null); // Resize the newly added panels
12251
12252
12253 panelsInserted.forEach(function (panel) {
12254 return panel.resize();
12255 }); // Update panel indexes & positions
12256
12257 panelsPushed.forEach(function (panel) {
12258 panel.increaseIndex(panelsInserted.length);
12259 panel.updatePosition();
12260 });
12261 return __spreadArray(__spreadArray([], __read$1(addedPanels)), __read$1(panelsInserted));
12262 }, []);
12263 if (allPanelsInserted.length <= 0) return []; // Update camera & control
12264
12265 this._updateCameraAndControl();
12266
12267 void this.render(); // Move to the first panel added if no panels existed
12268 // FIXME: fix for animating case
12269
12270 if (allPanelsInserted.length > 0 && !control.animating) {
12271 void control.moveToPanel(control.activePanel || allPanelsInserted[0], {
12272 duration: 0
12273 }).catch(function () {
12274 return void 0;
12275 });
12276 }
12277
12278 flicking.camera.updateOffset();
12279 flicking.trigger(new ComponentEvent$1(EVENTS.PANEL_CHANGE, {
12280 added: allPanelsInserted,
12281 removed: []
12282 }));
12283 this.checkPanelContentsReady(allPanelsInserted);
12284 return allPanelsInserted;
12285 };
12286 /**
12287 * Remove the panel at the given index
12288 * This will decrease index of panels after by the number of panels removed
12289 * @ko 주어진 인덱스의 패널을 제거합니다
12290 * 해당 인덱스보다 큰 인덱스를 가진 기존 패널들은 제거한 패널의 개수만큼 인덱스가 감소합니다
12291 * @param {number} index Index of panel to remove<ko>제거할 패널의 인덱스</ko>
12292 * @param {number} [deleteCount=1] Number of panels to remove from index<ko>`index` 이후로 제거할 패널의 개수</ko>
12293 * @return An array of removed panels<ko>제거된 패널들의 배열</ko>
12294 */
12295
12296
12297 __proto.batchRemove = function () {
12298 var _this = this;
12299
12300 var items = [];
12301
12302 for (var _i = 0; _i < arguments.length; _i++) {
12303 items[_i] = arguments[_i];
12304 }
12305
12306 var panels = this._panels;
12307 var flicking = getFlickingAttached(this._flicking, "Renderer");
12308 var camera = flicking.camera,
12309 control = flicking.control;
12310 var activePanel = control.activePanel;
12311 var activeIndex = control.activeIndex;
12312 var allPanelsRemoved = items.reduce(function (removed, item) {
12313 var index = item.index,
12314 deleteCount = item.deleteCount;
12315 var removingIdx = getMinusCompensatedIndex(index, panels.length);
12316 var panelsPulled = panels.slice(removingIdx + deleteCount);
12317 var panelsRemoved = panels.splice(removingIdx, deleteCount);
12318 if (panelsRemoved.length <= 0) return []; // Update panel indexes & positions
12319
12320 panelsPulled.forEach(function (panel) {
12321 panel.decreaseIndex(panelsRemoved.length);
12322 panel.updatePosition();
12323 });
12324
12325 _this._removePanelElements(panelsRemoved); // Remove panel elements
12326
12327
12328 panelsRemoved.forEach(function (panel) {
12329 return panel.destroy();
12330 }); // Update camera & control
12331
12332 _this._updateCameraAndControl();
12333
12334 if (includes(panelsRemoved, activePanel)) {
12335 control.resetActive();
12336 }
12337
12338 return __spreadArray(__spreadArray([], __read$1(removed)), __read$1(panelsRemoved));
12339 }, []);
12340 void this.render(); // FIXME: fix for animating case
12341
12342 if (allPanelsRemoved.length > 0 && !control.animating) {
12343 var targetPanel = includes(allPanelsRemoved, activePanel) ? panels[activeIndex] || panels[panels.length - 1] : activePanel;
12344
12345 if (targetPanel) {
12346 void control.moveToPanel(targetPanel, {
12347 duration: 0
12348 }).catch(function () {
12349 return void 0;
12350 });
12351 } else {
12352 // All panels removed
12353 camera.lookAt(0);
12354 }
12355 }
12356
12357 flicking.camera.updateOffset();
12358 flicking.trigger(new ComponentEvent$1(EVENTS.PANEL_CHANGE, {
12359 added: [],
12360 removed: allPanelsRemoved
12361 }));
12362 return allPanelsRemoved;
12363 };
12364 /**
12365 * @internal
12366 */
12367
12368
12369 __proto.checkPanelContentsReady = function (checkingPanels) {
12370 var _this = this;
12371
12372 var resizeOnContentsReady = getFlickingAttached(this._flicking, "Renderer").resizeOnContentsReady;
12373 var panels = this._panels;
12374 if (!resizeOnContentsReady) return;
12375
12376 var hasContents = function (panel) {
12377 return !!panel.element.querySelector("img, video");
12378 };
12379
12380 checkingPanels = checkingPanels.filter(function (panel) {
12381 return hasContents(panel);
12382 });
12383 if (checkingPanels.length <= 0) return;
12384 var contentsReadyChecker = new ImReady$1();
12385 checkingPanels.forEach(function (panel) {
12386 panel.loading = true;
12387 });
12388 contentsReadyChecker.on("readyElement", function (e) {
12389 var flicking = _this._flicking;
12390
12391 if (!flicking) {
12392 // Renderer's destroy() is called before
12393 contentsReadyChecker.destroy();
12394 return;
12395 }
12396
12397 var panel = checkingPanels[e.index];
12398 var camera = flicking.camera;
12399 var control = flicking.control;
12400 var prevProgressInPanel = control.activePanel ? camera.getProgressInPanel(control.activePanel) : 0;
12401 panel.loading = false;
12402 panel.resize();
12403 panels.slice(panel.index + 1).forEach(function (panelBehind) {
12404 return panelBehind.updatePosition();
12405 });
12406 if (!flicking.initialized) return;
12407 camera.updateRange();
12408 camera.updateAnchors();
12409
12410 if (control.animating) ; else {
12411 control.updatePosition(prevProgressInPanel);
12412 control.updateInput();
12413 }
12414 });
12415 contentsReadyChecker.on("preReady", function (e) {
12416 if (_this._flicking) {
12417 void _this.render();
12418 }
12419
12420 if (e.readyCount === e.totalCount) {
12421 contentsReadyChecker.destroy();
12422 }
12423 });
12424 contentsReadyChecker.on("ready", function () {
12425 if (_this._flicking) {
12426 void _this.render();
12427 }
12428
12429 contentsReadyChecker.destroy();
12430 });
12431 contentsReadyChecker.check(checkingPanels.map(function (panel) {
12432 return panel.element;
12433 }));
12434 };
12435
12436 __proto._getPanelAlign = function () {
12437 var align = this._align;
12438 return typeof align === "object" ? align.panel : align;
12439 };
12440
12441 __proto._updateCameraAndControl = function () {
12442 var flicking = getFlickingAttached(this._flicking, "Renderer");
12443 var camera = flicking.camera,
12444 control = flicking.control;
12445 camera.updateRange();
12446 camera.updateAnchors();
12447 camera.resetNeedPanelHistory();
12448 control.updateInput();
12449 };
12450
12451 __proto._updateRenderingPanels = function () {
12452 var flicking = getFlickingAttached(this._flicking, "Renderer");
12453
12454 if (flicking.renderOnlyVisible) {
12455 this._showOnlyVisiblePanels(flicking);
12456 } else {
12457 flicking.panels.forEach(function (panel) {
12458 return panel.markForShow();
12459 });
12460 }
12461 };
12462
12463 __proto._showOnlyVisiblePanels = function (flicking) {
12464 var panels = flicking.renderer.panels;
12465 var camera = flicking.camera;
12466 var visibleIndexes = camera.visiblePanels.reduce(function (visibles, panel) {
12467 visibles[panel.index] = true;
12468 return visibles;
12469 }, {});
12470 panels.forEach(function (panel) {
12471 if (panel.index in visibleIndexes || panel.loading) {
12472 panel.markForShow();
12473 } else if (!flicking.holding) {
12474 // During the input sequence,
12475 // Do not remove panel elements as it won't trigger touchend event.
12476 panel.markForHide();
12477 }
12478 });
12479 camera.updateOffset();
12480 };
12481
12482 __proto._updatePanelSizeByGrid = function (flicking) {
12483 var panels = flicking.panels;
12484 var panelsPerView = flicking.panelsPerView;
12485
12486 if (panelsPerView <= 0) {
12487 throw new FlickingError(MESSAGE.WRONG_OPTION("panelsPerView", panelsPerView), CODE.WRONG_OPTION);
12488 }
12489
12490 if (panels.length <= 0) return; // resize only the first panel
12491
12492 var firstPanel = panels[0];
12493 firstPanel.resize();
12494 var viewportSize = flicking.camera.size;
12495 var gap = firstPanel.margin.prev + firstPanel.margin.next;
12496 var panelSize = (viewportSize - gap * (panelsPerView - 1)) / panelsPerView;
12497 var panelSizeObj = flicking.horizontal ? {
12498 width: panelSize
12499 } : {
12500 height: panelSize
12501 };
12502 var firstPanelSizeObj = {
12503 size: panelSize,
12504 height: firstPanel.height,
12505 margin: firstPanel.margin
12506 };
12507
12508 if (!flicking.noPanelStyleOverride) {
12509 flicking.panels.forEach(function (panel) {
12510 return panel.setSize(panelSizeObj);
12511 });
12512 }
12513
12514 flicking.panels.forEach(function (panel) {
12515 return panel.resize(firstPanelSizeObj);
12516 });
12517 };
12518
12519 return Renderer;
12520 }();
12521
12522 var Panel = function () {
12523 /**
12524 * @param {object} options An options object<ko>옵션 오브젝트</ko>
12525 * @param {number} [options.index] An initial index of the panel<ko>패널의 초기 인덱스</ko>
12526 * @param {Constants.ALIGN | string | number} [options.align] An initial {@link Flicking#align align} value of the panel<ko>패널의 초기 {@link Flicking#align align}값</ko>
12527 * @param {Flicking} [options.flicking] A Flicking instance panel's referencing<ko>패널이 참조하는 {@link Flicking} 인스턴스</ko>
12528 */
12529 function Panel(_a) {
12530 var index = _a.index,
12531 align = _a.align,
12532 flicking = _a.flicking;
12533 this._index = index;
12534 this._flicking = flicking;
12535 this._align = align;
12536 this._removed = false;
12537 this._loading = false;
12538
12539 this._resetInternalStates();
12540 }
12541
12542 var __proto = Panel.prototype;
12543 Object.defineProperty(__proto, "index", {
12544 /**
12545 * Index of the panel
12546 * @ko 패널의 인덱스
12547 * @type {number}
12548 * @readonly
12549 */
12550 get: function () {
12551 return this._index;
12552 },
12553 enumerable: false,
12554 configurable: true
12555 });
12556 Object.defineProperty(__proto, "position", {
12557 /**
12558 * Position of the panel, including {@link Panel#alignPosition alignPosition}
12559 * @ko 패널의 현재 좌표, {@link Panel#alignPosition alignPosition}을 포함하고 있습니다
12560 * @type {number}
12561 * @readonly
12562 */
12563 get: function () {
12564 return this._pos + this._alignPos;
12565 },
12566 enumerable: false,
12567 configurable: true
12568 });
12569 Object.defineProperty(__proto, "size", {
12570 /**
12571 * Cached size of the panel element
12572 * This is equal to {@link Panel#element element}'s `offsetWidth` if {@link Flicking#horizontal horizontal} is `true`, and `offsetHeight` else
12573 * @ko 패널 엘리먼트의 캐시된 크기
12574 * 이 값은 {@link Flicking#horizontal horizontal}이 `true`일 경우 {@link Panel#element element}의 `offsetWidth`와 동일하고, `false`일 경우 `offsetHeight`와 동일합니다
12575 * @type {number}
12576 * @readonly
12577 */
12578 get: function () {
12579 return this._size;
12580 },
12581 enumerable: false,
12582 configurable: true
12583 });
12584 Object.defineProperty(__proto, "sizeIncludingMargin", {
12585 /**
12586 * Panel's size including CSS `margin`
12587 * This value includes {@link Panel#element element}'s margin left/right if {@link Flicking#horizontal horizontal} is `true`, and margin top/bottom else
12588 * @ko CSS `margin`을 포함한 패널의 크기
12589 * 이 값은 {@link Flicking#horizontal horizontal}이 `true`일 경우 margin left/right을 포함하고, `false`일 경우 margin top/bottom을 포함합니다
12590 * @type {number}
12591 * @readonly
12592 */
12593 get: function () {
12594 return this._size + this._margin.prev + this._margin.next;
12595 },
12596 enumerable: false,
12597 configurable: true
12598 });
12599 Object.defineProperty(__proto, "height", {
12600 /**
12601 * Height of the panel element
12602 * @ko 패널 엘리먼트의 높이
12603 * @type {number}
12604 * @readonly
12605 */
12606 get: function () {
12607 return this._height;
12608 },
12609 enumerable: false,
12610 configurable: true
12611 });
12612 Object.defineProperty(__proto, "margin", {
12613 /**
12614 * Cached CSS `margin` value of the panel element
12615 * @ko 패널 엘리먼트의 CSS `margin` 값
12616 * @type {object}
12617 * @property {number} prev CSS `margin-left` when the {@link Flicking#horizontal horizontal} is `true`, and `margin-top` else
12618 * <ko>{@link Flicking#horizontal horizontal}이 `true`일 경우 `margin-left`, `false`일 경우 `margin-top`에 해당하는 값</ko>
12619 * @property {number} next CSS `margin-right` when the {@link Flicking#horizontal horizontal} is `true`, and `margin-bottom` else
12620 * <ko>{@link Flicking#horizontal horizontal}이 `true`일 경우 `margin-right`, `false`일 경우 `margin-bottom`에 해당하는 값</ko>
12621 * @readonly
12622 */
12623 get: function () {
12624 return this._margin;
12625 },
12626 enumerable: false,
12627 configurable: true
12628 });
12629 Object.defineProperty(__proto, "alignPosition", {
12630 /**
12631 * Align position inside the panel where {@link Camera}'s {@link Camera#alignPosition alignPosition} inside viewport should be located at
12632 * @ko 패널의 정렬 기준 위치. {@link Camera}의 뷰포트 내에서의 {@link Camera#alignPosition alignPosition}이 위치해야 하는 곳입니다
12633 * @type {number}
12634 * @readonly
12635 */
12636 get: function () {
12637 return this._alignPos;
12638 },
12639 enumerable: false,
12640 configurable: true
12641 });
12642 Object.defineProperty(__proto, "removed", {
12643 /**
12644 * A value indicating whether the panel's {@link Flicking#remove remove}d
12645 * @ko 패널이 {@link Flicking#remove remove}되었는지 여부를 나타내는 값
12646 * @type {boolean}
12647 * @readonly
12648 */
12649 get: function () {
12650 return this._removed;
12651 },
12652 enumerable: false,
12653 configurable: true
12654 });
12655 Object.defineProperty(__proto, "loading", {
12656 /**
12657 * A value indicating whether the panel's image/video is not loaded and waiting for resize
12658 * @ko 패널 내부의 이미지/비디오가 아직 로드되지 않아 {@link Panel#resize resize}될 것인지를 나타내는 값
12659 * @type {boolean}
12660 * @readonly
12661 */
12662 get: function () {
12663 return this._loading;
12664 },
12665 set: function (val) {
12666 this._loading = val;
12667 },
12668 enumerable: false,
12669 configurable: true
12670 });
12671 Object.defineProperty(__proto, "range", {
12672 /**
12673 * Panel element's range of the bounding box
12674 * @ko 패널 엘리먼트의 Bounding box 범위
12675 * @type {object}
12676 * @property {number} [min] Bounding box's left({@link Flicking#horizontal horizontal}: true) / top({@link Flicking#horizontal horizontal}: false)
12677 * @property {number} [max] Bounding box's right({@link Flicking#horizontal horizontal}: true) / bottom({@link Flicking#horizontal horizontal}: false)
12678 * @readonly
12679 */
12680 get: function () {
12681 return {
12682 min: this._pos,
12683 max: this._pos + this._size
12684 };
12685 },
12686 enumerable: false,
12687 configurable: true
12688 });
12689 Object.defineProperty(__proto, "toggled", {
12690 /**
12691 * A value indicating whether the panel's position is toggled by circular behavior
12692 * @ko 패널의 위치가 circular 동작에 의해 토글되었는지 여부를 나타내는 값
12693 * @type {boolean}
12694 * @readonly
12695 */
12696 get: function () {
12697 return this._toggled;
12698 },
12699 enumerable: false,
12700 configurable: true
12701 });
12702 Object.defineProperty(__proto, "toggleDirection", {
12703 /**
12704 * A direction where the panel's position is toggled
12705 * @ko 패널의 위치가 circular 동작에 의해 토글되는 방향
12706 * @type {DIRECTION}
12707 * @readonly
12708 */
12709 get: function () {
12710 return this._toggleDirection;
12711 },
12712 enumerable: false,
12713 configurable: true
12714 });
12715 Object.defineProperty(__proto, "offset", {
12716 /**
12717 * Actual position offset determined by {@link Panel#order}
12718 * @ko {@link Panel#order}에 의한 실제 위치 변경값
12719 * @type {number}
12720 * @readonly
12721 */
12722 get: function () {
12723 var toggleDirection = this._toggleDirection;
12724 var cameraRangeDiff = this._flicking.camera.rangeDiff;
12725 return toggleDirection === DIRECTION.NONE || !this._toggled ? 0 : toggleDirection === DIRECTION.PREV ? -cameraRangeDiff : cameraRangeDiff;
12726 },
12727 enumerable: false,
12728 configurable: true
12729 });
12730 Object.defineProperty(__proto, "progress", {
12731 /**
12732 * Progress of movement between previous or next panel relative to current panel
12733 * @ko 이 패널로부터 이전/다음 패널으로의 이동 진행률
12734 * @type {number}
12735 * @readonly
12736 */
12737 get: function () {
12738 var flicking = this._flicking;
12739 return this.index - flicking.camera.progress;
12740 },
12741 enumerable: false,
12742 configurable: true
12743 });
12744 Object.defineProperty(__proto, "outsetProgress", {
12745 /**
12746 * Progress of movement between points that panel is completely invisible outside of viewport(prev direction: -1, selected point: 0, next direction: 1)
12747 * @ko 현재 패널이 뷰포트 영역 밖으로 완전히 사라지는 지점을 기준으로 하는 진행도(prev방향: -1, 선택 지점: 0, next방향: 1)
12748 * @type {number}
12749 * @readonly
12750 */
12751 get: function () {
12752 var position = this.position + this.offset;
12753 var alignPosition = this._alignPos;
12754 var camera = this._flicking.camera;
12755 var camPos = camera.position;
12756
12757 if (camPos === position) {
12758 return 0;
12759 }
12760
12761 if (camPos < position) {
12762 var disappearPosNext = position + (camera.size - camera.alignPosition) + alignPosition;
12763 return -getProgress(camPos, position, disappearPosNext);
12764 } else {
12765 var disappearPosPrev = position - (camera.alignPosition + this._size - alignPosition);
12766 return 1 - getProgress(camPos, disappearPosPrev, position);
12767 }
12768 },
12769 enumerable: false,
12770 configurable: true
12771 });
12772 Object.defineProperty(__proto, "visibleRatio", {
12773 /**
12774 * Percentage of area where panel is visible in the viewport
12775 * @ko 뷰포트 안에서 패널이 보이는 영역의 비율
12776 * @type {number}
12777 * @readonly
12778 */
12779 get: function () {
12780 var range = this.range;
12781 var size = this._size;
12782 var offset = this.offset;
12783 var visibleRange = this._flicking.camera.visibleRange;
12784 var checkingRange = {
12785 min: range.min + offset,
12786 max: range.max + offset
12787 };
12788
12789 if (checkingRange.max <= visibleRange.min || checkingRange.min >= visibleRange.max) {
12790 return 0;
12791 }
12792
12793 var visibleSize = size;
12794
12795 if (visibleRange.min > checkingRange.min) {
12796 visibleSize -= visibleRange.min - checkingRange.min;
12797 }
12798
12799 if (visibleRange.max < checkingRange.max) {
12800 visibleSize -= checkingRange.max - visibleRange.max;
12801 }
12802
12803 return visibleSize / size;
12804 },
12805 enumerable: false,
12806 configurable: true
12807 });
12808 Object.defineProperty(__proto, "align", {
12809 // Options Getter
12810
12811 /**
12812 * A value indicating where the {@link Panel#alignPosition alignPosition} should be located at inside the panel element
12813 * @ko {@link Panel#alignPosition alignPosition}이 패널 내의 어디에 위치해야 하는지를 나타내는 값
12814 * @type {Constants.ALIGN | string | number}
12815 */
12816 get: function () {
12817 return this._align;
12818 },
12819 // Options Setter
12820 set: function (val) {
12821 this._align = val;
12822 },
12823 enumerable: false,
12824 configurable: true
12825 });
12826 /**
12827 * Update size of the panel
12828 * @ko 패널의 크기를 갱신합니다
12829 * @param {object} cached Predefined cached size of the panel<ko>사전에 캐시된 패널의 크기 정보</ko>
12830 * @chainable
12831 * @return {this}
12832 */
12833
12834 __proto.resize = function (cached) {
12835 var el = this.element;
12836 var elStyle = getStyle(el);
12837 var flicking = this._flicking;
12838 var horizontal = flicking.horizontal;
12839
12840 if (cached) {
12841 this._size = cached.size;
12842 this._margin = __assign$2({}, cached.margin);
12843 this._height = cached.height;
12844 } else {
12845 this._size = horizontal ? el.offsetWidth : el.offsetHeight;
12846 this._margin = horizontal ? {
12847 prev: parseFloat(elStyle.marginLeft || "0"),
12848 next: parseFloat(elStyle.marginRight || "0")
12849 } : {
12850 prev: parseFloat(elStyle.marginTop || "0"),
12851 next: parseFloat(elStyle.marginBottom || "0")
12852 };
12853 this._height = horizontal ? el.offsetHeight : this._size;
12854 }
12855
12856 this.updatePosition();
12857
12858 this._updateAlignPos();
12859
12860 return this;
12861 };
12862 /**
12863 * Change panel's size. This will change the actual size of the panel element by changing its CSS width/height property
12864 * @ko 패널 크기를 변경합니다. 패널 엘리먼트에 해당 크기의 CSS width/height를 적용합니다
12865 * @param {object} [size] New panel size<ko>새 패널 크기</ko>
12866 * @param {number|string} [size.width] CSS string or number(in px)<ko>CSS 문자열 또는 숫자(px)</ko>
12867 * @param {number|string} [size.height] CSS string or number(in px)<ko>CSS 문자열 또는 숫자(px)</ko>
12868 * @chainable
12869 * @return {this}
12870 */
12871
12872
12873 __proto.setSize = function (_a) {
12874 var width = _a.width,
12875 height = _a.height;
12876 var el = this.element;
12877
12878 if (width != null) {
12879 if (isString(width)) {
12880 el.style.width = width;
12881 } else {
12882 el.style.width = width + "px";
12883 }
12884 }
12885
12886 if (height != null) {
12887 if (isString(height)) {
12888 el.style.height = height;
12889 } else {
12890 el.style.height = height + "px";
12891 }
12892 }
12893
12894 return this;
12895 };
12896 /**
12897 * Check whether the given element is inside of this panel's {@link Panel#element element}
12898 * @ko 해당 엘리먼트가 이 패널의 {@link Panel#element element} 내에 포함되어 있는지를 반환합니다
12899 * @param {HTMLElement} element The HTMLElement to check<ko>확인하고자 하는 HTMLElement</ko>
12900 * @return {boolean} A Boolean value indicating the element is inside of this panel {@link Panel#element element}<ko>패널의 {@link Panel#element element}내에 해당 엘리먼트 포함 여부</ko>
12901 */
12902
12903
12904 __proto.contains = function (element) {
12905 var _a;
12906
12907 return !!((_a = this.element) === null || _a === void 0 ? void 0 : _a.contains(element));
12908 };
12909 /**
12910 * Reset internal state and set {@link Panel#removed removed} to `true`
12911 * @ko 내부 상태를 초기화하고 {@link Panel#removed removed}를 `true`로 설정합니다.
12912 * @return {void}
12913 */
12914
12915
12916 __proto.destroy = function () {
12917 this._resetInternalStates();
12918
12919 this._removed = true;
12920 };
12921 /**
12922 * Check whether the given position is inside of this panel's {@link Panel#range range}
12923 * @ko 주어진 좌표가 현재 패널의 {@link Panel#range range}내에 속해있는지를 반환합니다.
12924 * @param {number} pos A position to check<ko>확인하고자 하는 좌표</ko>
12925 * @param {boolean} [includeMargin=false] Include {@link Panel#margin margin} to the range<ko>패널 영역에 {@link Panel#margin margin}값을 포함시킵니다</ko>
12926 * @return {boolean} A Boolean value indicating whether the given position is included in the panel range<ko>해당 좌표가 패널 영역 내에 속해있는지 여부</ko>
12927 */
12928
12929
12930 __proto.includePosition = function (pos, includeMargin) {
12931 if (includeMargin === void 0) {
12932 includeMargin = false;
12933 }
12934
12935 return this.includeRange(pos, pos, includeMargin);
12936 };
12937 /**
12938 * Check whether the given range is fully included in this panel's area
12939 * @ko 주어진 범위가 이 패널 내부에 완전히 포함되는지를 반환합니다
12940 * @param {number} min Minimum value of the range to check<ko>확인하고자 하는 최소 범위</ko>
12941 * @param {number} max Maximum value of the range to check<ko>확인하고자 하는 최대 범위</ko>
12942 * @param {boolean} [includeMargin=false] Include {@link Panel#margin margin} to the range<ko>패널 영역에 {@link Panel#margin margin}값을 포함시킵니다</ko>
12943 * @returns {boolean} A Boolean value indicating whether the given range is fully included in the panel range<ko>해당 범위가 패널 영역 내에 완전히 속해있는지 여부</ko>
12944 */
12945
12946
12947 __proto.includeRange = function (min, max, includeMargin) {
12948 if (includeMargin === void 0) {
12949 includeMargin = false;
12950 }
12951
12952 var margin = this._margin;
12953 var panelRange = this.range;
12954
12955 if (includeMargin) {
12956 panelRange.min -= margin.prev;
12957 panelRange.max += margin.next;
12958 }
12959
12960 return max >= panelRange.min && min <= panelRange.max;
12961 };
12962 /**
12963 * Move {@link Camera} to this panel
12964 * @ko {@link Camera}를 이 패널로 이동합니다
12965 * @param {number} [duration] Duration of the animation (unit: ms)<ko>애니메이션 진행 시간 (단위: ms)</ko>
12966 * @returns {Promise<void>} A Promise which will be resolved after reaching the panel<ko>패널 도달시에 resolve되는 Promise</ko>
12967 */
12968
12969
12970 __proto.focus = function (duration) {
12971 return this._flicking.moveTo(this._index, duration);
12972 };
12973 /**
12974 * Get previous(`index - 1`) panel. When the previous panel does not exist, this will return `null` instead
12975 * If the {@link Flicking#circularEnabled circular} is enabled, this will return the last panel if called from the first panel
12976 * @ko 이전(`index - 1`) 패널을 반환합니다. 이전 패널이 없을 경우 `null`을 반환합니다
12977 * {@link Flicking#circularEnabled circular} 모드가 활성화되었을 때 첫번째 패널에서 이 메소드를 호출할 경우 마지막 패널을 반환합니다
12978 * @returns {Panel | null} The previous panel<ko>이전 패널</ko>
12979 */
12980
12981
12982 __proto.prev = function () {
12983 var index = this._index;
12984 var flicking = this._flicking;
12985 var renderer = flicking.renderer;
12986 var panelCount = renderer.panelCount;
12987 if (panelCount === 1) return null;
12988 return flicking.circularEnabled ? renderer.getPanel(index === 0 ? panelCount - 1 : index - 1) : renderer.getPanel(index - 1);
12989 };
12990 /**
12991 * Get next(`index + 1`) panel. When the next panel does not exist, this will return `null` instead
12992 * If the {@link Flicking#circularEnabled circular} is enabled, this will return the first panel if called from the last panel
12993 * @ko 다음(`index + 1`) 패널을 반환합니다. 다음 패널이 없을 경우 `null`을 반환합니다
12994 * {@link Flicking#circularEnabled circular} 모드가 활성화되었을 때 마지막 패널에서 이 메소드를 호출할 경우 첫번째 패널을 반환합니다
12995 * @returns {Panel | null} The previous panel<ko>다음 패널</ko>
12996 */
12997
12998
12999 __proto.next = function () {
13000 var index = this._index;
13001 var flicking = this._flicking;
13002 var renderer = flicking.renderer;
13003 var panelCount = renderer.panelCount;
13004 if (panelCount === 1) return null;
13005 return flicking.circularEnabled ? renderer.getPanel(index === panelCount - 1 ? 0 : index + 1) : renderer.getPanel(index + 1);
13006 };
13007 /**
13008 * Increase panel's index by the given value
13009 * @ko 패널의 인덱스를 주어진 값만큼 증가시킵니다
13010 * @internal
13011 * @chainable
13012 * @param val An integer greater than or equal to 0<ko>0보다 같거나 큰 정수</ko>
13013 * @returns {this}
13014 */
13015
13016
13017 __proto.increaseIndex = function (val) {
13018 this._index += Math.max(val, 0);
13019 return this;
13020 };
13021 /**
13022 * Decrease panel's index by the given value
13023 * @ko 패널의 인덱스를 주어진 값만큼 감소시킵니다
13024 * @internal
13025 * @chainable
13026 * @param val An integer greater than or equal to 0<ko>0보다 같거나 큰 정수</ko>
13027 * @returns {this}
13028 */
13029
13030
13031 __proto.decreaseIndex = function (val) {
13032 this._index -= Math.max(val, 0);
13033 return this;
13034 };
13035 /**
13036 * @internal
13037 */
13038
13039
13040 __proto.updatePosition = function () {
13041 var prevPanel = this._flicking.renderer.panels[this._index - 1];
13042 this._pos = prevPanel ? prevPanel.range.max + prevPanel.margin.next + this._margin.prev : this._margin.prev;
13043 return this;
13044 };
13045 /**
13046 * @internal
13047 * @return {boolean} toggled
13048 */
13049
13050
13051 __proto.toggle = function (prevPos, newPos) {
13052 var toggleDirection = this._toggleDirection;
13053 var togglePosition = this._togglePosition;
13054 if (toggleDirection === DIRECTION.NONE || newPos === prevPos) return false;
13055 var prevToggled = this._toggled;
13056
13057 if (newPos > prevPos) {
13058 if (togglePosition >= prevPos && togglePosition <= newPos) {
13059 this._toggled = toggleDirection === DIRECTION.NEXT;
13060 }
13061 } else {
13062 if (togglePosition <= prevPos && togglePosition >= newPos) {
13063 this._toggled = toggleDirection !== DIRECTION.NEXT;
13064 }
13065 }
13066
13067 return prevToggled !== this._toggled;
13068 };
13069 /**
13070 * @internal
13071 */
13072
13073
13074 __proto.updateCircularToggleDirection = function () {
13075 var flicking = this._flicking;
13076
13077 if (!flicking.circularEnabled) {
13078 this._toggleDirection = DIRECTION.NONE;
13079 this._toggled = false;
13080 return this;
13081 }
13082
13083 var camera = flicking.camera;
13084 var camRange = camera.range;
13085 var camAlignPosition = camera.alignPosition;
13086 var camVisibleRange = camera.visibleRange;
13087 var camVisibleSize = camVisibleRange.max - camVisibleRange.min;
13088 var minimumVisible = camRange.min - camAlignPosition;
13089 var maximumVisible = camRange.max - camAlignPosition + camVisibleSize;
13090 var shouldBeVisibleAtMin = this.includeRange(maximumVisible - camVisibleSize, maximumVisible, false);
13091 var shouldBeVisibleAtMax = this.includeRange(minimumVisible, minimumVisible + camVisibleSize, false);
13092 this._toggled = false;
13093
13094 if (shouldBeVisibleAtMin) {
13095 this._toggleDirection = DIRECTION.PREV;
13096 this._togglePosition = this.range.max + camRange.min - camRange.max + camAlignPosition;
13097 this.toggle(Infinity, camera.position);
13098 } else if (shouldBeVisibleAtMax) {
13099 this._toggleDirection = DIRECTION.NEXT;
13100 this._togglePosition = this.range.min + camRange.max - camVisibleSize + camAlignPosition;
13101 this.toggle(-Infinity, camera.position);
13102 } else {
13103 this._toggleDirection = DIRECTION.NONE;
13104 this._togglePosition = 0;
13105 }
13106
13107 return this;
13108 };
13109
13110 __proto._updateAlignPos = function () {
13111 this._alignPos = parseAlign$1(this._align, this._size);
13112 };
13113
13114 __proto._resetInternalStates = function () {
13115 this._size = 0;
13116 this._pos = 0;
13117 this._margin = {
13118 prev: 0,
13119 next: 0
13120 };
13121 this._height = 0;
13122 this._alignPos = 0;
13123 this._toggled = false;
13124 this._togglePosition = 0;
13125 this._toggleDirection = DIRECTION.NONE;
13126 };
13127
13128 return Panel;
13129 }();
13130
13131 /**
13132 * An slide data component that holds information of a single HTMLElement
13133 * @ko 슬라이드 데이터 컴포넌트로, 단일 HTMLElement의 정보를 갖고 있습니다
13134 */
13135
13136 var ElementPanel = function (_super) {
13137 __extends$2(ElementPanel, _super);
13138 /**
13139 * @param {object} options An options object<ko>옵션 오브젝트</ko>
13140 * @param {HTMLElement} [options.el] A `HTMLElement` panel's referencing<ko>패널이 참조하는 `HTMLElement`</ko>
13141 * @param {number} [options.index] An initial index of the panel<ko>패널의 초기 인덱스</ko>
13142 * @param {Constants.ALIGN | string | number} [options.align] An initial {@link Flicking#align align} value of the panel<ko>패널의 초기 {@link Flicking#align align}값</ko>
13143 * @param {Flicking} [options.flicking] A Flicking instance panel's referencing<ko>패널이 참조하는 {@link Flicking} 인스턴스</ko>
13144 */
13145
13146
13147 function ElementPanel(options) {
13148 var _this = _super.call(this, options) || this;
13149
13150 _this._el = options.el;
13151 _this._rendered = true;
13152 return _this;
13153 }
13154
13155 var __proto = ElementPanel.prototype;
13156 Object.defineProperty(__proto, "element", {
13157 /**
13158 * `HTMLElement` that panel's referencing
13159 * @ko 패널이 참조하고 있는 `HTMLElement`
13160 * @type {HTMLElement}
13161 * @readonly
13162 */
13163 get: function () {
13164 return this._el;
13165 },
13166 enumerable: false,
13167 configurable: true
13168 });
13169 Object.defineProperty(__proto, "rendered", {
13170 get: function () {
13171 return this._rendered;
13172 },
13173 enumerable: false,
13174 configurable: true
13175 });
13176
13177 __proto.markForShow = function () {
13178 this._rendered = true;
13179 };
13180
13181 __proto.markForHide = function () {
13182 this._rendered = false;
13183 };
13184
13185 return ElementPanel;
13186 }(Panel);
13187
13188 /**
13189 *
13190 */
13191
13192 var VanillaRenderer = function (_super) {
13193 __extends$2(VanillaRenderer, _super);
13194
13195 function VanillaRenderer() {
13196 return _super !== null && _super.apply(this, arguments) || this;
13197 } // eslint-disable-next-line @typescript-eslint/require-await
13198
13199
13200 var __proto = VanillaRenderer.prototype;
13201
13202 __proto.render = function () {
13203 return __awaiter(this, void 0, void 0, function () {
13204 var flicking, cameraEl, wasRenderedPanels, renderingPanels;
13205 return __generator(this, function (_a) {
13206 flicking = getFlickingAttached(this._flicking, "Renderer");
13207 cameraEl = flicking.camera.element;
13208 wasRenderedPanels = this._panels.filter(function (panel) {
13209 return panel.element.parentElement === cameraEl;
13210 });
13211
13212 this._updateRenderingPanels();
13213
13214 renderingPanels = this._getRenderingPanelsByOrder();
13215
13216 this._removePanelElements(wasRenderedPanels.filter(function (panel) {
13217 return !panel.rendered;
13218 }));
13219
13220 this._insertPanelElements(renderingPanels.filter(function (panel) {
13221 return panel.element.parentElement !== cameraEl;
13222 }), null);
13223
13224 this._resetPanelElementOrder(renderingPanels);
13225
13226 return [2
13227 /*return*/
13228 ];
13229 });
13230 });
13231 }; // eslint-disable-next-line @typescript-eslint/require-await
13232
13233
13234 __proto.forceRenderAllPanels = function () {
13235 return __awaiter(this, void 0, void 0, function () {
13236 var flicking, camera, cameraElement, fragment;
13237 return __generator(this, function (_a) {
13238 flicking = getFlickingAttached(this._flicking, "Renderer");
13239 camera = flicking.camera;
13240 cameraElement = camera.element;
13241 fragment = document.createDocumentFragment();
13242
13243 this._panels.forEach(function (panel) {
13244 return fragment.appendChild(panel.element);
13245 });
13246
13247 this._removeAllChildsFromCamera();
13248
13249 cameraElement.appendChild(fragment);
13250 return [2
13251 /*return*/
13252 ];
13253 });
13254 });
13255 };
13256
13257 __proto._collectPanels = function () {
13258 var flicking = getFlickingAttached(this._flicking, "Renderer");
13259 var cameraElement = flicking.camera.element; // Remove all text nodes in the camera element
13260
13261 toArray$3(cameraElement.childNodes).forEach(function (node) {
13262 if (node.nodeType === Node.TEXT_NODE) {
13263 cameraElement.removeChild(node);
13264 }
13265 });
13266
13267 var align = this._getPanelAlign();
13268
13269 var cameraChilds = toArray$3(cameraElement.children);
13270 this._panels = cameraChilds.map(function (el, index) {
13271 return new ElementPanel({
13272 flicking: flicking,
13273 el: el,
13274 index: index,
13275 align: align
13276 });
13277 });
13278 };
13279
13280 __proto._createPanel = function (el, options) {
13281 return new ElementPanel(__assign$2({
13282 el: el
13283 }, options));
13284 };
13285
13286 __proto._insertPanelElements = function (panels, nextSibling) {
13287 var flicking = getFlickingAttached(this._flicking, "Renderer");
13288 var camera = flicking.camera;
13289 var cameraElement = camera.element;
13290 var nextSiblingElement = (nextSibling === null || nextSibling === void 0 ? void 0 : nextSibling.element) || null;
13291 var fragment = document.createDocumentFragment();
13292 panels.forEach(function (panel) {
13293 return fragment.appendChild(panel.element);
13294 });
13295 cameraElement.insertBefore(fragment, nextSiblingElement);
13296 return this;
13297 };
13298
13299 __proto._removePanelElements = function (panels) {
13300 var flicking = getFlickingAttached(this._flicking, "Renderer");
13301 var cameraElement = flicking.camera.element;
13302 panels.forEach(function (panel) {
13303 cameraElement.removeChild(panel.element);
13304 });
13305 return this;
13306 };
13307
13308 __proto._resetPanelElementOrder = function (panels) {
13309 var flicking = getFlickingAttached(this._flicking, "Renderer");
13310 var cameraEl = flicking.camera.element; // We're using reversed panels here as last panel should be the last element of camera element
13311
13312 var reversedPanels = __spreadArray([], __read$1(panels)).reverse();
13313
13314 reversedPanels.forEach(function (panel, idx) {
13315 var nextPanel = reversedPanels[idx - 1];
13316 var nextPanelEl = nextPanel ? nextPanel.element : null;
13317
13318 if (panel.element.nextElementSibling !== nextPanelEl) {
13319 cameraEl.insertBefore(panel.element, nextPanelEl);
13320 }
13321 });
13322 };
13323
13324 __proto._removeAllChildsFromCamera = function () {
13325 var flicking = getFlickingAttached(this._flicking, "Renderer");
13326 var cameraElement = flicking.camera.element; // Remove other elements
13327
13328 while (cameraElement.firstChild) {
13329 cameraElement.removeChild(cameraElement.firstChild);
13330 }
13331 };
13332
13333 __proto._getRenderingPanelsByOrder = function () {
13334 var flicking = getFlickingAttached(this._flicking, "Renderer");
13335 var panels = flicking.renderer.panels;
13336 return panels.filter(function (panel) {
13337 return panel.rendered;
13338 }).sort(function (a, b) {
13339 return a.position + a.offset - (b.position + b.offset);
13340 });
13341 };
13342
13343 return VanillaRenderer;
13344 }(Renderer$1);
13345
13346 /**
13347 *
13348 */
13349
13350 var ExternalRenderer = function (_super) {
13351 __extends$2(ExternalRenderer, _super);
13352
13353 function ExternalRenderer() {
13354 return _super !== null && _super.apply(this, arguments) || this;
13355 } // eslint-disable-next-line @typescript-eslint/no-unused-vars
13356
13357
13358 var __proto = ExternalRenderer.prototype;
13359
13360 __proto._insertPanelElements = function (panels, nextSibling) {// DO NOTHING
13361 }; // eslint-disable-next-line @typescript-eslint/no-unused-vars
13362
13363
13364 __proto._removePanelElements = function (panels) {// DO NOTHING
13365 };
13366
13367 return ExternalRenderer;
13368 }(Renderer$1);
13369
13370 /*
13371 * Copyright (c) 2015 NAVER Corp.
13372 * egjs projects are licensed under the MIT license
13373 */
13374
13375 var Renderer = {
13376 __proto__: null,
13377 Renderer: Renderer$1,
13378 VanillaRenderer: VanillaRenderer,
13379 ExternalRenderer: ExternalRenderer
13380 };
13381
13382 /**
13383 * @extends Component
13384 * @support {"ie": "9+(with polyfill)", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "4.X+"}
13385 * @requires {@link https://github.com/naver/egjs-component|@egjs/component}
13386 * @requires {@link https://github.com/naver/egjs-axes|@egjs/axes}
13387 */
13388
13389 var Flicking = function (_super) {
13390 __extends$2(Flicking, _super);
13391 /**
13392 * @param root A root HTMLElement to initialize Flicking on it. When it's a typeof `string`, it should be a css selector string
13393 * <ko>Flicking을 초기화할 HTMLElement로, `string` 타입으로 지정시 css 선택자 문자열을 지정해야 합니다.</ko>
13394 * @param {object} [options={}] An options object for Flicking.<ko>Flicking에 적용할 옵션 오브젝트</ko>
13395 * @throws {FlickingError}
13396 * |code|condition|
13397 * |---|---|
13398 * |{@link ERROR_CODE WRONG_TYPE}|When the root is not either string or HTMLElement|
13399 * |{@link ERROR_CODE ELEMENT_NOT_FOUND}|When the element with given CSS selector does not exist|
13400 * <ko>
13401 *
13402 * |code|조건|
13403 * |---|---|
13404 * |{@link ERROR_CODE WRONG_TYPE}|루트 엘리먼트가 string이나 HTMLElement가 아닐 경우|
13405 * |{@link ERROR_CODE ELEMENT_NOT_FOUND}|주어진 CSS selector로 엘리먼트를 찾지 못했을 경우|
13406 *
13407 * </ko>
13408 * @example
13409 * ```ts
13410 * import Flicking from "@egjs/flicking";
13411 *
13412 * // Creating new instance of Flicking with HTMLElement
13413 * const flicking = new Flicking(document.querySelector(".flicking-viewport"), { circular: true });
13414 *
13415 * // Creating new instance of Flicking with CSS selector
13416 * const flicking2 = new Flicking(".flicking-viewport", { circular: true });
13417 * ```
13418 */
13419
13420
13421 function Flicking(root, _a) {
13422 var _b = _a === void 0 ? {} : _a,
13423 _c = _b.align,
13424 align = _c === void 0 ? ALIGN.CENTER : _c,
13425 _d = _b.defaultIndex,
13426 defaultIndex = _d === void 0 ? 0 : _d,
13427 _e = _b.horizontal,
13428 horizontal = _e === void 0 ? true : _e,
13429 _f = _b.circular,
13430 circular = _f === void 0 ? false : _f,
13431 _g = _b.bound,
13432 bound = _g === void 0 ? false : _g,
13433 _h = _b.adaptive,
13434 adaptive = _h === void 0 ? false : _h,
13435 _j = _b.panelsPerView,
13436 panelsPerView = _j === void 0 ? -1 : _j,
13437 _k = _b.noPanelStyleOverride,
13438 noPanelStyleOverride = _k === void 0 ? false : _k,
13439 _l = _b.resizeOnContentsReady,
13440 resizeOnContentsReady = _l === void 0 ? false : _l,
13441 _m = _b.needPanelThreshold,
13442 needPanelThreshold = _m === void 0 ? 0 : _m,
13443 _o = _b.preventEventsBeforeInit,
13444 preventEventsBeforeInit = _o === void 0 ? true : _o,
13445 _p = _b.deceleration,
13446 deceleration = _p === void 0 ? 0.0075 : _p,
13447 _q = _b.duration,
13448 duration = _q === void 0 ? 500 : _q,
13449 _r = _b.easing,
13450 easing = _r === void 0 ? function (x) {
13451 return 1 - Math.pow(1 - x, 3);
13452 } : _r,
13453 _s = _b.inputType,
13454 inputType = _s === void 0 ? ["mouse", "touch"] : _s,
13455 _t = _b.moveType,
13456 moveType = _t === void 0 ? "snap" : _t,
13457 _u = _b.threshold,
13458 threshold = _u === void 0 ? 40 : _u,
13459 _v = _b.interruptable,
13460 interruptable = _v === void 0 ? true : _v,
13461 _w = _b.bounce,
13462 bounce = _w === void 0 ? "20%" : _w,
13463 _x = _b.iOSEdgeSwipeThreshold,
13464 iOSEdgeSwipeThreshold = _x === void 0 ? 30 : _x,
13465 _y = _b.preventClickOnDrag,
13466 preventClickOnDrag = _y === void 0 ? true : _y,
13467 _z = _b.disableOnInit,
13468 disableOnInit = _z === void 0 ? false : _z,
13469 _0 = _b.renderOnlyVisible,
13470 renderOnlyVisible = _0 === void 0 ? false : _0,
13471 _1 = _b.autoInit,
13472 autoInit = _1 === void 0 ? true : _1,
13473 _2 = _b.autoResize,
13474 autoResize = _2 === void 0 ? true : _2,
13475 _3 = _b.renderExternal,
13476 renderExternal = _3 === void 0 ? null : _3;
13477
13478 var _this = _super.call(this) || this; // Internal states
13479
13480
13481 _this._initialized = false;
13482 _this._plugins = []; // Bind options
13483
13484 _this._align = align;
13485 _this._defaultIndex = defaultIndex;
13486 _this._horizontal = horizontal;
13487 _this._circular = circular;
13488 _this._bound = bound;
13489 _this._adaptive = adaptive;
13490 _this._panelsPerView = panelsPerView;
13491 _this._noPanelStyleOverride = noPanelStyleOverride;
13492 _this._resizeOnContentsReady = resizeOnContentsReady;
13493 _this._needPanelThreshold = needPanelThreshold;
13494 _this._preventEventsBeforeInit = preventEventsBeforeInit;
13495 _this._deceleration = deceleration;
13496 _this._duration = duration;
13497 _this._easing = easing;
13498 _this._inputType = inputType;
13499 _this._moveType = moveType;
13500 _this._threshold = threshold;
13501 _this._interruptable = interruptable;
13502 _this._bounce = bounce;
13503 _this._iOSEdgeSwipeThreshold = iOSEdgeSwipeThreshold;
13504 _this._preventClickOnDrag = preventClickOnDrag;
13505 _this._disableOnInit = disableOnInit;
13506 _this._renderOnlyVisible = renderOnlyVisible;
13507 _this._autoResize = autoResize;
13508 _this._autoInit = autoInit;
13509 _this._renderExternal = renderExternal; // Create core components
13510
13511 _this._viewport = new Viewport(getElement(root));
13512 _this._renderer = _this._createRenderer();
13513 _this._camera = _this._createCamera();
13514 _this._control = _this._createControl();
13515 _this.resize = _this.resize.bind(_this);
13516
13517 if (_this._autoInit) {
13518 void _this.init();
13519 }
13520
13521 return _this;
13522 }
13523
13524 var __proto = Flicking.prototype;
13525 Object.defineProperty(__proto, "control", {
13526 // Components
13527
13528 /**
13529 * {@link Control} instance of the Flicking
13530 * @ko 현재 Flicking에 활성화된 {@link Control} 인스턴스
13531 * @type {Control}
13532 * @default SnapControl
13533 * @readonly
13534 * @see Control
13535 * @see SnapControl
13536 * @see FreeControl
13537 */
13538 get: function () {
13539 return this._control;
13540 },
13541 enumerable: false,
13542 configurable: true
13543 });
13544 Object.defineProperty(__proto, "camera", {
13545 /**
13546 * {@link Camera} instance of the Flicking
13547 * @ko 현재 Flicking에 활성화된 {@link Camera} 인스턴스
13548 * @type {Camera}
13549 * @default LinearCamera
13550 * @readonly
13551 * @see Camera
13552 * @see LinearCamera
13553 * @see BoundCamera
13554 * @see CircularCamera
13555 */
13556 get: function () {
13557 return this._camera;
13558 },
13559 enumerable: false,
13560 configurable: true
13561 });
13562 Object.defineProperty(__proto, "renderer", {
13563 /**
13564 * {@link Renderer} instance of the Flicking
13565 * @ko 현재 Flicking에 활성화된 {@link Renderer} 인스턴스
13566 * @type {Renderer}
13567 * @default VanillaRenderer
13568 * @readonly
13569 * @see Renderer
13570 * @see VanillaRenderer
13571 * @see ExternalRenderer
13572 */
13573 get: function () {
13574 return this._renderer;
13575 },
13576 enumerable: false,
13577 configurable: true
13578 });
13579 Object.defineProperty(__proto, "viewport", {
13580 /**
13581 * A component that manages viewport size
13582 * @ko 뷰포트 크기 정보를 담당하는 컴포넌트
13583 * @type {Viewport}
13584 * @readonly
13585 * @see Viewport
13586 */
13587 get: function () {
13588 return this._viewport;
13589 },
13590 enumerable: false,
13591 configurable: true
13592 });
13593 Object.defineProperty(__proto, "initialized", {
13594 // Internal States
13595
13596 /**
13597 * Whether Flicking's {@link Flicking#init init()} is called.
13598 * This is `true` when {@link Flicking#init init()} is called, and is `false` after calling {@link Flicking#destroy destroy()}.
13599 * @ko Flicking의 {@link Flicking#init init()}이 호출되었는지를 나타내는 멤버 변수.
13600 * 이 값은 {@link Flicking#init init()}이 호출되었으면 `true`로 변하고, {@link Flicking#destroy destroy()}호출 이후에 다시 `false`로 변경됩니다.
13601 * @type {boolean}
13602 * @default false
13603 * @readonly
13604 */
13605 get: function () {
13606 return this._initialized;
13607 },
13608 enumerable: false,
13609 configurable: true
13610 });
13611 Object.defineProperty(__proto, "circularEnabled", {
13612 /**
13613 * Whether the `circular` option is enabled.
13614 * The {@link Flicking#circular circular} option can't be enabled when sum of the panel sizes are too small.
13615 * @ko {@link Flicking#circular circular} 옵션이 활성화되었는지 여부를 나타내는 멤버 변수.
13616 * {@link Flicking#circular circular} 옵션은 패널의 크기의 합이 충분하지 않을 경우 비활성화됩니다.
13617 * @type {boolean}
13618 * @default false
13619 * @readonly
13620 */
13621 get: function () {
13622 return this._camera.controlParams.circular;
13623 },
13624 enumerable: false,
13625 configurable: true
13626 });
13627 Object.defineProperty(__proto, "index", {
13628 /**
13629 * Index number of the {@link Flicking#currentPanel currentPanel}
13630 * @ko {@link Flicking#currentPanel currentPanel}의 인덱스 번호
13631 * @type {number}
13632 * @default 0
13633 * @readonly
13634 */
13635 get: function () {
13636 return this._control.activeIndex;
13637 },
13638 enumerable: false,
13639 configurable: true
13640 });
13641 Object.defineProperty(__proto, "element", {
13642 /**
13643 * The root(`.flicking-viewport`) element
13644 * @ko root(`.flicking-viewport`) 엘리먼트
13645 * @type {HTMLElement}
13646 * @readonly
13647 */
13648 get: function () {
13649 return this._viewport.element;
13650 },
13651 enumerable: false,
13652 configurable: true
13653 });
13654 Object.defineProperty(__proto, "currentPanel", {
13655 /**
13656 * Currently active panel
13657 * @ko 현재 선택된 패널
13658 * @type {Panel}
13659 * @readonly
13660 * @see Panel
13661 */
13662 get: function () {
13663 return this._control.activePanel;
13664 },
13665 enumerable: false,
13666 configurable: true
13667 });
13668 Object.defineProperty(__proto, "panels", {
13669 /**
13670 * Array of panels
13671 * @ko 전체 패널들의 배열
13672 * @type {Panel[]}
13673 * @readonly
13674 * @see Panel
13675 */
13676 get: function () {
13677 return this._renderer.panels;
13678 },
13679 enumerable: false,
13680 configurable: true
13681 });
13682 Object.defineProperty(__proto, "panelCount", {
13683 /**
13684 * Count of panels
13685 * @ko 전체 패널의 개수
13686 * @type {number}
13687 * @readonly
13688 */
13689 get: function () {
13690 return this._renderer.panelCount;
13691 },
13692 enumerable: false,
13693 configurable: true
13694 });
13695 Object.defineProperty(__proto, "visiblePanels", {
13696 /**
13697 * Array of panels that is visible at the current position
13698 * @ko 현재 보이는 패널의 배열
13699 * @type {Panel[]}
13700 * @readonly
13701 * @see Panel
13702 */
13703 get: function () {
13704 return this._camera.visiblePanels;
13705 },
13706 enumerable: false,
13707 configurable: true
13708 });
13709 Object.defineProperty(__proto, "animating", {
13710 /**
13711 * Whether Flicking's animating
13712 * @ko 현재 애니메이션 동작 여부
13713 * @type {boolean}
13714 * @readonly
13715 */
13716 get: function () {
13717 return this._control.animating;
13718 },
13719 enumerable: false,
13720 configurable: true
13721 });
13722 Object.defineProperty(__proto, "holding", {
13723 /**
13724 * Whether user is clicking or touching
13725 * @ko 현재 사용자가 클릭/터치중인지 여부
13726 * @type {boolean}
13727 * @readonly
13728 */
13729 get: function () {
13730 return this._control.holding;
13731 },
13732 enumerable: false,
13733 configurable: true
13734 });
13735 Object.defineProperty(__proto, "activePlugins", {
13736 /**
13737 * A current list of activated plugins
13738 * @ko 현재 활성화된 플러그인 목록
13739 * @type {Plugin[]}
13740 * @readonly
13741 */
13742 get: function () {
13743 return this._plugins;
13744 },
13745 enumerable: false,
13746 configurable: true
13747 });
13748 Object.defineProperty(__proto, "align", {
13749 // Options Getter
13750 // UI / LAYOUT
13751
13752 /**
13753 * Align position of the panels within viewport. You can set different values each for the panel and camera
13754 * @ko 뷰포트 내에서 패널 정렬방식을 설정하는 옵션. 카메라와 패널 개별로 옵션을 설정할 수도 있습니다
13755 * @type {ALIGN | string | number | { panel: string | number, camera: string | number }}
13756 * @property {ALIGN | string | number} panel The align value for each {@link Panel}s<ko>개개의 {@link Panel}에 적용할 값</ko>
13757 * @property {ALIGN | string | number} camera The align value for {@link Camera}<ko>{@link Camera}에 적용할 값</ko>
13758 * @default "center"
13759 * @example
13760 * ```ts
13761 * const possibleOptions = [
13762 * // Literal strings
13763 * "prev", "center", "next",
13764 * // % values, applied to both panel & camera
13765 * "0%", "25%", "42%",
13766 * // px values, arithmetic calculation with (+/-) is also allowed.
13767 * "0px", "100px", "50% - 25px",
13768 * // numbers, same to number + px ("0px", "100px")
13769 * 0, 100, 1000,
13770 * // Setting a different value for panel & camera
13771 * { panel: "10%", camera: "25%" }
13772 * ];
13773 *
13774 * possibleOptions.forEach(align => {
13775 * new Flicking("#el", { align });
13776 * });
13777 * ```
13778 */
13779 get: function () {
13780 return this._align;
13781 },
13782 // Options Setter
13783 // UI / LAYOUT
13784 set: function (val) {
13785 this._align = val;
13786 this._renderer.align = val;
13787 this._camera.align = val;
13788 },
13789 enumerable: false,
13790 configurable: true
13791 });
13792 Object.defineProperty(__proto, "defaultIndex", {
13793 /**
13794 * Index of the panel to move when Flicking's {@link Flicking#init init()} is called. A zero-based integer
13795 * @ko Flicking의 {@link Flicking#init init()}이 호출될 때 이동할 디폴트 패널의 인덱스로, 0부터 시작하는 정수입니다
13796 * @type {number}
13797 * @default 0
13798 */
13799 get: function () {
13800 return this._defaultIndex;
13801 },
13802 set: function (val) {
13803 this._defaultIndex = val;
13804 },
13805 enumerable: false,
13806 configurable: true
13807 });
13808 Object.defineProperty(__proto, "horizontal", {
13809 /**
13810 * Direction of panel movement (true: horizontal, false: vertical)
13811 * @ko 패널 이동 방향 (true: 가로방향, false: 세로방향)
13812 * @type {boolean}
13813 * @default true
13814 */
13815 get: function () {
13816 return this._horizontal;
13817 },
13818 set: function (val) {
13819 this._horizontal = val;
13820 },
13821 enumerable: false,
13822 configurable: true
13823 });
13824 Object.defineProperty(__proto, "circular", {
13825 /**
13826 * Enables circular(continuous loop) mode, which connects first/last panel for continuous scrolling.
13827 * @ko 순환 모드를 활성화합니다. 순환 모드에서는 양 끝의 패널이 서로 연결되어 끊김없는 스크롤이 가능합니다.
13828 * @type {boolean}
13829 * @default false
13830 */
13831 get: function () {
13832 return this._circular;
13833 },
13834 set: function (val) {
13835 this._circular = val;
13836 },
13837 enumerable: false,
13838 configurable: true
13839 });
13840 Object.defineProperty(__proto, "bound", {
13841 /**
13842 * Prevent the view(camera element) from going out of the first/last panel, so it won't show empty spaces before/after the first/last panel
13843 * Only can be enabled when `circular=false`
13844 * @ko 뷰(카메라 엘리먼트)가 첫번째와 마지막 패널 밖으로 넘어가지 못하게 하여, 첫번째/마지막 패널 전/후의 빈 공간을 보이지 않도록 하는 옵션입니다
13845 * `circular=false`인 경우에만 사용할 수 있습니다
13846 * @type {boolean}
13847 * @default false
13848 */
13849 get: function () {
13850 return this._bound;
13851 },
13852 set: function (val) {
13853 this._bound = val;
13854 },
13855 enumerable: false,
13856 configurable: true
13857 });
13858 Object.defineProperty(__proto, "adaptive", {
13859 /**
13860 * Update height of the viewport element after movement same to the height of the panel below. This can be only enabled when `horizontal=true`
13861 * @ko 이동한 후 뷰포트 엘리먼트의 크기를 현재 패널의 높이와 동일하게 설정합니다. `horizontal=true`인 경우에만 사용할 수 있습니다.
13862 * @type {boolean}
13863 * @default false
13864 */
13865 get: function () {
13866 return this._adaptive;
13867 },
13868 set: function (val) {
13869 this._adaptive = val;
13870 },
13871 enumerable: false,
13872 configurable: true
13873 });
13874 Object.defineProperty(__proto, "panelsPerView", {
13875 /**
13876 * A visible number of panels on viewport. Enabling this option will automatically resize panel size
13877 * @ko 한 화면에 보이는 패널의 개수. 이 옵션을 활성화할 경우 패널의 크기를 강제로 재조정합니다
13878 * @type {number}
13879 * @default -1
13880 */
13881 get: function () {
13882 return this._panelsPerView;
13883 },
13884 set: function (val) {
13885 this._panelsPerView = val;
13886 },
13887 enumerable: false,
13888 configurable: true
13889 });
13890 Object.defineProperty(__proto, "noPanelStyleOverride", {
13891 /**
13892 * Enabling this option will not change `width/height` style of the panels if {@link Flicking#panelsPerView} is enabled.
13893 * This behavior can be useful in terms of performance when you're manually managing all panel sizes
13894 * @ko 이 옵션을 활성화할 경우, {@link Flicking#panelsPerView} 옵션이 활성화되었을 때 패널의 `width/height` 스타일을 변경하지 않도록 설정합니다.
13895 * 모든 패널들의 크기를 직접 관리하고 있을 경우, 이 옵션을 활성화하면 성능면에서 유리할 수 있습니다
13896 * @type {boolean}
13897 * @default false
13898 */
13899 get: function () {
13900 return this._noPanelStyleOverride;
13901 },
13902 set: function (val) {
13903 this._noPanelStyleOverride = val;
13904 },
13905 enumerable: false,
13906 configurable: true
13907 });
13908 Object.defineProperty(__proto, "resizeOnContentsReady", {
13909 /**
13910 * Enabling this option will automatically call {@link Flicking#resize} when all image/video inside panels are loaded.
13911 * This can be useful when you have contents inside Flicking that changes its size when it's loaded
13912 * @ko 이 옵션을 활성화할 경우, Flicking 패널 내부의 이미지/비디오들이 로드되었을 때 자동으로 {@link Flicking#resize}를 호출합니다.
13913 * 이 동작은 Flicking 내부에 로드 전/후로 크기가 변하는 콘텐츠를 포함하고 있을 때 유용하게 사용하실 수 있습니다.
13914 * @type {boolean}
13915 * @default false
13916 */
13917 get: function () {
13918 return this._resizeOnContentsReady;
13919 },
13920 set: function (val) {
13921 this._resizeOnContentsReady = val;
13922 },
13923 enumerable: false,
13924 configurable: true
13925 });
13926 Object.defineProperty(__proto, "needPanelThreshold", {
13927 // EVENTS
13928
13929 /**
13930 * A Threshold from viewport edge before triggering `needPanel` event
13931 * @ko `needPanel`이벤트가 발생하기 위한 뷰포트 끝으로부터의 최대 거리
13932 * @type {number}
13933 * @default 0
13934 */
13935 get: function () {
13936 return this._needPanelThreshold;
13937 },
13938 // EVENTS
13939 set: function (val) {
13940 this._needPanelThreshold = val;
13941 },
13942 enumerable: false,
13943 configurable: true
13944 });
13945 Object.defineProperty(__proto, "preventEventsBeforeInit", {
13946 /**
13947 * When enabled, events are not triggered before `ready` when initializing
13948 * @ko 활성화할 경우 초기화시 `ready` 이벤트 이전의 이벤트가 발생하지 않습니다.
13949 * @type {boolean}
13950 * @default true
13951 */
13952 get: function () {
13953 return this._preventEventsBeforeInit;
13954 },
13955 set: function (val) {
13956 this._preventEventsBeforeInit = val;
13957 },
13958 enumerable: false,
13959 configurable: true
13960 });
13961 Object.defineProperty(__proto, "deceleration", {
13962 // ANIMATION
13963
13964 /**
13965 * Deceleration value for panel movement animation which is triggered by user input. A higher value means a shorter animation time
13966 * @ko 사용자의 동작으로 가속도가 적용된 패널 이동 애니메이션의 감속도. 값이 높을수록 애니메이션 실행 시간이 짧아집니다
13967 * @type {number}
13968 * @default 0.0075
13969 */
13970 get: function () {
13971 return this._deceleration;
13972 },
13973 // ANIMATION
13974 set: function (val) {
13975 this._deceleration = val;
13976 },
13977 enumerable: false,
13978 configurable: true
13979 });
13980 Object.defineProperty(__proto, "easing", {
13981 /**
13982 * An easing function applied to the panel movement animation. Default value is `easeOutCubic`
13983 * @ko 패널 이동 애니메이션에 적용할 easing 함수. 기본값은 `easeOutCubic`이다
13984 * @type {function}
13985 * @default x => 1 - Math.pow(1 - x, 3)
13986 * @see Easing Functions Cheat Sheet {@link http://easings.net/} <ko>이징 함수 Cheat Sheet {@link http://easings.net/}</ko>
13987 */
13988 get: function () {
13989 return this._easing;
13990 },
13991 set: function (val) {
13992 this._easing = val;
13993 },
13994 enumerable: false,
13995 configurable: true
13996 });
13997 Object.defineProperty(__proto, "duration", {
13998 /**
13999 * Default duration of the animation (ms)
14000 * @ko 디폴트 애니메이션 재생 시간 (ms)
14001 * @type {number}
14002 * @default 500
14003 */
14004 get: function () {
14005 return this._duration;
14006 },
14007 set: function (val) {
14008 this._duration = val;
14009 },
14010 enumerable: false,
14011 configurable: true
14012 });
14013 Object.defineProperty(__proto, "inputType", {
14014 // INPUT
14015
14016 /**
14017 * Types of input devices to enable
14018 * @ko 활성화할 입력 장치 종류
14019 * @type {string[]}
14020 * @default ["touch", "mouse"]
14021 * @see {@link https://naver.github.io/egjs-axes/release/latest/doc/global.html#PanInputOption Possible values (PanInputOption#inputType)}
14022 * <ko>{@link https://naver.github.io/egjs-axes/release/latest/doc/global.html#PanInputOption 가능한 값들 (PanInputOption#inputType)}</ko>
14023 */
14024 get: function () {
14025 return this._inputType;
14026 },
14027 // INPUT
14028 set: function (val) {
14029 this._inputType = val;
14030 },
14031 enumerable: false,
14032 configurable: true
14033 });
14034 Object.defineProperty(__proto, "moveType", {
14035 /**
14036 * Movement style by user input. This will change instance type of {@link Flicking#control}
14037 * You can use the values of the constant {@link MOVE_TYPE}
14038 * @ko 사용자 입력에 의한 이동 방식. 이 값에 따라 {@link Flicking#control}의 인스턴스 타입이 결정됩니다
14039 * 상수 {@link MOVE_TYPE}에 정의된 값들을 이용할 수 있습니다
14040 * @type {MOVE_TYPE | Pair<string, object>}
14041 * @default "snap"
14042 * @example
14043 * |moveType|control|options|
14044 * |:---:|:---:|:---:|
14045 * |"snap"|{@link SnapControl}||
14046 * |"freeScroll"|{@link FreeControl}|{@link FreeControlOptions}|
14047 *
14048 * ```ts
14049 * import Flicking, { MOVE_TYPE } from "@egjs/flicking";
14050 *
14051 * const flicking = new Flicking({
14052 * moveType: MOVE_TYPE.SNAP
14053 * });
14054 * ```
14055 *
14056 * ```ts
14057 * const flicking = new Flicking({
14058 * // If you want more specific settings for the moveType
14059 * // [moveType, options for that moveType]
14060 * // In this case, it's ["freeScroll", FreeControlOptions]
14061 * moveType: [MOVE_TYPE.FREE_SCROLL, { stopAtEdge: true }]
14062 * });
14063 * ```
14064 */
14065 get: function () {
14066 return this._moveType;
14067 },
14068 set: function (val) {
14069 this._moveType = val;
14070 },
14071 enumerable: false,
14072 configurable: true
14073 });
14074 Object.defineProperty(__proto, "threshold", {
14075 /**
14076 * Movement threshold to change panel (unit: px). It should be dragged above the threshold to change the current panel.
14077 * @ko 패널 변경을 위한 이동 임계값 (단위: px). 주어진 값 이상으로 스크롤해야만 패널 변경이 가능하다.
14078 * @type {number}
14079 * @default 40
14080 */
14081 get: function () {
14082 return this._threshold;
14083 },
14084 set: function (val) {
14085 this._threshold = val;
14086 },
14087 enumerable: false,
14088 configurable: true
14089 });
14090 Object.defineProperty(__proto, "interruptable", {
14091 /**
14092 * Set animation to be interruptable by click/touch.
14093 * @ko 사용자의 클릭/터치로 인해 애니메이션을 도중에 멈출 수 있도록 설정합니다.
14094 * @type {boolean}
14095 * @default true
14096 */
14097 get: function () {
14098 return this._interruptable;
14099 },
14100 set: function (val) {
14101 this._interruptable = val;
14102 },
14103 enumerable: false,
14104 configurable: true
14105 });
14106 Object.defineProperty(__proto, "bounce", {
14107 /**
14108 * The size value of the bounce area. Only can be enabled when `circular=false`.
14109 * You can set different bounce value for prev/next direction by using array.
14110 * `number` for px value, and `string` for px, and % value relative to viewport size.
14111 * You have to call {@link Control#updateInput} after changing this to take effect.
14112 * @ko Flicking이 최대 영역을 넘어서 갈 수 있는 최대 크기. `circular=false`인 경우에만 사용할 수 있습니다.
14113 * 배열을 통해 prev/next 방향에 대해 서로 다른 바운스 값을 지정할 수 있습니다.
14114 * `number`를 통해 px값을, `stirng`을 통해 px 혹은 뷰포트 크기 대비 %값을 사용할 수 있습니다.
14115 * 이 값을 변경시 {@link Control#updateInput}를 호출해야 합니다.
14116 * @type {string | number | Array<string | number>}
14117 * @default "20%"
14118 * @example
14119 * ```ts
14120 * const possibleOptions = [
14121 * // % values, relative to viewport element(".flicking-viewport")'s size
14122 * "0%", "25%", "42%",
14123 * // px values, arithmetic calculation with (+/-) is also allowed.
14124 * "0px", "100px", "50% - 25px",
14125 * // numbers, same to number + px ("0px", "100px")
14126 * 0, 100, 1000
14127 * ];
14128 * ```
14129 *
14130 * @example
14131 * ```ts
14132 * const flicking = new Flicking("#el", { bounce: "20%" });
14133 *
14134 * flicking.bounce = "100%";
14135 * flicking.control.updateInput(); // Call this to update!
14136 * ```
14137 */
14138 get: function () {
14139 return this._bounce;
14140 },
14141 set: function (val) {
14142 this._bounce = val;
14143 },
14144 enumerable: false,
14145 configurable: true
14146 });
14147 Object.defineProperty(__proto, "iOSEdgeSwipeThreshold", {
14148 /**
14149 * Size of the area from the right edge in iOS safari (in px) which enables swipe-back or swipe-forward
14150 * @ko iOS Safari에서 swipe를 통한 뒤로가기/앞으로가기를 활성화하는 오른쪽 끝으로부터의 영역의 크기 (px)
14151 * @type {number}
14152 * @default 30
14153 */
14154 get: function () {
14155 return this._iOSEdgeSwipeThreshold;
14156 },
14157 set: function (val) {
14158 this._iOSEdgeSwipeThreshold = val;
14159 },
14160 enumerable: false,
14161 configurable: true
14162 });
14163 Object.defineProperty(__proto, "preventClickOnDrag", {
14164 /**
14165 * Automatically prevent `click` event if the user has dragged at least a single pixel on the viewport element
14166 * @ko 사용자가 뷰포트 영역을 1픽셀이라도 드래그했을 경우 자동으로 {@link https://developer.mozilla.org/ko/docs/Web/API/Element/click_event click} 이벤트를 취소합니다
14167 * @type {boolean}
14168 * @default true
14169 */
14170 get: function () {
14171 return this._preventClickOnDrag;
14172 },
14173 set: function (val) {
14174 var prevVal = this._preventClickOnDrag;
14175 if (val === prevVal) return;
14176 var controller = this._control.controller;
14177
14178 if (val) {
14179 controller.addPreventClickHandler();
14180 } else {
14181 controller.removePreventClickHandler();
14182 }
14183
14184 this._preventClickOnDrag = val;
14185 },
14186 enumerable: false,
14187 configurable: true
14188 });
14189 Object.defineProperty(__proto, "disableOnInit", {
14190 /**
14191 * Automatically call {@link Flicking#disableInput disableInput()} on initialization
14192 * @ko Flicking init시에 {@link Flicking#disableInput disableInput()}을 바로 호출합니다
14193 * @type {boolean}
14194 * @default false
14195 */
14196 get: function () {
14197 return this._disableOnInit;
14198 },
14199 set: function (val) {
14200 this._disableOnInit = val;
14201 },
14202 enumerable: false,
14203 configurable: true
14204 });
14205 Object.defineProperty(__proto, "renderOnlyVisible", {
14206 // PERFORMANCE
14207
14208 /**
14209 * Whether to render visible panels only. This can dramatically increase performance when there're many panels.
14210 * @ko 보이는 패널만 렌더링할지 여부를 설정합니다. 패널이 많을 경우에 퍼포먼스를 크게 향상시킬 수 있습니다.
14211 * @type {boolean}
14212 * @default false
14213 */
14214 get: function () {
14215 return this._renderOnlyVisible;
14216 },
14217 // PERFORMANCE
14218 set: function (val) {
14219 this._renderOnlyVisible = val;
14220 },
14221 enumerable: false,
14222 configurable: true
14223 });
14224 Object.defineProperty(__proto, "autoInit", {
14225 // OTHERS
14226
14227 /**
14228 * Call {@link Flicking#init init()} automatically when creating Flicking's instance
14229 * @ko Flicking 인스턴스를 생성할 때 자동으로 {@link Flicking#init init()}를 호출합니다
14230 * @type {boolean}
14231 * @default true
14232 * @readonly
14233 */
14234 get: function () {
14235 return this._autoInit;
14236 },
14237 enumerable: false,
14238 configurable: true
14239 });
14240 Object.defineProperty(__proto, "autoResize", {
14241 /**
14242 * Attach Flicking's {@link Flicking#resize resize} method to window's resize event.
14243 * Flicking will automatically call {@link Flicking#resize resize} window size and orientation change.
14244 * @ko Flicking의 {@link Flicking#resize resize} 메소드를 window의 resize 이벤트 핸들러로 등록합니다.
14245 * 설정시 window 창 크기 및 orientation 변경에 의해 자동으로 {@link Flicking#resize resize}를 호출합니다.
14246 * @type {boolean}
14247 * @default true
14248 */
14249 get: function () {
14250 return this._autoResize;
14251 },
14252 // OTHERS
14253 set: function (val) {
14254 this._autoResize = val;
14255 },
14256 enumerable: false,
14257 configurable: true
14258 });
14259 Object.defineProperty(__proto, "renderExternal", {
14260 /**
14261 * This is an option for the frameworks(React, Vue, Angular, ...). Don't set it as it's automatically managed by Flicking.
14262 * @ko 프레임워크(React, Vue, Angular, ...)에서만 사용하는 옵션으로, 자동으로 설정되므로 따로 사용하실 필요 없습니다!
14263 * @type {boolean}
14264 * @default false
14265 * @internal
14266 * @readonly
14267 */
14268 get: function () {
14269 return this._renderExternal;
14270 },
14271 enumerable: false,
14272 configurable: true
14273 });
14274 /**
14275 * Initialize Flicking and move to the default index
14276 * This is automatically called on Flicking's constructor when `autoInit` is true(default)
14277 * @ko Flicking을 초기화하고, 디폴트 인덱스로 이동합니다
14278 * 이 메소드는 `autoInit` 옵션이 true(default)일 경우 Flicking이 생성될 때 자동으로 호출됩니다
14279 * @fires Flicking#ready
14280 * @return {this}
14281 */
14282
14283 __proto.init = function () {
14284 return __awaiter(this, void 0, void 0, function () {
14285 var camera, renderer, control, originalTrigger, preventEventsBeforeInit;
14286
14287 var _this = this;
14288
14289 return __generator(this, function (_a) {
14290 switch (_a.label) {
14291 case 0:
14292 if (this._initialized) return [2
14293 /*return*/
14294 ];
14295 camera = this._camera;
14296 renderer = this._renderer;
14297 control = this._control;
14298 originalTrigger = this.trigger;
14299 preventEventsBeforeInit = this._preventEventsBeforeInit;
14300 camera.init(this);
14301 renderer.init(this);
14302 control.init(this);
14303
14304 if (preventEventsBeforeInit) {
14305 this.trigger = function () {
14306 return _this;
14307 };
14308 }
14309
14310 return [4
14311 /*yield*/
14312 , this.resize()];
14313
14314 case 1:
14315 _a.sent(); // Look at initial panel
14316
14317
14318 return [4
14319 /*yield*/
14320 , this._moveToInitialPanel()];
14321
14322 case 2:
14323 // Look at initial panel
14324 _a.sent();
14325
14326 if (this._autoResize) {
14327 window.addEventListener("resize", this.resize);
14328 }
14329
14330 if (this._preventClickOnDrag) {
14331 control.controller.addPreventClickHandler();
14332 }
14333
14334 if (this._disableOnInit) {
14335 this.disableInput();
14336 }
14337
14338 renderer.checkPanelContentsReady(renderer.panels);
14339
14340 this._plugins.forEach(function (plugin) {
14341 return plugin.init(_this);
14342 }); // Done initializing & emit ready event
14343
14344
14345 this._initialized = true;
14346
14347 if (preventEventsBeforeInit) {
14348 this.trigger = originalTrigger;
14349 }
14350
14351 this.trigger(new ComponentEvent$1(EVENTS.READY));
14352 return [2
14353 /*return*/
14354 ];
14355 }
14356 });
14357 });
14358 };
14359 /**
14360 * Destroy Flicking and remove all event handlers
14361 * @ko Flicking과 하위 컴포넌트들을 초기 상태로 되돌리고, 부착된 모든 이벤트 핸들러를 제거합니다
14362 * @return {void}
14363 */
14364
14365
14366 __proto.destroy = function () {
14367 this.off();
14368 window.removeEventListener("resize", this.resize);
14369
14370 this._control.destroy();
14371
14372 this._camera.destroy();
14373
14374 this._renderer.destroy();
14375
14376 this._plugins.forEach(function (plugin) {
14377 return plugin.destroy();
14378 });
14379
14380 this._initialized = false;
14381 };
14382 /**
14383 * Move to the previous panel (current index - 1)
14384 * @ko 이전 패널로 이동합니다 (현재 인덱스 - 1)
14385 * @param {number} [duration={@link Flicking#duration options.duration}] Duration of the panel movement animation (unit: ms)<ko>패널 이동 애니메이션 진행 시간 (단위: ms)</ko>
14386 * @async
14387 * @fires Flicking#moveStart
14388 * @fires Flicking#move
14389 * @fires Flicking#moveEnd
14390 * @fires Flicking#willChange
14391 * @fires Flicking#changed
14392 * @fires Flicking#willRestore
14393 * @fires Flicking#restored
14394 * @fires Flicking#needPanel
14395 * @fires Flicking#visibleChange
14396 * @fires Flicking#reachEdge
14397 * @throws {FlickingError}
14398 * |code|condition|
14399 * |---|---|
14400 * |{@link ERROR_CODE INDEX_OUT_OF_RANGE}|When the previous panel does not exist|
14401 * |{@link ERROR_CODE ANIMATION_ALREADY_PLAYING}|When the animation is already playing|
14402 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|
14403 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the any of the event's `stop()` is called|
14404 * <ko>
14405 *
14406 * |code|condition|
14407 * |---|---|
14408 * |{@link ERROR_CODE INDEX_OUT_OF_RANGE}|이전 패널이 존재하지 않을 경우|
14409 * |{@link ERROR_CODE ANIMATION_ALREADY_PLAYING}|애니메이션이 이미 진행중인 경우|
14410 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|
14411 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|
14412 * </ko>
14413 * @return {Promise<void>} A Promise which will be resolved after reaching the previous panel<ko>이전 패널 도달시에 resolve되는 Promise</ko>
14414 */
14415
14416
14417 __proto.prev = function (duration) {
14418 var _a, _b, _c;
14419
14420 if (duration === void 0) {
14421 duration = this._duration;
14422 }
14423
14424 return this.moveTo((_c = (_b = (_a = this._control.activePanel) === null || _a === void 0 ? void 0 : _a.prev()) === null || _b === void 0 ? void 0 : _b.index) !== null && _c !== void 0 ? _c : -1, duration, DIRECTION.PREV);
14425 };
14426 /**
14427 * Move to the next panel (current index + 1)
14428 * @ko 다음 패널로 이동합니다 (현재 인덱스 + 1)
14429 * @param {number} [duration={@link Flicking#duration options.duration}] Duration of the panel movement animation (unit: ms).<ko>패널 이동 애니메이션 진행 시간 (단위: ms)</ko>
14430 * @async
14431 * @fires Flicking#moveStart
14432 * @fires Flicking#move
14433 * @fires Flicking#moveEnd
14434 * @fires Flicking#willChange
14435 * @fires Flicking#changed
14436 * @fires Flicking#willRestore
14437 * @fires Flicking#restored
14438 * @fires Flicking#needPanel
14439 * @fires Flicking#visibleChange
14440 * @fires Flicking#reachEdge
14441 * @throws {FlickingError}
14442 * |code|condition|
14443 * |---|---|
14444 * |{@link ERROR_CODE INDEX_OUT_OF_RANGE}|When the next panel does not exist|
14445 * |{@link ERROR_CODE ANIMATION_ALREADY_PLAYING}|When the animation is already playing|
14446 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|
14447 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the any of the event's `stop()` is called|
14448 * <ko>
14449 *
14450 * |code|condition|
14451 * |---|---|
14452 * |{@link ERROR_CODE INDEX_OUT_OF_RANGE}|다음 패널이 존재하지 않을 경우|
14453 * |{@link ERROR_CODE ANIMATION_ALREADY_PLAYING}|애니메이션이 이미 진행중인 경우|
14454 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|
14455 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|
14456 *
14457 * </ko>
14458 * @return {Promise<void>} A Promise which will be resolved after reaching the next panel<ko>다음 패널 도달시에 resolve되는 Promise</ko>
14459 */
14460
14461
14462 __proto.next = function (duration) {
14463 var _a, _b, _c;
14464
14465 if (duration === void 0) {
14466 duration = this._duration;
14467 }
14468
14469 return this.moveTo((_c = (_b = (_a = this._control.activePanel) === null || _a === void 0 ? void 0 : _a.next()) === null || _b === void 0 ? void 0 : _b.index) !== null && _c !== void 0 ? _c : this._renderer.panelCount, duration, DIRECTION.NEXT);
14470 };
14471 /**
14472 * Move to the panel with given index
14473 * @ko 주어진 인덱스에 해당하는 패널로 이동합니다
14474 * @param {number} index The index of the panel to move<ko>이동할 패널의 인덱스</ko>
14475 * @param {number} [duration={@link Flicking#duration options.duration}] Duration of the animation (unit: ms)<ko>애니메이션 진행 시간 (단위: ms)</ko>
14476 * @param {DIRECTION} [direction=DIRECTION.NONE] Direction to move, only available in the {@link Flicking#circular circular} mode<ko>이동할 방향. {@link Flicking#circular circular} 옵션 활성화시에만 사용 가능합니다</ko>
14477 * @async
14478 * @fires Flicking#moveStart
14479 * @fires Flicking#move
14480 * @fires Flicking#moveEnd
14481 * @fires Flicking#willChange
14482 * @fires Flicking#changed
14483 * @fires Flicking#willRestore
14484 * @fires Flicking#restored
14485 * @fires Flicking#needPanel
14486 * @fires Flicking#visibleChange
14487 * @fires Flicking#reachEdge
14488 * @throws {FlickingError}
14489 * |code|condition|
14490 * |---|---|
14491 * |{@link ERROR_CODE INDEX_OUT_OF_RANGE}|When the root is not either string or HTMLElement|
14492 * |{@link ERROR_CODE ANIMATION_ALREADY_PLAYING}|When the animation is already playing|
14493 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|When the animation is interrupted by user input|
14494 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|When the any of the event's `stop()` is called|
14495 * <ko>
14496 *
14497 * |code|condition|
14498 * |---|---|
14499 * |{@link ERROR_CODE INDEX_OUT_OF_RANGE}|해당 인덱스를 가진 패널이 존재하지 않을 경우|
14500 * |{@link ERROR_CODE ANIMATION_ALREADY_PLAYING}|애니메이션이 이미 진행중인 경우|
14501 * |{@link ERROR_CODE ANIMATION_INTERRUPTED}|사용자 입력에 의해 애니메이션이 중단된 경우|
14502 * |{@link ERROR_CODE STOP_CALLED_BY_USER}|발생된 이벤트들 중 하나라도 `stop()`이 호출된 경우|
14503 *
14504 * </ko>
14505 * @return {Promise<void>} A Promise which will be resolved after reaching the target panel<ko>해당 패널 도달시에 resolve되는 Promise</ko>
14506 */
14507
14508
14509 __proto.moveTo = function (index, duration, direction) {
14510 if (duration === void 0) {
14511 duration = this._duration;
14512 }
14513
14514 if (direction === void 0) {
14515 direction = DIRECTION.NONE;
14516 }
14517
14518 var renderer = this._renderer;
14519 var panelCount = renderer.panelCount;
14520 var panel = renderer.getPanel(index);
14521
14522 if (!panel) {
14523 return Promise.reject(new FlickingError(MESSAGE.INDEX_OUT_OF_RANGE(index, 0, panelCount - 1), CODE.INDEX_OUT_OF_RANGE));
14524 }
14525
14526 if (this._control.animating) {
14527 return Promise.reject(new FlickingError(MESSAGE.ANIMATION_ALREADY_PLAYING, CODE.ANIMATION_ALREADY_PLAYING));
14528 }
14529
14530 return this._control.moveToPanel(panel, {
14531 duration: duration,
14532 direction: direction
14533 });
14534 };
14535 /**
14536 * Return the {@link Panel} at the given index. `null` if it doesn't exists.
14537 * @ko 주어진 인덱스에 해당하는 {@link Panel}을 반환합니다. 주어진 인덱스에 해당하는 패널이 존재하지 않을 경우 `null`을 반환합니다.
14538 * @return {Panel | null} Panel at the given index<ko>주어진 인덱스에 해당하는 패널</ko>
14539 * @see Panel
14540 * @example
14541 * ```ts
14542 * const panel = flicking.getPanel(0);
14543 * // Which is a shorthand to...
14544 * const samePanel = flicking.panels[0];
14545 * ```
14546 */
14547
14548
14549 __proto.getPanel = function (index) {
14550 return this._renderer.getPanel(index);
14551 };
14552 /**
14553 * Enable input from the user (mouse/touch)
14554 * @ko 사용자의 입력(마우스/터치)를 활성화합니다
14555 * @return {this}
14556 */
14557
14558
14559 __proto.enableInput = function () {
14560 this._control.enable();
14561
14562 return this;
14563 };
14564 /**
14565 * Disable input from the user (mouse/touch)
14566 * @ko 사용자의 입력(마우스/터치)를 막습니다
14567 * @return {this}
14568 */
14569
14570
14571 __proto.disableInput = function () {
14572 this._control.disable();
14573
14574 return this;
14575 };
14576 /**
14577 * Get current flicking status. You can restore current state by giving returned value to {@link Flicking#setStatus setStatus()}
14578 * @ko 현재 상태를 반환합니다. 반환받은 값을 {@link Flicking#setStatus setStatus()} 메소드의 인자로 지정하면 현재 상태를 복원할 수 있습니다
14579 * @param {object} options Status retrieving options<ko>Status 반환 옵션</ko>
14580 * @param {boolean} [options.index=true] Include current panel index to the returning status. Camera will automatically move to the given index when the {@link Flicking#setStatus setStatus} is called<ko>현재 패널 인덱스를 반환값에 포함시킵니다. {@link Flicking#setStatus setStatus} 호출시 자동으로 해당 인덱스로 카메라를 움직입니다</ko>
14581 * @param {boolean} [options.position=true] Include camera position to the returning status. This works only when the {@link Flicking#moveType moveType} is `freeScroll`<ko>카메라의 현재 위치를 반환값에 포함시킵니다. 이 옵션은 {@link Flicking#moveType moveType}이 `freeScroll`일 경우에만 동작합니다</ko>
14582 * @param {boolean} [options.includePanelHTML=false] Include panel's `outerHTML` to the returning status<ko>패널의 `outerHTML`을 반환값에 포함시킵니다</ko>
14583 * @param {boolean} [options.visiblePanelsOnly=false] Include only {@link Flicking#visiblePanel visiblePanel}'s HTML. This option is available only when the `includePanelHTML` is true
14584 * <ko>현재 보이는 패널({@link Flicking#visiblePanel visiblePanel})의 HTML만 반환합니다. `includePanelHTML`이 `true`일 경우에만 동작합니다.</ko>
14585 * @return {Partial<Status>} An object with current status value information<ko>현재 상태값 정보를 가진 객체.</ko>
14586 */
14587
14588
14589 __proto.getStatus = function (_a) {
14590 var _b, _c;
14591
14592 var _d = _a === void 0 ? {} : _a,
14593 _e = _d.index,
14594 index = _e === void 0 ? true : _e,
14595 _f = _d.position,
14596 position = _f === void 0 ? true : _f,
14597 _g = _d.includePanelHTML,
14598 includePanelHTML = _g === void 0 ? false : _g,
14599 _h = _d.visiblePanelsOnly,
14600 visiblePanelsOnly = _h === void 0 ? false : _h;
14601
14602 var camera = this._camera;
14603 var panels = visiblePanelsOnly ? this.visiblePanels : this.panels;
14604 var status = {
14605 panels: panels.map(function (panel) {
14606 var panelInfo = {
14607 index: panel.index
14608 };
14609
14610 if (includePanelHTML) {
14611 panelInfo.html = panel.element.outerHTML;
14612 }
14613
14614 return panelInfo;
14615 })
14616 };
14617
14618 if (index) {
14619 status.index = this.index;
14620 }
14621
14622 if (position) {
14623 var nearestAnchor = camera.findNearestAnchor(camera.position);
14624
14625 if (nearestAnchor) {
14626 status.position = {
14627 panel: nearestAnchor.panel.index,
14628 progressInPanel: camera.getProgressInPanel(nearestAnchor.panel)
14629 };
14630 }
14631 }
14632
14633 if (visiblePanelsOnly) {
14634 var visiblePanels = this.visiblePanels;
14635 status.visibleOffset = (_c = (_b = visiblePanels[0]) === null || _b === void 0 ? void 0 : _b.index) !== null && _c !== void 0 ? _c : 0;
14636 }
14637
14638 return status;
14639 };
14640 /**
14641 * Restore to the state of the given {@link Status}
14642 * @ko 주어진 {@link Status}의 상태로 복원합니다
14643 * @param {Partial<Status>} status Status value to be restored. You should use the return value of the {@link Flicking#getStatus getStatus()} method<ko>복원할 상태 값. {@link Flicking#getStatus getStatus()} 메서드의 반환값을 지정하면 됩니다</ko>
14644 * @return {void}
14645 */
14646
14647
14648 __proto.setStatus = function (status) {
14649 var _a;
14650
14651 if (!this._initialized) {
14652 throw new FlickingError(MESSAGE.NOT_INITIALIZED, CODE.NOT_INITIALIZED);
14653 }
14654
14655 var index = status.index,
14656 position = status.position,
14657 visibleOffset = status.visibleOffset,
14658 panels = status.panels;
14659 var renderer = this._renderer;
14660 var control = this._control; // Can't add/remove panels on external rendering
14661
14662 if (((_a = panels[0]) === null || _a === void 0 ? void 0 : _a.html) && !this._renderExternal) {
14663 renderer.batchRemove({
14664 index: 0,
14665 deleteCount: this.panels.length
14666 });
14667 renderer.batchInsert({
14668 index: 0,
14669 elements: parseElement(panels.map(function (panel) {
14670 return panel.html;
14671 }))
14672 });
14673 }
14674
14675 if (index) {
14676 var panelIndex = visibleOffset ? index - visibleOffset : index;
14677 void this.moveTo(panelIndex, 0).catch(function () {
14678 return void 0;
14679 });
14680 }
14681
14682 if (position && this._moveType === MOVE_TYPE.FREE_SCROLL) {
14683 var panel = position.panel,
14684 progressInPanel = position.progressInPanel;
14685 var panelIndex = visibleOffset ? panel - visibleOffset : panel;
14686 var panelRange = renderer.panels[panelIndex].range;
14687 var newCameraPos = panelRange.min + (panelRange.max - panelRange.min) * progressInPanel;
14688 void control.moveToPosition(newCameraPos, 0).catch(function () {
14689 return void 0;
14690 });
14691 }
14692 };
14693 /**
14694 * Add plugins that can have different effects on Flicking
14695 * @ko 플리킹에 다양한 효과를 부여할 수 있는 플러그인을 추가합니다
14696 * @param {...Plugin} plugins The plugin(s) to add<ko>추가할 플러그인(들)</ko>
14697 * @return {this}
14698 * @see https://github.com/naver/egjs-flicking-plugins
14699 */
14700
14701
14702 __proto.addPlugins = function () {
14703 var _a;
14704
14705 var _this = this;
14706
14707 var plugins = [];
14708
14709 for (var _i = 0; _i < arguments.length; _i++) {
14710 plugins[_i] = arguments[_i];
14711 }
14712
14713 if (this._initialized) {
14714 plugins.forEach(function (item) {
14715 return item.init(_this);
14716 });
14717 }
14718
14719 (_a = this._plugins).push.apply(_a, __spreadArray([], __read$1(plugins)));
14720
14721 return this;
14722 };
14723 /**
14724 * Remove plugins from Flicking.
14725 * @ko 플리킹으로부터 플러그인들을 제거합니다.
14726 * @param {...Plugin} plugin The plugin(s) to remove.<ko>제거 플러그인(들).</ko>
14727 * @return {this}
14728 * @see https://github.com/naver/egjs-flicking-plugins
14729 */
14730
14731
14732 __proto.removePlugins = function () {
14733 var _this = this;
14734
14735 var plugins = [];
14736
14737 for (var _i = 0; _i < arguments.length; _i++) {
14738 plugins[_i] = arguments[_i];
14739 }
14740
14741 plugins.forEach(function (item) {
14742 var foundIndex = findIndex(_this._plugins, function (val) {
14743 return val === item;
14744 });
14745
14746 if (foundIndex >= 0) {
14747 item.destroy();
14748
14749 _this._plugins.splice(foundIndex, 1);
14750 }
14751 });
14752 return this;
14753 };
14754 /**
14755 * Update viewport/panel sizes
14756 * @ko 패널 및 뷰포트의 크기를 갱신합니다
14757 * @method
14758 * @fires Flicking#beforeResize
14759 * @fires Flicking#afterResize
14760 * @return {this}
14761 */
14762
14763
14764 __proto.resize = function () {
14765 return __awaiter(this, void 0, void 0, function () {
14766 var viewport, renderer, camera, control, activePanel, prevWidth, prevHeight, prevProgressInPanel, newWidth, newHeight, sizeChanged;
14767 return __generator(this, function (_a) {
14768 switch (_a.label) {
14769 case 0:
14770 viewport = this._viewport;
14771 renderer = this._renderer;
14772 camera = this._camera;
14773 control = this._control;
14774 activePanel = control.activePanel;
14775 prevWidth = viewport.width;
14776 prevHeight = viewport.height;
14777 prevProgressInPanel = activePanel ? camera.getProgressInPanel(activePanel) : 0;
14778 this.trigger(new ComponentEvent$1(EVENTS.BEFORE_RESIZE, {
14779 width: prevWidth,
14780 height: prevHeight,
14781 element: viewport.element
14782 }));
14783 viewport.resize();
14784 return [4
14785 /*yield*/
14786 , renderer.forceRenderAllPanels()];
14787
14788 case 1:
14789 _a.sent(); // Render all panel elements, to update sizes
14790
14791
14792 renderer.updatePanelSize();
14793 camera.updateAlignPos();
14794 camera.updateRange();
14795 camera.updateAnchors();
14796 return [4
14797 /*yield*/
14798 , renderer.render()];
14799
14800 case 2:
14801 _a.sent();
14802
14803 if (control.animating) ; else {
14804 control.updatePosition(prevProgressInPanel);
14805 control.updateInput();
14806 }
14807
14808 newWidth = viewport.width;
14809 newHeight = viewport.height;
14810 sizeChanged = newWidth !== prevWidth || newHeight !== prevHeight;
14811 this.trigger(new ComponentEvent$1(EVENTS.AFTER_RESIZE, {
14812 width: viewport.width,
14813 height: viewport.height,
14814 prev: {
14815 width: prevWidth,
14816 height: prevHeight
14817 },
14818 sizeChanged: sizeChanged,
14819 element: viewport.element
14820 }));
14821 return [2
14822 /*return*/
14823 ];
14824 }
14825 });
14826 });
14827 };
14828 /**
14829 * Add new panels after the last panel
14830 * @ko 패널 목록의 제일 끝에 새로운 패널들을 추가합니다
14831 * @param {ElementLike | ElementLike[]} element A new HTMLElement, a outerHTML of element, or an array of both
14832 * <ko>새로운 HTMLElement, 혹은 엘리먼트의 outerHTML, 혹은 그것들의 배열</ko>
14833 * @return {Panel[]} An array of appended panels<ko>추가된 패널들의 배열</ko>
14834 * @see Panel
14835 * @see ElementLike
14836 * @throws {FlickingError} {@link ERROR_CODE ERROR_CODE.NOT_ALLOWED_IN_FRAMEWORK} if called on frameworks (React, Angular, Vue...)
14837 * @example
14838 * ```ts
14839 * const flicking = new Flicking("#flick");
14840 * // These are possible parameters
14841 * flicking.append(document.createElement("div"));
14842 * flicking.append("\<div\>Panel\</div\>");
14843 * flicking.append(["\<div\>Panel\</div\>", document.createElement("div")]);
14844 * // Even this is possible
14845 * flicking.append("\<div\>Panel 1\</div\>\<div\>Panel 2\</div\>");
14846 * ```
14847 */
14848
14849
14850 __proto.append = function (element) {
14851 return this.insert(this._renderer.panelCount, element);
14852 };
14853 /**
14854 * Add new panels before the first panel
14855 * This will increase index of panels after by the number of panels added
14856 * @ko 패널 목록의 제일 앞(index 0)에 새로운 패널들을 추가합니다
14857 * 추가한 패널의 개수만큼 기존 패널들의 인덱스가 증가합니다.
14858 * @param {ElementLike | ElementLike[]} element A new HTMLElement, a outerHTML of element, or an array of both
14859 * <ko>새로운 HTMLElement, 혹은 엘리먼트의 outerHTML, 혹은 그것들의 배열</ko>
14860 * @return {Panel[]} An array of prepended panels<ko>추가된 패널들의 배열</ko>
14861 * @see Panel
14862 * @see ElementLike
14863 * @throws {FlickingError} {@link ERROR_CODE ERROR_CODE.NOT_ALLOWED_IN_FRAMEWORK} if called on frameworks (React, Angular, Vue...)
14864 * @example
14865 * ```ts
14866 * const flicking = new eg.Flicking("#flick");
14867 * flicking.prepend(document.createElement("div"));
14868 * flicking.prepend("\<div\>Panel\</div\>");
14869 * flicking.prepend(["\<div\>Panel\</div\>", document.createElement("div")]);
14870 * // Even this is possible
14871 * flicking.prepend("\<div\>Panel 1\</div\>\<div\>Panel 2\</div\>");
14872 * ```
14873 */
14874
14875
14876 __proto.prepend = function (element) {
14877 return this.insert(0, element);
14878 };
14879 /**
14880 * Insert new panels at given index
14881 * This will increase index of panels after by the number of panels added
14882 * @ko 주어진 인덱스에 새로운 패널들을 추가합니다
14883 * 해당 인덱스보다 같거나 큰 인덱스를 가진 기존 패널들은 추가한 패널의 개수만큼 인덱스가 증가합니다.
14884 * @param {number} index Index to insert new panels at<ko>새로 패널들을 추가할 인덱스</ko>
14885 * @param {ElementLike | ElementLike[]} element A new HTMLElement, a outerHTML of element, or an array of both
14886 * <ko>새로운 HTMLElement, 혹은 엘리먼트의 outerHTML, 혹은 그것들의 배열</ko>
14887 * @return {Panel[]} An array of prepended panels<ko>추가된 패널들의 배열</ko>
14888 * @throws {FlickingError} {@link ERROR_CODE ERROR_CODE.NOT_ALLOWED_IN_FRAMEWORK} if called on frameworks (React, Angular, Vue...)
14889 * @example
14890 * ```ts
14891 * const flicking = new eg.Flicking("#flick");
14892 * flicking.insert(0, document.createElement("div"));
14893 * flicking.insert(2, "\<div\>Panel\</div\>");
14894 * flicking.insert(1, ["\<div\>Panel\</div\>", document.createElement("div")]);
14895 * // Even this is possible
14896 * flicking.insert(3, "\<div\>Panel 1\</div\>\<div\>Panel 2\</div\>");
14897 * ```
14898 */
14899
14900
14901 __proto.insert = function (index, element) {
14902 if (this._renderExternal) {
14903 throw new FlickingError(MESSAGE.NOT_ALLOWED_IN_FRAMEWORK, CODE.NOT_ALLOWED_IN_FRAMEWORK);
14904 }
14905
14906 return this._renderer.batchInsert({
14907 index: index,
14908 elements: parseElement(element)
14909 });
14910 };
14911 /**
14912 * Remove the panel at the given index
14913 * This will decrease index of panels after by the number of panels removed
14914 * @ko 주어진 인덱스의 패널을 제거합니다
14915 * 해당 인덱스보다 큰 인덱스를 가진 기존 패널들은 제거한 패널의 개수만큼 인덱스가 감소합니다
14916 * @param {number} index Index of panel to remove<ko>제거할 패널의 인덱스</ko>
14917 * @param {number} [deleteCount=1] Number of panels to remove from index<ko>`index` 이후로 제거할 패널의 개수</ko>
14918 * @return {Panel[]} An array of removed panels<ko>제거된 패널들의 배열</ko>
14919 */
14920
14921
14922 __proto.remove = function (index, deleteCount) {
14923 if (deleteCount === void 0) {
14924 deleteCount = 1;
14925 }
14926
14927 if (this._renderExternal) {
14928 throw new FlickingError(MESSAGE.NOT_ALLOWED_IN_FRAMEWORK, CODE.NOT_ALLOWED_IN_FRAMEWORK);
14929 }
14930
14931 return this._renderer.batchRemove({
14932 index: index,
14933 deleteCount: deleteCount
14934 });
14935 };
14936
14937 __proto._createControl = function () {
14938 var _a;
14939
14940 var moveType = this._moveType;
14941 var moveTypes = Object.keys(MOVE_TYPE).map(function (key) {
14942 return MOVE_TYPE[key];
14943 });
14944 var moveTypeStr = Array.isArray(moveType) ? moveType[0] : moveType;
14945 var moveTypeOptions = Array.isArray(moveType) ? (_a = moveType[1]) !== null && _a !== void 0 ? _a : {} : {};
14946
14947 if (!includes(moveTypes, moveTypeStr)) {
14948 throw new FlickingError(MESSAGE.WRONG_OPTION("moveType", JSON.stringify(moveType)), CODE.WRONG_OPTION);
14949 }
14950
14951 switch (moveTypeStr) {
14952 case MOVE_TYPE.SNAP:
14953 return new SnapControl(moveTypeOptions);
14954
14955 case MOVE_TYPE.FREE_SCROLL:
14956 return new FreeControl(moveTypeOptions);
14957
14958 case MOVE_TYPE.STRICT:
14959 return new StrictControl(moveTypeOptions);
14960 }
14961 };
14962
14963 __proto._createCamera = function () {
14964 var cameraOption = {
14965 align: this._align
14966 };
14967
14968 if (this._circular) {
14969 if (this._bound) {
14970 // eslint-disable-next-line no-console
14971 console.warn("\"circular\" and \"bound\" option cannot be used together, ignoring bound.");
14972 }
14973
14974 return new CircularCamera(cameraOption);
14975 } else if (this._bound) {
14976 return new BoundCamera(cameraOption);
14977 } else {
14978 return new LinearCamera(cameraOption);
14979 }
14980 };
14981
14982 __proto._createRenderer = function () {
14983 var rendererOptions = {
14984 align: this._align
14985 };
14986 var renderExternal = this._renderExternal;
14987 return renderExternal ? new renderExternal.renderer(__assign$2(__assign$2({}, rendererOptions), renderExternal.rendererOptions)) : new VanillaRenderer(rendererOptions);
14988 };
14989
14990 __proto._moveToInitialPanel = function () {
14991 return __awaiter(this, void 0, void 0, function () {
14992 var renderer, control, initialPanel;
14993 return __generator(this, function (_a) {
14994 renderer = this._renderer;
14995 control = this._control;
14996 initialPanel = renderer.getPanel(this._defaultIndex) || renderer.getPanel(0);
14997 if (!initialPanel) return [2
14998 /*return*/
14999 ];
15000 control.setActive(initialPanel, null, false);
15001 return [2
15002 /*return*/
15003 , control.moveToPanel(initialPanel, {
15004 duration: 0
15005 })];
15006 });
15007 });
15008 };
15009 /**
15010 * Version info string
15011 * @ko 버전정보 문자열
15012 * @type {string}
15013 * @readonly
15014 * @example
15015 * ```ts
15016 * Flicking.VERSION; // ex) 4.0.0
15017 * ```
15018 */
15019
15020
15021 Flicking.VERSION = "4.3.0";
15022 return Flicking;
15023 }(Component$2);
15024
15025 /**
15026 * An slide data component that holds information of a single HTMLElement
15027 * @ko 슬라이드 데이터 컴포넌트로, 단일 HTMLElement의 정보를 갖고 있습니다
15028 */
15029
15030 var ExternalPanel = function (_super) {
15031 __extends$2(ExternalPanel, _super);
15032 /**
15033 * @param {object} options An options object<ko>옵션 오브젝트</ko>
15034 * @param {HTMLElement} [options.el] A `HTMLElement` panel's referencing<ko>패널이 참조하는 `HTMLElement`</ko>
15035 * @param {number} [options.index] An initial index of the panel<ko>패널의 초기 인덱스</ko>
15036 * @param {Constants.ALIGN | string | number} [options.align] An initial {@link Flicking#align align} value of the panel<ko>패널의 초기 {@link Flicking#align align}값</ko>
15037 * @param {Flicking} [options.flicking] A Flicking instance panel's referencing<ko>패널이 참조하는 {@link Flicking} 인스턴스</ko>
15038 */
15039
15040
15041 function ExternalPanel(options) {
15042 var _this = _super.call(this, options) || this;
15043
15044 _this._externalComponent = options.externalComponent;
15045 return _this;
15046 }
15047
15048 return ExternalPanel;
15049 }(Panel);
15050
15051 /*
15052 * Copyright (c) 2015 NAVER Corp.
15053 * egjs projects are licensed under the MIT license
15054 */
15055
15056 var Core = {
15057 __proto__: null,
15058 Viewport: Viewport,
15059 FlickingError: FlickingError,
15060 AnchorPoint: AnchorPoint,
15061 Panel: Panel,
15062 ElementPanel: ElementPanel,
15063 ExternalPanel: ExternalPanel
15064 };
15065
15066 /**
15067 * Decorator that makes the method of flicking available in the framework.
15068 * @ko 프레임워크에서 플리킹의 메소드를 사용할 수 있게 하는 데코레이터.
15069 * @memberof eg.Flicking
15070 * @private
15071 * @example
15072 * ```js
15073 * import Flicking, { withFlickingMethods } from "@egjs/flicking";
15074 *
15075 * class Flicking extends React.Component<Partial<FlickingProps & FlickingOptions>> {
15076 * &#64;withFlickingMethods
15077 * private flicking: Flicking;
15078 * }
15079 * ```
15080 */
15081
15082 var withFlickingMethods = function (prototype, flickingName) {
15083 [Component$2.prototype, Flicking.prototype].forEach(function (proto) {
15084 Object.getOwnPropertyNames(proto).filter(function (name) {
15085 return !prototype[name] && !name.startsWith("_") && name !== "constructor";
15086 }).forEach(function (name) {
15087 var descriptor = Object.getOwnPropertyDescriptor(proto, name);
15088
15089 if (descriptor.value) {
15090 // Public Function
15091 Object.defineProperty(prototype, name, {
15092 value: function () {
15093 var _a;
15094
15095 var args = [];
15096
15097 for (var _i = 0; _i < arguments.length; _i++) {
15098 args[_i] = arguments[_i];
15099 }
15100
15101 return (_a = descriptor.value).call.apply(_a, __spreadArray([this[flickingName]], __read$1(args)));
15102 }
15103 });
15104 } else {
15105 var getterDescriptor = {};
15106
15107 if (descriptor.get) {
15108 getterDescriptor.get = function () {
15109 var _a;
15110
15111 return (_a = descriptor.get) === null || _a === void 0 ? void 0 : _a.call(this[flickingName]);
15112 };
15113 }
15114
15115 if (descriptor.set) {
15116 getterDescriptor.set = function () {
15117 var _a;
15118
15119 var args = [];
15120
15121 for (var _i = 0; _i < arguments.length; _i++) {
15122 args[_i] = arguments[_i];
15123 }
15124
15125 return (_a = descriptor.set) === null || _a === void 0 ? void 0 : _a.call.apply(_a, __spreadArray([this[flickingName]], __read$1(args)));
15126 };
15127 }
15128
15129 Object.defineProperty(prototype, name, getterDescriptor);
15130 }
15131 });
15132 });
15133 };
15134
15135 var sync = (function (flicking, diffResult, rendered) {
15136 var renderer = flicking.renderer;
15137 var panels = renderer.panels;
15138
15139 if (diffResult.removed.length > 0) {
15140 var endIdx_1 = -1;
15141 var prevIdx_1 = -1;
15142 diffResult.removed.forEach(function (removedIdx) {
15143 if (endIdx_1 < 0) {
15144 endIdx_1 = removedIdx;
15145 }
15146
15147 if (prevIdx_1 >= 0 && removedIdx !== prevIdx_1 - 1) {
15148 batchRemove(renderer, prevIdx_1, endIdx_1 + 1);
15149 endIdx_1 = removedIdx;
15150 prevIdx_1 = removedIdx;
15151 } else {
15152 prevIdx_1 = removedIdx;
15153 }
15154 });
15155 batchRemove(renderer, prevIdx_1, endIdx_1 + 1);
15156 }
15157
15158 diffResult.ordered.forEach(function (_a) {
15159 var _b = __read$1(_a, 2),
15160 prevIdx = _b[0],
15161 newIdx = _b[1];
15162
15163 var prevPanel = panels[prevIdx];
15164 var indexDiff = newIdx - prevIdx;
15165
15166 if (indexDiff > 0) {
15167 var middlePanels = panels.slice(prevIdx + 1, newIdx + 1);
15168 prevPanel.increaseIndex(indexDiff);
15169 middlePanels.forEach(function (panel) {
15170 return panel.decreaseIndex(1);
15171 });
15172 } else {
15173 var middlePanels = panels.slice(newIdx, prevIdx);
15174 prevPanel.decreaseIndex(-indexDiff);
15175 middlePanels.forEach(function (panel) {
15176 return panel.increaseIndex(1);
15177 });
15178 } // Update position
15179
15180
15181 prevPanel.resize();
15182 });
15183
15184 if (diffResult.ordered.length > 0) {
15185 panels.sort(function (panel1, panel2) {
15186 return panel1.index - panel2.index;
15187 });
15188 }
15189
15190 if (diffResult.added.length > 0) {
15191 var startIdx_1 = -1;
15192 var prevIdx_2 = -1;
15193 diffResult.added.forEach(function (addedIdx, idx) {
15194 if (startIdx_1 < 0) {
15195 startIdx_1 = idx;
15196 }
15197
15198 if (prevIdx_2 >= 0 && addedIdx !== prevIdx_2 + 1) {
15199 batchInsert(renderer, diffResult, rendered, startIdx_1, idx + 1);
15200 startIdx_1 = -1;
15201 prevIdx_2 = -1;
15202 } else {
15203 prevIdx_2 = addedIdx;
15204 }
15205 });
15206
15207 if (startIdx_1 >= 0) {
15208 batchInsert(renderer, diffResult, rendered, startIdx_1);
15209 }
15210 }
15211 });
15212
15213 var batchInsert = function (renderer, diffResult, rendered, startIdx, endIdx) {
15214 renderer.batchInsert.apply(renderer, __spreadArray([], __read$1(diffResult.added.slice(startIdx, endIdx).map(function (index, elIdx) {
15215 return {
15216 index: index,
15217 elements: [rendered[elIdx + diffResult.prevList.length]]
15218 };
15219 }))));
15220 };
15221
15222 var batchRemove = function (renderer, startIdx, endIdx) {
15223 var removed = renderer.panels.slice(startIdx, endIdx);
15224 renderer.batchRemove({
15225 index: startIdx,
15226 deleteCount: removed.length
15227 });
15228 };
15229
15230 var getRenderingPanels = (function (flicking, diffResult) {
15231 var removedPanels = diffResult.removed.reduce(function (map, idx) {
15232 map[idx] = true;
15233 return map;
15234 }, {});
15235 var maintainedMap = diffResult.maintained.reduce(function (map, _a) {
15236 var _b = __read$1(_a, 2),
15237 prev = _b[0],
15238 current = _b[1];
15239
15240 map[prev] = current;
15241 return map;
15242 }, {});
15243 return __spreadArray(__spreadArray([], __read$1(flicking.panels.filter(function (panel) {
15244 return !removedPanels[panel.index];
15245 }) // Sort panels by position
15246 .sort(function (panel1, panel2) {
15247 return panel1.position + panel1.offset - (panel2.position + panel2.offset);
15248 }).map(function (panel) {
15249 return diffResult.list[maintainedMap[panel.index]];
15250 }))), __read$1(diffResult.added.map(function (idx) {
15251 return diffResult.list[idx];
15252 })));
15253 });
15254
15255 var getDefaultCameraTransform = (function (align, horizontal, firstPanelSize) {
15256 if (align === void 0) {
15257 align = ALIGN.CENTER;
15258 }
15259
15260 if (horizontal === void 0) {
15261 horizontal = true;
15262 }
15263
15264 var cameraAlign = getCameraAlign(align);
15265 var panelAlign = getPanelAlign(align);
15266 if (panelAlign == null) return "";
15267 var camPosition = "calc(" + cameraAlign + " - (" + (firstPanelSize || "0px") + " * " + panelAlign.percentage + ") - " + panelAlign.absolute + "px)";
15268 return horizontal ? "translate(" + camPosition + ")" : "translate(0, " + camPosition + ")";
15269 });
15270
15271 var getCameraAlign = function (align) {
15272 var alignVal = typeof align === "object" ? align.camera : align;
15273 return parseAlign(alignVal);
15274 };
15275
15276 var getPanelAlign = function (align) {
15277 var alignVal = typeof align === "object" ? align.panel : align;
15278 return parseArithmeticExpression(parseAlign(alignVal));
15279 };
15280
15281 var parseAlign = function (alignVal) {
15282 if (typeof alignVal === "number") {
15283 return alignVal + "px";
15284 }
15285
15286 switch (alignVal) {
15287 case ALIGN.CENTER:
15288 return "50%";
15289
15290 case ALIGN.NEXT:
15291 return "100%";
15292
15293 case ALIGN.PREV:
15294 return "0%";
15295
15296 default:
15297 return alignVal;
15298 }
15299 };
15300
15301 var CFC = {
15302 __proto__: null,
15303 withFlickingMethods: withFlickingMethods,
15304 sync: sync,
15305 getRenderingPanels: getRenderingPanels,
15306 getDefaultCameraTransform: getDefaultCameraTransform
15307 };
15308
15309 /*
15310 * Copyright (c) 2015 NAVER Corp.
15311 * egjs projects are licensed under the MIT license
15312 */
15313 merge$1(Flicking, Core);
15314 merge$1(Flicking, Camera);
15315 merge$1(Flicking, Control);
15316 merge$1(Flicking, Renderer);
15317 merge$1(Flicking, Constants);
15318 merge$1(Flicking, CFC);
15319
15320 return Flicking;
15321
15322})));
15323//# sourceMappingURL=flicking.pkgd.js.map