PageSourceSearch

https://tintern.vic.edu.au/wp-content/plugins/tintern-flipbook/flipbook-source/js/dflip.js%3Fver=7.1.1

js tintern.vic.edu.au collected 2026-10-02 21:46:04 UTC 274,992 bytes, 8,601 lines download raw bytes

1/**
2 * @preserve
3 * Plugin Name: dflip
4 * Description: dflip - 3D & 2D FlipBook
5 *
6 * Author: Deepak Ghimire
7 * Author URI: http://codecanyon.net/user/deip?ref=deip
8 */
9
10"use strict";
11
12var DFLIP = DFLIP || {};
13
14// old fallback
15// use DFLIP instead of PRESENTATION as of v 1.1
16var PRESENTATION = DFLIP;
17
18(function dFlip(DFLIP, $) {
19  DFLIP.version = "1.2.8";
20
21  DFLIP.PAGE_MODE = { SINGLE: 1, DOUBLE: 2, AUTO: void 0 };
22  DFLIP.SINGLE_PAGE_MODE = { ZOOM: 1, BOOKLET: 2, AUTO: void 0 };
23  DFLIP.DIRECTION = { LTR: 1, RTL: 2 };
24
25  DFLIP.CORNERS = {
26    TL: "tl",
27    TR: "tr",
28    BL: "bl",
29    BR: "br",
30    L: "l",
31    R: "r",
32    NONE: void 0,
33  };
34
35  DFLIP.SOURCE_TYPE = { IMAGE: "image", PDF: "pdf", HTML: "html" };
36  DFLIP.DISPLAY_TYPE = { WEBGL: "3D", HTML: "2D" };
37  DFLIP.PAGE_SIZE = { AUTO: 0, SINGLE: 1, DOUBLEINTERNAL: 2 };
38
39  //defaults settings
40  var defaults = (DFLIP.defaults = {
41    //sets if to use 3d or not (true|false)
42    webgl: true,
43    //if you want to turn of shadow in 3d set it to false
44    webglShadow: true,
45
46    // if enable sound at start (true|false)
47    soundEnable: true,
48
49    // height of the container
50    // value(eg: 320) or percentage (eg: '50%')
51    // calculaton limit: minimum 320, max window height
52    height: "100%",
53
54    // set to true to show outline on open (true|false)
55    autoEnableOutline: false,
56
57    // set to true to show thumbnail on open (true|false)
58    autoEnableThumbnail: false,
59
60    // set to true if PDF inbuilt outline is to be removed (true|false)
61    overwritePDFOutline: false,
62
63    // enableDownload of PDF files (true|false)
64    enableDownload: true,
65
66    // duration of page turn in milliseconds
67    duration: 800,
68
69    //direction of flipbook
70    //DFLIP.DIRECTION.LTR or 1	for left to right(default),
71    //DFLIP.DIRECTION.RTL or 2	for right to left,
72    direction: DFLIP.DIRECTION.LTR,
73
74    //set as
75    //DFLIP.PAGE_MODE.AUTO	 				for auto-detect(default),
76    //DFLIP.PAGE_MODE.SINGLE or 1 			for singleview,
77    //DFLIP.PAGE_MODE.DOUBLE or 2 			for doubleview,
78    pageMode: DFLIP.PAGE_MODE.AUTO,
79
80    //set as
81    //DFLIP.SINGLE_PAGE_MODE.AUTO	 				for auto-detect(default),
82    //DFLIP.SINGLE_PAGE_MODE.ZOOM or 1 				for normal zoom single view,
83    //DFLIP.SINGLE_PAGE_MODE.BOOKLET or 2 			for Booklet mode,
84    singlePageMode: DFLIP.SINGLE_PAGE_MODE.AUTO,
85
86    //color value in hexadecimal
87    backgroundColor: "#fff",
88
89    forceFit: true, //very rare usage leave it as true unless page are not fitting wrong...
90    transparent: false, //true or false
91    hard: "none", //possible values are "hard", "none", "cover"
92
93    annotationClass: "",
94
95    // texture settings
96    maxTextureSize: 1600, //max page size to be rendered. for pdf files only
97    minTextureSize: 256, //min page size to be rendered. for pdf files only
98
99    // icons for the buttons
100    icons: {
101      altnext: "ti-angle-right",
102      altprev: "ti-angle-left",
103      next: "ti-angle-right",
104      prev: "ti-angle-left",
105      end: "ti-angle-double-right",
106      start: "ti-angle-double-left",
107      share: "ti-sharethis",
108      help: "ti-help-alt",
109      more: "ti-more-alt",
110      download: "ti-download",
111      zoomin: "ti-zoom-in",
112      zoomout: "ti-zoom-out",
113      fullscreen: "ti-fullscreen",
114      fitscreen: "ti-arrows-corner",
115      thumbnail: "ti-layout-grid2",
116      outline: "ti-menu-alt",
117      close: "ti-close",
118      doublepage: "ti-book",
119      singlepage: "ti-file",
120      sound: "ti-volume",
121      facebook: "ti-facebook",
122      google: "ti-google",
123      twitter: "ti-twitter-alt",
124      mail: "ti-email",
125    },
126
127    // TRANSLATION text to be displayed
128    text: {
129      toggleSound: "Turn on/off Sound",
130      toggleThumbnails: "Toggle Thumbnails",
131      toggleOutline: "Toggle Outline/Bookmark",
132      previousPage: "Previous Page",
133      nextPage: "Next Page",
134      toggleFullscreen: "Toggle Fullscreen",
135      zoomIn: "Zoom In",
136      zoomOut: "Zoom Out",
137      toggleHelp: "Toggle Help",
138
139      singlePageMode: "Single Page Mode",
140      doublePageMode: "Double Page Mode",
141      downloadPDFFile: "Download PDF File",
142      gotoFirstPage: "Goto First Page",
143      gotoLastPage: "Goto Last Page",
144
145      share: "Share",
146    },
147
148    //valid controlnames:
149    //altPrev,pageNumber,altNext,outline,thumbnail,zoomIn,zoomOut,fullScreen,share
150    //more,download,pageMode,startPage,endPage,sound
151    allControls:
152      "altPrev,pageNumber,altNext,outline,thumbnail,zoomIn,zoomOut,fullScreen,share,more,download,pageMode,startPage,endPage,sound",
153    mainControls:
154      "altPrev,pageNumber,altNext,outline,thumbnail,zoomIn,zoomOut,fullScreen,share,more",
155    hideControls: "",
156
157    //set if the zoom changes on mouse scroll (true|false)
158    scrollWheel: true,
159
160    // callbacks
161    onCreate: function (flipBook) {
162      // after flip book is created is fired
163    },
164    onCreateUI: function (flipBook) {
165      // after ui created event is fired
166    },
167    onFlip: function (flipBook) {
168      // after flip event is fired
169    },
170    beforeFlip: function (flipBook) {
171      // before flip event is fired
172    },
173    onReady: function (flipBook) {
174      // after flip book is completely loaded
175    },
176
177    zoomRatio: 1.5,
178    pageSize: DFLIP.PAGE_SIZE.AUTO,
179
180    /**
181     * NON-OPTIONS AREA
182     * These options are not supposed to be sent from options variable
183     */
184    /**
185     * dependency URLS (NON-OPTION):
186     * Do not set them as options,
187     * Refer to advance-examples
188     */
189    //(NON-OPTION) source link for PDF.JS file
190    // var plugin_dir="wp-content/plugin/tintern-flipbook/flipbook-source/js";
191    pdfjsSrc:
192      "/wp-content/plugins/tintern-flipbook/flipbook-source" +
193      "/js/libs/pdf.min.js",
194    //(NON-OPTION) source link for PDFcompatibility.JS file
195    pdfjsCompatibilitySrc:
196      "/wp-content/plugins/tintern-flipbook/flipbook-source" +
197      "/js/libs/compatibility.js",
198    //(NON-OPTION) source link for PDF.WORKER.JS file
199    pdfjsWorkerSrc:
200      "/wp-content/plugins/tintern-flipbook/flipbook-source" +
201      "/js/libs/pdf.worker.min.js",
202    //(NON-OPTION) source link for THREE.JS file
203    threejsSrc:
204      "/wp-content/plugins/tintern-flipbook/flipbook-source" +
205      "/js/libs/three.min.js",
206    //(NON-OPTION) source link for MOCKUP.JS file
207    mockupjsSrc:
208      "/wp-content/plugins/tintern-flipbook/flipbook-source" +
209      "/js/libs/mockup.min.js",
210    //(NON-OPTION) File path to the trun sound
211    soundFile:
212      "/wp-content/plugins/tintern-flipbook/flipbook-source" +
213      "/sound/turn2.mp3",
214    imagesLocation:
215      "/wp-content/plugins/tintern-flipbook/flipbook-source" + "/images",
216
217    //(NON-OPTION) developer parameters
218    enableDebugLog: false,
219    canvasToBlob: true,
220    enableAnnotation: true,
221
222    /**
223     * Let them be, change at your risk
224     */
225    // if texture fallback override is required
226    // note: if set to anything other than "blank" the first page is changed
227    // recommended : "blank"
228    textureLoadFallback: "blank", //"images/textures/white.jpg",
229    // controls the flexibility of the paper more value for more flexiblilty
230    stiffness: 3,
231    minTopOffset: 30,
232    // link to the images file that you want as background.
233    // supported files are jpgs,png. smaller files are preffered for performance
234    backgroundImage: "", //"images/textures/el.jpg",
235    // or any number like 5, 500. recommended: "auto"
236
237    pageRatio: void 0, //equals to width/height
238
239    defaultPageRatio: 210 / 297, //internal usage
240    pixelRatio: window.devicePixelRatio || 1,
241  });
242
243  var has3d =
244      "WebKitCSSMatrix" in window ||
245      (document.body && "MozPerspective" in document.body.style),
246    hasMouse = "onmousedown" in window,
247    hasTouch = "ontouchstart" in window;
248
249  var utils = (DFLIP.utils = {
250    drag: {
251      left: 0,
252      right: 1,
253      none: -1,
254    },
255    mouseEvents: hasMouse
256      ? { type: "mouse", start: "mousedown", move: "mousemove", end: "mouseup" }
257      : {
258          type: "touch",
259          start: "touchstart",
260          move: "touchmove",
261          end: "touchend",
262        },
263
264    html: {
265      div: "<div/>",
266      img: "<img/>",
267      a: "<a>",
268      input: "<input type='text'/>",
269    },
270    //functions or so
271    toRad: function (deg) {
272      return (deg * Math.PI) / 180;
273    },
274
275    toDeg: function (rad) {
276      return (rad * 180) / Math.PI;
277    },
278
279    transition: function (hasTransition, duration) {
280      return hasTransition ? duration / 1000 + "s ease-out" : "0s none";
281    },
282
283    display: function (hasDisplay) {
284      return hasDisplay ? "block" : "none";
285    },
286
287    resetTranslate: function () {
288      return translateStr(0, 0);
289    },
290
291    translateStr: function (x, y) {
292      return has3d
293        ? " translate3d(" + x + "px," + y + "px, 0px) "
294        : " translate(" + x + "px, " + y + "px) ";
295    },
296
297    resetBoxShadow: function () {
298      return "rgba(0, 0, 0, 0) 0px 0px 20px";
299    },
300
301    rotateStr: function (deg) {
302      return " rotateZ(" + deg + "deg) ";
303    },
304
305    bg: function (src) {
306      return "#fff" + bgImage(src);
307    },
308
309    bgImage: function (src) {
310      return src == void 0 || src == "blank" ? "" : " url(" + src + ")";
311    },
312
313    src: function (src) {
314      return src !== void 0 ? "" + src + "" : "";
315    },
316
317    limitAt: function (x, min, max) {
318      return x < min ? min : x > max ? max : x;
319    },
320
321    distOrigin: function (x, y) {
322      return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
323    },
324
325    distPoints: function (x1, y1, x2, y2) {
326      return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
327    },
328    calculateScale: function (startTouches, endTouches) {
329      var startDistance = distPoints(
330          startTouches[0].x,
331          startTouches[0].y,
332          startTouches[1].x,
333          startTouches[1].y
334        ),
335        endDistance = distPoints(
336          endTouches[0].x,
337          endTouches[0].y,
338          endTouches[1].x,
339          endTouches[1].y
340        );
341      return endDistance / startDistance;
342    },
343    /**
344     * Calculates the average of multiple vectors (x, y values)
345     */
346    getVectorAvg: function (vectors) {
347      return {
348        x:
349          vectors
350            .map(function (v) {
351              return v.x;
352            })
353            .reduce(utils.sum) / vectors.length,
354        y:
355          vectors
356            .map(function (v) {
357              return v.y;
358            })
359            .reduce(utils.sum) / vectors.length,
360      };
361    },
362    sum: function (a, b) {
363      return a + b;
364    },
365    /**
366     * Returns the touches of an event relative to the container offset
367     * @param event
368     * @return array touches
369     */
370    getTouches: function (event, position) {
371      position = position || { left: 0, top: 0 };
372      return Array.prototype.slice.call(event.touches).map(function (touch) {
373        return {
374          x: touch.pageX - position.left,
375          y: touch.pageY - position.top,
376        };
377      });
378    },
379
380    angleByDistance: function (distance, fullWidth) {
381      var h = fullWidth / 2;
382      var d = limitAt(distance, 0, fullWidth);
383
384      return d < h
385        ? toDeg(Math.asin(d / h))
386        : 90 + toDeg(Math.asin((d - h) / h));
387    },
388
389    log: function (args) {
390      if (defaults.enableDebugLog == true && window.console) console.log(args);
391    },
392    lowerPowerOfTwo: function (value) {
393      return Math.pow(2, Math.floor(Math.log(value) / Math.LN2));
394    },
395    nearestPowerOfTwo: function (value, max) {
396      return Math.min(
397        max || 2048,
398        Math.pow(2, Math.ceil(Math.log(value) / Math.LN2))
399      );
400    },
401    zoomStops: function (value, zoomRatio, ceil, min, max) {
402      if (min == void 0) min = 256;
403      if (max == void 0) max = 2048;
404      //Math.pow(2, Math.ceil(Math.log(value) / Math.LN2));
405
406      var factor = Math.log(value / min) / Math.log(zoomRatio);
407
408      return (
409        min *
410        Math.pow(
411          zoomRatio,
412          ceil == void 0
413            ? Math.round(factor)
414            : ceil == true
415            ? Math.ceil(factor)
416            : Math.floor(factor)
417        )
418      );
419    },
420
421    extendOptions: function (defaults, options) {
422      return $.extend(true, {}, defaults, options);
423    },
424    getFullscreenElement: function () {
425      return (
426        document.fullscreenElement ||
427        document.mozFullScreenElement ||
428        document.webkitFullscreenElement ||
429        document.msFullscreenElement
430      );
431    },
432    hasFullscreenEnabled: function () {
433      return (
434        document.fullscreenEnabled ||
435        document.mozFullScreenEnabled ||
436        document.webkitFullscreenEnabled ||
437        document.msFullscreenEnabled
438      );
439    },
440    getBasePage: function (pageNumber) {
441      return Math.floor(pageNumber / 2) * 2;
442    },
443
444    loadResources: function loadResources(resourceTag, src, callback) {
445      var doc = document,
446        element = doc.createElement(resourceTag),
447        refElement = doc.getElementsByTagName(resourceTag)[0];
448
449      element.async = true;
450      if (callback) {
451        element.addEventListener(
452          "load",
453          function (e) {
454            callback(null, e);
455          },
456          false
457        );
458      }
459
460      element.src = src;
461
462      refElement.parentNode.insertBefore(element, refElement);
463    },
464    getScript: function (source, callback, errorCallback) {
465      var script = document.createElement("script");
466      var prior = document.body.getElementsByTagName("script")[0];
467      script.async = 1;
468      script.setAttribute("data-cfasync", false);
469      if (prior != void 0) {
470        prior.parentNode.insertBefore(script, prior);
471        prior = null;
472      } else {
473        //sometimes if script are loaded in head and no scripts are present in body
474        document.body.appendChild(script);
475      }
476
477      function load(_, isAbort) {
478        if (script != void 0) {
479          //IE 10 doesn't regard
480          if (
481            isAbort ||
482            !script.readyState ||
483            /loaded|complete/.test(script.readyState)
484          ) {
485            //console.log("aborted loading :" + source);
486            script.onload = script.onreadystatechange = null;
487            script = void 0;
488            script = null;
489            if (!isAbort) {
490              if (callback) callback();
491              callback = null;
492              errorCallback = null;
493            }
494          }
495        }
496      }
497
498      script.addEventListener("load", load, false);
499      script.addEventListener("readystatechange", load, false);
500      script.addEventListener("complete", load, false);
501
502      if (errorCallback) {
503        script.addEventListener("error", errorCallback, false);
504      }
505      //script.onload = script.onreadystatechange = load;
506
507      script.src = source + (prefix.dom == "MS" ? "?" + Math.random(1) : "");
508    },
509    isHardPage: function (config, pageNumber, pageCount, isBooklet) {
510      if (config !== void 0) {
511        // var config = this.hardConfig;
512
513        if (config == "cover") {
514          return (
515            pageNumber == 0 ||
516            (isBooklet && pageNumber == 1) || //front cover is 0
517            pageNumber ==
518              Math.floor(pageCount / (isBooklet ? 1 : 2)) - (isBooklet ? 0 : 1)
519          ); //start with 0 so 1 minus
520        } else if (config == "all") {
521          return true;
522        } else {
523          var baseTest =
524            ("," + config + ",").indexOf("," + (pageNumber * 2 + 1) + ",") > -1;
525          var nextTest =
526            ("," + config + ",").indexOf("," + (pageNumber * 2 + 2) + ",") > -1;
527          return baseTest || nextTest;
528        }
529      }
530      return false;
531    },
532    fixMouseEvent: function (event) {
533      if (event) {
534        var originalEvent = event.originalEvent || event;
535
536        //noinspection JSUnresolvedVariable
537        if (
538          originalEvent.changedTouches &&
539          originalEvent.changedTouches.length > 0
540        ) {
541          var _event = $.event.fix(event);
542          //noinspection JSUnresolvedVariable
543          var touch = originalEvent.changedTouches[0];
544          _event.clientX = touch.clientX;
545          _event.clientY = touch.clientY;
546          _event.pageX = touch.pageX;
547          _event.touches = originalEvent.touches;
548          _event.pageY = touch.pageY;
549          _event.movementX = touch.movementX;
550          _event.movementY = touch.movementY;
551          return _event;
552        } else {
553          return event;
554        }
555      } else {
556        return event;
557      }
558    },
559
560    //self Execution
561    hasWebgl: (function () {
562      try {
563        var canvas = document.createElement("canvas");
564        //noinspection JSUnresolvedVariable
565        return !!(
566          window.WebGLRenderingContext &&
567          (canvas.getContext("webgl") ||
568            canvas.getContext("experimental-webgl"))
569        );
570      } catch (e) {
571        return false;
572      }
573    })(),
574    isBookletMode: function (book) {
575      return (
576        book.pageMode == DFLIP.PAGE_MODE.SINGLE &&
577        book.singlePageMode == DFLIP.SINGLE_PAGE_MODE.BOOKLET
578      );
579    },
580    isRTLMode: function (book) {
581      return book.direction == DFLIP.DIRECTION.RTL;
582    },
583    isMobile: (function () {
584      var check = false;
585      (function (a) {
586        if (
587          /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(
588            a
589          ) ||
590          /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(
591            a.substr(0, 4)
592          )
593        )
594          check = true;
595      })(navigator.userAgent || navigator.vendor || window.opera);
596      return check;
597    })(),
598    prefix: (function () {
599      var styles = window.getComputedStyle(document.documentElement, ""),
600        pre = Array.prototype.slice
601          .call(styles)
602          .join("")
603          .match(/-(moz|webkit|ms)-/)[1],
604        dom = "WebKit|Moz|MS".match(new RegExp("(" + pre + ")", "i"))[1];
605      return {
606        dom: dom,
607        lowercase: pre,
608        css: "-" + pre + "-",
609        js: pre[0].toUpperCase() + pre.substr(1),
610      };
611    })(),
612
613    __extends: function (child, parent) {
614      for (var key in parent)
615        if (parent.hasOwnProperty(key)) child[key] = parent[key];
616      function Ctor() {
617        this.constructor = child;
618      }
619
620      Ctor.prototype = parent.prototype;
621      child.prototype = new Ctor();
622      child.__super = parent.prototype;
623      return child;
624    },
625  });
626
627  //caching the utils
628
629  var SOURCE_TYPE = DFLIP.SOURCE_TYPE,
630    DISPLAY_TYPE = DFLIP.DISPLAY_TYPE,
631    drag = utils.drag,
632    mouseEvents = utils.mouseEvents,
633    html = utils.html,
634    toRad = utils.toRad,
635    toDeg = utils.toDeg,
636    transition = utils.transition,
637    translateStr = utils.translateStr,
638    resetBoxShadow = utils.resetBoxShadow,
639    rotateStr = utils.rotateStr,
640    bg = utils.bg,
641    bgImage = utils.bgImage,
642    src = utils.src,
643    limitAt = utils.limitAt,
644    distOrigin = utils.distOrigin,
645    distPoints = utils.distPoints,
646    angleByDistance = utils.angleByDistance,
647    log = utils.log,
648    nearestPowerOfTwo = utils.nearestPowerOfTwo,
649    extendOptions = utils.extendOptions,
650    getBasePage = utils.getBasePage,
651    getScript = utils.getScript,
652    fixMouseEvent = utils.fixMouseEvent,
653    prefix = utils.prefix,
654    isBookletMode = utils.isBookletMode,
655    isRTLMode = utils.isRTLMode,
656    isMobile = utils.isMobile,
657    hasWebgl = utils.hasWebgl,
658    isSafari =
659      /constructor/i.test(window.HTMLElement) ||
660      (function (p) {
661        return p.toString() === "[object SafariRemoteNotification]";
662      })(!window["safari"] || safari.pushNotification),
663    __extends = utils.__extends;
664
665  var extendDFlipOptions = function (options) {
666    return $.extend(true, {}, defaults, options);
667  };
668
669  //Creates ui for the flipbook
670  var createUI = function (container, object) {
671    var uiClass = "df-ui";
672    var wrapperClass = "df-ui-wrapper";
673    var buttonClass = uiClass + "-" + "btn";
674    var ui = (object.ui = $(html.div, { class: uiClass }));
675    var options = object.options;
676
677    ui.dispose = function () {
678      container.find("." + buttonClass).each(function () {
679        $(this).off();
680      });
681      help.off();
682      next.off();
683      prev.off();
684      zoom.off();
685      zoomIn.off();
686      zoomOut.off();
687      page.off();
688      sound.off();
689      more.off();
690      fullScreen.off();
691      fit.off();
692      share.off();
693      start.off();
694      end.off();
695      pageModeButton.off();
696      altPrev.off();
697      altNext.off();
698      thumbnail.off();
699      outline.off();
700
701      controls.remove();
702      sizeControls.remove();
703      prev.remove();
704      next.remove();
705      zoom.remove();
706      if (ui.shareBox) {
707        if (ui.shareBox.dispose) ui.shareBox.dispose();
708        ui.shareBox = null;
709      }
710      document.removeEventListener("keyup", onKeyUp, false);
711      window.removeEventListener("click", closeMoreOptions, false);
712      ui.update = null;
713      object = null;
714    };
715
716    var validPage = function (pageNumber) {
717      if (isNaN(pageNumber)) pageNumber = object.target._activePage;
718      else if (pageNumber < 1) pageNumber = 1;
719      else if (pageNumber > object.target.pageCount)
720        pageNumber = object.target.pageCount;
721      return pageNumber;
722    };
723
724    var next = (ui.next = $(html.div, {
725      class: buttonClass + " " + uiClass + "-next " + options.icons["next"],
726      title: options.text.nextPage,
727      html: "<span>" + options.text.nextPage + "</span>",
728    }).on("click", function () {
729      object.next();
730    }));
731
732    var prev = (ui.prev = $(html.div, {
733      class: buttonClass + " " + uiClass + "-prev " + options.icons["prev"],
734      title: options.text.previousPage,
735      html: "<span>" + options.text.previousPage + "</span>",
736    }).on("click", function () {
737      object.prev();
738    }));
739
740    var zoom = $(html.div, {
741      class: wrapperClass + " " + uiClass + "-zoom",
742    });
743
744    var zoomIn = (ui.zoomIn = $(html.div, {
745      class: buttonClass + " " + uiClass + "-zoomin " + options.icons["zoomin"],
746      title: options.text.zoomIn,
747      html: "<span>" + options.text.zoomIn + "</span>",
748    }).on("click", function () {
749      object.zoom(1);
750      ui.update();
751      if (object.target.startPoint && object.target.pan)
752        object.target.pan(object.target.startPoint);
753    }));
754
755    var zoomOut = (ui.zoomOut = $(html.div, {
756      class:
757        buttonClass + " " + uiClass + "-zoomout " + options.icons["zoomout"],
758      title: options.text.zoomOut,
759      html: "<span>" + options.text.zoomOut + "</span>",
760    }).on("click", function () {
761      object.zoom(-1);
762      ui.update();
763      if (object.target.startPoint && object.target.pan)
764        object.target.pan(object.target.startPoint);
765    }));
766    zoom.append(zoomIn).append(zoomOut);
767
768    var page = (ui.pageNumber = $(html.div, {
769      class: buttonClass + " " + uiClass + "-page",
770    })
771      .on("change", function () {
772        var pageNumber = parseInt(ui.pageInput.val(), 10);
773
774        pageNumber = validPage(pageNumber);
775        object.gotoPage(pageNumber);
776      })
777      .on("keyup", function (event) {
778        if (event.keyCode == 13) {
779          var pageNumber = parseInt(ui.pageInput.val(), 10);
780
781          pageNumber = validPage(pageNumber);
782          if (
783            pageNumber !==
784            validPage(object.target._activePage || object._activePage)
785          )
786            object.gotoPage(pageNumber);
787        }
788      }));
789
790    ui.pageInput = $('<input id="df_book_page_number" type="text"/>').appendTo(
791      page
792    );
793    ui.pageLabel = $('<label for="df_book_page_number"/>').appendTo(page);
794
795    var sizeControls = $(html.div, {
796      class: wrapperClass + " " + uiClass + "-size",
797    });
798
799    var help = $(html.div, {
800      class: buttonClass + " " + uiClass + "-help " + options.icons["help"],
801      title: options.text.toggleHelp,
802      html: "<span>" + options.text.toggleHelp + "</span>",
803    }).on("click", function () {});
804
805    //Sound Button
806    var sound = (ui.sound = $(html.div, {
807      class: buttonClass + " " + uiClass + "-sound " + options.icons["sound"],
808      title: options.text.toggleSound,
809      html: "<span>" + options.text.toggleSound + "</span>",
810    }).on("click", function () {
811      options.soundEnable = !options.soundEnable;
812      ui.updateSound();
813    }));
814
815    //Updates sound on click of sound button
816    ui.updateSound = function () {
817      if (options.soundEnable == false || options.soundEnable == "false")
818        sound.addClass("disabled");
819      else sound.removeClass("disabled");
820    };
821
822    //immediate check
823    ui.updateSound();
824
825    //More button
826    var more = (ui.more = $(html.div, {
827      class: buttonClass + " " + uiClass + "-more " + options.icons["more"],
828    }).on("click", function (event) {
829      if (!more.hasClass("df-active")) {
830        $(this).addClass("df-active");
831        event.stopPropagation();
832      }
833    }));
834
835    //closes moreoptions container
836    function closeMoreOptions(event) {
837      more.removeClass("df-active");
838    }
839
840    //register a click event on window to close the moreoptions
841    window.addEventListener("click", closeMoreOptions, false);
842
843    //more container that holds the moreoptions
844    var moreContainer = $(html.div, {
845      class: "more-container",
846    });
847    more.append(moreContainer);
848
849    if (typeof options.source == "string" && options.enableDownload == true) {
850      var downloadClass =
851        buttonClass + " " + uiClass + "-download " + options.icons["download"];
852      var download = (ui.download = $(
853        '<a download target="_blank" class="' +
854          downloadClass +
855          '"><span>' +
856          options.text.downloadPDFFile +
857          "</span></a>"
858      ));
859      download
860        .attr("href", options.source)
861        .attr("title", options.text.downloadPDFFile);
862      //moreContainer.append(download);
863    }
864
865    var fullscreenEnabled = utils.hasFullscreenEnabled();
866
867    if (!fullscreenEnabled) {
868      container.addClass("df-custom-fullscreen");
869    }
870
871    ui.switchFullscreen = function () {
872      var fullscreenElement = utils.getFullscreenElement();
873
874      var container = object.container[0];
875
876      if (ui.isFullscreen != true) {
877        object.container.addClass("df-fullscreen");
878        if (container.requestFullscreen) {
879          container.requestFullscreen();
880        } else if (container.msRequestFullscreen) {
881          container.msRequestFullscreen();
882        } else if (container.mozRequestFullScreen) {
883          container.mozRequestFullScreen();
884        } else if (container.webkitRequestFullscreen) {
885          container.webkitRequestFullscreen();
886        }
887
888        ui.isFullscreen = true;
889      } else {
890        object.container.removeClass("df-fullscreen");
891        ui.isFullscreen = false;
892
893        if (document.exitFullscreen) {
894          document.exitFullscreen();
895        } else if (document.msExitFullscreen) {
896          document.msExitFullscreen();
897        } else if (document.mozCancelFullScreen) {
898          document.mozCancelFullScreen();
899        } else if (document.webkitExitFullscreen) {
900          document.webkitExitFullscreen();
901        }
902      }
903
904      if (!utils.hasFullscreenEnabled()) {
905        setTimeout(function () {
906          object.resize();
907        }, 50);
908      }
909    };
910
911    var fullScreen = (ui.fullScreen = $(html.div, {
912      class:
913        buttonClass +
914        " " +
915        uiClass +
916        "-fullscreen " +
917        options.icons["fullscreen"],
918      title: options.text.toggleFullscreen,
919      html: "<span>" + options.text.toggleFullscreen + "</span>",
920    }).on("click", ui.switchFullscreen));
921
922    var fit = (ui.fit = $(html.div, {
923      class: buttonClass + " " + uiClass + "-fit " + options.icons["fitscreen"],
924    }).on("click", function () {
925      $(this).toggleClass("df-button-fit-active");
926    }));
927    sizeControls.append(fullScreen);
928
929    var controls = $(html.div, {
930      class: wrapperClass + " " + uiClass + "-controls", // todo : df-abs-h-center"
931    });
932
933    var shareBox = (ui.shareBox = new DFLIP.Share(container, options));
934
935    var share = (ui.share = $(html.div, {
936      class: buttonClass + " " + uiClass + "-share " + options.icons["share"],
937      title: options.text.share,
938      html: "<span>" + options.text.share + "</span>",
939    }).on("click", function (event) {
940      if (ui.shareBox.isOpen == true) ui.shareBox.close();
941      else {
942        ui.shareBox.update(object.getURLHash());
943        ui.shareBox.show();
944      }
945    }));
946
947    var start = (ui.startPage = $(html.div, {
948      class: buttonClass + " " + uiClass + "-start " + options.icons["start"],
949      title: options.text.gotoFirstPage,
950      html: "<span>" + options.text.gotoFirstPage + "</span>",
951    }).on("click", function () {
952      object.start();
953    }));
954
955    var end = (ui.endPage = $(html.div, {
956      class: buttonClass + " " + uiClass + "-end " + options.icons["end"],
957      title: options.text.gotoLastPage,
958      html: "<span>" + options.text.gotoLastPage + "</span>",
959    }).on("click", function () {
960      object.end();
961    }));
962
963    var pageModeButton = (ui.pageMode = $(html.div, {
964      class:
965        buttonClass +
966        " " +
967        uiClass +
968        "-pagemode " +
969        options.icons["singlepage"],
970      html: "<span>" + options.text.singlePageMode + "</span>",
971    }).on("click", function () {
972      var el = $(this);
973      object.setPageMode(!el.hasClass(options.icons["doublepage"]));
974    }));
975
976    object.setPageMode(object.target.pageMode == DFLIP.PAGE_MODE.SINGLE);
977    //moreContainer.append(pageModeButton).append(start).append(end).append(sound);
978
979    var altPrev = (ui.altPrev = $(html.div, {
980      class:
981        buttonClass +
982        " " +
983        uiClass +
984        "-prev" +
985        " " +
986        uiClass +
987        "-alt " +
988        options.icons["prev"],
989      title: options.text.previousPage,
990      html: "<span>" + options.text.previousPage + "</span>",
991    }).on("click", function () {
992      object.prev();
993    }));
994
995    var altNext = (ui.altNext = $(html.div, {
996      class:
997        buttonClass +
998        " " +
999        uiClass +
1000        "-next" +
1001        " " +
1002        uiClass +
1003        "-alt " +
1004        options.icons["next"],
1005      title: options.text.nextPage,
1006      html: "<span>" + options.text.nextPage + "</span>",
1007    }).on("click", function () {
1008      object.next();
1009    }));
1010
1011    var thumbnail = (ui.thumbnail = $(html.div, {
1012      class:
1013        buttonClass +
1014        " " +
1015        uiClass +
1016        "-thumbnail " +
1017        options.icons["thumbnail"],
1018      title: options.text.toggleThumbnails,
1019      html: "<span>" + options.text.toggleThumbnails + "</span>",
1020    }).on("click", function () {
1021      var $this = $(this);
1022      if (object.target.thumbContainer) {
1023        var thumbContainer = object.target.thumbContainer;
1024        thumbContainer.toggleClass("df-thumb-visible");
1025        $this.toggleClass("df-active");
1026      } else {
1027        object.contentProvider.initThumbs();
1028        $this.toggleClass("df-active");
1029      }
1030      if ($this.hasClass("df-active")) {
1031        $this.siblings(".df-active").trigger("click");
1032      }
1033      ui.update(true);
1034    }));
1035
1036    var outline = (ui.outline = $(html.div, {
1037      class:
1038        buttonClass + " " + uiClass + "-outline " + options.icons["outline"],
1039      title: options.text.toggleOutline,
1040      html: "<span>" + options.text.toggleOutline + "</span>",
1041    }).on("click", function () {
1042      var $this = $(this);
1043      if (object.target.outlineContainer) {
1044        var outlineContainer = object.target.outlineContainer;
1045        $this.toggleClass("df-active");
1046        outlineContainer.toggleClass("df-outline-visible");
1047        if ($this.hasClass("df-active")) {
1048          $this.siblings(".df-active").trigger("click");
1049        }
1050        ui.update(true);
1051      }
1052    }));
1053
1054    /**
1055     * Controls position and pplace ment is determined by options.maincrontrols and options.hidecontrols
1056     */
1057    var allControls = options.allControls.replace(/ /g, "").split(","),
1058      mainControls = "," + options.mainControls.replace(/ /g, "") + ",",
1059      hideControls = "," + options.hideControls.replace(/ /g, "") + ",";
1060
1061    var mainControlsArray = mainControls.split(",");
1062
1063    //if controls name is available in morecontrols it will be added into maincontrols else it will be added to morecontrols. if added in hide it will not be added in any
1064    for (
1065      var mainControlCount = 0;
1066      mainControlCount < mainControlsArray.length;
1067      mainControlCount++
1068    ) {
1069      //if hidden skip
1070      var mainControlName = mainControlsArray[mainControlCount];
1071      if (hideControls.indexOf("," + mainControlName + ",") < 0) {
1072        var mainControl = ui[mainControlName];
1073        if (mainControl !== void 0) {
1074          if (mainControls.indexOf("," + mainControlName + ",") > -1)
1075            controls.append(mainControl);
1076        }
1077      }
1078    }
1079
1080    for (
1081      var controlCount = 0;
1082      controlCount < allControls.length;
1083      controlCount++
1084    ) {
1085      //if hidden skip
1086      var controlName = allControls[controlCount];
1087      if (hideControls.indexOf("," + controlName + ",") < 0) {
1088        var control = ui[controlName];
1089        if (control !== void 0) {
1090          if (mainControls.indexOf("," + controlName + ",") > -1) {
1091            //skip
1092          } else if (controlName !== "more" && controlName !== "pageNumber")
1093            moreContainer.append(control);
1094        }
1095      }
1096    }
1097
1098    container.append(controls).append(prev).append(next).append(zoom);
1099
1100    //container.append(ui);
1101
1102    var ctrlDown = false,
1103      shiftDown = false,
1104      altDown = false;
1105    var shiftKey = 16,
1106      ctrlKey = 17,
1107      altKey = 18,
1108      sKey = 83,
1109      vKey = 86,
1110      cKey = 67,
1111      eKey = 69,
1112      gKey = 71,
1113      nKey = 78,
1114      oKey = 79,
1115      deleteKey = 46,
1116      rightKey = 39,
1117      leftKey = 37,
1118      escKey = 27;
1119
1120    document.addEventListener("keyup", onKeyUp, false);
1121
1122    function onKeyUp(event) {
1123      switch (event.keyCode) {
1124        case escKey:
1125          if (ui.isFullscreen == true) ui.fullScreen.trigger("click");
1126          break;
1127        case shiftKey:
1128          shiftDown = false;
1129          break;
1130        case ctrlKey:
1131          ctrlDown = false;
1132          break;
1133        case altKey:
1134          altDown = false;
1135          break;
1136        case leftKey:
1137          object.prev();
1138          break;
1139        case rightKey:
1140          object.next();
1141          break;
1142        default:
1143          break;
1144      }
1145      //log(event.keyCode);
1146    }
1147
1148    ui.update = function (resize) {
1149      log("ui update");
1150      var target = object.target;
1151
1152      var pageNumber = validPage(target._activePage || object._activePage);
1153      var pageCount = target.pageCount || object.pageCount;
1154
1155      var isRTL = target.direction == DFLIP.DIRECTION.RTL,
1156        isStart = pageNumber == 1 || pageNumber == 0,
1157        isEnd = pageNumber == pageCount;
1158
1159      ui.next.show();
1160      ui.prev.show();
1161      ui.altNext.removeClass("disabled");
1162      ui.altPrev.removeClass("disabled");
1163
1164      if ((isStart && !isRTL) || (isEnd && isRTL)) {
1165        ui.prev.hide();
1166        ui.altPrev.addClass("disabled");
1167      }
1168      if ((isEnd && !isRTL) || (isStart && isRTL)) {
1169        ui.next.hide();
1170        ui.altNext.addClass("disabled");
1171      }
1172
1173      ui.pageInput.val(pageNumber);
1174      ui.pageLabel.html(pageNumber + "/" + pageCount);
1175
1176      if (container.find(".df-thumb-visible, .df-outline-visible").length > 0) {
1177        container.addClass("df-sidemenu-open");
1178      } else {
1179        container.removeClass("df-sidemenu-open");
1180      }
1181      if (resize == true) object.resize();
1182
1183      if (target.contentProvider.zoomScale == target.contentProvider.maxZoom) {
1184        ui.zoomIn.addClass("disabled");
1185      } else {
1186        ui.zoomIn.removeClass("disabled");
1187      }
1188
1189      if (target.contentProvider.zoomScale == 1) {
1190        ui.zoomOut.addClass("disabled");
1191      } else {
1192        ui.zoomOut.removeClass("disabled");
1193      }
1194    };
1195
1196    if (object.target !== void 0) {
1197      object.target.ui = ui;
1198    }
1199
1200    if (options.onCreateUI !== void 0) options.onCreateUI(object);
1201  };
1202  var PreviewStage = void 0;
1203  //later updated via RegisterMockupObjects in case 3d is requested
1204
1205  //Registers necessary mockup object when required
1206  function RegisterMockupObjects() {
1207    PreviewStage = (function (_super) {
1208      __extends(PreviewStage, _super);
1209      function PreviewStage(parameters) {
1210        parameters = parameters || {};
1211        var _this = this;
1212        _super.call(this, parameters);
1213        _this.options = parameters;
1214        _this.canvas = $(_this.renderer.domElement).addClass("df-3dcanvas");
1215        _this.container = parameters.container;
1216        _this.container.append(_this.canvas);
1217        //_this.container.height(parameters.height);
1218        _this.type = "PreviewStage";
1219        _this.mouse = new THREE.Vector2();
1220        _this.raycaster = new THREE.Raycaster();
1221
1222        _this.camera.position.set(0, 20, 600);
1223        _this.camera.lookAt(new THREE.Vector3(0, 0, 0));
1224
1225        //shadows are zigzap due to shadow camera position
1226        _this.spotLight.position.set(-220, 330, 550);
1227
1228        _this.spotLight.castShadow = isMobile ? false : parameters.webglShadow;
1229        //_this.spotLight.shadowDarkness = 0.6;
1230        if (_this.spotLight.shadow) {
1231          _this.spotLight.shadow.bias = -0.0008;
1232        }
1233        _this.spotLight.intensity = 0.22;
1234        _this.ambientLight.color = new THREE.Color("#888");
1235        _this.ambientLight.intensity = 1.45;
1236
1237        var material = new THREE.ShadowMaterial();
1238        material.opacity = 0.15;
1239
1240        _this.ground.material = material;
1241        _this.ground.position.z = -2;
1242
1243        _this.orbitControl.maxAzimuthAngle = 0.4;
1244        _this.orbitControl.minAzimuthAngle = -0.4;
1245        _this.orbitControl.minPolarAngle = 1.4;
1246        _this.orbitControl.maxPolarAngle = 2.2;
1247
1248        //_this.orbitControl.maxPolarAngle = 10;
1249        _this.orbitControl.mouseButtons.ORBIT = THREE.MOUSE.RIGHT;
1250        _this.orbitControl.mouseButtons.PAN = -1;
1251        _this.orbitControl.maxDistance = 5000;
1252        _this.orbitControl.minDistance = 50;
1253        _this.orbitControl.noZoom = true;
1254
1255        _this.selectiveRendering = true;
1256
1257        _this.orbitControl.zoomSpeed = 5;
1258
1259        _this.orbitControl.keyPanSpeed = 0;
1260        _this.orbitControl.center.set(0, 0, 0);
1261        _this.orbitControl.update();
1262
1263        _this.swipe_threshold = isMobile ? 15 : 20;
1264
1265        var cssRenderer = (_this.cssRenderer = new THREE.CSS3DRenderer());
1266        $(cssRenderer.domElement)
1267          .css({
1268            position: "absolute",
1269            top: 0,
1270            pointerEvents: "none",
1271          })
1272          .addClass("df-3dcanvas df-csscanvas");
1273        _this.container[0].appendChild(cssRenderer.domElement);
1274
1275        var cssScene = (_this.cssScene = new THREE.Scene());
1276
1277        var divLeftDOM = document.createElement("div");
1278        divLeftDOM.className = "df-page-content df-page-content-left";
1279
1280        var divRightDOM = document.createElement("div");
1281        divRightDOM.className = "df-page-content df-page-content-right";
1282
1283        var divLeft = (cssScene.divLeft = new THREE.CSS3DObject(divLeftDOM));
1284        var divRight = (cssScene.divRight = new THREE.CSS3DObject(divRightDOM));
1285        cssScene.add(divLeft);
1286        cssScene.add(divRight);
1287
1288        _this.resizeCallback = function () {
1289          cssRenderer.setSize(_this.canvas.width(), _this.canvas.height());
1290        };
1291
1292        function requestRender() {
1293          _this.renderRequestPending = true;
1294        }
1295
1296        window.addEventListener(mouseEvents.move, requestRender, false);
1297
1298        window.addEventListener("keyup", requestRender, false);
1299
1300        _this.dispose = function () {
1301          _this.clearChild();
1302          _this.render();
1303
1304          window.removeEventListener(mouseEvents.move, requestRender, false);
1305
1306          if (_this.options.scrollWheel == true) {
1307            _this.renderer.domElement.removeEventListener(
1308              "mousewheel",
1309              onMouseWheel,
1310              false
1311            );
1312            _this.renderer.domElement.removeEventListener(
1313              "DOMMouseScroll",
1314              onMouseWheel,
1315              false
1316            ); // firefox
1317          }
1318
1319          window.removeEventListener("keyup", requestRender, false);
1320
1321          _this.renderer.domElement.removeEventListener(
1322            "mousemove",
1323            editor_mouseMove,
1324            false
1325          );
1326          _this.renderer.domElement.removeEventListener(
1327            "touchmove",
1328            editor_mouseMove,
1329            false
1330          );
1331
1332          _this.renderer.domElement.removeEventListener(
1333            "mousedown",
1334            editor_mouseDown,
1335            false
1336          );
1337          _this.renderer.domElement.removeEventListener(
1338            "touchstart",
1339            editor_mouseDown,
1340            false
1341          );
1342          _this.renderer.domElement.removeEventListener(
1343            "mouseup",
1344            editor_mouseUp,
1345            false
1346          );
1347          _this.renderer.domElement.removeEventListener(
1348            "touchend",
1349            editor_mouseUp,
1350            false
1351          );
1352
1353          _this.canvas.remove();
1354
1355          cssRenderer.domElement.parentNode.removeChild(cssRenderer.domElement);
1356
1357          cssRenderer = null;
1358
1359          _this.renderCallback = null;
1360          _this.renderCallback = void 0;
1361          _this.orbitControl.dispose();
1362          _this.orbitControl = null;
1363
1364          _this.renderer.dispose();
1365
1366          _this.cancelRAF();
1367        };
1368
1369        _this.renderCallback = function () {
1370          if (TWEEN.getAll().length > 0) _this.renderRequestPending = true;
1371          TWEEN.update();
1372          cssRenderer.render(cssScene, _this.camera);
1373        };
1374
1375        var onMouseWheel = function (event) {
1376          var delta = 0;
1377
1378          if (event.wheelDelta !== void 0) {
1379            // WebKit / Opera / Explorer 9
1380
1381            delta = event.wheelDelta;
1382          } else if (event.detail !== void 0) {
1383            // Firefox
1384
1385            delta = -event.detail;
1386          }
1387          if (delta) {
1388            var currentZoom = _this.previewObject.contentProvider.zoomScale;
1389            if (
1390              (delta > 0 && currentZoom == 1) ||
1391              (delta < 0 && currentZoom > 1)
1392            ) {
1393              event.preventDefault();
1394            }
1395            _this.previewObject.zoom(delta > 0 ? 1 : -1);
1396          }
1397
1398          requestRender();
1399        };
1400
1401        var editor_mouseMove = function (event) {
1402          _this.renderRequestPending = true;
1403          event = fixMouseEvent(event);
1404          if (
1405            _this.isMouseDown &&
1406            event.movementX != 0 &&
1407            event.movementY != 0
1408          ) {
1409            _this.isMouseMoving = true;
1410          }
1411          if (
1412            event.touches !== void 0 &&
1413            event.touches.length == 2 &&
1414            _this.startTouches !== void 0
1415          ) {
1416            //return;
1417            // _this.startTouches = event.touches;
1418            _this.zoomDirty = true;
1419            var touchCenter = utils.getVectorAvg(
1420                utils.getTouches(event, _this.container.offset())
1421              ),
1422              newScale = utils.calculateScale(
1423                _this.startTouches,
1424                utils.getTouches(event)
1425              ),
1426              scale = newScale / _this.lastScale;
1427
1428            var zoom = _this.previewObject.contentProvider.zoomScale,
1429              x = touchCenter.x,
1430              y = touchCenter.y;
1431
1432            _this.camera.position.z = _this.originalZ / newScale;
1433            _this.lastScale = newScale;
1434
1435            _this.lastZoomCenter = touchCenter;
1436            event.preventDefault();
1437            return;
1438          }
1439          if (
1440            _this.isMouseDown == true &&
1441            _this.previewObject.contentProvider.zoomScale == 1
1442          ) {
1443            //check if swipe has happened
1444
1445            var swipe_dist = event.pageX - _this.lastPos,
1446              swipe_time = performance.now() - _this.lastTime;
1447
1448            //$("body > p").html(swipe_dist);
1449
1450            if (Math.abs(swipe_dist) > _this.swipe_threshold) {
1451              //swipe has triggered
1452              //_this.dragPage.pendingPoint = point;
1453              if (swipe_dist < 0) {
1454                _this.target.next();
1455              } else {
1456                _this.target.prev();
1457              }
1458              event.preventDefault();
1459              _this.isMouseDown = false;
1460            }
1461            _this.lastPos = event.pageX;
1462            _this.lastTime = performance.now();
1463          }
1464        };
1465
1466        var editor_mouseDown = function (event) {
1467          event = fixMouseEvent(event);
1468          if (
1469            event.touches !== void 0 &&
1470            event.touches.length == 2 &&
1471            _this.startTouches == void 0
1472          ) {
1473            _this.startTouches = utils.getTouches(event);
1474            _this.lastScale = 1;
1475            _this.originalZ = _this.camera.position.z * 1;
1476          }
1477          document.activeElement.blur();
1478          _this.mouseValue = event.pageX + "," + event.pageY;
1479          _this.isMouseMoving = false;
1480          _this.isMouseDown = true;
1481          _this.lastPos = event.pageX;
1482          _this.lastTime = performance.now();
1483        };
1484
1485        var editor_click = function (event) {
1486          _this.isMouseDown = false;
1487          //bail out if it's not left click
1488          if (event.button !== 0) return this;
1489          var mouseValue = event.pageX + "," + event.pageY;
1490
1491          if (_this.isMouseMoving) {
1492          } else if (mouseValue == _this.mouseValue) {
1493            event = event || window.event;
1494            event = $.event.fix(event);
1495
1496            var mouse = _this.mouse,
1497              raycaster = _this.raycaster;
1498            mouse.x = (event.offsetX / _this.canvas.innerWidth()) * 2 - 1;
1499            mouse.y = 1 - (event.offsetY / _this.canvas.innerHeight()) * 2;
1500
1501            raycaster.setFromCamera(mouse, _this.camera);
1502
1503            var intersects = raycaster.intersectObjects(
1504              _this.target instanceof MOCKUP.Bundle
1505                ? _this.target.children
1506                : [_this.target],
1507              true
1508            );
1509
1510            if (intersects.length > 0) {
1511              var object,
1512                objectCount = 0;
1513              do {
1514                object =
1515                  intersects[objectCount] !== void 0
1516                    ? intersects[objectCount].object
1517                    : void 0;
1518                //bookStage.clickFace = intersects[objectCount].face;
1519                objectCount++;
1520              } while (
1521                (object instanceof THREE.BoxHelper ||
1522                  !(object instanceof MOCKUP.Paper) ||
1523                  object.isFlipping == true) &&
1524                objectCount < intersects.length
1525              );
1526
1527              //if (object.parent instanceof  MOCKUP.Bundle) {
1528              //    object = object.parent;
1529              //}
1530
1531              if (object.userData.object !== void 0) {
1532                // helper
1533                //bookStage.selectObject(object.userData.object);
1534              } else {
1535                if (object.angles[1] > 90) {
1536                  if (object.isEdge != true) _this.target.next();
1537                } else {
1538                  if (object.isEdge != true) _this.target.prev();
1539                }
1540              }
1541            } else {
1542              //bookStage.selectObject(null);
1543            }
1544          }
1545          //bookStage.stage.render();
1546        };
1547
1548        var editor_mouseUp = function (event) {
1549          event = fixMouseEvent(event);
1550          if (event.touches !== void 0 && event.touches.length == 0) {
1551            var zoom = _this.previewObject.contentProvider.zoomScale;
1552            if (_this.zoomDirty == true) {
1553              _this.previewObject.contentProvider.zoomScale = utils.limitAt(
1554                _this.previewObject.contentProvider.zoomScale * _this.lastScale,
1555                1,
1556                _this.previewObject.contentProvider.maxZoom
1557              );
1558              _this.previewObject.zoomValue =
1559                _this.previewObject.contentProvider.zoomScale * 1;
1560              //_this.previewObject.zoom(_this.lastScale < 1 ? -1 : 1);
1561              //console.log(_this.previewObject.contentProvider.zoomScale * _this.lastScale,_this.previewObject.contentProvider.maxZoom)
1562              //_this.previewObject.pendingZoom = true;
1563              _this.previewObject.resize();
1564              _this.zoomDirty = false;
1565            }
1566
1567            _this.lastScale = void 0;
1568            _this.startTouches = void 0;
1569          }
1570          if (event.touches !== void 0 && event.touches.length > 1) return;
1571          editor_click(event);
1572        };
1573        //if (MOCKUP.mode !== MOCKUP.MODE.PLUGIN) {
1574
1575        //_this.renderer.domElement.addEventListener('click', editor_click, false);
1576        //bookStage.renderer.domElement.addEventListener('dblclick', editor_dblclick, false);
1577        _this.renderer.domElement.addEventListener(
1578          "mousemove",
1579          editor_mouseMove,
1580          false
1581        );
1582        _this.renderer.domElement.addEventListener(
1583          "touchmove",
1584          editor_mouseMove,
1585          false
1586        );
1587
1588        _this.renderer.domElement.addEventListener(
1589          "mousedown",
1590          editor_mouseDown,
1591          false
1592        );
1593        _this.renderer.domElement.addEventListener(
1594          "touchstart",
1595          editor_mouseDown,
1596          false
1597        );
1598        _this.renderer.domElement.addEventListener(
1599          "mouseup",
1600          editor_mouseUp,
1601          false
1602        );
1603        _this.renderer.domElement.addEventListener(
1604          "touchend",
1605          editor_mouseUp,
1606          false
1607        );
1608        if (_this.options.scrollWheel == true) {
1609          _this.renderer.domElement.addEventListener(
1610            "mousewheel",
1611            onMouseWheel,
1612            false
1613          );
1614          _this.renderer.domElement.addEventListener(
1615            "DOMMouseScroll",
1616            onMouseWheel,
1617            false
1618          ); // firefox
1619        }
1620
1621        //}
1622
1623        $(_this.renderer.domElement).css({ display: "block" });
1624
1625        $(window).trigger("resize");
1626
1627        return this;
1628      }
1629
1630      PreviewStage.prototype.width = function () {
1631        return this.container.width();
1632      };
1633
1634      PreviewStage.prototype.height = function () {
1635        return this.container.height();
1636      };
1637
1638      return PreviewStage;
1639    })(MOCKUP.Stage);
1640    MOCKUP.PreviewStage = PreviewStage;
1641
1642    var BookPaper = (function (_super) {
1643      __extends(BookPaper, _super);
1644      function BookPaper(parameters, stage) {
1645        parameters = parameters || {};
1646        parameters.folds = 1;
1647        _super.call(this, parameters, stage);
1648        this.angle = 0;
1649        this.isFlipping = false;
1650        this.material.materials[5].transparent = true;
1651        this.material.materials[4].transparent = true;
1652        this.type = "BookPaper";
1653      }
1654
1655      BookPaper.prototype.tween = function (oldAngle, newAngle) {
1656        var page = this;
1657        var epsilon = 0.00001;
1658        page.originalStiff = page.stiffness;
1659        var oldTarget = page.newStiffness;
1660        var isBooklet = isBookletMode(page.parent);
1661        //console.log(page.stiffness);
1662        var diff = newAngle - oldAngle; //170 -5 == 165 :  5-170 = -165
1663
1664        var isRight = oldAngle > 90;
1665        var isRTL = page.parent.direction == DFLIP.DIRECTION.RTL;
1666        page.init = {
1667          angle: oldAngle,
1668          angle2: oldAngle < 90 ? 0 : 180,
1669          stiff: page.originalStiff,
1670          index: (isRight && !isRTL) || (!isRight && isRTL) ? 1 : 0,
1671        };
1672        page.first = {
1673          angle: oldAngle + diff / 4,
1674          angle2: oldAngle < 90 ? 90 : 90,
1675          stiff: page.originalStiff,
1676          index: (isRight && !isRTL) || (!isRight && isRTL) ? 1 : 0.25,
1677        };
1678        page.mid = {
1679          angle: oldAngle + (diff * 2) / 4,
1680          angle2: oldAngle < 90 ? 135 : 45,
1681          stiff: page.newStiffness,
1682          index: (isRight && !isRTL) || (!isRight && isRTL) ? 0.5 : 0.5,
1683        };
1684        page.mid2 = {
1685          angle: oldAngle + (diff * 3) / 4,
1686          angle2: oldAngle < 90 ? 180 : 0,
1687          stiff: page.newStiffness,
1688          index: (isRight && !isRTL) || (!isRight && isRTL) ? 0.25 : 1,
1689        };
1690        page.end = {
1691          angle: newAngle,
1692          angle2: oldAngle < 90 ? 180 : 0,
1693          stiff: page.newStiffness,
1694          index: (isRight && !isRTL) || (!isRight && isRTL) ? 0 : 1,
1695        };
1696
1697        //console.log(page.init, page.first, page.mid, page.end);
1698        page.isFlipping = true;
1699
1700        var update = function (tween, event) {
1701          page.angles[1] = tween.angle;
1702          page.angles[4] = page.isHard ? tween.angle : tween.angle2;
1703          if (page.isHard == true) {
1704            page.stiffness = 0;
1705          } else {
1706            page.stiffness =
1707              (tween.stiff / (oldTarget + epsilon)) *
1708              (page.newStiffness + epsilon);
1709            page.stiffness = isNaN(page.stiffness) ? 0 : tween.stiff;
1710          }
1711          if (isBooklet) {
1712            page.material.materials[5].opacity =
1713              page.material.materials[4].opacity = tween.index;
1714            page.castShadow =
1715              (isRight && !isRTL) || (!isRight && isRTL)
1716                ? tween.index > 0.5
1717                : tween.index > 0.5;
1718          }
1719          //check if any sibling is flipping and their stiff is more that this
1720
1721          page.updateAngle(true);
1722        };
1723
1724        if (isBooklet && ((!isRight && !isRTL) || (isRight && isRTL))) {
1725          page.material.materials[5].opacity =
1726            page.material.materials[4].opacity = 0;
1727          page.castShadow = false;
1728        }
1729
1730        new TWEEN.Tween(page.init)
1731          .to(
1732            {
1733              angle: [
1734                page.first.angle,
1735                page.mid.angle,
1736                page.mid2.angle,
1737                page.end.angle,
1738              ],
1739              angle2: [
1740                page.first.angle2,
1741                page.mid.angle2,
1742                page.mid2.angle2,
1743                page.end.angle2,
1744              ],
1745              stiff: [
1746                page.first.stiff,
1747                page.mid.stiff,
1748                page.mid2.stiff,
1749                page.end.stiff,
1750              ],
1751              index: [
1752                page.first.index,
1753                page.mid.index,
1754                page.mid2.index,
1755                page.end.index,
1756              ],
1757            },
1758            page.parent.duration
1759          )
1760          .onUpdate(function (event) {
1761            update(this, event);
1762          })
1763          .easing(TWEEN.Easing.Sinusoidal.Out)
1764          .onComplete(function (event) {
1765            page.stiffness = page.newStiffness;
1766            page.updateAngle();
1767            page.material.materials[5].opacity =
1768              page.material.materials[4].opacity = 1;
1769            page.castShadow = true;
1770            page.isFlipping = false;
1771            if (page.parent && page.parent.refresh) page.parent.refresh();
1772            //console.log(page.stiffness);
1773          })
1774          .start();
1775      };
1776
1777      return BookPaper;
1778    })(MOCKUP.FlexBoxPaper);
1779    MOCKUP.BookPaper = BookPaper;
1780
1781    var Book = (function (_super) {
1782      __extends(Book, _super);
1783
1784      function Book(parameters, stage) {
1785        parameters = parameters || {};
1786        parameters.segments = parameters.segments || 50;
1787        this.pageCount = parameters.pageCount;
1788
1789        this.height = parameters.height;
1790        this.width = parameters.width;
1791
1792        //correcting page count as multiple of 2
1793        this.pageCount =
1794          this.pageCount == 1
1795            ? this.pageCount
1796            : Math.ceil(this.pageCount / 2) * 2;
1797
1798        this.direction = parameters.direction || DFLIP.DIRECTION.LTR;
1799
1800        this.startPage = 1;
1801        this.endPage = this.pageCount;
1802
1803        this.stackCount = parameters.stackCount || 6; // = 15;
1804        this.materials = [];
1805
1806        _super.call(this, parameters, stage);
1807        this.angles = [0, 0, 0, 0, 0, 0];
1808        this.stiffness = parameters.stiffness || 1.5;
1809        this.hardConfig = "none"; //parameters.hard; hard is not that good in 3d
1810        this._activePage = parameters.openPage || this.startPage;
1811
1812        this.createStack(parameters);
1813        this.pageMode =
1814          parameters.pageMode ||
1815          (isMobile || this.pageCount <= 2
1816            ? DFLIP.PAGE_MODE.SINGLE
1817            : DFLIP.PAGE_MODE.DOUBLE);
1818
1819        this.singlePageMode =
1820          parameters.singlePageMode ||
1821          (isMobile
1822            ? DFLIP.SINGLE_PAGE_MODE.BOOKLET
1823            : DFLIP.SINGLE_PAGE_MODE.ZOOM);
1824
1825        this.type = "Book";
1826      }
1827
1828      Book.prototype.getPageByNumber = function (pageNumber) {
1829        var relativePageNumber = isBookletMode(this)
1830          ? isRTLMode(this)
1831            ? pageNumber + 1
1832            : pageNumber
1833          : Math.floor((pageNumber - 1) / 2);
1834        return this.getObjectByName(relativePageNumber.toString());
1835      };
1836
1837      Book.prototype.isPageHard = function (pageNumber) {
1838        return utils.isHardPage(this.hardConfig, pageNumber, this.pageCount);
1839      };
1840
1841      Book.prototype.activePage = function (pageNumber) {
1842        if (pageNumber == void 0) return this._activePage;
1843        this.gotoPage(pageNumber);
1844      };
1845
1846      Book.prototype.gotoPage = function (pageNumber) {
1847        pageNumber = parseInt(pageNumber, 10);
1848        this._activePage = pageNumber;
1849        this.updatePage(pageNumber);
1850      };
1851
1852      Book.prototype.moveBy = function (step) {
1853        var nextPage = this._activePage + step;
1854        nextPage = limitAt(nextPage, this.startPage, this.endPage);
1855
1856        this.gotoPage(nextPage);
1857      };
1858
1859      Book.prototype.next = function (step) {
1860        if (step == void 0)
1861          step =
1862            this.direction == DFLIP.DIRECTION.RTL
1863              ? -this.pageMode
1864              : this.pageMode;
1865
1866        this.moveBy(step);
1867      };
1868
1869      Book.prototype.prev = function (step) {
1870        if (step == void 0)
1871          step =
1872            this.direction == DFLIP.DIRECTION.RTL
1873              ? this.pageMode
1874              : -this.pageMode;
1875
1876        this.moveBy(step);
1877      };
1878
1879      Book.prototype.updateAngle = function () {
1880        var startAngle = this.angles[1];
1881        var endAngle = this.angles[4];
1882
1883        var spreadAngle = endAngle - startAngle;
1884        var stacks = this.stackCount;
1885
1886        for (var _stackCount = 0; _stackCount < stacks; _stackCount++) {
1887          var clone = this.children[_stackCount];
1888          //start from angle[1] and end at angles[4]
1889          clone.angles[1] =
1890            startAngle + (_stackCount * spreadAngle) / (stacks * 100);
1891          clone.stiffness = this.stiffness; //_stackCount/stacks;
1892          clone.updateAngle();
1893        }
1894      };
1895
1896      Book.prototype.refresh = function () {
1897        this.updatePage(this._activePage);
1898        if (this.flipCallback !== void 0) this.flipCallback();
1899      };
1900
1901      Book.prototype.updatePage = function (pageNumber) {
1902        // this.contentProvider.setLoading(pageNumber, true);
1903        var isRTL = this.direction == DFLIP.DIRECTION.RTL,
1904          isBooklet = isBookletMode(this),
1905          newBaseNumber = getBasePage(pageNumber);
1906
1907        var pageDivisor = isBooklet ? 1 : 2;
1908
1909        pageNumber = Math.floor(pageNumber / pageDivisor);
1910
1911        if (isRTL) pageNumber = this.pageCount / pageDivisor - pageNumber;
1912
1913        var oldBaseNumber = this.oldBaseNumber || 0;
1914        var pageCount = this.pageCount / pageDivisor;
1915        var stackCount = this.stackCount;
1916        var angleShift = 0.02;
1917        var depth = 0.4;
1918        var stiffFactor = isBooklet
1919          ? 0
1920          : (0.5 - Math.abs(pageCount / 2 - pageNumber) / pageCount) /
1921            this.stiffness;
1922        var positionFactor = 1; //(stiffFactor +width);
1923        // var centre = Math.floor(stackCount / 2);
1924        var midPoint = Math.floor(stackCount / 2); //pageNumber < centre ? pageNumber //starting center pages
1925        // : ((pageCount - pageNumber > centre) ? centre //other pages
1926        //: (pageNumber + centre - pageCount)) ;//remainig center page
1927        //console.log(midPoint);
1928
1929        //var targetIndex = midPoint;
1930        //if(midPoint == centre) {
1931        /*This sitaution is good when there is icrement or decrement by 1*/
1932        var isLeft = false;
1933        if (oldBaseNumber > pageNumber) {
1934          isLeft = true;
1935          this.children[stackCount - 1].skipFlip = true;
1936          this.children.unshift(this.children.pop());
1937
1938          // this.contentProvider.setLoading(pageNumber, true);
1939        } else if (oldBaseNumber < pageNumber) {
1940          this.children[0].skipFlip = true;
1941          this.children.push(this.children.shift());
1942
1943          // this.contentProvider.setLoading(pageNumber, true);
1944        } else {
1945          //midPoint = centre;
1946        }
1947        if (Math.abs(oldBaseNumber - pageNumber) > 1) {
1948        }
1949        //}
1950        var remainingPages = pageCount - pageNumber;
1951        var stackDepth = 5 / pageCount;
1952        var leftDepth = (stackDepth * pageNumber) / 2;
1953        var rightDepth = (stackDepth * remainingPages) / 2;
1954        var maxDepth = leftDepth < rightDepth ? rightDepth : leftDepth;
1955        //maxDepth = maxDepth > 5 ? 5: maxDepth;
1956        for (var _pageCount = 0; _pageCount < stackCount; _pageCount++) {
1957          var page = this.children[_pageCount]; //this.getObjectByName("page"+_pageCount);//this.children[_pageCount];
1958
1959          var color = page.color;
1960          var oldAngle = page.angles[1];
1961          var newAngle;
1962          var relativePageNumber = pageNumber - midPoint + _pageCount;
1963
1964          var isHard = (page.isHard = this.isPageHard(relativePageNumber));
1965          var oldName = page.name;
1966
1967          //Sizing
1968          page.isEdge = false; //true;
1969          if (_pageCount == 0) {
1970            page.depth = leftDepth < depth ? depth : leftDepth;
1971          } else if (_pageCount == stackCount - 1) {
1972            page.depth = rightDepth < depth ? depth : rightDepth;
1973          } else {
1974            page.depth = depth;
1975            page.isEdge = false;
1976          }
1977          if (page.isFlipping == true) {
1978            page.depth = depth;
1979          }
1980          page.position.x = 0;
1981
1982          var leftAngle = angleShift * _pageCount,
1983            rightAngle =
1984              180 -
1985              angleShift * (_pageCount - midPoint) +
1986              angleShift * _pageCount;
1987
1988          if (_pageCount < midPoint) {
1989            page.newStiffness = isHard
1990              ? 0
1991              : stiffFactor / (pageNumber / pageCount) / 4;
1992            newAngle = leftAngle;
1993            page.position.z = maxDepth - (-_pageCount + midPoint) * depth; //(pageNumber < pageCount / 2)
1994            if (isLeft == true) page.position.z -= depth;
1995          } else {
1996            newAngle = rightAngle;
1997            page.newStiffness = isHard
1998              ? 0
1999              : stiffFactor /
2000                (Math.abs(pageCount - pageNumber) / pageCount) /
2001                4;
2002            page.position.z =
2003              maxDepth -
2004              (-stackCount + _pageCount + midPoint + 1) * depth -
2005              page.depth; //(pageNumber < pageCount / 2)
2006          }
2007
2008          if (page.isFlipping == false) {
2009            if (Math.abs(oldAngle - newAngle) > 20 && page.skipFlip == false) {
2010              page.depth = depth;
2011              //we need predicted stiffness so that there is no overlap issues
2012              var predicted = page.stiffness;
2013
2014              if (oldAngle > newAngle) {
2015                //left
2016                predicted =
2017                  stiffFactor /
2018                  (Math.abs(pageCount - pageNumber) / pageCount) /
2019                  4;
2020              } else {
2021                //right
2022                predicted = stiffFactor / (pageNumber / pageCount) / 4;
2023              }
2024              page.position.z += depth; //((_pageCount < midPoint) ? 0 : depth) * 2;/// 2;
2025
2026              page.stiffness = isNaN(predicted) ? page.stiffness : predicted;
2027              page.updateAngle(true);
2028              page.targetStiffness =
2029                _pageCount < pageNumber
2030                  ? stiffFactor /
2031                    (Math.abs(pageCount - pageNumber) / pageCount) /
2032                    4
2033                  : stiffFactor / (pageNumber / pageCount) / 4;
2034
2035              page.targetStiffness = isNaN(page.targetStiffness)
2036                ? page.stiffness
2037                : page.targetStiffness;
2038
2039              page.isFlipping = true;
2040
2041              page.tween(oldAngle, newAngle);
2042
2043              if (this.preFlipCallback !== void 0) this.preFlipCallback();
2044            } else {
2045              page.skipFlip = false;
2046              page.newStiffness = isNaN(page.newStiffness)
2047                ? 0
2048                : page.newStiffness;
2049              if (
2050                page.angles[1] != newAngle ||
2051                page.stiffness != page.newStiffness ||
2052                page.depth != page.oldDepth
2053              ) {
2054                page.angles[1] = page.angles[4] = newAngle;
2055                page.stiffness = page.newStiffness;
2056                page.updateAngle(true);
2057              } else {
2058                //console.log("skipped");
2059              }
2060            }
2061          }
2062
2063          page.visible = isBooklet
2064            ? isRTL
2065              ? _pageCount < midPoint || page.isFlipping
2066              : _pageCount >= midPoint || page.isFlipping
2067            : (relativePageNumber >= 0 && relativePageNumber < pageCount) ||
2068              (isBooklet && relativePageNumber == pageCount);
2069
2070          if (this.requestPage !== void 0 && page.visible == true) {
2071            if (isRTL)
2072              relativePageNumber = isBooklet
2073                ? this.pageCount - relativePageNumber
2074                : Math.floor(this.pageCount / 2) - relativePageNumber - 1;
2075
2076            page.name = relativePageNumber.toString();
2077            if (page.name != oldName) {
2078              page.textureLoaded = false;
2079
2080              page.frontImage(defaults.textureLoadFallback);
2081              page.frontPageStamp = "-1";
2082              page.frontTextureLoaded = false;
2083              page.thumbLoaded = false;
2084
2085              // if (!isBooklet) {
2086              page.backImage(defaults.textureLoadFallback);
2087              page.backPageStamp = "-1";
2088              page.backTextureLoaded = false;
2089              // }
2090              this.requestPage();
2091            }
2092          }
2093
2094          //if (isBooklet && _pageCount < midPoint && page.isFlipping == false)
2095          //	page.visible = false;
2096
2097          page.oldDepth = page.depth;
2098          var xPos =
2099            Math.abs(page.geometry.boundingBox.max.x) <
2100            Math.abs(page.geometry.boundingBox.min.x)
2101              ? page.geometry.boundingBox.max.x
2102              : page.geometry.boundingBox.min.x;
2103          page.position.x =
2104            page.isEdge == true && page.isFlipping == false
2105              ? _pageCount < midPoint
2106                ? xPos
2107                : -xPos
2108              : 0;
2109        }
2110        //$(".quick-hint").html(pageNumber);
2111        //console.log("leftDepth:" + leftDepth, "rightDepth:" + rightDepth, "midPoint:" + midPoint, "oldBaseNumber:" + oldBaseNumber, "pageNumber:" + pageNumber);
2112        this.oldBaseNumber = pageNumber;
2113
2114        if (this.updatePageCallback !== void 0) this.updatePageCallback();
2115      };
2116      //if (window.flipBook != void 0)flipBook.book.refresh();
2117      //book.activePage(book.activePage());
2118      Book.prototype.createCover = function (parameters) {
2119        parameters.width = parameters.width * 2;
2120        this.cover = new MOCKUP.BiFold(parameters);
2121        this.add(this.cover);
2122      };
2123
2124      Book.prototype.createStack = function (parameters) {
2125        var colors = "red,green,blue,yellow,orange,black".split(",");
2126
2127        for (
2128          var _stackCount = 0;
2129          _stackCount < this.stackCount;
2130          _stackCount++
2131        ) {
2132          parameters.angles = [, this.stackCount - _stackCount]; //[1] = (this.stackCount - _stackCount);
2133          parameters.stiffness = (this.stackCount - _stackCount) / 100;
2134
2135          var clone = new MOCKUP.BookPaper(parameters);
2136          clone.angles[1] = 180;
2137          //clone.name = "page" + _stackCount;
2138          clone.index = _stackCount;
2139          clone.updateAngle();
2140          clone.textureReady = false;
2141          clone.textureRequested = false;
2142          this.add(clone);
2143          clone.color = colors[_stackCount];
2144          //for (var _count = 0; _count < 4; _count++) {
2145          //    clone.material.materials[_count].color = new THREE.Color(THREE.ColorKeywords[colors[_stackCount]]);
2146          //}
2147          clone.position.z = -1 * _stackCount; // * (this.mainObject.depth * 1.05);
2148        }
2149      };
2150
2151      Book.prototype.shininess = function (shininess) {
2152        if (shininess == void 0) {
2153          return this.mainObject.shininess();
2154        } else {
2155          this.mainObject.shininess(shininess);
2156        }
2157      };
2158
2159      Book.prototype.bumpScale = function (bumpScale) {
2160        if (bumpScale == void 0) {
2161          return this.mainObject.bumpScale();
2162        } else {
2163          this.mainObject.bumpScale(bumpScale);
2164        }
2165      };
2166
2167      Book.prototype.frontImage = function (frontImage) {
2168        if (frontImage == void 0) {
2169          return this.mainObject.frontImage();
2170        } else {
2171          this.mainObject.frontImage(frontImage);
2172        }
2173      };
2174
2175      Book.prototype.backImage = function (backImage) {
2176        if (backImage == void 0) {
2177          return this.mainObject.backImage();
2178        } else {
2179          this.mainObject.backImage(backImage);
2180        }
2181      };
2182
2183      return Book;
2184    })(MOCKUP.Bundle);
2185    MOCKUP.Book = Book;
2186  }
2187
2188  //base object of flipbook or other trifold objects
2189  var PreviewObject = (function (_super) {
2190    function PreviewObject(parameters) {
2191      parameters = parameters || {};
2192      //_super.call(this, parameters);
2193      this.type = "PreviewObject";
2194      var _this = this;
2195
2196      _this.zoomValue = 1;
2197      function resizeDelay() {
2198        setTimeout(function () {
2199          _this.resize();
2200        }, 50);
2201      }
2202
2203      window.addEventListener("resize", resizeDelay, false);
2204
2205      this.sound = document.createElement("audio");
2206      this.sound.setAttribute(
2207        "src",
2208        parameters.soundFile + "?ver=" + DFLIP.version
2209      );
2210      this.sound.setAttribute("type", "audio/mpeg");
2211
2212      //this.pageMode = DFLIP.PAGE_MODE.DOUBLE;
2213      this.dispose = function () {
2214        if (this.container && this.container.info && this.container.info.remove)
2215          this.container.info.remove();
2216
2217        if (this.target && this.target.dispose) this.target.dispose();
2218        this.target = null;
2219
2220        if (this.stage && this.stage.dispose) this.stage.dispose();
2221        this.stage = null;
2222
2223        //if (this.target && this.target.outlineContainer) this.target.outlineContainer.remove();
2224        if (this.ui && this.ui.dispose) this.ui.dispose();
2225        this.ui = null;
2226
2227        if (this.contentProvider && this.contentProvider.dispose)
2228          this.contentProvider.dispose();
2229        this.contentProvider = null;
2230
2231        window.removeEventListener("resize", resizeDelay);
2232      };
2233    }
2234
2235    PreviewObject.prototype = {
2236      start: function () {
2237        this.target.gotoPage(this.target.startPage);
2238      },
2239
2240      end: function () {
2241        this.target.gotoPage(this.target.endPage);
2242      },
2243
2244      next: function () {},
2245
2246      prev: function () {},
2247
2248      zoom: function (delta) {
2249        this.pendingZoom = true;
2250        this.zoomDelta = delta;
2251        /*
2252				 var contentProvider = this.contentProvider;
2253
2254				 contentProvider.zoomScale += delta;
2255
2256				 contentProvider.zoomScale = limitAt(contentProvider.zoomScale,1,contentProvider.maxZoom);//(delta == true) ? 2 : 1;
2257
2258				 //contentProvider.checkViewportSize();
2259				 //contentProvider.zoomScale = (zoom == true) ? contentProvider.normalViewport.height * contentProvider.viewport.scale / contentProvider.viewport.height : 1;
2260				 if (this.stage !== void 0) {
2261				 //this.stage.pendingZoom = true;//not used anymore
2262				 //this.stage.resize();
2263				 //var cameraZ =  this.stage.camera.position.z;
2264				 //this.stage.camera.position.set(0, 0, zoom == true ? 300 : 600);
2265
2266				 }
2267				 else {
2268
2269				 //this.target.wrapper.css({
2270				 //    transform: "scale(" + 1*/
2271        /*contentProvider.zoomScale*/
2272        /* + ")"
2273				 //});
2274				 this.target.left = 0;
2275				 this.target.top = 0;
2276				 }*/
2277        /*				if (contentProvider.zoomScale != 1) {
2278				 this.target.container.addClass("df-zoom-enabled");
2279				 }
2280				 else {
2281				 this.target.container.removeClass("df-zoom-enabled");
2282				 }*/
2283        this.resize();
2284        this.ui.update();
2285      },
2286
2287      resize: function () {
2288        var _this = this;
2289
2290        if (
2291          _this.target == void 0 ||
2292          _this.target.ui == void 0 ||
2293          _this.target.contentProvider == void 0 ||
2294          _this.target.contentProvider.viewport == void 0 ||
2295          _this.target.stage == void 0
2296        )
2297          return;
2298
2299        var isSingle = this.target.pageMode == DFLIP.PAGE_MODE.SINGLE,
2300          isFloating = _this.container.hasClass("df-floating");
2301        var target = _this.target,
2302          stage = target.stage,
2303          contentProvider = target.contentProvider,
2304          pageRatio = contentProvider.pageRatio,
2305          zoomViewport = contentProvider.zoomViewport,
2306          is3d = target.mode !== "css";
2307
2308        var parentWidth,
2309          parentHeight,
2310          windowHeight = $(window).height();
2311
2312        //checking if the container height is more than the window height
2313
2314        if (
2315          this.ui &&
2316          this.ui.isFullscreen == true &&
2317          utils.hasFullscreenEnabled() == true &&
2318          utils.getFullscreenElement() == void 0
2319        ) {
2320          this.ui.switchFullscreen();
2321        }
2322        var containerHeight = this.options.height; //target.ui.isFullscreen == true ? windowHeight : this.options.height;
2323
2324        _this.container.height(containerHeight);
2325
2326        if (Math.min(_this.container.height(), windowHeight) == windowHeight)
2327          containerHeight = windowHeight;
2328
2329        _this.container.height(containerHeight);
2330
2331        containerHeight = _this.container.height(); //fixing if the options are set on percentage
2332
2333        if (!is3d) {
2334          stage.css({
2335            top: 0,
2336            bottom: 0,
2337            right: 0,
2338            left: 0,
2339            transform:
2340              "translate3d(" +
2341              _this.target.left +
2342              "px," +
2343              _this.target.top +
2344              "px,0)",
2345          });
2346          target.stageHeight = stage.height();
2347        }
2348        parentWidth = stage.width();
2349        parentHeight = stage.height();
2350
2351        var availableWidth = parentWidth - (is3d ? 100 : 0),
2352          availableHeight = Math.min(
2353            parentHeight - (is3d ? 100 : 0),
2354            windowHeight
2355          ),
2356          possibleWidth = Math.floor(
2357            isSingle ? availableWidth : availableWidth / 2
2358          );
2359
2360        var requiredHeight = Math.floor(possibleWidth / pageRatio);
2361        var height, width, cameraZ, fov, zoom;
2362
2363        height = Math.min(requiredHeight, availableHeight);
2364
2365        width = Math.floor(height * pageRatio);
2366
2367        contentProvider.maxZoom = contentProvider.zoomViewport.height / height;
2368
2369        /*
2370				 if (_this.pendingZoom == true && _this.zoomDelta !== void 0) {
2371
2372				 _this.pendingZoom = false;
2373				 var delta = _this.zoomDelta, predictedIndex, currentMaxDimension = Math.max(height, width);
2374
2375				 var improperZoom = contentProvider.zoomScale == 1;
2376
2377				 var currentZoomScale = limitAt(improperZoom ? contentProvider.zoomScale
2378				 : contentProvider.zoomScale + delta, 1, contentProvider.maxZoom);
2379
2380				 */
2381        /*					if (delta > 0) {
2382				 predictedIndex = nearestPowerOfTwo(currentMaxDimension * currentZoomScale);
2383				 } else {
2384				 predictedIndex = utils.lowerPowerOfTwo(currentMaxDimension * currentZoomScale);
2385				 }*/
2386        /*
2387
2388				 predictedIndex = utils.zoomStops(currentMaxDimension * currentZoomScale,1.5,delta>0);
2389				 contentProvider.zoomScale += delta;
2390				 contentProvider.zoomScale = limitAt(predictedIndex / currentMaxDimension, 1, contentProvider.maxZoom);
2391				 //contentProvider.zoomScale = limitAt(delta > 0 ? _this.options.zoomRatio * contentProvider.zoomScale
2392				 //	: contentProvider.zoomScale / _this.options.zoomRatio, 1, contentProvider.maxZoom);
2393
2394				 _this.zoomDelta = void 0;
2395
2396				 }
2397				 */
2398        if (_this.zoomValue == void 0) _this.zoomValue = 1;
2399
2400        if (_this.pendingZoom == true && _this.zoomDelta !== void 0) {
2401          var delta = _this.zoomDelta,
2402            predictedIndex,
2403            currentMaxDimension = Math.max(height, width);
2404
2405          _this.zoomValue =
2406            _this.zoomDelta > 0
2407              ? _this.zoomValue * _this.options.zoomRatio
2408              : _this.zoomValue / _this.options.zoomRatio;
2409          _this.zoomValue = limitAt(
2410            _this.zoomValue,
2411            1,
2412            contentProvider.maxZoom
2413          );
2414
2415          if (_this.zoomValue == 1) {
2416            contentProvider.zoomScale = 1;
2417          } else {
2418            predictedIndex = height * _this.zoomValue;
2419            predictedIndex = utils.zoomStops(
2420              predictedIndex,
2421              _this.options.zoomRatio
2422            );
2423            contentProvider.zoomScale = limitAt(
2424              predictedIndex / currentMaxDimension,
2425              1,
2426              contentProvider.maxZoom
2427            );
2428          }
2429        }
2430
2431        zoom =
2432          contentProvider.zoomScale == 1 || contentProvider.zoomScale == void 0
2433            ? 1
2434            : contentProvider.zoomScale; //zoomViewport.height / parentHeight,//target.contentProvider.zoomScale,
2435
2436        //findout which cacheIndex to use
2437        contentProvider.checkViewportSize(width, height, zoom);
2438
2439        if (_this.contentSourceType == SOURCE_TYPE.PDF) {
2440          //recalculation is required for pixel shift issue only if the source is PDF
2441          width = contentProvider.viewport.width / zoom;
2442          height = contentProvider.viewport.height / zoom;
2443        }
2444
2445        if (contentProvider.zoomScale != 1) {
2446          this.target.container.addClass("df-zoom-enabled");
2447        }
2448
2449        //if(contentProvider.zoomScale != 1)
2450        //zoom = contentProvider.cacheIndex / height;
2451
2452        //rather than responsive lets use
2453        var containerWidth = _this.container.width();
2454        if (containerWidth < 400) {
2455          _this.container.addClass("df-xs");
2456        } else {
2457          _this.container.removeClass("df-xs");
2458        }
2459
2460        var maxZoom = contentProvider.maxZoom;
2461
2462        if (is3d) {
2463          //stage.resize();
2464          //_this.container.height(height);
2465
2466          //height = containerHeight;
2467          var controlsHeight = _this.container.find(".df-ui-controls").height();
2468          if (controlsHeight == null || isFloating) controlsHeight = 0;
2469          stage.canvas.height(containerHeight - controlsHeight);
2470          if (_this.container.hasClass("df-sidemenu-open")) {
2471            parentWidth = parentWidth - 220;
2472          }
2473          stage.resizeCanvas(parentWidth, containerHeight - controlsHeight);
2474
2475          //if (target !== void 0)
2476          //    target.height = height;
2477
2478          //target.contentProvider.checkViewportSize();
2479
2480          //height = 300;//flipBook.target.height;
2481          //var contentHeight = target.contentProvider.viewport.height * target.contentProvider.viewport.scale;
2482          //zoom = zoom ==1 ? zoom: zoom * zoom;
2483          //if (zoom == 1) {
2484          //    cameraZ = (height) * Math.tan(stage.camera.fov * 2 * Math.PI / 180);
2485          //}
2486          //else {
2487
2488          //var height = flipBook.options.height, visible = height ,zoom = (1600+ 1)/height
2489
2490          var imageHeight = height * zoom,
2491            imageWidth = width * zoom,
2492            pageHeight = target.height,
2493            expectedWidth = (parentWidth * pageHeight) / containerHeight,
2494            ppi = imageHeight / pageHeight, //realpixels per canvas pixel
2495            aspect = parentWidth / containerHeight;
2496
2497          var pageModeWidth = target.width * (isSingle ? 1 : 2);
2498
2499          var refWidth =
2500            expectedWidth < pageModeWidth
2501              ? pageModeWidth / aspect
2502              : target.height;
2503
2504          var padding = _this.options.minTopOffset + (isFloating ? 60 : 30);
2505
2506          var adjustment = containerHeight / (containerHeight - padding);
2507          /*
2508					 cameraZ = 1000,
2509					 fov = 2 * Math.atan((refLength) / (zoom / adjustment) / ( 2 * cameraZ )) * ( 180 / Math.PI );
2510
2511					 */
2512          //cameraZ = 1000,
2513          cameraZ =
2514            1 /
2515            ((2 * Math.tan((Math.PI * stage.camera.fov * 0.5) / 180)) /
2516              (refWidth / (zoom / adjustment)));
2517          //0.5* (zoom / adjustment) / (refLength) /  Math.tan((fov /2) * Math.PI /180) ;
2518
2519          //cameraZ = 1000/(zoom / adjustment);
2520          //stage.camera.fov = fov;
2521          stage.camera.updateProjectionMatrix();
2522
2523          //cameraZ = ((height + 60)*2 / zoom )* Math.tan(stage.camera.fov * Math.PI / 180);//(height /zoom) * Math.tan(stage.camera.fov * 2  * Math.PI / 180)/zoom;
2524          //}
2525
2526          stage.renderRequestPending = true;
2527          //if (stage.pendingZoom == true || zoom !== 1) {
2528          //stage.camera.position.z = cameraZ;
2529
2530          //pixel value to stage position value
2531
2532          var shift = padding / 2 - _this.options.minTopOffset;
2533
2534          //put a check if the existing gap is enough
2535          _this.target.position.y =
2536            (shift * pageHeight) / (_this.container.height() - padding);
2537          stage.cssScene.position.y = _this.target.position.y;
2538
2539          //stage.oldPositionZ = stage.camera.position.z;
2540
2541          /*					if (contentProvider.zoomScale == 1) {
2542					 stage.camera.position.set(0, 0, cameraZ);
2543					 stage.orbitControl.target = new THREE.Vector3(0, 0, 0);
2544					 //stage.orbitControl.panUp(shift);
2545					 }*/
2546          var _reset = contentProvider.zoomScale == 1;
2547          if (
2548            stage.camera.position.z !== cameraZ &&
2549            _this.pendingZoom == true
2550          ) {
2551            //avoid recreating the tween if the target is same as before
2552            if (_this.zoomTween !== void 0) _this.zoomTween.stop();
2553            _this.zoomTween = new TWEEN.Tween({
2554              campos: stage.camera.position.z,
2555              otx: stage.orbitControl.target.x,
2556              oty: stage.orbitControl.target.y,
2557              otz: stage.orbitControl.target.z,
2558            })
2559              .delay(0)
2560              .to(
2561                {
2562                  campos: cameraZ,
2563                  otx: 0,
2564                  oty: 0,
2565                  otz: 0,
2566                },
2567                100
2568              )
2569              .onUpdate(function () {
2570                stage.camera.position.z = this.campos;
2571                if (_reset) {
2572                  //console.log(this);
2573                  stage.orbitControl.target = new THREE.Vector3(
2574                    this.otx,
2575                    this.oty,
2576                    this.otz
2577                  );
2578                }
2579                //if(contentProvider.zoomScale == 1){
2580                //stage.camera.position.x = this.x;
2581                //stage.camera.position.y = this.y;
2582                //}
2583                stage.orbitControl.update();
2584              })
2585              .easing(TWEEN.Easing.Linear.None)
2586              .onComplete(function () {
2587                stage.camera.position.z = cameraZ;
2588                if (contentProvider.zoomScale == 1) {
2589                  stage.camera.position.set(0, 0, cameraZ);
2590                  stage.orbitControl.target = new THREE.Vector3(0, 0, 0);
2591                  //stage.orbitControl.panUp(shift);
2592                }
2593                stage.orbitControl.update();
2594              })
2595              .start();
2596            //stage.oldPositionZ = cameraZ;
2597          } else {
2598            if (contentProvider.zoomScale == 1) {
2599              stage.camera.position.set(0, 0, cameraZ);
2600              stage.orbitControl.target = new THREE.Vector3(0, 0, 0);
2601              //stage.orbitControl.panUp(shift);
2602            } else {
2603              stage.camera.position.z = cameraZ;
2604            }
2605            stage.orbitControl.update();
2606          }
2607
2608          stage.orbitControl.update();
2609          stage.orbitControl.mouseButtons.ORBIT =
2610            zoom != 1 ? -1 : THREE.MOUSE.RIGHT;
2611          stage.orbitControl.mouseButtons.PAN =
2612            zoom != 1 ? THREE.MOUSE.LEFT : -1;
2613          //}
2614
2615          //if(isMobile) stage.orbitControl.mouseButtons.PAN = -1;
2616        } else {
2617          if (target !== void 0) {
2618            //if (zoom > 1) {
2619            //	height = target.contentProvider.zoomViewport.height / zoom;//Math.min(requiredHeight, availableHeight);
2620            //	width = target.contentProvider.zoomViewport.width / zoom;
2621            //}
2622
2623            target.pageWidth = Math.round(width);
2624            target.fullWidth = target.pageWidth * 2;
2625            target.height = Math.round(height);
2626            var zoomWidth = (target.zoomWidth = Math.floor(width * zoom)),
2627              zoomHeight = (target.zoomHeight = Math.floor(height * zoom));
2628            //target.wrapper.width(target.fullWidth).height(height);
2629
2630            var stagePaddingW =
2631                target.stage.innerWidth() - target.stage.width(),
2632              stagePaddingH =
2633                target.stage.innerHeight() - target.stage.height();
2634
2635            var shiftHeight = (target.shiftHeight = Math.round(
2636                limitAt(
2637                  (zoomHeight - (containerHeight - stagePaddingH)) / 2,
2638                  0,
2639                  zoomHeight
2640                )
2641              )),
2642              shiftWidth = (target.shiftWidth = Math.round(
2643                limitAt(
2644                  zoom == 1
2645                    ? 1
2646                    : (zoomWidth * 2 -
2647                        target.container.width() +
2648                        stagePaddingW) /
2649                        2,
2650                  0,
2651                  target.fullWidth * zoom
2652                )
2653              ));
2654            if (zoom == 1) {
2655              target.left = 0;
2656              target.top = 0;
2657            }
2658            target.stage.css({
2659              top: -shiftHeight,
2660              bottom: -shiftHeight,
2661              right: -shiftWidth,
2662              left: -shiftWidth,
2663              transform:
2664                "translate3d(" + target.left + "px," + target.top + "px,0)",
2665            });
2666            //target.foldSense = this.pageWidth / 5;
2667
2668            var stageInnerHeight = target.stage.innerHeight();
2669            target.wrapper.css({
2670              width: zoomWidth * 2,
2671              height: zoomHeight,
2672              marginTop:
2673                containerHeight - zoomHeight - stagePaddingH > 0
2674                  ? (containerHeight - stagePaddingH - zoomHeight) / 2
2675                  : 0,
2676            });
2677
2678            var wrapperSize = Math.floor(distOrigin(width, height) * zoom);
2679
2680            target.stage
2681              .find(".df-page-wrapper")
2682              .width(wrapperSize)
2683              .height(wrapperSize);
2684
2685            target.stage
2686              .find(
2687                ".df-book-page, .df-page-front , .df-page-back, .df-page-fold-inner-shadow"
2688              )
2689              .height(zoomHeight)
2690              .width(zoomWidth);
2691
2692            //target.contentProvider.checkViewportSize();
2693            //log("resized");
2694
2695            //target.resize();
2696          }
2697        }
2698
2699        _this.checkCenter({ type: "resize" });
2700
2701        if (contentProvider.zoomScale == 1) {
2702          this.target.container.removeClass("df-zoom-enabled");
2703        }
2704
2705        if (target.thumblist) {
2706          target.thumblist.reset($(target.thumblist.container).height());
2707        }
2708
2709        /*				$(".quick-hint").html(JSON.stringify({
2710				 size: contentProvider.cacheIndex,
2711				 zoom: Math.round(contentProvider.zoomScale * 10) / 10,
2712				 height: height * zoom
2713				 }));*/
2714
2715        _this.pendingZoom = false;
2716      },
2717
2718      playSound: function () {
2719        try {
2720          if (this.options && this.options.soundEnable == true) {
2721            this.sound.currentTime = 0;
2722            this.sound.play();
2723          }
2724        } catch (error) {}
2725      },
2726
2727      setPageMode: function (isSingle) {
2728        if (isSingle == true) {
2729          this.ui.pageMode.addClass(this.options.icons["doublepage"]);
2730          this.ui.pageMode.html(
2731            "<span>" + this.options.text.doublePageMode + "</span>"
2732          );
2733          this.ui.pageMode.attr("title", this.options.text.doublePageMode);
2734          this.target.pageMode = DFLIP.PAGE_MODE.SINGLE;
2735        } else {
2736          this.ui.pageMode.removeClass(this.options.icons["doublepage"]);
2737          this.ui.pageMode.html(
2738            "<span>" + this.options.text.singlePageMode + "</span>"
2739          );
2740          this.ui.pageMode.attr("title", this.options.text.singlePageMode);
2741          this.target.pageMode = DFLIP.PAGE_MODE.DOUBLE;
2742        }
2743
2744        if (
2745          this.target &&
2746          this.target.singlePageMode == DFLIP.SINGLE_PAGE_MODE.BOOKLET
2747        ) {
2748          this.target.reset();
2749        }
2750
2751        this.resize();
2752      },
2753      height: function (height) {
2754        if (height == void 0) {
2755          return this.container.height();
2756        } else {
2757          this.options.height = height;
2758          this.container.height(height);
2759          this.resize();
2760        }
2761      },
2762      /**
2763       *checks whether the book is closed and needs to be centered
2764       */
2765      checkCenter: function (options) {
2766        options = options == void 0 ? {} : options;
2767        this.centerType = this.centerType || "start";
2768        var target = this.target;
2769        var singleShift = 0,
2770          left = 0,
2771          right = 0;
2772        var basePage = utils.getBasePage(target._activePage);
2773        var isEven = target._activePage % 2 == 0;
2774        var isRTL = target.direction == DFLIP.DIRECTION.RTL;
2775        var isSingle = target.pageMode == DFLIP.PAGE_MODE.SINGLE,
2776          isBooklet =
2777            isSingle && target.singlePageMode == DFLIP.SINGLE_PAGE_MODE.BOOKLET;
2778        var stageWidth = target.stage.width(),
2779          width;
2780
2781        if (target.mode == "css") {
2782          width = target.wrapper.width();
2783          //calculate the excess shift required for correction in case width is too small
2784          singleShift = Math.max((width - stageWidth) / 2, 0);
2785
2786          left = -width / 4;
2787          right = width / 4;
2788
2789          if (basePage == 0 || isBooklet) {
2790            target.wrapper.css({
2791              left: isSingle
2792                ? isRTL
2793                  ? right - singleShift
2794                  : left - singleShift
2795                : isRTL
2796                ? right
2797                : left,
2798            });
2799            target.shadow.css({
2800              width: "50%",
2801              left: isRTL ? 0 : "50%",
2802              transitionDelay: "",
2803            });
2804          } else if (basePage == target.pageCount) {
2805            target.wrapper.css({
2806              left: isSingle
2807                ? isRTL
2808                  ? left - singleShift
2809                  : right - singleShift
2810                : isRTL
2811                ? left
2812                : right,
2813            });
2814            target.shadow.css({
2815              width: "50%",
2816              left: isRTL ? "50%" : 0,
2817              transitionDelay: "",
2818            });
2819          } else {
2820            target.wrapper.css({
2821              left: isSingle
2822                ? isRTL
2823                  ? isEven
2824                    ? left - singleShift
2825                    : right - singleShift
2826                  : isEven
2827                  ? right - singleShift
2828                  : left - singleShift
2829                : 0,
2830            });
2831            target.shadow.css({
2832              width: "100%",
2833              left: 0,
2834              transitionDelay: parseInt(target.duration, 10) + 50 + "ms",
2835            });
2836          }
2837
2838          target.wrapper.css({
2839            transition: options.type == "resize" ? "none" : "",
2840          });
2841        } else if (target.stage !== void 0) {
2842          var init = target.position.x,
2843            end;
2844          singleShift = target.width / 4;
2845          width = target.width;
2846          left = -width / 2;
2847          right = width / 2;
2848
2849          if (basePage == 0 || isBooklet) {
2850            end = isRTL ? right : left;
2851          }
2851 else if (basePage == target.pageCount) {
2852            end = isRTL ? left : right;
2853          } else {
2854            end = isSingle
2855              ? isRTL
2856                ? isEven
2857                  ? left
2858                  : right
2859                : isEven
2860                ? right
2861                : left
2862              : 0;
2863          }
2864          //create a centertween
2865          if (end !== this.centerEnd) {
2866            //avoid recreating the tween if the target is same as before
2867            this.centerTween = new TWEEN.Tween({ x: init })
2868              .delay(0)
2869              .to({ x: end }, target.duration)
2870              .onUpdate(function () {
2871                target.position.x = this.x;
2872                target.stage.cssScene.position.x = this.x;
2873              })
2874              .easing(target.ease)
2875              .start();
2876            this.centerEnd = end;
2877          }
2878        }
2879        // log("checkcenter at : " + left);
2880      },
2881
2882      width: function (width) {
2883        if (width == void 0) {
2884          return this.container.width();
2885        } else {
2886          this.options.width = width;
2887          this.container.width(width);
2888          this.resize();
2889        }
2890      },
2891    };
2892
2893    return PreviewObject;
2894  })({});
2895
2896  DFLIP.PreviewObject = PreviewObject;
2897
2898  //contentprovider that handles the source of book
2899  var ContentProvider = (function (_super) {
2900    __extends(ContentProvider, _super);
2901    var textureLoadTimeOut = void 0;
2902
2903    function ContentProvider(contentSource, callback, parameters, flipbook) {
2904      parameters = parameters || {};
2905
2906      var _this = this;
2907
2908      _this.contentRawSource = contentSource || [defaults.textureLoadFallback];
2909      _this.contentSource = _this.contentRawSource;
2910      _this.contentSourceType = void 0;
2911      _this.minDimension = parameters.minTextureSize || 256;
2912      _this.maxDimension = parameters.maxTextureSize || 2048;
2913      _this.flipbook = flipbook;
2914      _this.waitPeriod = 50;
2915      _this.enableDebug = false;
2916      _this.zoomScale = 1;
2917      _this.maxZoom = 2;
2918      _this.options = parameters;
2919      _this.outline = parameters.outline;
2920      _this.links = parameters.links;
2921      _this.html = parameters.html;
2922      _this.isCrossOrigin = parameters.isCrossOrigin;
2923
2924      _this.normalViewport = {
2925        height: 297,
2926        width: 210,
2927        scale: 1,
2928      };
2929      _this.viewport = {
2930        height: 297,
2931        width: 210,
2932        scale: 1,
2933      };
2934      _this.zoomViewport = {
2935        height: 297,
2936        width: 210,
2937      };
2938
2939      _this.thumbsize = 128;
2940      _this.cacheIndex = 256; //index of bigger dimension height or width
2941      _this.cache = [];
2942
2943      _this.pageRatio =
2944        parameters.pageRatio || _this.viewport.width / _this.viewport.height;
2945
2946      //texture load control so that it wont delay the transition
2947      _this.textureLoadTimeOut = void 0;
2948
2949      _this.type = "TextureLibrary";
2950
2951      if (
2952        Array === _this.contentSource.constructor ||
2953        Array.isArray(_this.contentSource) ||
2954        _this.contentSource instanceof Array
2955      ) {
2956        //case of images and html content
2957        _this.contentSourceType = SOURCE_TYPE.IMAGE;
2958        _this.pageCount = _this.contentSource.length;
2959
2960        //_this.setLoading(1, true);
2961
2962        // Make in memory copy of image to avoid css issues
2963        $("<img/>")
2964          .attr("src", _this.contentSource[0])
2965          .on("load", function () {
2966            _this.viewport.height = this.height;
2967            _this.viewport.width = this.width;
2968
2969            _this.pageRatio = _this.viewport.width / _this.viewport.height;
2970
2971            _this.zoomViewport = {
2972              width:
2973                (_this.pageRatio > 1 ? 1 : _this.pageRatio) *
2974                _this.maxDimension,
2975              height:
2976                _this.maxDimension /
2977                (_this.pageRatio < 1 ? 1 : _this.pageRatio),
2978            };
2979
2980            _this.linkService = new PDFLinkService();
2981
2982            $(this).off();
2983
2984            if (_this.options.pageSize == DFLIP.PAGE_SIZE.DOUBLEINTERNAL) {
2985              _this.pageCount = _this.contentSource.length * 2 - 2;
2986              if (_this.options.webgl == true)
2987                _this.requiresImageTextureScaling = true;
2988            }
2989
2990            if (callback != void 0) {
2991              callback(_this);
2992              callback = null;
2993            }
2994            //_this.setLoading(1);
2995
2996            //console.log(_this.zoomViewport);
2997            log(this.height + ":" + this.width);
2998            //pic_real_width = this.width;   // Note: $(this).width() will not
2999            //pic_real_height = this.height; // work for in memory images.
3000            //moved to set target function
3001            //_this.
3002            // ();
3003          });
3004      } else if (
3005        typeof _this.contentSource == "string" ||
3006        _this.contentSource instanceof String
3007      ) {
3008        //case of link to pdf file
3009
3010        var processSource = function () {
3011          if (_this) {
3012            //configurePDFJS(PDFJS);
3013            PDFJS.workerSrc = defaults.pdfjsWorkerSrc;
3014
3015            _this.contentSourceType = SOURCE_TYPE.PDF;
3016            //PDFJS.disableWorker = true;
3017            PDFJS.disableAutoFetch = true;
3018            PDFJS.disableStream = true;
3019            if (isSafari) {
3020              PDFJS.disableFontFace = isSafari;
3021            }
3022            PDFJS.imageResourcesPath = defaults.imagesLocation + "/pdfjs/";
3023            PDFJS.externalLinkTarget = PDFJS.LinkTarget.BLANK;
3024
3025            var loading = (_this.loading = PDFJS.getDocument(
3026              _this.options.docParameters
3027                ? _this.options.docParameters
3028                : contentSource
3029            ));
3030
3031            loading.then(
3032              function sourceLoaded(pdf) {
3033                _this.pdfDocument = pdf;
3034                pdf.getPage(1).then(function (page) {
3035                  _this.normalViewport = page.getViewport(1);
3036                  _this.viewport = page.getViewport(1);
3037                  _this.viewport.height = _this.viewport.height / 10;
3038                  _this.viewport.width = _this.viewport.width / 10;
3039
3040                  _this.pageRatio =
3041                    _this.viewport.width / _this.viewport.height;
3042
3043                  _this.zoomViewport = {
3044                    width:
3045                      (_this.pageRatio > 1 ? 1 : _this.pageRatio) *
3046                      _this.maxDimension,
3047                    height:
3048                      _this.maxDimension /
3049                      (_this.pageRatio < 1 ? 1 : _this.pageRatio),
3050                  };
3051
3052                  _this.refPage = page;
3053
3054                  //console.log(_this.zoomViewport);
3055
3056                  //check if intenal pages are of double sizes.
3057                  if (pdf.numPages > 1) {
3058                    pdf.getPage(2).then(function (page) {
3059                      if (_this.options.pageSize == DFLIP.PAGE_SIZE.AUTO) {
3060                        var _viewport = page.getViewport(1);
3061                        //Update: doing width check gives false alarm if the internal pages are of different sizes yet follow same aspect ratio
3062                        //if (_viewport.width > _this.normalViewport.width * 1.5) {
3063                        var _pageRatio = _viewport.width / _viewport.height;
3064                        if (_pageRatio > _this.pageRatio * 1.5) {
3065                          _this.options.pageSize =
3066                            DFLIP.PAGE_SIZE.DOUBLEINTERNAL;
3067                          _this.pageCount = pdf.numPages * 2 - 2;
3068                        } else {
3069                          _this.options.pageSize = DFLIP.PAGE_SIZE.SINGLE;
3070                        }
3071                      }
3072                      if (callback != void 0) {
3073                        callback(_this);
3074                        callback = null;
3075                      }
3076                    });
3077                  } else {
3078                    if (callback != void 0) {
3079                      callback(_this);
3080                      callback = null;
3081                    }
3082                  }
3083                });
3084                _this.linkService = new PDFLinkService();
3085                _this.linkService.setDocument(pdf, null);
3086
3087                //moved to set target function
3088                //_this.initThumbs();
3089                _this.pageCount = pdf.numPages;
3090                _this.contentSource = pdf;
3091              },
3092              function loadingError(error) {
3093                if (_this) {
3094                  var cors = "",
3095                    tmp = document.createElement("a");
3096                  tmp.href = _this.contentSource;
3097
3098                  if (tmp.hostname !== window.location.hostname)
3099                    cors = "CROSS ORIGIN!! ";
3100
3101                  _this.updateInfo(
3102                    cors + "Cannot access file!  " + _this.contentSource
3103                  );
3104                }
3105              }
3106            );
3107
3108            loading.onProgress = function getDocumentProgress(progressData) {
3109              if (_this) {
3110                var percentage =
3111                  (100 * progressData.loaded) / progressData.total;
3112                if (isNaN(percentage)) {
3113                  if (progressData && progressData.loaded) {
3114                    _this.updateInfo(
3115                      "Loading PDF " +
3116                        (
3117                          Math.ceil(progressData.loaded / 10000) / 100
3118                        ).toString() +
3119                        "MB ..."
3120                    );
3121                  } else {
3122                    _this.updateInfo("Loading PDF ...");
3123                  }
3124                } else {
3125                  _this.updateInfo(
3126                    "Loading PDF " +
3127                      percentage.toString().split(".")[0] +
3128                      "% ..."
3129                  );
3130                }
3131              }
3132            };
3133          }
3134        };
3135        var checkCORS = function () {
3136          if (_this) {
3137            defaults.pdfjsWorkerSrc += "?ver=" + DFLIP.version;
3138
3139            _this.updateInfo("Loading PDF Worker ...");
3140            var tmp = document.createElement("a");
3141            tmp.href = defaults.pdfjsWorkerSrc;
3142
3143            if (tmp.hostname !== window.location.hostname) {
3144              _this.updateInfo("Loading PDF Worker CORS ...");
3145              $.ajax({
3146                url: defaults.pdfjsWorkerSrc,
3147                cache: true,
3148                success: function (data) {
3149                  defaults.pdfjsWorkerSrc = DFLIP.createObjectURL(
3150                    data,
3151                    "text/javascript"
3152                  );
3153                  processSource();
3154                },
3155              });
3156            } else {
3157              processSource();
3158            }
3159          }
3160        };
3161        if (window.PDFJS == void 0) {
3162          if (_this) {
3163            _this.updateInfo("Loading PDF Service ...");
3164            //getScript(defaults.pdfjsCompatibilitySrc + "?ver=" + DFLIP.version, function () {
3165
3166            getScript(
3167              defaults.pdfjsSrc + "?ver=" + DFLIP.version,
3168              function () {
3169                if (typeof define === "function" && define.amd) {
3170                  _this.updateInfo("Loading PDF Service (require) ...");
3171                  require(["pdfjs-dist/build/pdf"], function (pdf) {
3172                    checkCORS();
3173                  });
3174                } else {
3175                  checkCORS();
3176                }
3177              },
3178              function () {
3179                _this.updateInfo("Unable to load PDF service..");
3180              }
3181            );
3182            //});
3183          }
3184        } else {
3185          processSource();
3186        }
3187      } else {
3188        console.error(
3189          "Unknown source type. Please check documentation for help"
3190        );
3191      }
3192
3193      this.dispose = function () {
3194        if (_this.loading && _this.loading.destroy) {
3195          _this.loading.destroy();
3196        }
3197        _this.loading = null;
3198        if (this.targetObject) {
3199          if (
3200            this.targetObject.thumbContainer &&
3201            this.targetObject.thumbContainer.remove
3202          )
3203            this.targetObject.thumbContainer.remove();
3204          if (
3205            this.targetObject.outlineContainer &&
3206            this.targetObject.outlineContainer.remove
3207          )
3208            this.targetObject.outlineContainer.remove();
3209          if (this.targetObject.dispose) this.targetObject.dispose();
3210          this.targetObject.processPage = null;
3211          this.targetObject.requestPage = null;
3212          if (this.targetObject.container && this.targetObject.container.off)
3213            this.targetObject.container.off();
3214        }
3215        if (this.pdfDocument && this.pdfDocument.destroy)
3216          this.pdfDocument.destroy();
3217        if (this.linkService && this.linkService.dispose)
3218          this.linkService.dispose();
3219        if (this.outlineViewer && this.outlineViewer.dispose)
3220          this.outlineViewer.dispose();
3221        if (this.thumblist && this.thumblist.dispose) this.thumblist.dispose();
3222
3223        this.targetObject = null;
3224        this.pdfDocument = null;
3225        this.linkService = null;
3226        this.outlineViewer = null;
3227        this.thumblist = null;
3228        _this = null;
3229      };
3230      return this;
3231    }
3232
3233    ContentProvider.prototype.updateInfo = function (info) {
3234      if (this.flipbook && this.flipbook.updateInfo) {
3235        this.flipbook.updateInfo(info);
3236      }
3237    };
3238
3239    ContentProvider.prototype.initThumbs = function () {
3240      var _this = this;
3241      if (_this.cache[_this.thumbsize] == void 0)
3242        _this.cache[_this.thumbsize] = [];
3243      var thumbLoadTimeOut;
3244      var review = function () {
3245        clearTimeout(thumbLoadTimeOut);
3246        thumbLoadTimeOut = setTimeout(function () {
3247          thumbLoadTimeOut = setTimeout(reviewThumbs, _this.waitPerio
3247d / 2);
3248        }, _this.waitPeriod);
3249      };
3250
3251      var reviewThumbs = function () {
3252        var requestCount = 0;
3253        if (Date.now() - _this.thumblist.lastScrolled < 100) {
3254          requestCount = 1;
3255        } else {
3256          _this.targetObject.container
3257            .find(".df-thumb-container .df-vrow")
3258            .each(function () {
3259              var thumb = $(this);
3260              if (!thumb.hasClass("df-thumb-loaded")) {
3261                requestCount++;
3262                var id = $(this).attr("id").replace("df-thumb", "");
3263                _this.getPage(id, review, true);
3264                thumb.addClass("df-thumb-loaded");
3265                return false;
3266              }
3267            });
3268          if (requestCount == 0) {
3269            clearTimeout(thumbLoadTimeOut);
3270          }
3271        }
3272
3273        if (requestCount > 0) {
3274          review();
3275        }
3276      };
3277
3278      _this.thumblist = _this.targetObject.thumblist = new ThumbList({
3279        //w: 128 * _this.viewport.width/_this.viewport.height,
3280        h: 500,
3281        addFn: function (row) {},
3282        scrollFn: review,
3283        itemHeight: 128,
3284        totalRows: _this.pageCount,
3285        generatorFn: function (row) {
3286          var el = document.createElement("div");
3287          var pageNumber = row + 1;
3288          el.id = "df-thumb" + pageNumber;
3289          var elText = document.createElement("div");
3290          elText.innerHTML = pageNumber;
3291          el.appendChild(elText);
3292          //el.style.position = "absolute";
3293          //el.callback = function_this.getPage(pageNumber,void 0,true);
3294          return el;
3295        },
3296      });
3297
3298      _this.thumblist.lastScrolled = Date.now();
3299      review();
3300
3301      //_this.thumblist.container.classList.add('thumb-container');
3302      var thumbContainer = $("<div>").addClass(
3303        "df-thumb-container df-thumb-visible"
3304      );
3305      thumbContainer.append(
3306        $(_this.thumblist.container).addClass("df-thumb-wrapper")
3307      );
3308      _this.targetObject.thumbContainer = thumbContainer;
3309      _this.targetObject.container.append(thumbContainer);
3310
3311      var sideMenuClose = $(html.div, {
3312        class: "df-ui-btn df-ui-sidemenu-close ti-close",
3313      });
3314      thumbContainer.append(sideMenuClose);
3315      _this.thumblist.reset($(_this.thumblist.container).height());
3316      _this.targetObject.container.on(
3317        "click",
3318        ".df-thumb-container .df-vrow",
3319        function (e) {
3320          e.stopPropagation();
3321          var id = $(this).attr("id").replace("df-thumb", "");
3322          _this.targetObject.gotoPage(parseInt(id, 10));
3323        }
3324      );
3325    };
3326
3327    ContentProvider.prototype.initOutline = function () {
3328      var _this = this;
3329      var outlineContainer = $("<div>").addClass("df-outline-container");
3330      var outlineWrapper = $("<div>").addClass("df-outline-wrapper");
3331
3332      var sideMenuClose = $(html.div, {
3333        class: "df-ui-btn df-ui-sidemenu-close ti-close",
3334      });
3335
3336      outlineContainer.append(sideMenuClose).append(outlineWrapper);
3337      _this.targetObject.container.append(outlineContainer);
3338      _this.targetObject.outlineContainer = outlineContainer;
3339
3340      _this.outlineViewer = new BookMarkViewer({
3341        container: outlineWrapper[0],
3342        linkService: _this.linkService,
3343        outlineItemClass: "df-outline-item",
3344        outlineToggleClass: "df-outline-toggle",
3345        outlineToggleHiddenClass: "df-outlines-hidden",
3346      });
3347
3348      function processOutline(outline) {
3349        if (_this.options.overwritePDFOutline == true) {
3350          outline = [];
3351        }
3352        outline = outline || [];
3353
3354        if (_this.outline) {
3355          for (var count = 0; count < _this.outline.length; count++) {
3356            _this.outline[count].custom = true;
3357            if (outline) outline.push(_this.outline[count]);
3358          }
3359          /*                    _this.outline.forEach(function(v) {
3360					 //v.custom = true;
3361					 this.push(v);
3362					 }, this);
3363					 outline.push(_this.outline)*/
3364        }
3365
3366        _this.outlineViewer.render({ outline: outline });
3367      }
3368
3369      if (_this.pdfDocument) {
3370        _this.pdfDocument.getOutline().then(function (outline) {
3371          processOutline(outline);
3372        });
3373      } else {
3374        processOutline([]);
3375      }
3376
3377      if (_this.options.autoEnableOutline == true) {
3378        _this.targetObject.ui.outline.trigger("click");
3379      }
3380
3381      if (_this.options.autoEnableThumbnail == true) {
3382        _this.targetObject.ui.thumbnail.trigger("click");
3383      }
3384    };
3385
3386    ContentProvider.prototype.checkViewportSize = function (
3387      width,
3388      height,
3389      zoom
3390    ) {
3391      var _this = this;
3392      var target = _this.targetObject;
3393      var zoomWidth = width * zoom,
3394        zoomHeight = height * zoom;
3395
3396      var oldCacheSize = _this.cacheIndex;
3397
3398      /*            var height = target.mode == "css"
3399			 ? (target.container.height() - (target.stage.innerWidth() - target.stage.width()) )
3400			 : target.stage.height();
3401
3402			 var width = height * _this.normalViewport.width / _this.normalViewport.height;*/
3403
3404      //var zoom = _this.zoomScale != 1;
3405
3406      if (_this.contentSourceType == SOURCE_TYPE.PDF) {
3407        /*                _this.viewport.height = height;
3408				 _this.viewport.width = width;*/
3409        _this.cacheIndex = Math.ceil(Math.max(zoomWidth, zoomHeight));
3410
3411        if (zoom !== 1) {
3412          _this.cacheIndex = nearestPowerOfTwo(Math.max(zoomWidth, zoomHeight)); // * _this.zoomScale;//nearestPowerOfTwo(Math.max(_this.viewport.width,_this.viewport.height));
3413          _this.cacheIndex = utils.zoomStops(
3414            Math.max(zoomWidth, zoomHeight),
3415            _this.options.zoomRatio,
3416            oldCacheSize < _this.cacheIndex
3417          );
3418        }
3419
3420        _this.cacheIndex = limitAt(
3421          _this.cacheIndex * defaults.pixelRatio,
3422          _this.minDimension,
3423          _this.maxDimension
3424        );
3425        //removed to force internal page size fit incase the internal pages are of different sizes.
3426        // _this.cacheScale = _this.cacheIndex / Math.max(_this.normalViewport.width, _this.normalViewport.height);
3427
3428        if (_this.cache[_this.cacheIndex] == void 0)
3429          _this.cache[_this.cacheIndex] = [];
3430
3431        if (oldCacheSize !== _this.cacheIndex) {
3432          for (
3433            var pageCount = 0;
3434            pageCount < target.children.length;
3435            pageCount++
3436          ) {
3437            var page = target.children[pageCount];
3438            //page.name = '-2';
3439          }
3440          target.refresh();
3441        }
3442
3443        //if(zoom !==1){
3444        //	zoomHeight = height> width ? _this.cacheIndex : _this.cacheIndex * _this.pageRatio;
3445        //}
3446
3447        _this.viewport =
3448          target.mode == "css"
3449            ? _this.refPage.getViewport(
3450                zoomHeight / _this.normalViewport.height
3451              )
3452            : _this.refPage.getViewport(300 / _this.normalViewport.height);
3453
3454        log(_this.cacheIndex);
3455
3456        var div = target.container.find(".linkAnnotation"),
3457          viewportClone = _this.viewport.clone({ dontFlip: true });
3458        div.css({
3459          transform: "matrix(" + viewportClone.transform.join(",") + ")",
3460        });
3461        //_this.zoomScale = (zoom == true) ? _this.normalViewport.height * _this.viewport.scale / _this.viewport.height : 1;
3462      } else {
3463        if (_this.cache[_this.cacheIndex] == void 0)
3464          _this.cache[_this.cacheIndex] = [];
3465        /*                _this.cacheIndex = _this.zoomScale == 1 ? limitAt(_this.cacheIndex, _this.minDimension, _this.maxDimension) : _this.maxDimension;*/
3466
3467        //_this.zoomScale = (zoom == true) ? _this.zoomViewport.height / height : 1;
3468      }
3469
3470      //_this.zoomScale = (zoom == true) ? _this.zoomViewport.height / height : 1;
3471    };
3472
3473    ContentProvider.prototype.getCache = function (index, isThumb) {
3474      return isThumb == true
3475        ? this.cache[this.thumbsize] == void 0
3476          ? void 0
3477          : this.cache[this.thumbsize][index]
3478        : this.cache[this.cacheIndex] == void 0
3479        ? void 0
3480        : this.cache[this.cacheIndex][index];
3481    };
3482
3483    ContentProvider.prototype.setCache = function (
3484      index,
3485      src,
3486      isThumb,
3487      cacheIndexSize
3488    ) {
3489      if (isThumb == true) {
3490        if (this.cache[this.thumbsize] != void 0)
3491          this.cache[this.thumbsize][index] = src;
3492      } else {
3493        var cacheIndex =
3494          cacheIndexSize == void 0 ? this.cacheIndex : cacheIndexSize;
3495        if (this.cache[cacheIndex] != void 0)
3496          this.cache[cacheIndex][index] = src;
3497      }
3498    };
3499
3500    ContentProvider.prototype.setTarget = function (targetObject) {
3501      var _this = this;
3502      if (targetObject == void 0) {
3503        return this.targetObject;
3504      } else {
3505        this.targetObject = targetObject;
3506        targetObject.contentProvider = this;
3507
3508        targetObject.container.removeClass("df-loading df-init");
3509
3510        //_this.initThumbs();
3511
3512        if (_this.linkService !== void 0) {
3513          _this.linkService.setViewer(targetObject);
3514
3515          _this.initOutline();
3516        }
3517
3518        targetObject.processPage = function (pageNumber, callback) {
3519          if (pageNumber > 0 && pageNumber <= _this.pageCount) {
3520            //log("Loading page :" + pageNumber);
3521            _this.getPage(pageNumber, callback);
3522          } else {
3523            _this.setPage(pageNumber, defaults.textureLoadFallback, callback);
3524            //log("Invalid PageNumber :" + pageNumber);
3525          }
3526        };
3527
3528        targetObject.requestPage = function () {
3529          _this.review("Request");
3530        };
3531
3532        if (targetObject.resize !== void 0) targetObject.resize();
3533      }
3534    };
3535
3536    ContentProvider.prototype.review = function (message) {
3537      var _this = this;
3538      message = message || "timer review";
3539      clearTimeout(textureLoadTimeOut);
3540      textureLoadTimeOut = setTimeout(function () {
3541        textureLoadTimeOut = setTimeout(
3542          _this.reviewPages,
3543          _this.waitPeriod / 2,
3544          _this,
3545          message
3546        );
3547      }, _this.waitPeriod);
3548    };
3549
3550    ContentProvider.prototype.reviewPages = function (_this, message) {
3551      _this = _this || this;
3552      var target = _this.targetObject;
3553
3554      if (target == void 0) return;
3555
3556      var isBooklet = isBookletMode(target);
3557      if (message !== void 0) log(message);
3558      var requiresRevisit = false;
3559      var pageCount, page;
3560
3561      for (
3562        pageCount = 0;
3563        pageCount < _this.targetObject.children.length;
3564        pageCount++
3565      ) {
3566        page = target.children[pageCount];
3567        if (page.isFlipping == true) {
3568          //requires revisit
3569          requiresRevisit = true;
3570          break;
3571        }
3572      }
3573      if (requiresRevisit == false) {
3574        var pageLength =
3575          target.children.length > 3 ? 3 : target.children.length;
3576        var midPoint = pageLength / 2;
3577
3578        var basePage = isBooklet
3579          ? target._activePage
3580          : getBasePage(target._activePage);
3581
3582        if (_this.zoomScale > 1) {
3583          pageLength = 1;
3584        }
3585
3586        for (pageCount = 0; pageCount < pageLength; pageCount++) {
3587          var dividend = Math.floor(pageCount / 2);
3588          var diff =
3589            pageCount % 2 == 0
3590              ? -dividend * (isBooklet ? 1 : 2)
3591              : (dividend == 0 ? 1 : dividend) * (isBooklet ? 1 : 2);
3592
3593          var frontPageNumber = basePage + diff,
3594            backPageNumber = basePage + diff + 1;
3595
3596          var page1 = target.getPageByNumber(frontPageNumber),
3597            page2 = target.getPageByNumber(backPageNumber),
3598            reqFrontPageStamp = frontPageNumber + "|" + _this.cacheIndex,
3599            reqBackPageStamp = backPageNumber + "|" + _this.cacheIndex;
3600
3601          var requestCount = 0;
3602          if (
3603            page1 !== void 0 &&
3604            page1.frontPageStamp != reqFrontPageStamp &&
3605            page1.visible == true
3606          ) {
3607            target.processPage(frontPageNumber, function () {
3608              _this.review("Batch Call");
3609            });
3610            page1.frontPageStamp = reqFrontPageStamp;
3611            page1.frontTextureLoaded = true;
3612            requestCount++;
3613          }
3614          if (
3615            page2 !== void 0 &&
3616            page2.backPageStamp != reqBackPageStamp &&
3617            page2.visible == true &&
3618            !isBooklet
3619          ) {
3620            target.processPage(backPageNumber, function () {
3621              _this.review("Batch Call");
3622            });
3623            page2.backPageStamp = reqBackPageStamp;
3624            page2.backTextureLoaded = true;
3625            requestCount++;
3626          }
3627
3628          //diff is 0 only at the open pages
3629          if (
3630            diff == 0 &&
3631            _this.annotedPage !== basePage &&
3632            target.mode !== "css"
3633          ) {
3634            _this.getAnnotations(frontPageNumber);
3635            if (!isBooklet) _this.getAnnotations(backPageNumber);
3636            _this.annotedPage = basePage;
3637          }
3638
3639          if (requestCount > 0) {
3640            break;
3641          }
3642        }
3643        if (requestCount == 0) {
3644          if (target.mode !== "css") {
3645            _this.setLoading(basePage);
3646          } else {
3647            _this.setLoading(basePage);
3648            _this.setLoading(basePage + 1);
3649          }
3650        }
3651      } else {
3652        _this.review("Revisit request");
3653        if (_this.annotedPage !== void 0 && target.mode !== "css") {
3654          var baseActive = getBasePage(target._activePage);
3655          $(target.getContentLayer(baseActive)).html("");
3656          $(target.getContentLayer(baseActive + 1)).html("");
3657          _this.annotedPage = void 0;
3658        }
3659      }
3660    };
3661
3662    ContentProvider.prototype.getPage = function (
3663      pageNumber,
3664      callbackFunction,
3665      isThumb
3666    ) {
3667      var _this = this;
3668
3669      pageNumber = parseInt(pageNumber, 10);
3670      var _pageNumber = pageNumber;
3671      var source = _this.contentSource;
3672      if (pageNumber <= 0 && pageNumber >= _this.pageCount) {
3673        _this.setPage(
3674          pageNumber,
3675          defaults.textureLoadFallback,
3676          callbackFunction,
3677          isThumb
3678        );
3679      } else {
3680        if (_this.contentSourceType == SOURCE_TYPE.PDF) {
3681          if (_this.getCache(pageNumber, isThumb) !== void 0) {
3682            _this.setPage(
3683              pageNumber,
3684              _this.getCache(pageNumber, isThumb),
3685              callbackFunction,
3686              isThumb
3687            );
3688            log("Page " + pageNumber + " loaded from cache");
3689          } else {
3690            if (isThumb !== true) _this.setLoading(pageNumber, true);
3691
3692            if (
3693              _this.options.pageSize == DFLIP.PAGE_SIZE.DOUBLEINTERNAL &&
3694              pageNumber > 2
3695            ) {
3696              _pageNumber = Math.ceil((pageNumber - 1) / 2) + 1;
3697            }
3698            source.getPage(_pageNumber, isThumb).then(function (page) {
3699              renderPage(page, pageNumber, callbackFunction, isThumb);
3700            });
3701          }
3702        } else if (
3703          _this.contentSourceType == SOURCE_TYPE.IMAGE ||
3704          _this.contentSourceType == SOURCE_TYPE.HTML
3705        ) {
3706          if (_this.getCache(pageNumber, isThumb) !== void 0) {
3707            _this.setPage(
3708              pageNumber,
3709              _this.getCache(pageNumber, isThumb),
3710              callbackFunction,
3711              isThumb
3712            );
3713            log("Page " + pageNumber + " loaded from cache");
3714          } else {
3715            if (isThumb !== true) _this.setLoading(pageNumber, true);
3716
3717            if (
3718              _this.options.pageSize == DFLIP.PAGE_SIZE.DOUBLEINTERNAL &&
3719              pageNumber > 2
3720            ) {
3721              _pageNumber = Math.ceil((pageNumber - 1) / 2) + 1;
3722            }
3723
3724            //if (_this.isCrossOrigin == void 0) {
3725            //
3726            //	_this.setCache(pageNumber, source[_pageNumber - 1], isThumb, _this.cacheIndex);
3727            //	_this.setPage(pageNumber, source[_pageNumber - 1], callbackFunction, isThumb);
3728            //
3729            //	if (callbackFunction != void 0) callbackFunction();
3730            //
3731            //} else {
3732            loadImage(
3733              source[_pageNumber - 1],
3734              function (src) {
3735                _this.setCache(pageNumber, src, isThumb, _this.cacheIndex);
3736                _this.setPage(pageNumber, src, callbackFunction, isThumb);
3737
3738                if (callbackFunction != void 0) callbackFunction();
3739              },
3740              _this.isCrossOrigin
3741            );
3742            //}
3743          }
3744
3745          //_this.setPage(pageNumber, source[pageNumber - 1], callbackFunction, isThumb);
3746        }
3747      }
3748
3749      function loadImage(src, callback, isCrossOrigin) {
3750        var img = new Image();
3751
3752        img.crossOrigin = "Anonymous";
3753
3754        img.onload = function () {
3755          if (isCrossOrigin == true) {
3756            var canvas = document.createElement("canvas"),
3757              ctx = canvas.getContext("2d");
3758            canvas.width = img.width;
3759            canvas.height = img.height;
3760            ctx.drawImage(img, 0, 0);
3761            //localStorage.setItem( "savedImageData", canvas.toDataURL("image/png") );
3762
3763            if (defaults.canvasToBlob == true) {
3764              canvas.toBlob(
3765                function (blob) {
3766                  var src = DFLIP.createObjectURL(blob, "image/jpeg");
3767
3768                  if (callback != void 0) callback(src);
3769                },
3770                "image/jpeg",
3771                0.85
3772              );
3773            } else {
3774              if (callback != void 0) callback(canvas);
3775            }
3776          } else {
3777            if (callback != void 0) callback(src);
3778          }
3779          //$(this).off();
3780          img.onload = null;
3781          img = null;
3782        };
3783
3784        img.src = src;
3785
3786        // make sure the load event fires for cached images too
3787        if (img.complete || img.complete === undefined) {
3788          img.src =
3789            "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
3790          img.src = src;
3791        }
3792      }
3793
3794      function renderPage(page, pageNumber, callbackFunction, isThumb) {
3795        var forceFit = _this.options.forceFit;
3796        var isDoublePage =
3797          _this.options.pageSize == DFLIP.PAGE_SIZE.DOUBLEINTERNAL &&
3798          pageNumber > 1 &&
3799          pageNumber < _this.pageCount;
3800        var widthFix = isDoublePage && forceFit ? 2 : 1;
3801
3802        /*                var heightScale = _this.pageRatio < 1
3803				 ? _this.cacheScale
3804				 : _this.cacheScale / _this.pageRatio;*/
3805        //_this.cacheScale = _this.cacheIndex / Math.max(_this.normalViewport.width, _this.normalViewport.height);
3806        //scales are calculated based on perpage in case per page fitting is required.
3807        var viewport = forceFit ? page.getViewport(1) : _this.normalViewport;
3808
3809        var scale =
3810          _this.cacheIndex /
3811          Math.max(viewport.width / widthFix, viewport.height); //heightScale /_this.normalViewport.height;
3812        if (_this.webgl == true) {
3813          scale =
3814            nearestPowerOfTwo(_this.cacheIndex) /
3815            (_this.pageRatio > 1 ? viewport.width / widthFix : viewport.height);
3816        }
3817
3818        var canvas = document.createElement("canvas");
3819        var start = performance.now();
3820
3821        var requestedCacheSize = _this.cacheIndex;
3822
3823        var context = canvas.getContext("2d");
3824
3825        // scale = scale * defaults.pixelRatio;
3826
3827        if (isThumb == true) {
3828          scale = _this.thumbsize / _this.normalViewport.height;
3829        }
3830
3831        canvas.height = Math.round(viewport.height * scale); //causes fluctuation in value like 22.99999 as 22
3832        canvas.width = Math.round((viewport.width / widthFix) * scale);
3833
3834        if (
3835          _this.targetObject.mode == "css" &&
3836          Math.abs(_this.targetObject.zoomHeight - canvas.height) < 2
3837        ) {
3838          canvas.height = _this.targetObject.zoomHeight + 0; //causes fluctuation in value like 22.99999 as 22
3839          canvas.width = _this.targetObject.zoomWidth + 0;
3840        }
3841
3842        viewport = page.getViewport(scale);
3843        log(
3844          "rendering " +
3845            pageNumber +
3846            " at " +
3847            canvas.width +
3848            "x" +
3849            canvas.height
3850        );
3851        if (isDoublePage && pageNumber % 2 == 1) {
3852          //viewport = new PDFJS.PageViewport(viewport.viewBox.slice(), viewport.scale, viewport.rotation,
3853          //	canvas.width, 0);
3854          viewport.transform[4] = -canvas.width;
3855        }
3856        var renderContext = {
3857          canvasContext: context,
3858          viewport: viewport,
3859        };
3860
3861        page.cleanupAfterRender = true;
3862        var pageRendering = page.render(renderContext);
3863
3864        pageRendering.promise.then(function () {
3865          log(performance.now() - start);
3866          start = performance.now();
3867          if (
3868            isThumb == true ||
3869            (_this.options.canvasToBlob == true && _this.webgl !== true)
3870          ) {
3871            canvas.toBlob(
3872              function (blob) {
3873                var src = DFLIP.createObjectURL(blob, "image/jpeg");
3874                log(performance.now() - start);
3875                _this.setCache(pageNumber, src, isThumb, requestedCacheSize);
3876                _this.setPage(pageNumber, src, callbackFunction, isThumb);
3877
3878                //canvas.width = canvas.height = 1;
3879                //context.clearRect( 0, 0, canvas.width, canvas.height );
3880
3881                //page.cleanup();
3882              },
3883              "image/jpeg",
3884              0.9
3885            );
3886          } else {
3887            _this.setPage(pageNumber, canvas, callbackFunction, isThumb);
3888          }
3889          renderContext = null;
3890        });
3891      }
3892    };
3893
3894    ContentProvider.prototype.getTargetPage = function (pageNumber) {};
3895
3896    ContentProvider.prototype.setLoading = function (pageNumber, show) {
3897      if (this.targetObject !== void 0) {
3898        if (this.webgl == true) {
3899          var container = this.targetObject.container;
3900          if (show == true) {
3901            if (container.isLoading !== true) {
3902              container.addClass("df-loading");
3903              container.isLoading = true;
3904              log("Loading icon at " + pageNumber + " as " + show);
3905            }
3906          } else {
3907            if (container.isLoading !== void 0) {
3908              container.removeClass("df-loading");
3909              container.isLoading = void 0;
3910              log("Loading icon at " + pageNumber + " as " + show);
3911            }
3912          }
3913        } else {
3914          var contentLayer = $(this.targetObject.getContentLayer(pageNumber));
3915          if (contentLayer !== void 0) {
3916            if (show == true) contentLayer.addClass("df-page-loading");
3917            else contentLayer.removeClass("df-page-loading");
3918          }
3919        }
3920      }
3921    };
3922
3923    ContentProvider.prototype.getAnnotations = function (pageNumber) {
3924      var _this = this;
3925
3926      if (_this.options.enableAnnotation == false) return;
3927
3928      var target = _this.targetObject;
3929
3930      pageNumber = parseInt(pageNumber, 10);
3931      var source = _this.contentSource;
3932      var contentLayer = $(target.getContentLayer(pageNumber));
3933      contentLayer.empty();
3934      if (pageNumber > 0 && pageNumber <= _this.pageCount) {
3935        if (_this.contentSourceType == SOURCE_TYPE.PDF) {
3936          var basePage = getBasePage(pageNumber);
3937
3938          var _pageNumber = pageNumber;
3939          if (
3940            _this.options.pageSize == DFLIP.PAGE_SIZE.DOUBLEINTERNAL &&
3941            pageNumber > 2
3942          ) {
3943            _pageNumber = Math.ceil((pageNumber - 1) / 2) + 1;
3944          }
3945
3946          source.getPage(_pageNumber).then(function (page) {
3947            if (contentLayer !== void 0 && contentLayer.length > 0) {
3948              _this.setupAnnotations(
3949                page,
3950                _this.viewport,
3951                contentLayer,
3952                pageNumber
3953              );
3954
3955              /*                            //it's just resizing nothing to do with annotation fetch
3956							 if (target.mode != "css") {
3957
3958							 var page3d = target.getPageByNumber(pageNumber);
3959							 if (page3d !== void 0) {
3960							 var isLeft = (pageNumber % 2 == 0);
3961							 var width = Math.abs(page3d.geometry.boundingBox.max.x - page3d.geometry.boundingBox.min.x);
3962							 var height = Math.abs(page3d.geometry.boundingBox.max.z - page3d.geometry.boundingBox.min.z);
3963
3964							 var div3d = isLeft ? target.parent.cssScene.divLeft : target.parent.cssScene.divRight;
3965							 if (div3d !== void 0) {
3966							 div3d.rotation.y = (isLeft ? -1 : 1 ) * Math.atan2(height, width) * 0.9;
3967							 div3d.position.z = height * 0.8;
3968							 div3d.position.x = (isLeft ? 1 : -1 ) * height / 2.5;
3969							 $(div3d.element).css({
3970							 width: width,
3971							 left: isLeft ? -width / 2 : width / 2
3972							 });
3973
3974							 }
3975							 }
3976							 }*/
3977            }
3978          });
3979        }
3980
3981        //render any custom liks available for page.
3982
3983        if (_this.links !== void 0 && _this.links[pageNumber] !== void 0) {
3984          var pageLinks = _this.links[pageNumber];
3985          for (var index = 0; index < pageLinks.length; index++) {
3986            var pageLink = pageLinks[index];
3987
3988            var annotation;
3989            if (
3990              pageLink.dest &&
3991              pageLink.dest.indexOf &&
3992              pageLink.dest.indexOf("[html]") == 0
3993            ) {
3994              annotation = document.createElement("div");
3995              annotation.innerHTML = pageLink.dest.substr(6);
3996              annotation.className = "customHtmlAnnotation";
3997            } else {
3998              annotation = document.createElement("a");
3999              annotation.setAttribute("dest", pageLink.dest);
4000              annotation.className = "customLinkAnnotation";
4001              annotation.href = "#" + pageLink.dest;
4002              annotation.onclick = function () {
4003                var dest = this.getAttribute("dest");
4004                if (dest) {
4005                  _this.linkService.customNavigateTo(dest);
4006                }
4007                return false;
4008              };
4009            }
4010            annotation.style.left = pageLink.x + "%";
4011            annotation.style.top = pageLink.y + "%";
4012
4013            annotation.style.width = pageLink.w + "%";
4014            annotation.style.height = pageLink.h + "%";
4015            contentLayer[0].appendChild(annotation);
4016          }
4017        }
4018
4019        //render any html available for page.
4020
4021        if (_this.html !== void 0 && _this.html[pageNumber] !== void 0) {
4022          var pageHTML = _this.html[pageNumber];
4023          contentLayer.append(
4024            $("<div class='customHTMLAnnotation'>").html(pageHTML)
4025          );
4026        }
4027      }
4028    };
4029
4030    ContentProvider.prototype.setPage = function (
4031      pageNumber,
4032      textureSrc,
4033      callbackFunction,
4034      isThumb
4035    ) {
4036      var _this = this;
4037      var target = _this.targetObject;
4038      var isRTL = isRTLMode(target);
4039      var isBooklet = isBookletMode(target);
4040      if (isThumb == true) {
4041        var page = _this.targetObject.container.find("#df-thumb" + pageNumber);
4042        //log("setting:" + pageNumber + " " + bgImage(textureSrc));
4043        page.css({
4044          backgroundImage: bgImage(textureSrc),
4045        });
4046      } else {
4047        if (textureSrc == defaults.textureLoadFallback) {
4048          log("Fallback on " + pageNumber);
4049        } else {
4050          if (target.mode == "css") _this.getAnnotations(pageNumber);
4051        }
4052
4053        var bookPage = target.getPageByNumber(pageNumber);
4054        if (bookPage !== void 0) {
4055          if (
4056            (pageNumber % 2 != 0 && !isRTL) ||
4057            (pageNumber % 2 != 1 && isRTL && !isBooklet) ||
4058            (isBooklet && !isRTL)
4059          ) {
4060            log(pageNumber + "rendered to back of " + bookPage.color);
4061            //if (!(bookPage.backTextureLoaded == true && textureSrc == defaults.textureLoadFallback)) {
4062            bookPage.backImage(textureSrc, function (object, texture) {
4063              _this.setLoading(pageNumber);
4064              if (
4065                _this.requiresImageTextureScaling &&
4066                texture &&
4067                pageNumber != 1 &&
4068                pageNumber != _this.pageCount
4069              ) {
4070                texture.repeat.x = 0.5;
4071                texture.offset.x = 0.5;
4072              }
4073              if (callbackFunction != void 0) callbackFunction();
4074            });
4075            //}
4076          } else {
4077            log(pageNumber + "rendered to front of " + bookPage.color);
4078            //if (!(bookPage.frontTextureLoaded == true && textureSrc == defaults.textureLoadFallback)) {
4079            bookPage.frontImage(textureSrc, function (object, texture) {
4080              _this.setLoading(pageNumber);
4081              if (
4082                _this.requiresImageTextureScaling &&
4083                texture &&
4084                pageNumber != 1 &&
4085                pageNumber != _this.pageCount
4086              ) {
4087                texture.repeat.x = 0.5;
4088              }
4089              if (callbackFunction != void 0) callbackFunction();
4090            });
4091            //}
4092          }
4093        } else {
4094          log("Invalid set request on Page " + pageNumber);
4095        }
4096      }
4097    };
4098
4099    ContentProvider.prototype.setupAnnotations = function (
4100      page,
4101      viewport,
4102      pageDiv,
4103      pageNumber
4104    ) {
4105      if (pageDiv == void 0 || $(pageDiv).length == 0) return;
4106      var _this = this;
4107      return page.getAnnotations().then(function (annotationsData) {
4108        viewport = viewport.clone({
4109          dontFlip: true,
4110        });
4111
4112        if (
4113          _this.options.pageSize == DFLIP.PAGE_SIZE.DOUBLEINTERNAL &&
4114          pageNumber > 2 &&
4115          pageNumber % 2 == 1
4116        ) {
4117          //viewport.transform[4]= -viewport.scale * page.view[2]/2;
4118        } else if (pageNumber == 1) {
4119        }
4120        if (pageDiv == void 0) {
4121          return;
4122        }
4123        pageDiv = $(pageDiv);
4124        if (pageDiv.find(".annotationDiv").length == 0) {
4125          pageDiv.append($("<div class='annotationDiv'>"));
4126        }
4127        var div = pageDiv.find(".annotationDiv");
4128        div.empty();
4129        if (
4130          _this.options.pageSize == DFLIP.PAGE_SIZE.DOUBLEINTERNAL &&
4131          pageNumber > 2 &&
4132          pageNumber % 2 == 1
4133        ) {
4134          //viewport.transform[4]= -viewport.scale * page.view[2]/2;
4135          div.css({ left: "-100%" });
4136        } else if (pageNumber == 1) {
4137          div.css({ left: "" });
4138        }
4139        /*                div.css({
4140				 transform:'matrix(' + _this.viewport.transform.join(',') + ')'
4141				 });*/
4142
4143        PDFJS.AnnotationLayer.render({
4144          annotations: annotationsData,
4145          div: div[0],
4146          page: page,
4147          viewport: viewport,
4148          linkService: _this.linkService,
4149        });
4150
4151        if (
4152          _this.options.annotationClass &&
4153          _this.options.annotationClass !== ""
4154        ) {
4155          div.find(" > section").addClass(_this.options.annotationClass);
4156        }
4157        // div.find(" > section").addClass("someclass");
4158        /*				page.getTextContent().then(function(textContent){
4159				 console.log( textContent );
4160				 var textLayer = new DFLIP.TextLayerBuilder({
4161				 textLayerDiv :div[0],
4162				 pageIndex : void 0,
4163				 viewport : viewport.clone({
4164				 dontFlip: false
4165				 })
4166				 });
4167
4168				 textLayer.setTextContent(textContent);
4169				 textLayer.render();
4170				 });*/
4171      });
4172    };
4173
4174    return ContentProvider;
4175  })({});
4176
4177  var PageCSS = (function () {
4178    function PageCSS(parameters) {
4179      this.angles = parameters.angles || [0, 0, 0, 0, 0, 0];
4180      this.stiffness = parameters.angles || 0.1;
4181      this.segments = parameters.segments || 1;
4182      this.initDOM();
4183    }
4184
4185    function createInternals(pageSide) {
4186      var contentLayer = (pageSide.contentLayer = $(html.div, {
4187        class: "df-page-content",
4188      }));
4189      pageSide.append(contentLayer);
4190    }
4191
4192    PageCSS.prototype = {
4193      initDOM: function () {
4194        var element = (this.element = $(html.div, {
4195          class: "df-book-page",
4196        }));
4197        var wrapper = (this.wrapper = $(html.div, {
4198          class: "df-page-wrapper",
4199        }));
4200        var front = (this.front = $(html.div, {
4201          class: "df-page-front",
4202        }));
4203        var back = (this.back = $(html.div, {
4204          class: "df-page-back",
4205        }));
4206        var foldInnerShadow = (this.foldInnerShadow = $(html.div, {
4207          class: "df-page-fold-inner-shadow",
4208        }));
4209        var foldOuterShadow = (this.foldOuterShadow = $(html.div, {
4210          class: "df-page-fold-outer-shadow",
4211        }));
4212        this.frontIMG = new Image();
4213        this.backIMG = new Image();
4214
4215        createInternals(front, this.segments, true);
4216        createInternals(back, this.segments, false);
4217        element.append(wrapper).append(foldOuterShadow);
4218        wrapper.append(front).append(back).append(foldInnerShadow);
4219      },
4220
4221      updatePoint: function (point) {
4222        if (point == void 0) return;
4223
4224        //detect the current page
4225        var page =
4226          this.parent.dragPage != void 0
4227            ? this.parent.dragPage
4228            : point.page != void 0
4229            ? point.page
4230            : this;
4231
4232        //get the pageWidth and pageHeight
4233        var pageWidth = page.element.width(),
4234          pageHeight = page.element.height();
4235
4236        //the corner where the drag started
4237        var corner =
4238            this.parent.corner !== void 0 ? this.parent.corner : point.corner,
4239          corners = DFLIP.CORNERS;
4240
4241        var isRight = page.side == drag.right,
4242          isBottom = corner == corners.BL || corner == corners.BR;
4243
4244        point.rx = isRight == true ? pageWidth * 2 - point.x : point.x;
4245
4246        point.ry = isBottom == true ? pageHeight - point.y : point.y;
4247
4248        var radAngle = Math.atan2(point.ry, point.rx);
4249
4250        radAngle = Math.PI / 2 - limitAt(radAngle, 0, toRad(90));
4251
4252        var correctionX = isRight ? point.x / 2 : pageWidth - point.x / 2,
4253          correctionY = point.ry / 2,
4254          refLength = Math.max(
4255            0,
4256            Math.sin(radAngle - Math.atan2(correctionY, correctionX)) *
4257              distOrigin(correctionX, correctionY)
4258          ),
4259          foldLength = 0.5 * distOrigin(point.rx, point.ry);
4260
4261        var x = Math.round(pageWidth - refLength * Math.sin(radAngle)),
4262          y = Math.round(refLength * Math.cos(radAngle)),
4263          angle = toDeg(radAngle);
4264
4265        var angle1 = isBottom
4266          ? isRight
4267            ? 180 + (90 - angle)
4268            : 180 + angle
4269          : isRight
4270          ? angle
4271          : 90 - angle;
4272
4273        var angle2 = isBottom
4274            ? isRight
4275              ? 180 + (90 - angle)
4276              : angle
4277            : isRight
4278            ? angle + 180
4279            : angle1,
4280          angleS = isBottom
4281            ? isRight
4282              ? 90 - angle
4283              : angle + 90
4284            : isRight
4285            ? angle1 - 90
4286            : angle1 + 180,
4287          x1 = isRight ? pageWidth - x : x,
4288          y1 = isBottom ? pageHeight + y : -y,
4289          x2 = isRight ? -x : x - pageWidth,
4290          y2 = isBottom ? -pageHeight - y : y;
4291
4292        var opacity = limitAt((point.distance * 0.5) / pageWidth, 0, 0.5);
4293        var foldOpacity = limitAt(
4294          ((pageWidth * 2 - point.rx) * 0.5) / pageWidth,
4295          0.05,
4296          0.3
4297        );
4298
4299        page.element.addClass("df-folding");
4300
4301        var front = isRight ? page.back : page.front;
4302        var back = isRight ? page.front : page.back;
4303        var outerShadow = page.foldOuterShadow;
4304        var innerShadow = page.foldInnerShadow;
4305        page.wrapper.css({
4306          transform: translateStr(x1, y1) + rotateStr(angle1),
4307        });
4308
4309        front.css({
4310          transform: rotateStr(-angle1) + translateStr(-x1, -y1),
4311        });
4312
4313        back.css({
4314          transform: rotateStr(angle2) + translateStr(x2, y2),
4315          boxShadow: "rgba(0, 0, 0, " + opacity + ") 0px 0px 20px",
4316        });
4317
4318        innerShadow.css({
4319          transform: rotateStr(angle2) + translateStr(x2, y2),
4320          opacity: foldOpacity / 2,
4321          backgroundImage:
4322            prefix.css +
4323            "linear-gradient( " +
4324            angleS +
4325            "deg, rgba(0, 0, 0, 0.25) , rgb(0, 0, 0) " +
4326            foldLength * 0.7 +
4327            "px, rgb(255, 255, 255) " +
4328            foldLength +
4329            "px)",
4330        });
4331
4332        outerShadow.css({
4333          //transform: rotateStr(angle - (isRight ? -180 : 0)) + translateStr(isRight ? -x : x - pageWidth, y),
4334          opacity: foldOpacity / 2,
4335          left: isRight ? "auto" : 0,
4336          right: isRight ? 0 : "auto",
4337          backgroundImage:
4338            prefix.css +
4339            "linear-gradient( " +
4340            (-angleS + 180) +
4341            "deg, rgba(0, 0, 0,0) " +
4342            foldLength / 3 +
4343            "px, rgb(0, 0, 0) " +
4344            foldLength +
4345            "px)",
4346        });
4347
4348        //$("body > p").html(JSON.stringify({
4349        //	x: Math.round(point.rx),
4350        //	y: Math.round(point.ry),
4351        //	a: Math.round(angle),
4352        //	a1: Math.round(angle1),
4353        //	cx: Math.round(correctionX),
4354        //	cy: Math.round(correctionY),
4355        //	dx: Math.round(x),
4356        //	dy: Math.round(y),
4357        //	ref: Math.round(refLength),
4358        //	dis: Math.round(distOrigin(point.x, point.y))
4359        //}));
4360      },
4361
4362      updateAngle: function (angle, isRight) {
4363        var width = this.element.width() * 5;
4364
4365        //if(prefix.dom!=='MS') {
4366        this.wrapper.css({
4367          perspective: width,
4368          perspectiveOrigin: isRight == true ? "0% 50%" : "100% 50%",
4369        });
4370        //}
4371
4372        this.front.css({
4373          display:
4374            isRight == true
4375              ? angle <= -90
4376                ? "block"
4377                : "none"
4378              : angle < 90
4379              ? "block"
4380              : "none",
4381          transform:
4382            (prefix.dom !== "MfS" ? "" : "perspective(" + width + "px) ") +
4383            (isRight == true ? "translateX(-100%) " : "") +
4384            "rotateY(" +
4385            ((isRight == true ? 180 : 0) + angle) +
4386            "deg)",
4387        });
4388        this.back.css({
4389          display:
4390            isRight == true
4391              ? angle > -90
4392                ? "block"
4393                : "none"
4394              : angle >= 90
4395              ? "block"
4396              : "none",
4397          transform:
4398            (prefix.dom !== "MSd" ? "" : "perspective(" + width + "px) ") +
4399            (isRight == false ? "translateX(100%) " : "") +
4400            "rotateY(" +
4401            ((isRight == false ? -180 : 0) + angle) +
4402            "deg)",
4403        });
4404        //$("body > p").html(JSON.stringify({
4405        //	a: Math.round(angle)
4406        //}));
4407        return;
4408        /*if(this.angles[1] != void 0) {
4409				 var segsb = this.back.segments;
4410				 var segsf = this.front.segments;
4411				 var width = this.element.width();
4412				 var angle1 = this.angles[1];
4413				 var angle2 = this.angles[4]/segsb.length;
4414				 var step = Math.floor(width/segsb.length);
4415
4416				 for (var count = 0; count < segsb.length; count++) {
4417				 var segb = segsb[count];
4418				 var segf = segsf[count];
4419				 segb.css({
4420				 transform: "rotate3d(0,1,0," + (count == 0 ? angle1 : angle2) + "deg)",
4421				 //backgroundPositionX: -step * count,
4422				 //backgroundSize: width + "px 100%"
4423				 });
4424
4425				 segf.css({
4426				 transform: "rotate3d(0,1,0," + (count == 0 ? 180 + angle1 : angle2) + "deg)",
4427				 //backgroundPositionX: step * (count + 1),
4428				 //backgroundSize: width + "px 100%"
4429				 });
4430				 }
4431				 }
4432				 else{
4433				 this.element.find(".bg-segment").css({
4434				 transform: "translate3d(0px,0,0) rotate3d(0,1,0,0deg)"
4435				 });
4436				 }*/
4437      },
4438
4439      tween: function (point) {
4440        var page = this;
4441        if (page == void 0 || page.parent == void 0) return;
4442        var isBooklet = isBookletMode(page.parent);
4443        var isRight = page.side == drag.right;
4444        var isRTL = page.parent.direction == DFLIP.DIRECTION.RTL;
4445        var isBottom =
4446          page.parent.corner == DFLIP.CORNERS.BL ||
4447          page.parent.corner == DFLIP.CORNERS.BR;
4448        var isMagnetic = page.magnetic == true;
4449        var travelY = isBottom ? page.parent.height : 0;
4450
4451        var init,
4452          first,
4453          mid,
4454          angle = 0;
4455
4456        var end = (page.end =
4457          page && page.animateToReset == true
4458            ? { x: isRight ? page.parent.fullWidth : 0, y: travelY }
4459            : { x: isRight ? 0 : page.parent.fullWidth, y: travelY });
4460
4461        page.ease = page.isHard
4462          ? TWEEN.Easing.Quadratic.InOut
4463          : TWEEN.Easing.Linear.None;
4464
4465        var tempDuration = page.parent.duration;
4466
4467        if (page.isHard == true) {
4468          if (point != void 0) {
4469            angle = angleByDistance(point.distance, point.fullWidth);
4470          }
4471
4472          init = page.init = { angle: angle * (isRight ? -1 : 1) };
4473          end = page.end =
4474            page && page.animateToReset == true
4475              ? { angle: isRight ? 0 : -0 }
4476              : { angle: isRight ? -180 : 180 };
4477        } else {
4478          if (point == void 0) {
4479            init = page.init =
4480              page && page.animateToReset == true
4481                ? { x: isRight ? 0 : page.parent.fullWidth, y: 0 }
4482                : { x: isRight ? page.parent.fullWidth : 0, y: 0 };
4483
4484            first = page.first = {
4485              x: ((isRight ? 3 : 1) * page.parent.fullWidth) / 4,
4486              y: 0,
4487            };
4488
4489            mid = page.mid = {
4490              x: ((isRight ? 1 : 3) * page.parent.fullWidth) / 4,
4491              y: 0,
4492            };
4493          } else {
4494            init = page.init = { x: point.x, y: point.y, opacity: 1 };
4495            first = page.first = {
4496              x: (point.x * 3) / 4,
4497              y: (point.y * 3) / 4,
4498              opacity: 1,
4499            };
4500            mid = page.mid = { x: point.x / 4, y: point.y / 4, opacity: 1 };
4501
4502            tempDuration =
4503              (page.parent.duration *
4504                distPoints(init.x, init.y, end.x, end.y)) /
4505              page.parent.fullWidth;
4506
4507            tempDuration = limitAt(
4508              tempDuration,
4509              page.parent.duration / 3,
4510              page.parent.duration
4511            );
4512          }
4513        }
4514        init.index = 0;
4515        // first.index = 0;
4516        // mid.index = 0;
4517        end.index = 1;
4518        page.isFlipping = true;
4519
4520        var update = function (tween) {
4521          if (page.isHard == true) {
4522            page.updateAngle(tween.angle, isRight);
4523     
4523       page.angle = tween.angle;
4524          } else {
4525            page.updatePoint({
4526              x: tween.x,
4527              y: tween.y,
4528            });
4529            page.x = tween.x;
4530            page.y = tween.y;
4531          }
4532          if (isBooklet && !isMagnetic)
4533            page.element[0].style.opacity =
4534              (isRight && !isRTL) || (!isRight && isRTL)
4535                ? tween.index > 0.5
4536                  ? 2 * (1 - tween.index)
4537                  : 1
4538                : tween.index < 0.5
4539                ? 2 * tween.index
4540                : 1;
4541        };
4542
4543        if (isBooklet && ((!isRight && !isRTL) || (isRight && isRTL)))
4544          page.element[0].style.opacity = 0;
4545
4546        var completeTween = (page.completeTween =
4547          page.completeTween ||
4548          function (skipRefresh) {
4549            page.isFlipping = false;
4550
4551            if (page.isHard == true) {
4552              page.updateAngle(page.end.angle);
4553              page.back.css({ display: "block" });
4554              page.front.css({ display: "block" });
4555            } else {
4556              page.updatePoint({
4557                x: page.end.x,
4558                y: page.end.y,
4559              });
4560            }
4561
4562            page.element[0].style.opacity = 1;
4563
4564            if (page.animateToReset !== true) {
4565              page.side = page.side == drag.right ? drag.left : drag.right;
4566            } else page.animateToReset = void 0;
4567
4568            page.currentTween = void 0;
4569            page.pendingPoint = void 0;
4570            page.magnetic = false;
4571            page.parent.dragPage = void 0;
4572            page.parent.corner = DFLIP.CORNERS.NONE;
4573
4574            if (skipRefresh != true) page.parent.refresh();
4575
4576            //log("Tween Completed");
4577          });
4578        if (page.isHard == true) {
4579          page.currentTween = new TWEEN.Tween(init)
4580            .delay(0)
4581            .to(end, page.parent.duration)
4582            .onUpdate(function () {
4583              update(this);
4584            })
4585            .easing(page.ease)
4586            .onComplete(page.completeTween)
4587            .start();
4588        } else {
4589          if (point == void 0) {
4590            page.currentTween = new TWEEN.Tween(init)
4591              .delay(0)
4592              .to(end, page.parent.duration)
4593              .onUpdate(function () {
4594                update(this);
4595              })
4596              .easing(TWEEN.Easing.Sinusoidal.Out)
4597              .onComplete(page.completeTween)
4598              .start();
4599          } else {
4600            page.currentTween = new TWEEN.Tween(init)
4601              .delay(0)
4602              .to(end, tempDuration)
4603              .onUpdate(function () {
4604                update(this);
4605              })
4606              .easing(TWEEN.Easing.Sinusoidal.Out)
4607              .onComplete(page.completeTween);
4608            page.currentTween.start();
4609          }
4610        }
4611        //page.currentTween.parent= page;
4612      },
4613      frontImage: function (texture, callback) {
4614        var _this = this;
4615
4616        function completed() {
4617          _this.front.css({
4618            backgroundImage: bgImage(texture),
4619          });
4620          if (callback !== void 0) callback();
4621        }
4622
4623        if (texture.nodeName == "CANVAS") {
4624          _this.front.find(">canvas").remove();
4625          _this.front.append($(texture));
4626          if (callback !== void 0) callback();
4627        } else {
4628          if (texture == defaults.textureLoadFallback) {
4629            completed();
4630          } else {
4631            _this.frontIMG.onload = completed;
4632            _this.frontIMG.src = texture;
4633          }
4634        }
4635      },
4636      backImage: function (texture, callback) {
4637        var _this = this;
4638
4639        function completed() {
4640          _this.back.css({
4641            backgroundImage: bgImage(texture),
4642          });
4643          if (callback !== void 0) callback();
4644        }
4645
4646        if (texture.nodeName == "CANVAS") {
4647          _this.back.find(">canvas").remove();
4648          _this.back.append($(texture));
4649          if (callback !== void 0) callback();
4650        } else {
4651          if (texture == defaults.textureLoadFallback) {
4652            completed();
4653          } else {
4654            _this.backIMG.onload = completed;
4655            _this.backIMG.src = texture;
4656          }
4657        }
4658      },
4659      updateCSS: function (css) {
4660        this.element.css(css);
4661      },
4662      resetCSS: function () {
4663        this.wrapper.css({
4664          transform: "",
4665        });
4666
4667        this.front.css({
4668          transform: "",
4669          boxShadow: "",
4670        });
4671
4672        this.back.css({
4673          transform: "",
4674          boxShadow: "",
4675        });
4676      },
4677      clearTween: function (skipRefresh) {
4678        this.currentTween.stop();
4679        this.completeTween(skipRefresh == true);
4680        this.resetCSS();
4681      },
4682    };
4683
4684    return PageCSS;
4685  })();
4686
4687  var BookCSS = (function (_super) {
4688    __extends(BookCSS, _super);
4689
4690    function updateFolding(dragPage) {
4691      dragPage.parent.container.find(".df-folding").removeClass("df-folding");
4692      dragPage.element.addClass("df-folding");
4693    }
4694
4695    function hasFlipping(book) {
4696      var hasFlipping = false;
4697      for (var pageCount = 0; pageCount < book.pages.length; pageCount++) {
4698        var page = book.pages[pageCount];
4699        if (page.isFlipping == true) {
4700          hasFlipping = true;
4701          break;
4702        }
4703      }
4704      return hasFlipping;
4705    }
4706
4707    function BookCSS(parameters, container) {
4708      //parameters = extendOptions(parameters);
4709
4710      //_super.call(this, parameters, stage);
4711      var _this = this;
4712      _this.type = "BookCSS";
4713      _this.images = parameters.images || [];
4714      _this.pageCount = parameters.pageCount || 2;
4715      //_this.segments = parameters.segments = 5;
4716
4717      _this.foldSense = 50;
4718
4719      _this.stackCount = 4;
4720      _this.mode = "css";
4721      _this.pages = [];
4722      _this.duration = parameters.duration;
4723
4724      _this.container = $(container);
4725      _this.options = parameters;
4726      _this.drag = drag.none;
4727      _this.pageCount =
4728        _this.pageCount == 1
4729          ? _this.pageCount
4730          : Math.ceil(_this.pageCount / 2) * 2;
4731      _this.pageMode =
4732        parameters.pageMode ||
4733        (isMobile || _this.pageCount <= 2
4734          ? DFLIP.PAGE_MODE.SINGLE
4735          : DFLIP.PAGE_MODE.DOUBLE);
4736
4737      _this.singlePageMode =
4738        parameters.singlePageMode ||
4739        (isMobile
4740          ? DFLIP.SINGLE_PAGE_MODE.BOOKLET
4741          : DFLIP.SINGLE_PAGE_MODE.ZOOM);
4742
4743      _this.swipe_threshold = isMobile ? 15 : 50;
4744
4745      _this.direction = parameters.direction || DFLIP.DIRECTION.LTR;
4746
4747      _this.startPage = 1;
4748      _this.endPage = _this.pageCount;
4749
4750      _this._activePage = parameters.openPage || _this.startPage;
4751
4752      _this.hardConfig = parameters.hard;
4753      //var foldTime = void 0;
4754      has3d =
4755        "WebKitCSSMatrix" in window ||
4756        (document.body && "MozPerspective" in document.body.style);
4757
4758      _this.animateF = function () {
4759        if (TWEEN.getAll().length > 0) TWEEN.update();
4760        else clearInterval(_this.animate);
4761      };
4762
4763      _this.init(parameters);
4764
4765      _this.skipDrag = false;
4766
4767      function checkPage(point) {
4768        if (_this.dragPage != point.page && point.page.visible == true) {
4769          _this.dragPage.clearTween(true);
4770          _this.dragPage = point.page;
4771          _this.corner = point.corner;
4772          _this.dragPage.pendingPoint = point;
4773        }
4774      }
4775
4776      var mouseMove = function (event) {
4777          //event.preventDefault();
4778          var point = _this.eventToPoint(event);
4779          if (
4780            event.touches !== void 0 &&
4781            event.touches.length == 2 &&
4782            _this.startTouches !== void 0
4783          ) {
4784            //return;
4785            // _this.startTouches = event.touches;
4786            _this.zoomDirty = true;
4787            var touchCenter = utils.getVectorAvg(
4788                utils.getTouches(event, _this.container.offset())
4789              ),
4790              newScale = utils.calculateScale(
4791                _this.startTouches,
4792                utils.getTouches(event)
4793              ),
4794              scale = newScale / _this.lastScale;
4795
4796            var zoom = _this.contentProvider.zoomScale,
4797              x = touchCenter.x,
4798              y = touchCenter.y;
4799
4800            _this.stage.css({
4801              transform:
4802                "translate3d(" +
4803                _this.left +
4804                "px," +
4805                _this.top +
4806                "px,0) scale3d(" +
4807                newScale +
4808                "," +
4809                newScale +
4810                ",1)",
4811            });
4812
4813            _this.lastScale = newScale;
4814
4815            _this.lastZoomCenter = touchCenter;
4816            event.preventDefault();
4817          }
4818
4819          if (
4820            (event.touches !== void 0 && event.touches.length > 1) ||
4821            _this.startPoint == void 0 ||
4822            _this.startTouches !== void 0
4823          )
4824            return;
4825
4826          var targetPage = _this.dragPage || point.page;
4827
4828          if (_this.contentProvider.zoomScale !== 1) {
4829            if (event.touches !== void 0 || _this.isPanning == true) {
4830              _this.pan(point);
4831              event.preventDefault();
4832            }
4833          } else {
4834            if (_this.skipDrag !== true) {
4835              //if (_this.cancelMouse != true) {
4836
4837              var distance = point.distance; //_this.getDistance(event);//point.x < _this.pageWidth ? point.x : _this.fullWidth - point.x;
4838
4839              if (!hasFlipping(_this)) {
4840                if (_this.dragPage !== void 0 || point.isInside == true) {
4841                  //$(".quick-hint").html(distance);
4842                  if (_this.dragPage !== void 0) {
4843                    log("set mouse down move");
4844                  } else {
4845                    point.y = limitAt(point.y, 1, _this.height - 1);
4846                    point.x = limitAt(point.x, 1, point.fullWidth - 1);
4847                  }
4848
4849                  var corner = _this.corner || point.corner;
4850                  if (targetPage.isHard) {
4851                    var isRight =
4852                      corner == DFLIP.CORNERS.BR || corner == DFLIP.CORNERS.TR;
4853
4854                    var angle = angleByDistance(
4855                      point.distance,
4856                      point.fullWidth
4857                    );
4858
4859                    targetPage.updateAngle(angle * (isRight ? -1 : 1), isRight);
4860                  } else {
4861                    targetPage.updatePoint(point, _this);
4862                  }
4863
4864                  targetPage.magnetic = true;
4865                  targetPage.magneticCorner = point.corner;
4866                  event.preventDefault();
4867                  //point.page.updatePoint(point);
4868                }
4869
4870                if (
4871                  _this.dragPage == void 0 &&
4872                  targetPage !== void 0 &&
4873                  point.isInside == false &&
4874                  targetPage.magnetic == true
4875                ) {
4876                  targetPage.pendingPoint = point;
4877                  targetPage.animateToReset = true;
4878                  _this.corner = targetPage.magneticCorner;
4879                  _this.animatePage(targetPage);
4880                  targetPage.pendingPoint = void 0;
4881                  targetPage.magnetic = false;
4882                  targetPage.magneticCorner = void 0;
4883                }
4884
4885                if (
4886                  _this.isPanning == true &&
4887                  _this.dragPage == void 0 &&
4888                  _this.contentProvider.zoomScale == 1
4889                ) {
4890                  //check if swipe has happened
4891                  //console.log(_this.lastPos - point.x,performance.now()-_this.lastTime);
4892                  var swipe_dist = point.x - _this.lastPos,
4893                    swipe_time = performance.now() - _this.lastTime;
4894                  if (Math.abs(swipe_dist) > _this.swipe_threshold) {
4895                    //swipe has triggered
4896                    //_this.dragPage.pendingPoint = point;
4897                    if (swipe_dist < 0) {
4898                      _this.next();
4899                    } else {
4900                      _this.prev();
4901                    }
4902                    _this.drag = drag.none;
4903                    _this.isPanning = false;
4904                    event.preventDefault();
4905                  }
4906                  _this.lastPos = point.x;
4907                  _this.lastTime = performance.now();
4908                }
4909              }
4910            }
4911          }
4912        },
4913        mouseUp = function (event) {
4914          if (event.touches !== void 0 && event.touches.length == 0) {
4915            var zoom = _this.contentProvider.zoomScale;
4916            if (_this.zoomDirty == true) {
4917              _this.previewObject.contentProvider.zoomScale = utils.limitAt(
4918                _this.previewObject.contentProvider.zoomScale * _this.lastScale,
4919                1,
4920                _this.previewObject.contentProvider.maxZoom
4921              );
4922              _this.previewObject.zoomValue =
4923                _this.previewObject.contentProvider.zoomScale * 1;
4924              //_this.previewObject.zoom(_this.lastScale < 1 ? -1 : 1);
4925              //console.log(_this.previewObject.contentProvider.zoomScale * _this.lastScale,_this.previewObject.contentProvider.maxZoom)
4926              //_this.previewObject.pendingZoom = true;
4927              _this.previewObject.resize();
4928              _this.zoomDirty = false;
4929            }
4930            _this.wrapper.css({
4931              transform: "",
4932            });
4933            _this.lastScale = void 0;
4934            _this.startTouches = void 0;
4935          }
4936          _this.isPanning = false;
4937          if (event.touches !== void 0 && event.touches.length > 1) return;
4938          if (_this.skipDrag !== true) {
4939            //completeFold();
4940            var point = _this.eventToPoint(event);
4941            if (_this.dragPage) {
4942              event.preventDefault();
4943
4944              /*							if (_this.animate !== void 0) {
4945							 clearInterval(_this.animate);
4946							 }
4947
4948							 _this.animate = setInterval(_this.animateF, 30);
4949
4950							 _this.dragPage.tween(point);*/
4951
4952              //use something like pending point
4953              // detect the next page anbd call the updatepage
4954              //will be better
4955
4956              _this.dragPage.pendingPoint = point;
4957              if (
4958                point.x == _this.startPoint.x &&
4959                point.y == _this.startPoint.y &&
4960                point.isInside == true
4961              ) {
4962                if (
4963                  _this.corner == DFLIP.CORNERS.BR ||
4964                  _this.corner == DFLIP.CORNERS.TR
4965                ) {
4966                  checkPage(point);
4967                  if (_this.dragPage.isFlipping !== true) _this.next();
4968                } else if (
4969                  _this.corner == DFLIP.CORNERS.BL ||
4970                  _this.corner == DFLIP.CORNERS.TL
4971                ) {
4972                  checkPage(point);
4973                  if (_this.dragPage.isFlipping !== true) _this.prev();
4974                }
4975              } else if (_this.dragPage.isFlipping !== true) {
4976                if (point.distance > point.fullWidth / 2) {
4977                  if (point.x > point.fullWidth / 2) _this.prev();
4978                  else _this.next();
4979                } else {
4980                  _this.dragPage.animateToReset = true;
4981                  _this.animatePage(_this.dragPage);
4982                }
4983              }
4984              //_this.dragPage.animateToReset = true;
4985              if (_this.dragPage) {
4986                _this.dragPage.pendingPoint = void 0;
4987                _this.dragPage.magnetic = false;
4988              }
4989            } else {
4990              //detect click
4991              /*if(_this.wrapper[0].contains(event.target) && _this.contentProvider.zoomScale == 1 && point.x == _this.startPoint.x && point.y == _this.startPoint.y && point.isInsidePage && _this.startPoint.page == point.page && !point.page.isFlipping && event.srcElement.nodeName!=="A"){
4992							 if(_this.startPoint.page.side ==0){
4993							 _this.prev();
4994							 _this.startPoint.page = void 0;
4995							 }
4996							 else{
4997							 _this.next();
4998							 _this.startPoint.page = void 0;
4999							 }
5000							 }*/
5001            }
5002
5003            _this.drag = drag.none;
5004
5005            //_this.dragPage = void 0;
5006            //_this.corner = DFLIP.CORNERS.NONE;
5007            //log("set mouse up");
5008          }
5009        },
5010        mouseClick = function (event) {
5011          var point = _this.eventToPoint(event);
5012
5013          var element = event.srcElement || event.originalTarget;
5014
5015          if (_this.dragPage && _this.dragPage.magnetic) return;
5016
5017          if (
5018            _this.wrapper[0].contains(event.target) &&
5019            _this.contentProvider.zoomScale == 1 &&
5020            point.x == _this.startPoint.x &&
5021            point.y == _this.startPoint.y &&
5022            point.isInsidePage &&
5023            _this.startPoint.page == point.page &&
5024            !point.page.isFlipping &&
5025            element.nodeName !== "A"
5026          ) {
5027            if (_this.startPoint.page.side == 0) {
5028              _this.corner = DFLIP.CORNERS.TL;
5029              _this.prev();
5030              _this.startPoint.page = void 0;
5031            } else {
5032              _this.corner = DFLIP.CORNERS.TR;
5033              _this.next();
5034              _this.startPoint.page = void 0;
5035            }
5036            _this.isPanning = false;
5037          }
5038        },
5039        mouseDown = function (event) {
5040          if (
5041            event.touches !== void 0 &&
5042            event.touches.length == 2 &&
5043            _this.startTouches == void 0
5044          ) {
5045            _this.startTouches = utils.getTouches(event);
5046            _this.lastScale = 1;
5047          }
5048          if (
5049            (event.touches !== void 0 && event.touches.length > 1) ||
5050            (event.touches == void 0 && event.button !== 0)
5051          )
5052            return;
5053          var point = _this.eventToPoint(event);
5054          _this.startPoint = point;
5055          _this.left = _this.left || 0;
5056          _this.top = _this.top || 0;
5057          _this.isPanning = true;
5058          _this.lastPos = point.x;
5059          _this.lastTime = performance.now();
5060
5061          if (_this.skipDrag !== true) {
5062            if (point.isInside == true && !hasFlipping(_this)) {
5063              _this.startPoint = point;
5064              _this.drag = point.drag;
5065              _this.dragPage = point.page;
5066
5067              _this.corner = point.corner;
5068
5069              log(_this.corner);
5070
5071              updateFolding(_this.dragPage);
5072              //log("set mouse down");
5073              if (point.page.isHard) {
5074              } else {
5075                point.page.updatePoint(point, _this);
5076              }
5077              if (point.page.name == "0") {
5078                _this.shadow.css({
5079                  width: "50%",
5080                  left: _this.direction == DFLIP.DIRECTION.RTL ? 0 : "50%",
5081                  transitionDelay: "",
5082                });
5083              } else if (
5084                point.page.name ==
5085                Math.ceil(_this.pageCount / 2) - 1
5086              ) {
5087                _this.shadow.css({
5088                  width: "50%",
5089                  left: _this.direction == DFLIP.DIRECTION.RTL ? "50%" : 0,
5090                  transitionDelay: "",
5091                });
5092              }
5093            }
5094          }
5095        },
5096        onMouseWheel = function (event) {
5097          var delta = 0;
5098
5099          //var zoom = _this.contentProvider.zoomScale > 1;
5100          if (event.wheelDelta != void 0) {
5101            // WebKit / Opera / Explorer 9
5102
5103            delta = event.wheelDelta / 120;
5104          } else if (event.detail !== void 0) {
5105            // Firefox
5106
5107            delta = -event.detail / 3;
5108          }
5109
5110          var zoom1 = _this.contentProvider.zoomScale,
5111            maxZoom = _this.contentProvider.maxZoom;
5112
5113          if (delta) {
5114            if ((delta > 0 && zoom1 < maxZoom) || (delta < 0 && zoom1 > 1)) {
5115              event.stopPropagation();
5116              event.preventDefault();
5117
5118              var pointOld = _this.eventToPoint(event);
5119              var pointNew = _this.eventToPoint(event);
5120
5121              var origin = {
5122                x: _this.container.width() / 2,
5123                y: -23 + _this.container.height() / 2,
5124              };
5125
5126              _this.previewObject.zoom(delta);
5127
5128              var zoom2 = _this.contentProvider.zoomScale;
5129              if (zoom1 !== zoom2) {
5130                var dz = zoom2 / zoom1;
5131
5132                //fix zoom to previous center
5133                if (zoom2 == 1) {
5134                  _this.left = 0;
5135                  _this.top = 0;
5136                } else {
5137                  _this.left *= dz;
5138                  _this.top *= dz;
5139                }
5140
5141                //fix zoom to previous pointer
5142                var dx = (pointOld.raw.x - origin.x) * dz,
5143                  dy = (pointOld.raw.y - origin.y) * dz;
5144
5145                pointNew.raw.x = origin.x + dx; // origin.x + dz * (point.x-origin.x);
5146                pointNew.raw.y = origin.y + dy; // origin.y + dz * (point.y-origin.y);
5147
5148                _this.startPoint = pointNew;
5149                //console.log(pointOld.raw.x - origin.x,dx,pointOld.raw.y - origin.y,dy,pointNew.raw,_this.startPoint.raw);
5150                _this.pan(pointOld);
5151
5152                var targetPage = _this.dragPage || pointOld.page;
5153                if (
5154                  _this.dragPage == void 0 &&
5155                  targetPage !== void 0 &&
5156                  pointOld.isInside == true &&
5157                  targetPage.magnetic == true
5158                ) {
5159                  targetPage.pendingPoint = pointOld;
5160                  targetPage.animateToReset = true;
5161                  _this.corner = targetPage.magneticCorner;
5162                  _this.animatePage(targetPage);
5163                  targetPage.pendingPoint = void 0;
5164                  targetPage.magnetic = false;
5165                  targetPage.magneticCorner = void 0;
5166                }
5167              }
5168            }
5169          }
5170        };
5171
5172      var containerDom = _this.container[0];
5173      var stageDom = _this.stage[0];
5174      if (containerDom) {
5175        containerDom.addEventListener("mousemove", mouseMove, false);
5176        containerDom.addEventListener("touchmove", mouseMove, false);
5177
5178        containerDom.addEventListener("mousedown", mouseDown, false);
5179        containerDom.addEventListener("click", mouseClick, false);
5180        containerDom.addEventListener("mouseup", mouseUp, false);
5181        containerDom.addEventListener("touchend", mouseUp, false);
5182        containerDom.addEventListener("touchstart", mouseDown, false);
5183
5184        if (_this.options.scrollWheel == true) {
5185          //lets not trigger scroll when in outline or another
5186          stageDom.addEventListener("mousewheel", onMouseWheel, false);
5187          stageDom.addEventListener("DOMMouseScroll", onMouseWheel, false); // firefox
5188        }
5189      }
5190
5191      this.dispose = function () {
5192        containerDom.removeEventListener("mousemove", mouseMove, false);
5193        containerDom.removeEventListener("touchmove", mouseMove, false);
5194
5195        containerDom.removeEventListener("mousedown", mouseDown, false);
5196        containerDom.removeEventListener("click", mouseClick, false);
5197        containerDom.removeEventListener("mouseup", mouseUp, false);
5198        containerDom.removeEventListener("touchend", mouseUp, false);
5199        containerDom.removeEventListener("touchstart", mouseDown, false);
5200
5201        if (_this.options.scrollWheel == true) {
5202          stageDom.removeEventListener("mousewheel", onMouseWheel, false);
5203          stageDom.removeEventListener("DOMMouseScroll", onMouseWheel, false); // firefox
5204        }
5205        _this.flipCallback = null;
5206        _this.animateF = null;
5207        _this.stage.remove();
5208      };
5209    }
5210
5211    BookCSS.prototype = {
5212      add: function (object) {
5213        if (object instanceof PageCSS) this.container.append($(object.element));
5214        else this.container.append($(object));
5215      },
5216      pan: function (point) {
5217        var origin = this.startPoint;
5218        var scale = this.contentProvider.zoomScale;
5219
5220        var left = this.left + (point.raw.x - origin.raw.x),
5221          top = this.top + (point.raw.y - origin.raw.y);
5222
5223        //round removes blur due to decimal value in transform.
5224        this.left = Math.round(
5225          limitAt(left, -this.shiftWidth, this.shiftWidth)
5226        );
5227        this.top = Math.round(
5228          limitAt(top, -this.shiftHeight, this.shiftHeight)
5229        );
5230
5231        this.startPoint = point;
5232
5233        //console.log(point, origin);
5234        this.stage.css({
5235          transform: "translate3d(" + this.left + "px," + this.top + "px,0)",
5236        });
5237
5238        //var a = book.wrapper.height();
5239      },
5240      getPageByNumber: function (pageNumber) {
5241        var relativePageNumber = isBookletMode(this)
5242          ? isRTLMode(this)
5243            ? pageNumber + 1
5244            : pageNumber
5245          : Math.floor((pageNumber - 1) / 2);
5246        var page;
5247        for (var count = 0; count < this.pages.length; count++) {
5248          if (relativePageNumber == parseInt(this.pages[count].name, 10))
5249            page = this.pages[count];
5250        }
5251        return page;
5252      },
5253      getPageSide: function (pageNumber) {
5254        var isRTL = this.direction == DFLIP.DIRECTION.RTL;
5255
5256        var page = this.getPageByNumber(pageNumber);
5257        if (page == void 0) return;
5258        if (isBookletMode(this)) return isRTL ? page.front : page.back;
5259        if (pageNumber % 2 == 0) return isRTL ? page.back : page.front;
5260        else return isRTL ? page.front : page.back;
5261      },
5262      getContentLayer: function (pageNumber) {
5263        var pageSide = this.getPageSide(pageNumber);
5264        return pageSide == void 0 ? void 0 : pageSide.contentLayer;
5265      },
5266    };
5267
5268    BookCSS.prototype.init = function (parameters) {
5269      var _this = this;
5270      _this.stage = $(html.div, {
5271        class: "df-book-stage",
5272      });
5273      _this.wrapper = $(html.div, {
5274        class: "df-book-wrapper",
5275      });
5276      _this.shadow = $(html.div, {
5277        class: "df-book-shadow",
5278      });
5279      //_this.resize();
5280      _this.container.append(_this.stage);
5281      _this.stage.append(_this.wrapper);
5282      _this.wrapper.append(_this.shadow);
5283      /*			_this.nextButton = $(html.div, {
5284			 class: "df-book-next-button df-book-side-buttons " + parameters.icons['altnext']
5285			 }).appendTo(_this.wrapper).on("click", function () {
5286			 _this.next();
5287			 });
5288			 _this.prevButton = $(html.div, {
5289			 class: "df-book-prev-button df-book-side-buttons " + parameters.icons['altprev']
5290			 }).appendTo(_this.wrapper).on("click", function () {
5291			 _this.prev();
5292			 });*/
5293
5294      //_this.container.height(parameters.height);
5295
5296      _this.createStack(parameters);
5297    };
5298
5299    BookCSS.prototype.createStack = function (parameters) {
5300      var colors = "red,green,blue,yellow,orange,black".split(",");
5301
5302      for (var _stackCount = 0; _stackCount < this.stackCount; _stackCount++) {
5303        parameters.angles = [, this.stackCount - _stackCount]; //[1] = (this.stackCount - _stackCount);
5304        parameters.stiffness = (this.stackCount - _stackCount) / 100;
5305
5306        var clone = new PageCSS(parameters);
5307        clone.angles[1] = 180;
5308        clone.index = _stackCount;
5309        clone.parent = this;
5310        clone.textureReady = false;
vendor: 5,173 bytes, lines 5311-5484
5311        clone.textureRequested = false;
5312        this.wrapper.append(clone.element);
5313        clone.isFlipping = false;
5314        this.pages.push(clone);
5315        clone.color = colors[_stackCount];
5316        //for (var _count = 0; _count < 4; _count++) {
5317        //    clone.element.css({
5318        //        backgroundColor : colors[_stackCount]
5319        //    });
5320        //}
5321      }
5322
5323      this.children = this.pages;
5324    };
5325
5326    BookCSS.prototype.isPageHard = function (pageNumber) {
5327      return utils.isHardPage(
5328        this.hardConfig,
5329        pageNumber,
5330        this.pageCount,
5331        isBookletMode(this)
5332      );
5333    };
5334
5335    BookCSS.prototype.setDuration = function (_duration) {
5336      this.duration = _duration;
5337    };
5338
5339    BookCSS.prototype.moveBy = function (step) {
5340      var nextPage = this._activePage + step;
5341
5342      nextPage = limitAt(nextPage, this.startPage, this.endPage);
5343
5344      this.gotoPage(nextPage);
5345    };
5346
5347    BookCSS.prototype.next = function (step) {
5348      if (step == void 0)
5349        step =
5350          this.direction == DFLIP.DIRECTION.RTL
5351            ? -this.pageMode
5352            : this.pageMode;
5353
5354      this.moveBy(step);
5355    };
5356
5357    BookCSS.prototype.prev = function (step) {
5358      if (step == void 0)
5359        step =
5360          this.direction == DFLIP.DIRECTION.RTL
5361            ? this.pageMode
5362            : -this.pageMode;
5363
5364      this.moveBy(step);
5365    };
5366    BookCSS.prototype.eventToPoint = function (event) {
5367      event = fixMouseEvent(event);
5368
5369      var wrapper = this.wrapper,
5370        pages = this.pages,
5371        pageWidth = this.pageWidth,
5372        fullWidth = this.fullWidth,
5373        height = this.height,
5374        win = $(window),
5375        point = { x: event.clientX, y: event.clientY };
5376
5377      var left = point.x - wrapper[0].getBoundingClientRect().left; // + win['scrollLeft']();
5378
5379      var top = point.y - wrapper[0].getBoundingClientRect().top; // + win['scrollTop']();
5380
5381      point.x = point.x - this.container[0].getBoundingClientRect().left;
5382      point.y = point.y - this.container[0].getBoundingClientRect().top;
5383
5384      var distance =
5385        this.drag == drag.none
5386          ? left < pageWidth
5387            ? left
5388            : fullWidth - left
5389          : this.drag == drag.left
5390          ? left
5391          : fullWidth - left;
5392
5393      var page = //((left >= 0 && left <= fullWidth)?
5394        left < pageWidth
5395          ? pages[this.stackCount / 2 - 1]
5396          : pages[this.stackCount / 2];
5397
5398      var pageDrag =
5399        left < this.foldSense
5400          ? drag.left
5401          : left > fullWidth - this.foldSense
5402          ? drag.right
5403          : drag.none;
5404
5405      //determine the corner
5406      var x = left,
5407        y = top,
5408        h = height,
5409        w = fullWidth,
5410        delta = this.foldSense,
5411        corners = DFLIP.CORNERS,
5412        corner;
5413
5414      if (x >= 0 && x < delta) {
5415        if (y >= 0 && y <= delta) corner = corners.TL;
5416        else if (y >= h - delta && y <= h) corner = corners.BL;
5417        else if (y > delta && y < h - delta) corner = corners.L;
5418        else corner = corners.NONE;
5419      } else if (x >= w - delta && x <= w) {
5420        if (y >= 0 && y <= delta) corner = corners.TR;
5421        else if (y >= h - delta && y <= h) corner = corners.BR;
5422        else if (y > delta && y < h - delta) corner = corners.R;
5423        else corner = corners.NONE;
5424      } else corner = corners.NONE;
5425
5426      return {
5427        isInsidePage: x >= 0 && x <= w && y >= 0 && y <= h,
5428        isInside:
5429          corner !== corners.NONE &&
5430          corner !== corners.L &&
5431          corner !== corners.R,
5432        x: left,
5433        y: top,
5434        fullWidth: fullWidth,
5435        rawDistance: fullWidth - left,
5436        distance: distance,
5437        page: page,
5438        drag: pageDrag,
5439        foldSense: this.foldSense,
5440        event: event,
5441        raw: point,
5442        corner: corner,
5443      };
5444    };
5445
5446    BookCSS.prototype.gotoPage = function (pageNumber) {
5447      pageNumber = parseInt(pageNumber, 10);
5448      this._activePage = pageNumber;
5449      this.updatePage(pageNumber);
5450    };
5451
5452    BookCSS.prototype.refresh = function () {
5453      this.updatePage(this._activePage);
5454      if (this.flipCallback !== void 0) this.flipCallback();
5455    };
5456
5457    BookCSS.prototype.updatePage = function (pageNumber) {
5458      var isRTL = this.direction == DFLIP.DIRECTION.RTL,
5459        isBooklet = isBookletMode(this),
5460        newBaseNumber = getBasePage(pageNumber);
5461
5462      var pageDivisor = isBooklet ? 1 : 2;
5463
5464      pageNumber = Math.floor(pageNumber / pageDivisor);
5465
5466      if (isRTL) pageNumber = this.pageCount / pageDivisor - pageNumber;
5467
5468      var oldBaseNumber = this.oldBaseNumber || 0;
5469      var pageCount = this.pageCount / pageDivisor;
5470      var stackCount = this.stackCount;
5471
5472      var midPoint = Math.floor(stackCount / 2);
5473
5474      if (oldBaseNumber > pageNumber) {
5475        this.children[stackCount - 1].skipFlip = true;
5476        this.children.unshift(this.children.pop());
5477      } else if (oldBaseNumber < pageNumber) {
5478        this.children[0].skipFlip = true;
5479        this.children.push(this.children.shift());
5480      }
5481
5482      /*            if(oldBaseNumber !==pageNumber){
5483			 var tweens = TWEEN.getAll();
5484			 for(var count = 0; count< tweens.length ;
5484 count++){
5485			 var tween = tweens[0];
5486			 if(tween.parent!==void 0){
5487			 tween.stop();
5488			 }
5489			 }
5490			 }*/
5491
5492      for (var _pageCount = 0; _pageCount < stackCount; _pageCount++) {
5493        var page = this.children[_pageCount];
5494
5495        if (oldBaseNumber !== pageNumber) {
5496          if (page.currentTween !== void 0) {
5497            page.clearTween(true);
5498            //page.currentTween.stop();
5499            //page.completeTween(true);
5500            //page.resetCSS();
5501            //page.currentTween = null;
5502          }
5503        }
5504
5505        var oldSide = page.side;
5506        var newSide;
5507        var relativePageNumber = pageNumber - midPoint + _pageCount;
5508        var oldName = page.name;
5509
5510        page.isHard = this.isPageHard(relativePageNumber);
5511        if (page.isHard) {
5512          page.element.addClass("df-hard-page");
5513        } else {
5514          page.element.removeClass("df-hard-page");
5515          page.front.css({ display: "block" });
5516          page.back.css({ display: "block" });
5517        }
5518        if (relativePageNumber == 0 || relativePageNumber == pageCount) {
5519          page.element.addClass("df-cover-page");
5520        } else {
5521          page.element.removeClass("df-cover-page");
5522        }
5523
5524        var oldPageNumber = $(page.element).attr("pageNumber");
5525        if (oldPageNumber != relativePageNumber) {
5526          page.front.contentLayer.empty();
5527          page.back.contentLayer.empty();
5528        }
5529        $(page.element).attr("pageNumber", relativePageNumber);
5530
5531        //Sizing
5532        page.isEdge = false; //true;
5533        if (_pageCount == 0) {
5534        } else if (_pageCount == stackCount - 1) {
5535        } else {
5536          page.isEdge = false;
5537        }
5538
5539        if (_pageCount < midPoint) {
5540          newSide = drag.left;
5541        } else {
5542          newSide = drag.right;
5543        }
5544
5545        if (page.isFlipping == false) {
5546          if (newSide !== oldSide && page.skipFlip == false) {
5547            this.animatePage(page);
5548
5549            if (this.preFlipCallback !== void 0) this.preFlipCallback();
5550          } else {
5551            page.skipFlip = false;
5552            page.element.removeClass(
5553              "df-flipping df-quick-turn df-folding df-left-side df-right-side"
5554            );
5555            page.element.addClass(
5556              _pageCount < midPoint ? "df-left-side" : "df-right-side"
5557            );
5558            page.side = newSide;
5559          }
5560        }
5561
5562        page.visible = isBooklet
5563          ? isRTL
5564            ? _pageCount < midPoint || page.isFlipping
5565            : _pageCount >= midPoint || page.isFlipping
5566          : (relativePageNumber >= 0 && relativePageNumber < pageCount) ||
5567            (isBooklet && relativePageNumber == pageCount);
5568
5569        //if (isBooklet && !isRTL && _pageCount < midPoint && page.isFlipping == false)
5570        //	page.visible = false;
5571        //if (isBooklet && isRTL && _pageCount > midPoint && page.isFlipping == false)
5572        //	page.visible = false;
5573
5574        if (this.requestPage !== void 0 && page.visible == true) {
5575          if (isRTL)
5576            relativePageNumber = isBooklet
5577              ? this.pageCount - relativePageNumber
5578              : Math.floor(this.pageCount / 2) - relativePageNumber - 1;
5579          page.name = relativePageNumber.toString();
5580          if (page.name != oldName) {
5581            page.backTextureLoaded = false;
5582            page.frontTextureLoaded = false;
5583            page.backPageStamp = "-1";
5584            page.frontPageStamp = "-1";
5585            page.thumbLoaded = false;
5586            page.front.contentLayer.html("");
5587            page.back.contentLayer.html("");
5588            //if (oldName !== '-2') {
5589            page.frontImage(defaults.textureLoadFallback);
5590            page.backImage(defaults.textureLoadFallback);
5591            //}
5592            this.requestPage();
5593          }
5594        }
5595
5596        page.oldDepth = page.depth;
5597        page.updateCSS({
5598          display: page.visible == true ? "block" : "none",
5599          zIndex:
5600            6 +
5601            (_pageCount < midPoint
5602              ? _pageCount - midPoint
5603              : midPoint - _pageCount),
5604          transform: "",
5605        });
5606
5607        if (page.pendingPoint == void 0 && page.isFlipping == false) {
5608          page.resetCSS();
5609        }
5610      }
5611
5612      if (TWEEN.getAll().length == 0) {
5613        clearInterval(this.animate);
5614      }
5615      $(".quick-hint").html(pageNumber);
5616
5617      this.oldBaseNumber = pageNumber;
5618
5619      if (this.updatePageCallback !== void 0) this.updatePageCallback();
5620    };
5621
5622    BookCSS.prototype.animatePage = function (page) {
5623      page.element.addClass("df-flipping");
5624      page.isFlipping = true;
5625
5626      if (this.animate !== void 0) {
5627        clearInterval(this.animate);
5628      }
5629
5630      this.animate = setInterval(this.animateF, 30);
5631
5632      page.tween(page.pendingPoint);
5633    };
5634
5635    return BookCSS;
5636  })({});
5637
5638  var FlipBook = (function (_super) {
5639    __extends(FlipBook, _super);
5640
5641    function FlipBook(container, source, parameters) {
5642      _super.call(this, parameters);
5643      var _this = this;
5644
5645      _this.type = "FlipBook";
5646      _this.container = container;
5647      _this.options = parameters;
5648      _this.options.source = source;
5649      _this.contentSource = source;
5650
5651      if (
5652        parameters.height !== void 0 &&
5653        parameters.height.toString().indexOf("%") < 0
5654      ) {
5655        _this.container.height(Math.min(parameters.height, $(window).height()));
5656      } else {
5657        _this.container.height(parameters.height);
5658      }
5659
5660      if (_this.options.isLightBox) {
5661        window.dfLightBox.closeButton.addClass(_this.options.icons["close"]);
5662      }
5663      if (_this.options.pageSize == DFLIP.PAGE_SIZE.DOUBLEINTERNAL) {
5664        //currently booklet version cannot handle double sized image pages
5665        if (
5666          Array === _this.contentSource.constructor ||
5667          Array.isArray(_this.contentSource) ||
5668          _this.contentSource instanceof Array
5669        ) {
5670          _this.options.singlePageMode = DFLIP.SINGLE_PAGE_MODE.ZOOM;
5671        }
5672        _this.container.addClass("df-double-internal");
5673      }
5674      if (!_this.options.isLightBox && _this.container.attr("id") !== void 0) {
5675        _this.options.id = _this.container.attr("id");
5676      }
5677
5678      if (_this.options.parsed !== true && _this.options.links != void 0) {
5679        DFLIP.parseLinks(_this.options.links);
5680      }
5681      var webgl = (_this.webgl = parameters.webgl == true && hasWebgl == true);
5682
5683      container.addClass("df-container df-loading df-init df-floating");
5684
5685      if (_this.options.transparent == true) {
5686        container.addClass("df-transparent");
5687      }
5688      //if (_this.options.direction == DFLIP.DIRECTION.RTL) {
5689      //	container.addClass("df-rtl");
5690      //}
5691      _this.container.info = $(html.div, {
5692        class: "loading-info",
5693      })
5694        .appendTo(_this.container)
5695        .html("Loading...");
5696
5697      if (
5698        navigator.userAgent.indexOf("MSIE") !== -1 ||
5699        navigator.appVersion.indexOf("Trident/") > 0
5700      ) {
5701        _this.options.webgl = false; //IE 11
5702      }
5703
5704      if (!!navigator.userAgent.match(/msie\s[5-9]/i)) {
5705        _this.container.info
5706          .html(
5707            "Your browser (Internet Explorer) is out of date to run DFlip Flipbook Plugin. <br><a href='http://browsehappy.com/'>Upgrade to a new one</a>"
5708          )
5709          .addClass("df-old-browser");
5710        container.removeClass("df-loading");
5711        return _this;
5712      }
5713
5714      var backgroundImage =
5715        parameters.backgroundImage == void 0 || parameters.backgroundImage == ""
5716          ? ""
5717          : "url('" + parameters.backgroundImage + "')";
5718
5719      _this.container.css({
5720        position: "relative",
5721        overflow: "hidden",
5722        backgroundColor: parameters.backgroundColor,
5723        backgroundImage: backgroundImage,
5724      });
5725
5726      _this.init(webgl, source);
5727
5728      if (_this.options.onCreate !== void 0) _this.options.onCreate(_this);
5729
5730      return _this;
5731    }
5732
5733    FlipBook.prototype.init = function (webgl) {
5734      var _this = this;
5735      var book = _this.target;
5736
5737      var options = _this.options;
5738
5739      if (webgl == true) {
5740        var updateMockupJs = function (callback) {
5741          var process3d = function () {
5742            MOCKUP.defaults.anisotropy = 0;
5743            MOCKUP.defaults.groundTexture = "blank";
5744            THREE.skipPowerOfTwo = true;
5745
5746            RegisterMockupObjects();
5747
5748            if (callback !== void 0) callback();
5749          };
5750
5751          if (window.MOCKUP == void 0) {
5752            _this.updateInfo("Loading WEBGL 3D ...");
5753            getScript(
5754              defaults.threejsSrc + "?ver=" + DFLIP.version,
5755              function () {
5756                //_this.updateInfo("Loading 3D Pages ..."); this was retainnng _this and not releasing memory
5757                getScript(
5758                  defaults.mockupjsSrc + "?ver=" + DFLIP.version,
5759                  function () {
5760                    process3d();
5761                  }
5762                );
5763              }
5764            );
5765          } else {
5766            process3d();
5767          }
5768        };
5769
5770        updateMockupJs(function () {
5771          //Todo: ability to use anisotropy
5772
5773          _this.container.css({
5774            minHeight: 300,
5775            minWidth: 300,
5776          });
5777
5778          _this.stage = new PreviewStage(
5779            extendOptions(_this.options, { container: _this.container })
5780          );
5781          _this.stage.previewObject = _this;
5782
5783          _this.contentProvider = new ContentProvider(
5784            _this.contentSource,
5785            function (contentProvider) {
5786              var options = {
5787                pageCount: contentProvider.pageCount, //Math.ceil(contentProvider.pageCount / 2) * 2,
5788                stackCount: 6,
5789                segments: 20,
5790                width: 300 * contentProvider.pageRatio,
5791                height: 300,
5792              };
5793
5794              _this.checkOpenPage();
5795              _this.target =
5796                book =
5797                _this.stage.target =
5798                  new MOCKUP.Book(
5799                    extendOptions(_this.options, options),
5800                    _this.stage
5801                  );
5802              _this.extendtarget();
5803              createUI(_this.container, _this);
5804
5805              //bookStage.setTarget(_this.target);
5806              book.ui = _this.ui;
5807              book.container = _this.container;
5808              contentProvider.webgl = webgl;
5809              contentProvider.setTarget(_this.target);
5810
5811              book.getContentLayer = function (pageNumber) {
5812                var isRTL = book.direction == DFLIP.DIRECTION.RTL,
5813                  left = _this.stage.cssScene.divLeft.element,
5814                  right = _this.stage.cssScene.divRight.element;
5815
5816                var baseActive = getBasePage(book._activePage);
5817
5818                //if(isRTL){
5819                //	if(pageNumber == 0 || pageNumber == 1) return right;
5820                //	if(pageNumber == book.pageCount) return left;
5821                //}
5822
5823                if (isBookletMode(book)) return isRTL ? left : right;
5824
5825                if (pageNumber % 2 == 0) return isRTL ? right : left;
5826                else return isRTL ? left : right;
5827                //else
5828                //	return void 0;
5829              };
5830              book.stage = _this.stage;
5831
5832              book.flipCallback = function () {
5833                if (_this.contentProvider) {
5834                  _this.contentProvider.review("flipCallback");
5835
5836                  var baseActive = getBasePage(book._activePage);
5837
5838                  var width, height;
5839                  var pageLeft = book.getPageByNumber(baseActive),
5840                    pageRight = book.getPageByNumber(baseActive + 1);
5841                  //if (page3d !== void 0) {
5842                  //    var isLeft = (pageNumber % 2 == 0);
5843                  var divLeft = book.parent.cssScene.divLeft,
5844                    divRight = book.parent.cssScene.divRight;
5845
5846                  var isSingle = book.pageMode == DFLIP.PAGE_MODE.SINGLE;
5847                  var isRTL = book.direction == DFLIP.DIRECTION.RTL;
5848
5849                  if (pageLeft !== void 0 && divLeft !== void 0) {
5850                    width = Math.abs(
5851                      pageLeft.geometry.boundingBox.max.x -
5852                        pageLeft.geometry.boundingBox.min.x
5853                    );
5854                    height = Math.abs(
5855                      pageLeft.geometry.boundingBox.max.z -
5856                        pageLeft.geometry.boundingBox.min.z
5857                    );
5858
5859                    divLeft.rotation.y = -Math.atan2(height, width) * 0.9;
5860                    divLeft.position.z = height * 0.8;
5861                    divLeft.position.x = height / 2.5;
5862                    $(divLeft.element).css({
5863                      width: width,
5864                      left: -width / 2, //baseActive == 0 && isRTL == true? width
5865                      //: baseActive == book.pageCount && isRTL == true ? 0 : -width / 2
5866                    });
5867                  }
5868
5869                  if (pageRight !== void 0 && divRight !== void 0) {
5870                    width = Math.abs(
5871                      pageRight.geometry.boundingBox.max.x -
5872                        pageRight.geometry.boundingBox.min.x
5873                    );
5874                    height = Math.abs(
5875                      pageRight.geometry.boundingBox.max.z -
5876                        pageRight.geometry.boundingBox.min.z
5877                    );
5878
5879                    divRight.rotation.y = Math.atan2(height, width) * 0.9;
5880                    divRight.position.z = height * 0.8;
5881                    divRight.position.x = -height / 2.5;
5882                    $(divRight.element).css({
5883                      width: width,
5884                      left: width / 2, // == 0 && isRTL == true ? 0
5885                      //: baseActive == book.pageCount && isRTL == true ? -width : width / 2
5886                    });
5887                  }
5888
5889                  if (_this.options.onFlip !== void 0)
5890                    _this.options.onFlip(_this);
5891                }
5892              };
5893
5894              book.resize = (function () {
5895                _this.resize();
5896              })();
5897
5898              book.updatePageCallback = function () {
5899                _this.ui.update();
5900                _this.checkCenter();
5901                _this.stage.renderRequestPending = true;
5902              };
5903
5904              var divLeft = $(_this.stage.cssScene.divLeft.element);
5905              var divRight = $(_this.stage.cssScene.divRight.element);
5906
5907              book.preFlipCallback = function () {
5908                divLeft.empty();
5909                divRight.empty();
5910                if (_this.options.beforeFlip !== void 0)
5911                  _this.options.beforeFlip(_this);
5912
5913                _this.playSound();
5914              };
5915
5916              $(window).trigger("resize");
5917
5918              divLeft.css({
5919                width: 300 * contentProvider.pageRatio,
5920                height: 300,
5921                left: (-300 * contentProvider.pageRatio) / 2,
5922              });
5923
5924              divRight.css({
5925                width: 300 * contentProvider.pageRatio,
5926                height: 300,
5927                left: (300 * contentProvider.pageRatio) / 2,
5928              });
5929
5930              book.ease = TWEEN.Easing.Cubic.InOut;
5931              //book.ease = TWEEN.Easing.Quadratic.InOut;
5932              book.contentProvider = contentProvider;
5933              book.duration = _this.options.duration;
5934              book.gotoPage(book._activePage);
5935              book.flipCallback();
5936
5937              if (_this.options.onReady !== void 0)
5938                _this.options.onReady(_this);
5939            },
5940            options,
5941            _this
5942          );
5943        });
5944      } else {
5945        _this.contentProvider = new ContentProvider(
5946          _this.contentSource,
5947          function (contentProvider) {
5948            var options = {
5949              pageCount: contentProvider.pageCount, //Math.ceil(contentProvider.pageCount / 2) * 2
5950            };
5951
5952            _this.checkOpenPage();
5953            _this.target = book = new BookCSS(
5954              extendOptions(_this.options, options),
5955              _this.container
5956            );
5957            _this.target.previewObject = _this;
5958            _this.extendtarget();
5959            createUI(_this.container, _this);
5960            contentProvider.webgl = webgl;
5961            contentProvider.setTarget(_this.target);
5962            contentProvider.waitPeriod = 2;
5963            book.ease = TWEEN.Easing.Quadratic.InOut;
5964            book.duration = _this.options.duration;
5965
5966            /*					_this.ui.prev.hide();
5967					 _this.ui.next.hide();
5968
5969					 _this.ui.prev = book.prevButton;
5970					 _this.ui.next = book.nextButton;*/
5971
5972            book.container = _this.container;
5973            book.updatePageCallback = function () {
5974              _this.ui.update();
5975              _this.checkCenter();
5976            };
5977
5978            book.gotoPage(book._activePage);
5979
5980            book.resize = (function () {
5981              _this.resize();
5982            })();
5983
5984            $(window).trigger("resize");
5985
5986            book.flipCallback = function () {
5987              if (_this.contentProvider) {
5988                _this.contentProvider.review("flipCallback");
5989
5990                if (_this.options.onFlip !== void 0)
5991                  _this.options.onFlip(_this);
5992              }
5993            };
5994
5995            book.preFlipCallback = function () {
5996              if (_this.options.beforeFlip !== void 0)
5997                _this.options.beforeFlip(_this);
5998
5999              _this.playSound();
6000            };
6001
6002            if (_this.options.onReady !== void 0) _this.options.onReady(_this);
6003          },
6004          options,
6005          _this
6006        );
6007      }
6008    };
6009
6010    FlipBook.prototype.extendtarget = function () {
6011      var _this = this;
6012      _this.target.reset = function () {
6013        for (
6014          var pageCount = 0;
6015          pageCount < _this.target.children.length;
6016          pageCount++
6017        ) {
6018          var page = _this.target.children[pageCount];
6019          page.skipFlip = true;
6020          page.name = "-2";
6021        }
6022        _this.contentProvider.annotedPage = "-2";
6023        _this.target.refresh();
6024      };
6025    };
6026
6027    FlipBook.prototype.getURLHash = function () {
6028      if (this.options.id != void 0) {
6029        var hash =
6030          "dflip-" +
6031          (this.options.slug !== void 0 ? this.options.slug : this.options.id) +
6032          "/";
6033        if (this.target != void 0 && this.target._activePage != void 0) {
6034          hash += this.target._activePage + "/";
6035        }
6036        window.location.hash = hash;
6037      }
6038      return window.location.href;
6039    };
6040
6041    FlipBook.prototype.checkOpenPage = function () {
6042      //options value is overridden by attribute
6043      if (this.options.id != void 0) {
6044        var book = $("#" + this.options.id);
6045        if (book.length > 0 && book.data("page") !== void 0) {
6046          var pageNumber = parseInt(book.data("page"), 10);
6047          if (!isNaN(pageNumber)) this.options.openPage = pageNumber;
6048        }
6049      }
6050    };
6051
6052    FlipBook.prototype.end = function () {
6053      this.target.gotoPage(this.target.endPage);
6054    };
6055
6056    FlipBook.prototype.gotoPage = function (pageNumber) {
6057      this.target.gotoPage(pageNumber);
6058      if (this.ui !== void 0) this.ui.update();
6059    };
6060
6061    FlipBook.prototype.prev = function () {
6062      this.target.prev();
6063    };
6064
6065    FlipBook.prototype.next = function () {
6066      this.target.next();
6067    };
6068
6069    FlipBook.prototype.updateInfo = function (info) {
6070      if (this.container && this.container.info && this.container.info.html)
6071        this.container.info.html(info);
6072    };
6073    return FlipBook;
6074  })(PreviewObject);
6075
6076  $.fn.extend({
6077    shelf: function () {},
6078    flipBook: function (source, options) {
6079      return new FlipBook($(this), source, extendDFlipOptions(options));
6080    },
6081  });
6082})(DFLIP, jQuery);
6083
6084//Polyfills
6085
6086/**
6087 * Blob.js Polyfill
6088 * A Blob implementation.
6089 * 2014-07-24
6090 *
6091 * By Eli Grey, http://eligrey.com
6092 * By Devin Samarin, https://github.com/dsamarin
6093 * License: X11/MIT
6094 */
6095(function (view) {
6096  "use strict";
6097
6098  view.URL = view.URL || view.webkitURL;
6099
6100  if (view.Blob && view.URL) {
6101    try {
6102      new Blob();
6103      return;
6104    } catch (e) {}
6105  }
6106
6107  // Internally we use a BlobBuilder implementation to base Blob off of
6108  // in order to support older browsers that only have BlobBuilder
6109  var BlobBuilder =
6110    view.BlobBuilder ||
6111    view.WebKitBlobBuilder ||
6112    view.MozBlobBuilder ||
6113    (function (view) {
6114      var get_class = function (object) {
6115          return Object.prototype.toString
6116            .call(object)
6117            .match(/^\[object\s(.*)\]$/)[1];
6118        },
6119        FakeBlobBuilder = function BlobBuilder() {
6120          this.data = [];
6121        },
6122        FakeBlob = function Blob(data, type, encoding) {
6123          this.data = data;
6124          this.size = data.length;
6125          this.type = type;
6126          this.encoding = encoding;
6127        },
6128        FBB_proto = FakeBlobBuilder.prototype,
6129        FB_proto = FakeBlob.prototype,
6130        FileReaderSync = view.FileReaderSync,
6131        FileException = function (type) {
6132          this.code = this[(this.name = type)];
6133        },
6134        file_ex_codes = (
6135          "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR " +
6136          "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
6137        ).split(" "),
6138        file_ex_code = file_ex_codes.length,
6139        real_URL = view.URL || view.webkitURL || view,
6140        real_create_object_URL = real_URL.createObjectURL,
6141        real_revoke_object_URL = real_URL.revokeObjectURL,
6142        URL = real_URL,
6143        btoa = view.btoa,
6144        atob = view.atob,
6145        ArrayBuffer = view.ArrayBuffer,
6146        Uint8Array = view.Uint8Array,
6147        origin = /^[\w-]+:\/*\[?[\w\.:-]+\]?(?::[0-9]+)?/;
6148      FakeBlob.fake = FB_proto.fake = true;
6149      while (file_ex_code--) {
6150        FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
6151      }
6152      // Polyfill URL
6153      if (!real_URL.createObjectURL) {
6154        URL = view.URL = function (uri) {
6155          var uri_info = document.createElementNS(
6156              "http://www.w3.org/1999/xhtml",
6157              "a"
6158            ),
6159            uri_origin;
6160          uri_info.href = uri;
6161          if (!("origin" in uri_info)) {
6162            if (uri_info.protocol.toLowerCase() === "data:") {
6163              uri_info.origin = null;
6164            } else {
6165              uri_origin = uri.match(origin);
6166              uri_info.origin = uri_origin && uri_origin[1];
6167            }
6168          }
6169          return uri_info;
6170        };
6171      }
6172      URL.createObjectURL = function (blob) {
6173        var type = blob.type,
6174          data_URI_header;
6175        if (type === null) {
6176          type = "application/octet-stream";
6177        }
6178        if (blob instanceof FakeBlob) {
6179          data_URI_header = "data:" + type;
6180          if (blob.encoding === "base64") {
6181            return data_URI_header + ";base64," + blob.data;
6182          } else if (blob.encoding === "URI") {
6183            return data_URI_header + "," + decodeURIComponent(blob.data);
6184          }
6185          if (btoa) {
6186            return data_URI_header + ";base64," + btoa(blob.data);
6187          } else {
6188            return data_URI_header + "," + encodeURIComponent(blob.data);
6189          }
6190        } else if (real_create_object_URL) {
6191          return real_create_object_URL.call(real_URL, blob);
6192        }
6193      };
6194      URL.revokeObjectURL = function (object_URL) {
6195        if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
6196          real_revoke_object_URL.call(real_URL, object_URL);
6197        }
6198      };
6199      FBB_proto.append = function (data /*, endings*/) {
6200        var bb = this.data;
6201        // decode data to a binary string
6202        if (
6203          Uint8Array &&
6204          (data instanceof ArrayBuffer || data instanceof Uint8Array)
6205        ) {
6206          var str = "",
6207            buf = new Uint8Array(data),
6208            i = 0,
6209            buf_len = buf.length;
6210          for (; i < buf_len; i++) {
6211            str += String.fromCharCode(buf[i]);
6212          }
6213          bb.push(str);
6214        } else if (get_class(data) === "Blob" || get_class(data) === "File") {
6215          if (FileReaderSync) {
6216            var fr = new FileReaderSync();
6217            bb.push(fr.readAsBinaryString(data));
6218          } else {
6219            // async FileReader won't work as BlobBuilder is sync
6220            throw new FileException("NOT_READABLE_ERR");
6221          }
6222        } else if (data instanceof FakeBlob) {
6223          if (data.encoding === "base64" && atob) {
6224            bb.push(atob(data.data));
6225          } else if (data.encoding === "URI") {
6226            bb.push(decodeURIComponent(data.data));
6227          } else if (data.encoding === "raw") {
6228            bb.push(data.data);
6229          }
6230        } else {
6231          if (typeof data !== "string") {
6232            data += ""; // convert unsupported types to strings
6233          }
6234          // decode UTF-16 to binary string
6235          bb.push(unescape(encodeURIComponent(data)));
6236        }
6237      };
6238      FBB_proto.getBlob = function (type) {
6239        if (!arguments.length) {
6240          type = null;
6241        }
6242        return new FakeBlob(this.data.join(""), type, "raw");
6243      };
6244      FBB_proto.toString = function () {
6245        return "[object BlobBuilder]";
6246      };
6247      FB_proto.slice = function (start, end, type) {
6248        var args = arguments.length;
6249        if (args < 3) {
6250          type = null;
6251        }
6252        return new FakeBlob(
6253          this.data.slice(start, args > 1 ? end : this.data.length),
6254          type,
6255          this.encoding
6256        );
6257      };
6258      FB_proto.toString = function () {
6259        return "[object Blob]";
6260      };
6261      FB_proto.close = function () {
6262        this.size = 0;
6263        delete this.data;
6264      };
6265      return FakeBlobBuilder;
6266    })(view);
6267
6268  view.Blob = function (blobParts, options) {
6269    var type = options ? options.type || "" : "";
6270    var builder = new BlobBuilder();
6271    if (blobParts) {
6272      for (var i = 0, len = blobParts.length; i < len; i++) {
6273        if (Uint8Array && blobParts[i] instanceof Uint8Array) {
6274          builder.append(blobParts[i].buffer);
6275        } else {
6276          builder.append(blobParts[i]);
6277        }
6278      }
6279    }
6280    var blob = builder.getBlob(type);
6281    if (!blob.slice && blob.webkitSlice) {
6282      blob.slice = blob.webkitSlice;
6283    }
6284    return blob;
6285  };
6286
6287  var getPrototypeOf =
6288    Object.getPrototypeOf ||
6289    function (object) {
6290      return object.__proto__;
6291    };
6292  view.Blob.prototype = getPrototypeOf(new view.Blob());
6293})(window);
6294
6295/**
6296 * canvas-toBlob.js Polyfill
6297 * A canvas.toBlob() implementation.
6298 * 2013-12-27
6299 *
6300 * By Eli Grey, http://eligrey.com and Devin Samarin, https://github.com/eboyjr
6301 * License: X11/MIT
6302 *   See https://github.com/eligrey/canvas-toBlob.js/blob/master/LICENSE.md
6303 */
6304(function (view) {
6305  "use strict";
6306  var Uint8Array = view.Uint8Array,
6307    HTMLCanvasElement = view.HTMLCanvasElement,
6308    canvas_proto = HTMLCanvasElement && HTMLCanvasElement.prototype,
6309    is_base64_regex = /\s*;\s*base64\s*(?:;|$)/i,
6310    to_data_url = "toDataURL",
6311    base64_ranks,
6312    decode_base64 = function (base64) {
6313      var len = base64.length,
6314        buffer = new Uint8Array(((len / 4) * 3) | 0),
6315        i = 0,
6316        outptr = 0,
6317        last = [0, 0],
6318        state = 0,
6319        save = 0,
6320        rank,
6321        code;
6322      while (len--) {
6323        code = base64.charCodeAt(i++);
6324        rank = base64_ranks[code - 43];
6325        if (rank !== 255 && rank !== void 0) {
6326          last[1] = last[0];
6327          last[0] = code;
6328          save = (save << 6) | rank;
6329          state++;
6330          if (state === 4) {
6331            buffer[outptr++] = save >>> 16;
6332            if (last[1] !== 61 /* padding character */) {
6333              buffer[outptr++] = save >>> 8;
6334            }
6335            if (last[0] !== 61 /* padding character */) {
6336              buffer[outptr++] = save;
6337            }
6338            state = 0;
6339          }
6340        }
6341      }
6342      // 2/3 chance there's going to be some null bytes at the end, but that
6343      // doesn't really matter with most image formats.
6344      // If it somehow matters for you, truncate the buffer up outptr.
6345      return buffer;
6346    };
6347  if (Uint8Array) {
6348    base64_ranks = new Uint8Array([
6349      62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, 0,
6350      -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
6351      18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29,
6352      30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
6353      48, 49, 50, 51,
6354    ]);
6355  }
6356  if (HTMLCanvasElement && !canvas_proto.toBlob) {
6357    canvas_proto.toBlob = function (callback, type /*, ...args*/) {
6358      if (!type) {
6359        type = "image/png";
6360      }
6361      if (this.mozGetAsFile) {
6362        callback(this.mozGetAsFile("canvas", type));
6363        return;
6364      }
6365      if (this.msToBlob && /^\s*image\/png\s*(?:$|;)/i.test(type)) {
6366        callback(this.msToBlob());
6367        return;
6368      }
6369
6370      var args = Array.prototype.slice.call(arguments, 1),
6371        dataURI = this[to_data_url].apply(this, args),
6372        header_end = dataURI.indexOf(","),
6373        data = dataURI.substring(header_end + 1),
6374        is_base64 = is_base64_regex.test(dataURI.substring(0, header_end)),
6375        blob;
6376      if (Blob.fake) {
6377        // no reason to decode a data: URI that's just going to become a data URI again
6378        blob = new Blob();
6379        if (is_base64) {
6380          blob.encoding = "base64";
6381        } else {
6382          blob.encoding = "URI";
6383        }
6384        blob.data = data;
6385        blob.size = data.length;
6386      } else if (Uint8Array) {
6387        if (is_base64) {
6388          blob = new Blob([decode_base64(data)], { type: type });
6389        } else {
6390          blob = new Blob([decodeURIComponent(data)], { type: type });
6391        }
6392      }
6393      callback(blob);
6394    };
6395
6396    if (canvas_proto.toDataURLHD) {
6397      canvas_proto.toBlobHD = function () {
6398        to_data_url = "toDataURLHD";
6399        var blob = this.toBlob();
6400        to_data_url = "toDataURL";
6401        return blob;
6402      };
6403    } else {
6404      canvas_proto.toBlobHD = canvas_proto.toBlob;
6405    }
6406  }
6407})(window);
6408
6409/**
6410 * performance.now polyfill
6411 **/
6412(function PerformanceNowPolyfill() {
6413  if ("performance" in window === false) {
6414    window.performance = {};
6415  }
6416
6417  // IE 8
6418  Date.now =
6419    Date.now ||
6420    function () {
6421      return new Date().getTime();
6422    };
6423
6424  if ("now" in window.performance === false) {
6425    var offset =
6426      window.performance.timing && window.performance.timing.navigationStart
6427        ? window.performance.timing.navigationStart
6428        : Date.now();
6429
6430    window.performance.now = function () {
6431      return Date.now() - offset;
6432    };
6433  }
6434})();
6435
6436/**
6437 * Tween.js - Licensed under the MIT license
6438 * https://github.com/tweenjs/tween.js
6439 */
6440(function TweenJs() {
6441  var TWEEN =
6442    TWEEN ||
6443    (function () {
6444      var _tweens = [];
6445
6446      return {
6447        getAll: function () {
6448          return _tweens;
6449        },
6450
6451        removeAll: function () {
6452          _tweens = [];
6453        },
6454
6455        add: function (tween) {
6456          _tweens.push(tween);
6457        },
6458
6459        remove: function (tween) {
6460          var i = _tweens.indexOf(tween);
6461
6462          if (i !== -1) {
6463            _tweens.splice(i, 1);
6464          }
6465        },
6466
6467        update: function (time) {
6468          if (_tweens.length === 0) {
6469            return false;
6470          }
6471
6472          var i = 0;
6473
6474          time = time !== void 0 ? time : window.performance.now();
6475
6476          while (i < _tweens.length) {
6477            if (_tweens[i].update(time)) {
6478              i++;
6479            } else {
6480              _tweens.splice(i, 1);
6481            }
6482          }
6483
6484          return true;
6485        },
6486      };
6487    })();
6488
6489  TWEEN.Tween = function (object) {
6490    var _object = object;
6491    var _valuesStart = {};
6492    var _valuesEnd = {};
6493    var _valuesStartRepeat = {};
6494    var _duration = 1000;
6495    var _repeat = 0;
6496    var _yoyo = false;
6497    var _isPlaying = false;
6498    var _reversed = false;
6499    var _delayTime = 0;
6500    var _startTime = null;
6501    var _easingFunction = TWEEN.Easing.Linear.None;
6502    var _interpolationFunction = TWEEN.Interpolation.Linear;
6503    var _chainedTweens = [];
6504    var _onStartCallback = null;
6505    var _onStartCallbackFired = false;
6506    var _onUpdateCallback = null;
6507    var _onCompleteCallback = null;
6508    var _onStopCallback = null;
6509
6510    // Set all starting values present on the target object
6511    for (var field in object) {
6512      _valuesStart[field] = parseFloat(object[field], 10);
6513    }
6514
6515    this.to = function (properties, duration) {
6516      if (duration !== void 0) {
6517        _duration = duration;
6518      }
6519
6520      _valuesEnd = properties;
6521
6522      return this;
6523    };
6524
6525    this.start = function (time) {
6526      TWEEN.add(this);
6527
6528      _isPlaying = true;
6529
6530      _onStartCallbackFired = false;
6531
6532      _startTime = time !== void 0 ? time : window.performance.now();
6533      _startTime += _delayTime;
6534
6535      for (var property in _valuesEnd) {
6536        // Check if an Array was provided as property value
6537        if (_valuesEnd[property] instanceof Array) {
6538          if (_valuesEnd[property].length === 0) {
6539            continue;
6540          }
6541
6542          // Create a local copy of the Array with the start value at the front
6543          _valuesEnd[property] = [_object[property]].concat(
6544            _valuesEnd[property]
6545          );
6546        }
6547
6548        // If `to()` specifies a property that doesn't exist in the source object,
6549        // we should not set that property in the object
6550        if (_valuesStart[property] === void 0) {
6551          continue;
6552        }
6553
6554        _valuesStart[property] = _object[property];
6555
6556        if (_valuesStart[property] instanceof Array === false) {
6557          _valuesStart[property] *= 1.0; // Ensures we're using numbers, not strings
6558        }
6559
6560        _valuesStartRepeat[property] = _valuesStart[property] || 0;
6561      }
6562
6563      return this;
6564    };
6565
6566    this.stop = function () {
6567      if (!_isPlaying) {
6568        return this;
6569      }
6570
6571      TWEEN.remove(this);
6572      _isPlaying = false;
6573
6574      if (_onStopCallback !== null) {
6575        _onStopCallback.call(_object);
6576      }
6577
6578      this.stopChainedTweens();
6579      return this;
6580    };
6581
6582    this.stopChainedTweens = function () {
6583      for (
6584        var i = 0, numChainedTweens = _chainedTweens.length;
6585        i < numChainedTweens;
6586        i++
6587      ) {
6588        _chainedTweens[i].stop();
6589      }
6590    };
6591
6592    this.complete = function () {
6593      if (!_isPlaying) {
6594        return this;
6595      }
6596
6597      TWEEN.remove(this);
6598      _isPlaying = false;
6599
6600      if (_onCompleteCallback !== null) {
6601        _onCompleteCallback.call(_object);
6602      }
6603
6604      this.completeChainedTweens();
6605      return this;
6606    };
6607
6608    this.completeChainedTweens = function () {
6609      for (
6610        var i = 0, numChainedTweens = _chainedTweens.length;
6611        i < numChainedTweens;
6612        i++
6613      ) {
6614        _chainedTweens[i].complete();
6615      }
6616    };
6617
6618    this.delay = function (amount) {
6619      _delayTime = amount;
6620      return this;
6621    };
6622
6623    this.repeat = function (times) {
6624      _repeat = times;
6625      return this;
6626    };
6627
6628    this.yoyo = function (yoyo) {
6629      _yoyo = yoyo;
6630      return this;
6631    };
6632
6633    this.easing = function (easing) {
6634      _easingFunction = easing == void 0 ? _easingFunction : easing;
6635      return this;
6636    };
6637
6638    this.interpolation = function (interpolation) {
6639      _interpolationFunction = interpolation;
6640      return this;
6641    };
6642
6643    this.chain = function () {
6644      _chainedTweens = arguments;
6645      return this;
6646    };
6647
6648    this.onStart = function (callback) {
6649      _onStartCallback = callback;
6650      return this;
6651    };
6652
6653    this.onUpdate = function (callback) {
6654      _onUpdateCallback = callback;
6655      return this;
6656    };
6657
6658    this.onComplete = function (callback) {
6659      _onCompleteCallback = callback;
6660      return this;
6661    };
6662
6663    this.onStop = function (callback) {
6664      _onStopCallback = callback;
6665      return this;
6666    };
6667
6668    this.update = function (time) {
6669      var property;
6670      var elapsed;
6671      var value;
6672
6673      if (time < _startTime) {
6674        return true;
6675      }
6676
6677      if (_onStartCallbackFired === false) {
6678        if (_onStartCallback !== null) {
6679          _onStartCallback.call(_object);
6680        }
6681
6682        _onStartCallbackFired = true;
6683      }
6684
6685      elapsed = (time - _startTime) / _duration;
6686      elapsed = elapsed > 1 ? 1 : elapsed;
6687
6688      value = _easingFunction(elapsed);
6689
6690      for (property in _valuesEnd) {
6691        // Don't update properties that do not exist in the source object
6692        if (_valuesStart[property] === void 0) {
6693          continue;
6694        }
6695
6696        var start = _valuesStart[property] || 0;
6697        var end = _valuesEnd[property];
6698
6699        if (end instanceof Array) {
6700          _object[property] = _interpolationFunction(end, value);
6701        } else {
6702          // Parses relative end values with start as base (e.g.: +10, -3)
6703          if (typeof end === "string") {
6704            if (end.startsWith("+") || end.startsWith("-")) {
6705              end = start + parseFloat(end, 10);
6706            } else {
6707              end = parseFloat(end, 10);
6708            }
6709          }
6710
6711          // Protect against non numeric properties.
6712          if (typeof end === "number") {
6713            _object[property] = start + (end - start) * value;
6714          }
6715        }
6716      }
6717
6718      if (_onUpdateCallback !== null) {
6719        _onUpdateCallback.call(_object, value);
6720      }
6721
6722      if (elapsed === 1) {
6723        if (_repeat > 0) {
6724          if (isFinite(_repeat)) {
6725            _repeat--;
6726          }
6727
6728          // Reassign starting values, restart by making startTime = now
6729          for (property in _valuesStartRepeat) {
6730            if (typeof _valuesEnd[property] === "string") {
6731              _valuesStartRepeat[property] =
6732                _valuesStartRepeat[property] +
6733                parseFloat(_valuesEnd[property], 10);
6734            }
6735
6736            if (_yoyo) {
6737              var tmp = _valuesStartRepeat[property];
6738
6739              _valuesStartRepeat[property] = _valuesEnd[property];
6740              _valuesEnd[property] = tmp;
6741            }
6742
6743            _valuesStart[property] = _valuesStartRepeat[property];
6744          }
6745
6746          if (_yoyo) {
6747            _reversed = !_reversed;
6748          }
6749
6750          _startTime = time + _delayTime;
6751
6752          return true;
6753        } else {
6754          if (_onCompleteCallback !== null) {
6755            _onCompleteCallback.call(_object);
6756          }
6757
6758          for (
6759            var i = 0, numChainedTweens = _chainedTweens.length;
6760            i < numChainedTweens;
6761            i++
6762          ) {
6763            // Make the chained tweens start exactly at the time they should,
6764            // even if the `update()` method was called way past the duration of the tween
6765            _chainedTweens[i].start(_startTime + _duration);
6766          }
6767
6768          return false;
6769        }
6770      }
6771
6772      return true;
6773    };
6774  };
6775
6776  TWEEN.Easing = {
6777    Linear: {
6778      None: function (k) {
6779        return k;
6780      },
6781    },
6782
6783    Quadratic: {
6784      In: function (k) {
6785        return k * k;
6786      },
6787
6788      Out: function (k) {
6789        return k * (2 - k);
6790      },
6791
6792      InOut: function (k) {
6793        if ((k *= 2) < 1) {
6794          return 0.5 * k * k;
6795        }
6796
6797        return -0.5 * (--k * (k - 2) - 1);
6798      },
6799    },
6800    Quartic: {
6801      In: function (k) {
6802        return k * k * k * k;
6803      },
6804
6805      Out: function (k) {
6806        return 1 - --k * k * k * k;
6807      },
6808
6809      InOut: function (k) {
6810        if ((k *= 2) < 1) {
6811          return 0.5 * k * k * k * k;
6812        }
6813
6814        return -0.5 * ((k -= 2) * k * k * k - 2);
6815      },
6816    },
6817    Sinusoidal: {
6818      In: function (k) {
6819        return 1 - Math.cos((k * Math.PI) / 2);
6820      },
6821
6822      Out: function (k) {
6823        return Math.sin((k * Math.PI) / 2);
6824      },
6825
6826      InOut: function (k) {
6827        return 0.5 * (1 - Math.cos(Math.PI * k));
6828      },
6829    },
6830    Cubic: {
6831      In: function (k) {
6832        return k * k * k;
6833      },
6834
6835      Out: function (k) {
6836        return --k * k * k + 1;
6837      },
6838
6839      InOut: function (k) {
6840        if ((k *= 2) < 1) {
6841          return 0.5 * k * k * k;
6842        }
6843
6844        return 0.5 * ((k -= 2) * k * k + 2);
6845      },
6846    },
6847  };
6848
6849  TWEEN.Interpolation = {
6850    Linear: function (v, k) {
6851      var m = v.length - 1;
6852      var f = m * k;
6853      var i = Math.floor(f);
6854      var fn = TWEEN.Interpolation.Utils.Linear;
6855
6856      if (k < 0) {
6857        return fn(v[0], v[1], f);
6858      }
6859
6860      if (k > 1) {
6861        return fn(v[m], v[m - 1], m - f);
6862      }
6863
6864      return fn(v[i], v[i + 1 > m ? m : i + 1], f - i);
6865    },
6866
6867    Bezier: function (v, k) {
6868      var b = 0;
6869      var n = v.length - 1;
6870      var pw = Math.pow;
6871      var bn = TWEEN.Interpolation.Utils.Bernstein;
6872
6873      for (var i = 0; i <= n; i++) {
6874        b += pw(1 - k, n - i) * pw(k, i) * v[i] * bn(n, i);
6875      }
6876
6877      return b;
6878    },
6879
6880    Utils: {
6881      Linear: function (p0, p1, t) {
6882        return (p1 - p0) * t + p0;
6883      },
6884
6885      Bernstein: function (n, i) {
6886        var fc = TWEEN.Interpolation.Utils.Factorial;
6887
6888        return fc(n) / fc(i) / fc(n - i);
6889      },
6890
6891      Factorial: (function () {
6892        var a = [1];
6893
6894        return function (n) {
6895          var s = 1;
6896
6897          if (a[n]) {
6898            return a[n];
6899          }
6900
6901          for (var i = n; i > 1; i--) {
6902            s *= i;
6903          }
6904
6905          a[n] = s;
6906          return s;
6907        };
6908      })(),
6909
6910      CatmullRom: function (p0, p1, p2, p3, t) {
6911        var v0 = (p2 - p0) * 0.5;
6912        var v1 = (p3 - p1) * 0.5;
6913        var t2 = t * t;
6914        var t3 = t * t2;
6915
6916        return (
6917          (2 * p1 - 2 * p2 + v0 + v1) * t3 +
6918          (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 +
6919          v0 * t +
6920          p1
6921        );
6922      },
6923    },
6924  };
6925
6926  window.TWEEN = TWEEN;
6927})();
6928
6929DFLIP.createBlob = function createBlob(data, contentType) {
6930  if (typeof Blob !== "undefined") {
6931    return new Blob([data], { type: contentType });
6932  }
6933  // Blob builder is deprecated in FF14 and removed in FF18.
6934  var bb = new MozBlobBuilder();
6935  bb.append(data);
6936  return bb.getBlob(contentType);
6937};
6938
6939DFLIP.createObjectURL = (function createObjectURLClosure() {
6940  // Blob/createObjectURL is not available, falling back to data schema.
6941  var digits =
6942    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
6943
6944  return function createObjectURL(data, contentType) {
6945    if (typeof URL !== "undefined" && URL.createObjectURL) {
6946      var blob = DFLIP.createBlob(data, contentType);
6947      return URL.createObjectURL(blob);
6948    }
6949
6950    var buffer = "data:" + contentType + ";base64,";
6951    for (var i = 0, ii = data.length; i < ii; i += 3) {
6952      var b1 = data[i] & 0xff;
6953      var b2 = data[i + 1] & 0xff;
6954      var b3 = data[i + 2] & 0xff;
6955      var d1 = b1 >> 2,
6956        d2 = ((b1 & 3) << 4) | (b2 >> 4);
6957      var d3 = i + 1 < ii ? ((b2 & 0xf) << 2) | (b3 >> 6) : 64;
6958      var d4 = i + 2 < ii ? b3 & 0x3f : 64;
6959      buffer += digits[d1] + digits[d2] + digits[d3] + digits[d4];
6960    }
6961    return buffer;
6962  };
6963})();
6964
6965var ThumbList = (function ThumbListClosure() {
6966  function ThumbList(config) {
6967    var width = (config && config.w + "px") || "100%";
6968    var height = (config && config.h + "px") || "100%";
6969    var itemHeight = (this.itemHeight = config.itemHeight);
6970
6971    this.items = config.items;
6972    this.generatorFn = config.generatorFn;
6973    this.totalRows = config.totalRows || (config.items && config.items.length);
6974
6975    this.addFn = config.addFn;
6976    this.scrollFn = config.scrollFn;
6977
6978    var scroller = ThumbList.createScroller(itemHeight * this.totalRows);
6979    this.container = ThumbList.createContainer(width, height);
6980    this.container.appendChild(scroller);
6981
6982    this.screenItemsLen = Math.ceil(config.h / itemHeight);
6983    this.offsetItems = this.screenItemsLen;
6984    // Cache 4 times the number of items that fit in the container viewport
6985    this.cachedItemsLen = this.screenItemsLen + this.offsetItems * 2;
6986    this._renderChunk(this.container, 0);
6987
6988    var self = this;
6989    self.lastRepaintY = 0;
6990    var maxBuffer = this.screenItemsLen * itemHeight;
6991    var lastScrolled = 0;
6992
6993    var requestInterval;
6994
6995    function onScroll(e) {
6996      var scrollTop = e.target.scrollTop; // Triggers reflow
6997      if (
6998        !self.lastRepaintY ||
6999        Math.abs(scrollTop - self.lastRepaintY) >=
7000          self.offsetItems * self.itemHeight
7001      ) {
7002        var first = parseInt(scrollTop / itemHeight, 10) - self.offsetItems;
7003        self._renderChunk(self.container, first < 0 ? 0 : first);
7004        self.lastRepaintY = scrollTop;
7005      }
7006
7007      self.lastScrolled = lastScrolled = Date.now();
7008
7009      if (self.scrollFn !== void 0) {
7010        self.scrollFn();
7011      }
7012
7013      e.preventDefault && e.preventDefault();
7014    }
7015
7016    self.dispose = function () {
7017      if (self.container) {
7018        if (self.container.parentNode) {
7019          self.container.parentNode.removeChild(self.container);
7020        }
7021      }
7022
7023      self.container.removeEventListener("scroll", onScroll);
7024    };
7025
7026    self.container.addEventListener("scroll", onScroll);
7027  }
7028
7029  ThumbList.prototype.reset = function (height) {
7030    //container.find(".df-vrow").remove();
7031    this.screenItemsLen = Math.ceil(height / this.itemHeight);
7032    this.cachedItemsLen = this.screenItemsLen + this.offsetItems * 2;
7033    var first =
7034      parseInt(this.lastRepaintY / this.itemHeight, 10) - this.offsetItems;
7035    //this.lastRepaintY = 0;
7036    this.needReset = true;
7037    this._renderChunk(this.container, Math.max(first, 0));
7038  };
7039
7040  ThumbList.prototype.createRow = function (i) {
7041    var item;
7042    if (this.generatorFn) {
7043      item = this.generatorFn(i);
7044      item.classList.add("df-vrow");
7045      item.style.position = "absolute";
7046      item.style.top = i * this.itemHeight + "px";
7047      item.setAttribute("index", i);
7048    }
7049    return item;
7050  };
7051
7052  /**
7053   * Renders a particular, consecutive chunk of the total rows in the list. To
7054   * keep acceleration while scrolling, we mark the nodes that are candidate for
7055   * deletion instead of deleting them right away, which would suddenly stop the
7056   * acceleration. We delete them once scrolling has finished.
7057   *
7058   * @param {Node} node Parent node where we want to append the children chunk.
7059   * @param {Number} from Starting position, i.e. first children index.
7060   * @return {void}
7061   */
7062  ThumbList.prototype._renderChunk = function (node, from) {
7063    var isEmpty = this.range == void 0;
7064    this.range = this.range || { min: 0, max: this.cachedItemsLen };
7065    var range = this.range;
7066
7067    var min = range.min,
7068      max = range.max;
7069
7070    var isAdd = isEmpty ? true : from >= min;
7071
7072    if (!isEmpty && from == min && this.needReset == false) return;
7073
7074    var countVar;
7075
7076    var start = isEmpty ? min : isAdd ? max : from; // - this.cachedItemsLen/3;
7077
7078    start = start > this.totalRows ? this.totalRows : start < 0 ? 0 : start;
7079
7080    var end = from + this.cachedItemsLen; //this.cachedItemsLen/3);
7081
7082    end = end > this.totalRows ? this.totalRows : end;
7083
7084    for (countVar = start; countVar < end; countVar++) {
7085      if (isAdd) node.appendChild(this.createRow(countVar));
7086      else
7087        node.insertBefore(
7088          this.createRow(countVar),
7089          node.childNodes[1 + countVar - start]
7090        );
7091      if (this.addFn !== void 0) {
7092        this.addFn(countVar);
7093      }
7094    }
7095    var difference = Math.abs(from - min);
7096    this.needReset = false;
7097    if (!isEmpty && node.childNodes.length > this.cachedItemsLen + 1) {
7098      // Hide and mark obsolete nodes for deletion.
7099      var delStart = isAdd ? 1 : 1 + this.cachedItemsLen,
7100        delEnd = delStart + (end - start);
7101
7102      for (var j = delEnd; j > delStart; j--) {
7103        if (node.childNodes[delStart])
7104          this.container.removeChild(node.childNodes[delStart]);
7105      }
7106    }
7107    this.range.min = from;
7108    this.range.max = end;
7109  };
7110
7111  ThumbList.createContainer = function (w, h) {
7112    var c = document.createElement("div");
7113    c.style.width = w;
7114    c.style.height = h;
7115    c.style.overflow = "auto";
7116    c.style.position = "relative";
7117    c.style.padding = 0;
7118    //c.style.border = '1px solid black';
7119    return c;
7120  };
7121
7122  ThumbList.createScroller = function (h) {
7123    var scroller = document.createElement("div");
7124    scroller.style.opacity = 0;
7125    scroller.style.position = "absolute";
7126    scroller.style.top = 0;
7127    scroller.style.left = 0;
7128    scroller.style.width = "1px";
7129    scroller.style.height = h + "px";
7130    return scroller;
7131  };
7132  return ThumbList;
7133})();
7134
7135/**
7136 * @typedef {Object} BookMarkViewerOptions
7137 * @property {HTMLDivElement} container - The viewer element.
7138 * @property {IPDFLinkService} linkService - The navigation/linking service.
7139 */
7140
7141/**
7142 * @typedef {Object} BookMarkViewerRenderParameters
7143 * @property {Array|null} outline - An array of outline objects.
7144 */
7145
7146/**
7147 * @class
7148 */
7149var BookMarkViewer = (function BookMarkViewerClosure() {
7150  /**
7151   * @constructs BookMarkViewer
7152   * @param {BookMarkViewerOptions} options
7153   */
7154  function BookMarkViewer(options) {
7155    this.outline = null;
7156    this.lastToggleIsShow = true;
7157    this.container = options.container;
7158    this.linkService = options.linkService;
7159    this.outlineItemClass = options.outlineItemClass || "outlineItem";
7160    this.outlineToggleClass =
7161      options.outlineToggleClass || "outlineItemToggler";
7162    this.outlineToggleHiddenClass =
7163      options.outlineToggleHiddenClass || "outlineItemsHidden";
7164  }
7165
7166  BookMarkViewer.prototype = {
7167    dispose: function () {
7168      if (this.container) {
7169        if (this.container.parentNode) {
7170          this.container.parentNode.removeChild(this.container);
7171        }
7172      }
7173      this.linkService = null;
7174    },
7175    reset: function BookMarkViewer_reset() {
7176      this.outline = null;
7177      this.lastToggleIsShow = true;
7178
7179      var container = this.container;
7180      while (container.firstChild) {
7181        container.removeChild(container.firstChild);
7182      }
7183    },
7184
7185    /**
7186     * @private
7187     */
7188    _dispatchEvent: function BookMarkViewer_dispatchEvent(outlineCount) {
7189      var event = document.createEvent("CustomEvent");
7190      event.initCustomEvent("outlineloaded", true, true, {
7191        outlineCount: outlineCount,
7192      });
7193      this.container.dispatchEvent(event);
7194    },
7195
7196    /**
7197     * @private
7198     */
7199    _bindLink: function BookMarkViewer_bindLink(element, item) {
7200      var linkService = this.linkService;
7201      if (item.custom == true) {
7202        element.href = linkService.getCustomDestinationHash(item.dest);
7203        element.onclick = function goToDestination(e) {
7204          linkService.customNavigateTo(item.dest);
7205          return false;
7206        };
7207      } else {
7208        if (item.url) {
7209          PDFJS.addLinkAttributes(element, { url: item.url });
7210          return;
7211        }
7212
7213        element.href = linkService.getDestinationHash(item.dest);
7214        element.onclick = function goToDestination(e) {
7215          linkService.navigateTo(item.dest);
7216          return false;
7217        };
7218      }
7219    },
7220
7221    /**
7222     * Prepend a button before an outline item which allows the user to toggle
7223     * the visibility of all outline items at that level.
7224     *
7225     * @private
7226     */
7227    _addToggleButton: function BookMarkViewer_addToggleButton(div) {
7228      var toggler = document.createElement("div");
7229      toggler.className =
7230        this.outlineToggleClass + " " + this.outlineToggleHiddenClass;
7231      toggler.onclick = function (event) {
7232        event.stopPropagation();
7233        toggler.classList.toggle(this.outlineToggleHiddenClass);
7234
7235        if (event.shiftKey) {
7236          var shouldShowAll = !toggler.classList.contains(
7237            this.outlineToggleHiddenClass
7238          );
7239          this._toggleOutlineItem(div, shouldShowAll);
7240        }
7241      }.bind(this);
7242      div.insertBefore(toggler, div.firstChild);
7243    },
7244
7245    /**
7246     * Toggle the visibility of the subtree of an outline item.
7247     *
7248     * @param {Element} root - the root of the outline (sub)tree.
7249     * @param {boolean} show - whether to show the outline (sub)tree. If false,
7250     *   the outline subtree rooted at |root| will be collapsed.
7251     *
7252     * @private
7253     */
7254    _toggleOutlineItem: function BookMarkViewer_toggleOutlineItem(root, show) {
7255      this.lastToggleIsShow = show;
7256      var togglers = root.querySelectorAll("." + this.outlineToggleClass);
7257      for (var i = 0, ii = togglers.length; i < ii; ++i) {
7258        togglers[i].classList[show ? "remove" : "add"](
7259          this.outlineToggleHiddenClass
7260        );
7261      }
7262    },
7263
7264    /**
7265     * Collapse or expand all subtrees of the outline.
7266     */
7267    toggleOutlineTree: function BookMarkViewer_toggleOutlineTree() {
7268      if (!this.outline) {
7269        return;
7270      }
7271      this._toggleOutlineItem(this.container, !this.lastToggleIsShow);
7272    },
7273
7274    /**
7275     * @param {BookMarkViewerRenderParameters} params
7276     */
7277    render: function BookMarkViewer_render(params) {
7278      var outline = (params && params.outline) || null;
7279      var outlineCount = 0;
7280
7281      if (this.outline) {
7282        this.reset();
7283      }
7284      this.outline = outline;
7285
7286      if (!outline) {
7287        //this._dispatchEvent(outlineCount);
7288        return;
7289      }
7290
7291      var fragment = document.createDocumentFragment();
7292      var queue = [{ parent: fragment, items: this.outline }];
7293      var hasAnyNesting = false;
7294      while (queue.length > 0) {
7295        var levelData = queue.shift();
7296        var isCustom = levelData.custom;
7297        for (var i = 0, len = levelData.items.length; i < len; i++) {
7298          var item = levelData.items[i];
7299
7300          var div = document.createElement("div");
7301          div.className = this.outlineItemClass;
7302
7303          var element = document.createElement("a");
7304          if (item.custom == void 0 && isCustom !== void 0)
7305            item.custom = isCustom;
7306
7307          this._bindLink(element, item);
7308          //element.
7309          element.textContent = item.title.replace(/\x00/g, "");
7310          //PDFJS.removeNullCharacters(item.title) || "Untitled Bookmark";
7311
7312          div.appendChild(element);
7313
7314          if (item.items && item.items.length > 0) {
7315            hasAnyNesting = true;
7316            this._addToggleButton(div);
7317
7318            var itemsDiv = document.createElement("div");
7319            itemsDiv.className = this.outlineItemClass + "s";
7320            div.appendChild(itemsDiv);
7321            queue.push({
7322              parent: itemsDiv,
7323              custom: item.custom,
7324              items: item.items,
7325            });
7326          }
7327
7328          levelData.parent.appendChild(div);
7329          outlineCount++;
7330        }
7331      }
7332      if (hasAnyNesting) {
7333        if (this.container.classList != void 0) {
7334          this.container.classList.add(this.outlineItemClass + "s");
7335        } else if (this.container.className != void 0) {
7336          this.container.className += " picWindow";
7337        }
7338      }
7339
7340      this.container.appendChild(fragment);
7341
7342      this._dispatchEvent(outlineCount);
7343    },
7344  };
7345
7346  return BookMarkViewer;
7347})();
7348//PDFJS.PDFOutlineViewer = PDFOutlineViewer;
7349
7350var DFLightBox = (function DFLightBoxClosure($) {
7351  /**
7352   * @constructs DFLightBox
7353   * @param closeCallback callBack function required to dispose object properly when lighbox is closed
7354   */
7355  function DFLightBox(closeCallback, options) {
7356    this.duration = 300;
7357
7358    //cache this
7359    var _this = this;
7360    //lightbox wrapper div
7361    _this.lightboxWrapper = $("<div>").addClass("df-lightbox-wrapper");
7362
7363    //lightbox container
7364    _this.container = $("<div>")
7365      .addClass("df-container")
7366      .appendTo(_this.lightboxWrapper);
7367    //lightbox controls
7368    _this.controls = $("<div>")
7369      .addClass("df-lightbox-controls")
7370      .appendTo(_this.lightboxWrapper);
7371
7372    //lightbox close button
7373    _this.closeButton = $("<div>")
7374      .addClass("df-lightbox-close df-ui-btn")
7375      .on("click", function () {
7376        _this.close(closeCallback);
7377      })
7378      .appendTo(_this.controls);
7379
7380    _this.lightboxWrapper.append(_this.container);
7381
7382    return _this;
7383  }
7384
7385  DFLightBox.prototype.show = function (callback) {
7386    if (this.lightboxWrapper.parent().length == 0)
7387      $("body").append(this.lightboxWrapper);
7388
7389    this.lightboxWrapper.fadeIn(this.duration, callback);
7390
7391    return this;
7392  };
7393
7394  DFLightBox.prototype.close = function (callback) {
7395    this.lightboxWrapper.fadeOut(this.duration);
7396    setTimeout(callback, this.duration);
7397
7398    return this;
7399  };
7400
7401  return DFLightBox;
7402})(jQuery);
7403
7404DFLIP.Share = (function ShareClosure($) {
7405  function Share(container, options) {
7406    var _this = this;
7407    var htmlDiv = "<div>";
7408    var shareButtonClass = "df-share-button";
7409    var windowParameters = "width=500,height=400";
7410    _this.isOpen = false;
7411    _this.shareUrl = "";
7412    _this.wrapper = $(
7413      '<div class="df-share-wrapper" style="display: none;">'
7414    ).on("click", function (e) {
7415      _this.close();
7416    });
7417    _this.box = $('<div class="df-share-box">')
7418      .on("click", function (e) {
7419        e.preventDefault();
7420        e.stopPropagation();
7421      })
7422      .appendTo(_this.wrapper)
7423      .html('<span class="df-share-title">' + options.text.share + "</span>");
7424    _this.urlInput = $('<textarea class="df-share-url">').on(
7425      "click",
7426      function () {
7427        $(this).select();
7428      }
7429    );
7430
7431    _this.facebook = $(htmlDiv, {
7432      class:
7433        shareButtonClass + " df-share-facebook " + options.icons["facebook"],
7434    }).on("click", function (e) {
7435      window.open(
7436        "https://www.facebook.com/sharer/sharer.php?u=" +
7437          encodeURIComponent(_this.shareUrl),
7438        "Sharer",
7439        windowParameters
7440      );
7441    });
7442    _this.google = $(htmlDiv, {
7443      class: shareButtonClass + " df-share-google " + options.icons["google"],
7444    }).on("click", function (e) {
7445      window.open(
7446        "https://plus.google.com/share?url=" +
7447          encodeURIComponent(_this.shareUrl),
7448        "Sharer",
7449        windowParameters
7450      );
7451    });
7452    _this.twitter = $(htmlDiv, {
7453      class: shareButtonClass + " df-share-twitter " + options.icons["twitter"],
7454    }).on("click", function (e) {
7455      window.open(
7456        "http://twitter.com/share?url=" + encodeURIComponent(_this.shareUrl),
7457        "Sharer",
7458        windowParameters
7459      );
7460    });
7461    _this.mail = $("<a>", {
7462      class: shareButtonClass + " df-share-mail " + options.icons["mail"],
7463      href:
7464        "mailto:?subject=I wanted you to see this FlipBook&body=Check out this site " +
7465        encodeURIComponent(_this.shareUrl),
7466      target: "_blank",
7467    }).on("click", function (e) {
7468      $(this).attr(
7469        "href",
7470        "mailto:?subject=I wanted you to see this FlipBook&body=Check out this site " +
7471          encodeURIComponent(_this.shareUrl)
7472      );
7473      e.stopPropagation(); //so the default event is not cancelled by parent element
7474    });
7475
7476    _this.box
7477      .append(_this.urlInput)
7478      .append(_this.facebook)
7479      .append(_this.google)
7480      .append(_this.twitter)
7481      .append(_this.mail);
7482    $(container).append(_this.wrapper);
7483  }
7484
7485  Share.prototype.show = function () {
7486    this.wrapper.fadeIn(300);
7487    this.urlInput.val(this.shareUrl);
7488    this.urlInput.trigger("click");
7489    this.isOpen = true;
7490  };
7491
7492  Share.prototype.dispose = function () {
7493    var _this = this;
7494    _this.box.off();
7495    _this.google.off();
7496    _this.twitter.off();
7497    _this.facebook.off();
7498    _this.mail.off();
7499    _this.urlInput.off();
7500    _this.wrapper.off().remove();
7501  };
7502
7503  Share.prototype.close = function () {
7504    this.wrapper.fadeOut(300);
7505    this.isOpen = false;
7506  };
7507
7508  Share.prototype.update = function (url) {
7509    this.shareUrl = url;
7510  };
7511
7512  return Share;
7513})(jQuery);
7514DFLIP.Popup = (function PopupClosure($) {
7515  function Popup(container, options) {
7516    var _this = this;
7517    var htmlDiv = "<div>";
7518    var windowParameters = "width=500,height=400";
7519    _this.isOpen = false;
7520    _this.wrapper = $(
7521      '<div class="df-popup-wrapper" style="display: none;">'
7522    ).on("click", function (e) {
7523      _this.close();
7524    });
7525    _this.box = $('<div class="df-popup-box">')
7526      .on("click", function (e) {
7527        e.preventDefault();
7528        e.stopPropagation();
7529      })
7530      .appendTo(_this.wrapper);
7531
7532    $(container).append(_this.wrapper);
7533  }
7534
7535  Popup.prototype.show = function () {
7536    this.wrapper.fadeIn(300);
7537    this.isOpen = true;
7538  };
7539
7540  Popup.prototype.dispose = function () {
7541    var _this = this;
7542    _this.box.off();
7543    _this.wrapper.off().remove();
7544  };
7545
7546  Popup.prototype.close = function () {
7547    this.wrapper.fadeOut(300);
7548    this.isOpen = false;
7549  };
7550
7551  return Popup;
7552})(jQuery);
7553
7554/**
7555 * Performs navigation functions inside PDF, such as opening specified page,
7556 * or destination.
7557 * @class
7558 * @implements {IPDFLinkService}
7559 */
7560var PDFLinkService = (function () {
7561  /**
7562   * @constructs PDFLinkService
7563   */
7564  function PDFLinkService() {
7565    this.baseUrl = null;
7566    this.pdfDocument = null;
7567    this.pdfViewer = null;
7568    this.pdfHistory = null;
7569
7570    this._pagesRefCache = null;
7571  }
7572
7573  PDFLinkService.prototype = {
7574    dispose: function () {
7575      this.baseUrl = null;
7576      this.pdfDocument = null;
7577      this.pdfViewer = null;
7578      this.pdfHistory = null;
7579
7580      this._pagesRefCache = null;
7581    },
7582    setDocument: function PDFLinkService_setDocument(pdfDocument, baseUrl) {
7583      this.baseUrl = baseUrl;
7584      this.pdfDocument = pdfDocument;
7585      this._pagesRefCache = Object.create(null);
7586    },
7587
7588    setViewer: function PDFLinkService_setViewer(pdfViewer) {
7589      this.pdfViewer = pdfViewer;
7590    },
7591
7592    setHistory: function PDFLinkService_setHistory(pdfHistory) {
7593      this.pdfHistory = pdfHistory;
7594    },
7595
7596    /**
7597     * @returns {number}
7598     */
7599    get pagesCount() {
7600      return this.pdfDocument.numPages;
7601    },
7602
7603    /**
7604     * @returns {number}
7605     */
7606    get page() {
7607      return this.pdfViewer.currentPageNumber;
7608    },
7609
7610    /**
7611     * @param {number} value
7612     */
7613    set page(value) {
7614      this.pdfViewer.currentPageNumber = value;
7615    },
7616
7617    /**
7618     * @param dest - The PDF destination object.
7619     */
7620    navigateTo: function PDFLinkService_navigateTo(dest) {
7621      var destString = "";
7622      var self = this;
7623
7624      var goToDestination = function (destRef) {
7625        // dest array looks like that: <page-ref> </XYZ|FitXXX> <args..>
7626        var pageNumber =
7627          destRef instanceof Object
7628            ? self._pagesRefCache[destRef.num + " " + destRef.gen + " R"]
7629            : destRef + 1;
7630        if (pageNumber) {
7631          if (pageNumber > self.pagesCount) {
7632            pageNumber = self.pagesCount;
7633          }
7634          self.pdfViewer.gotoPage(pageNumber);
7635          // self.pdfViewer.scrollPageIntoView(pageNumber, dest);
7636
7637          if (self.pdfHistory) {
7638            // Update the browsing history.
7639            self.pdfHistory.push({
7640              dest: dest,
7641              hash: destString,
7642              page: pageNumber,
7643            });
7644          }
7645        } else {
7646          self.pdfDocument.getPageIndex(destRef).then(function (pageIndex) {
7647            var pageNum = pageIndex + 1;
7648            var cacheKey = destRef.num + " " + destRef.gen + " R";
7649            self._pagesRefCache[cacheKey] = pageNum;
7650            goToDestination(destRef);
7651          });
7652        }
7653      };
7654
7655      var destinationPromise;
7656      if (typeof dest === "string") {
7657        destString = dest;
7658        destinationPromise = this.pdfDocument.getDestination(dest);
7659      } else {
7660        destinationPromise = Promise.resolve(dest);
7661      }
7662      destinationPromise.then(function (destination) {
7663        dest = destination;
7664        if (!(destination instanceof Array)) {
7665          return; // invalid destination
7666        }
7667        goToDestination(destination[0]);
7668      });
7669    },
7670
7671    /**
7672     * @param dest - The PDF destination object.
7673     */
7674    customNavigateTo: function PDFLinkService_navigateTo(dest) {
7675      if (dest == "" || dest == void 0 || dest == "void 0") return;
7676      var pageNumber = void 0;
7677      if (!isNaN(Math.round(dest))) {
7678        pageNumber = dest;
7679      } else if (typeof dest === "string") {
7680        pageNumber = parseInt(dest.replace("#", ""), 10);
7681        if (isNaN(pageNumber)) {
7682          window.open(dest);
7683          return;
7684        }
7685      }
7686
7687      if (pageNumber !== void 0) this.pdfViewer.gotoPage(pageNumber);
7688    },
7689
7690    /**
7691     * @param dest - The PDF destination object.
7692     * @returns {string} The hyperlink to the PDF object.
7693     */
7694    getDestinationHash: function PDFLinkService_getDestinationHash(dest) {
7695      if (typeof dest === "string") {
7696        return this.getAnchorUrl("#" + escape(dest));
7697      }
7698      if (dest instanceof Array) {
7699        var destRef = dest[0]; // see navigateTo method for dest format
7700        var pageNumber =
7701          destRef instanceof Object
7702            ? this._pagesRefCache[destRef.num + " " + destRef.gen + " R"]
7703            : destRef + 1;
7704        if (pageNumber) {
7705          var pdfOpenParams = this.getAnchorUrl("#page=" + pageNumber);
7706          var destKind = dest[1];
7707          if (
7708            typeof destKind === "object" &&
7709            "name" in destKind &&
7710            destKind.name === "XYZ"
7711          ) {
7712            var scale = dest[4] || this.pdfViewer.currentScaleValue;
7713            var scaleNumber = parseFloat(scale);
7714            if (scaleNumber) {
7715              scale = scaleNumber * 100;
7716            }
7717            pdfOpenParams += "&zoom=" + scale;
7718            if (dest[2] || dest[3]) {
7719              pdfOpenParams += "," + (dest[2] || 0) + "," + (dest[3] || 0);
7720            }
7721          }
7722          return pdfOpenParams;
7723        }
7724      }
7725      return this.getAnchorUrl("");
7726    },
7727
7728    /**
7729     * @param dest - The PDF destination object.
7730     * @returns {string} The hyperlink to the PDF object.
7731     */
7732    getCustomDestinationHash: function PDFLinkService_getCustomDestinationHash(
7733      dest
7734    ) {
7735      //if (typeof dest === 'string') {
7736      return "#" + escape(dest);
7737      //}
7738      //return this.getAnchorUrl('');
7739    },
7740
7741    /**
7742     * Prefix the full url on anchor links to make sure that links are resolved
7743     * relative to the current URL instead of the one defined in <base href>.
7744     * @param {String} anchor The anchor hash, including the #.
7745     * @returns {string} The hyperlink to the PDF object.
7746     */
7747    getAnchorUrl: function PDFLinkService_getAnchorUrl(anchor) {
7748      return (this.baseUrl || "") + anchor;
7749    },
7750
7751    /**
7752     * @param {string} hash
7753     */
7754    setHash: function PDFLinkService_setHash(hash) {
7755      if (hash.indexOf("=") >= 0) {
7756        var params = parseQueryString(hash);
7757        // borrowing syntax from "Parameters for Opening PDF Files"
7758        if ("nameddest" in params) {
7759          if (this.pdfHistory) {
7760            this.pdfHistory.updateNextHashParam(params.nameddest);
7761          }
7762          this.navigateTo(params.nameddest);
7763          return;
7764        }
7765        var pageNumber, dest;
7766        if ("page" in params) {
7767          pageNumber = params.page | 0 || 1;
7768        }
7769        if ("zoom" in params) {
7770          // Build the destination array.
7771          var zoomArgs = params.zoom.split(","); // scale,left,top
7772          var zoomArg = zoomArgs[0];
7773          var zoomArgNumber = parseFloat(zoomArg);
7774
7775          if (zoomArg.indexOf("Fit") === -1) {
7776            // If the zoomArg is a number, it has to get divided by 100. If it's
7777            // a string, it should stay as it is.
7778            dest = [
7779              null,
7780              { name: "XYZ" },
7781              zoomArgs.length > 1 ? zoomArgs[1] | 0 : null,
7782              zoomArgs.length > 2 ? zoomArgs[2] | 0 : null,
7783              zoomArgNumber ? zoomArgNumber / 100 : zoomArg,
7784            ];
7785          } else {
7786            if (zoomArg === "Fit" || zoomArg === "FitB") {
7787              dest = [null, { name: zoomArg }];
7788            } else if (
7789              zoomArg === "FitH" ||
7790              zoomArg === "FitBH" ||
7791              zoomArg === "FitV" ||
7792              zoomArg === "FitBV"
7793            ) {
7794              dest = [
7795                null,
7796                { name: zoomArg },
7797                zoomArgs.length > 1 ? zoomArgs[1] | 0 : null,
7798              ];
7799            } else if (zoomArg === "FitR") {
7800              if (zoomArgs.length !== 5) {
7801                console.error(
7802                  "PDFLinkService_setHash: " +
7803                    "Not enough parameters for 'FitR'."
7804                );
7805              } else {
7806                dest = [
7807                  null,
7808                  { name: zoomArg },
7809                  zoomArgs[1] | 0,
7810                  zoomArgs[2] | 0,
7811                  zoomArgs[3] | 0,
7812                  zoomArgs[4] | 0,
7813                ];
7814              }
7815            } else {
7816              console.error(
7817                "PDFLinkService_setHash: '" +
7818                  zoomArg +
7819                  "' is not a valid zoom value."
7820              );
7821            }
7822          }
7823        }
7824        if (dest) {
7825          this.pdfViewer.scrollPageIntoView(pageNumber || this.page, dest);
7826        } else if (pageNumber) {
7827          this.page = pageNumber; // simple page
7828        }
7829        if ("pagemode" in params) {
7830          var event = document.createEvent("CustomEvent");
7831          event.initCustomEvent("pagemode", true, true, {
7832            mode: params.pagemode,
7833          });
7834          this.pdfViewer.container.dispatchEvent(event);
7835        }
7836      } else if (/^\d+$/.test(hash)) {
7837        // page number
7838        this.page = hash;
7839      } else {
7840        // named destination
7841        if (this.pdfHistory) {
7842          this.pdfHistory.updateNextHashParam(unescape(hash));
7843        }
7844        this.navigateTo(unescape(hash));
7845      }
7846    },
7847
7848    /**
7849     * @param {string} action
7850     */
7851    executeNamedAction: function PDFLinkService_executeNamedAction(action) {
7852      // See PDF reference, table 8.45 - Named action
7853      switch (action) {
7854        case "GoBack":
7855          if (this.pdfHistory) {
7856            this.pdfHistory.back();
7857          }
7858          break;
7859
7860        case "GoForward":
7861          if (this.pdfHistory) {
7862            this.pdfHistory.forward();
7863          }
7864          break;
7865
7866        case "NextPage":
7867          this.page++;
7868          break;
7869
7870        case "PrevPage":
7871          this.page--;
7872          break;
7873
7874        case "LastPage":
7875          this.page = this.pagesCount;
7876          break;
7877
7878        case "FirstPage":
7879          this.page = 1;
7880          break;
7881
7882        default:
7883          break; // No action according to spec
7884      }
7885
7886      var event = document.createEvent("CustomEvent");
7887      event.initCustomEvent("namedaction", true, true, {
7888        action: action,
7889      });
7890      this.pdfViewer.container.dispatchEvent(event);
7891    },
7892
7893    /**
7894     * @param {number} pageNum - page number.
7895     * @param {Object} pageRef - reference to the page.
7896     */
7897    cachePageRef: function PDFLinkService_cachePageRef(pageNum, pageRef) {
7898      var refStr = pageRef.num + " " + pageRef.gen + " R";
7899      this._pagesRefCache[refStr] = pageNum;
7900    },
7901  };
7902
7903  return PDFLinkService;
7904})();
7905//PDFJS.PDFLinkService = PDFLinkService;
7906
7907/**
7908 * @typedef {Object} TextLayerBuilderOptions
7909 * @property {HTMLDivElement} textLayerDiv - The text layer container.
7910 * @property {EventBus} eventBus - The application event bus.
7911 * @property {number} pageIndex - The page index.
7912 * @property {PageViewport} viewport - The viewport of the text layer.
7913 * @property {PDFFindController} findController
7914 * @property {boolean} enhanceTextSelection - Option to turn on improved
7915 *   text selection.
7916 */
7917
7918/**
7919 * TextLayerBuilder provides text-selection functionality for the PDF.
7920 * It does this by creating overlay divs over the PDF text. These divs
7921 * contain text that matches the PDF text they are overlaying. This object
7922 * also provides a way to highlight text that is being searched for.
7923 * @class
7924 */
7925DFLIP.TextLayerBuilder = (function TextLayerBuilderClosure() {
7926  function TextLayerBuilder(options) {
7927    this.textLayerDiv = options.textLayerDiv;
7928    this.renderingDone = false;
7929    this.divContentDone = false;
7930    this.pageIdx = options.pageIndex;
7931    this.pageNumber = this.pageIdx + 1;
7932    this.matches = [];
7933    this.viewport = options.viewport;
7934    this.textDivs = [];
7935    this.findController = options.findController || null;
7936    this.textLayerRenderTask = null;
7937    this.enhanceTextSelection = options.enhanceTextSelection;
7938    this._bindMouse();
7939  }
7940
7941  TextLayerBuilder.prototype = {
7942    _finishRendering: function TextLayerBuilder_finishRendering() {
7943      this.renderingDone = true;
7944
7945      if (!this.enhanceTextSelection) {
7946        var endOfContent = document.createElement("div");
7947        endOfContent.className = "endOfContent";
7948        this.textLayerDiv.appendChild(endOfContent);
7949      }
7950
7951      /*			this.eventBus.dispatch('textlayerrendered', {
7952			 source: this,
7953			 pageNumber: this.pageNumber
7954			 });*/
7955    },
7956
7957    /**
7958     * Renders the text layer.
7959     * @param {number} timeout (optional) if specified, the rendering waits
7960     *   for specified amount of ms.
7961     */
7962    render: function TextLayerBuilder_render(timeout) {
7963      if (!this.divContentDone || this.renderingDone) {
7964        return;
7965      }
7966
7967      if (this.textLayerRenderTask) {
7968        this.textLayerRenderTask.cancel();
7969        this.textLayerRenderTask = null;
7970      }
7971
7972      this.textDivs = [];
7973      var textLayerFrag = document.createDocumentFragment();
7974      this.textLayerRenderTask = PDFJS.renderTextLayer({
7975        textContent: this.textContent,
7976        container: textLayerFrag,
7977        viewport: this.viewport,
7978        textDivs: this.textDivs,
7979        timeout: timeout,
7980        enhanceTextSelection: this.enhanceTextSelection,
7981      });
7982      this.textLayerRenderTask.promise.then(
7983        function () {
7984          this.textLayerDiv.appendChild(textLayerFrag);
7985          this._finishRendering();
7986          this.updateMatches();
7987        }.bind(this),
7988        function (reason) {
7989          // canceled or failed to render text layer -- skipping errors
7990        }
7991      );
7992    },
7993
7994    setTextContent: function TextLayerBuilder_setTextContent(textContent) {
7995      if (this.textLayerRenderTask) {
7996        this.textLayerRenderTask.cancel();
7997        this.textLayerRenderTask = null;
7998      }
7999      this.textContent = textContent;
8000      this.divContentDone = true;
8001    },
8002
8003    convertMatches: function TextLayerBuilder_convertMatches(
8004      matches,
8005      matchesLength
8006    ) {
8007      var i = 0;
8008      var iIndex = 0;
8009      var bidiTexts = this.textContent.items;
8010      var end = bidiTexts.length - 1;
8011      var queryLen =
8012        this.findController === null
8013          ? 0
8014          : this.findController.state.query.length;
8015      var ret = [];
8016      if (!matches) {
8017        return ret;
8018      }
8019      for (var m = 0, len = matches.length; m < len; m++) {
8020        // Calculate the start position.
8021        var matchIdx = matches[m];
8022
8023        // Loop over the divIdxs.
8024        while (i !== end && matchIdx >= iIndex + bidiTexts[i].str.length) {
8025          iIndex += bidiTexts[i].str.length;
8026          i++;
8027        }
8028
8029        if (i === bidiTexts.length) {
8030          console.error("Could not find a matching mapping");
8031        }
8032
8033        var match = {
8034          begin: {
8035            divIdx: i,
8036            offset: matchIdx - iIndex,
8037          },
8038        };
8039
8040        // Calculate the end position.
8041        if (matchesLength) {
8042          // multiterm search
8043          matchIdx += matchesLength[m];
8044        } else {
8045          // phrase search
8046          matchIdx += queryLen;
8047        }
8048
8049        // Somewhat the same array as above, but use > instead of >= to get
8050        // the end position right.
8051        while (i !== end && matchIdx > iIndex + bidiTexts[i].str.length) {
8052          iIndex += bidiTexts[i].str.length;
8053          i++;
8054        }
8055
8056        match.end = {
8057          divIdx: i,
8058          offset: matchIdx - iIndex,
8059        };
8060        ret.push(match);
8061      }
8062
8063      return ret;
8064    },
8065
8066    renderMatches: function TextLayerBuilder_renderMatches(matches) {
8067      // Early exit if there is nothing to render.
8068      if (matches.length === 0) {
8069        return;
8070      }
8071
8072      var bidiTexts = this.textContent.items;
8073      var textDivs = this.textDivs;
8074      var prevEnd = null;
8075      var pageIdx = this.pageIdx;
8076      var isSelectedPage =
8077        this.findController === null
8078          ? false
8079          : pageIdx === this.findController.selected.pageIdx;
8080      var selectedMatchIdx =
8081        this.findController === null
8082          ? -1
8083          : this.findController.selected.matchIdx;
8084      var highlightAll =
8085        this.findController === null
8086          ? false
8087          : this.findController.state.highlightAll;
8088      var infinity = {
8089        divIdx: -1,
8090        offset: undefined,
8091      };
8092
8093      function beginText(begin, className) {
8094        var divIdx = begin.divIdx;
8095        textDivs[divIdx].textContent = "";
8096        appendTextToDiv(divIdx, 0, begin.offset, className);
8097      }
8098
8099      function appendTextToDiv(divIdx, fromOffset, toOffset, className) {
8100        var div = textDivs[divIdx];
8101        var content = bidiTexts[divIdx].str.substring(fromOffset, toOffset);
8102        var node = document.createTextNode(content);
8103        if (className) {
8104          var span = document.createElement("span");
8105          span.className = className;
8106          span.appendChild(node);
8107          div.appendChild(span);
8108          return;
8109        }
8110        div.appendChild(node);
8111      }
8112
8113      var i0 = selectedMatchIdx,
8114        i1 = i0 + 1;
8115      if (highlightAll) {
8116        i0 = 0;
8117        i1 = matches.length;
8118      } else if (!isSelectedPage) {
8119        // Not highlighting all and this isn't the selected page, so do nothing.
8120        return;
8121      }
8122
8123      for (var i = i0; i < i1; i++) {
8124        var match = matches[i];
8125        var begin = match.begin;
8126        var end = match.end;
8127        var isSelected = isSelectedPage && i === selectedMatchIdx;
8128        var highlightSuffix = isSelected ? " selected" : "";
8129
8130        if (this.findController) {
8131          this.findController.updateMatchPosition(
8132            pageIdx,
8133            i,
8134            textDivs,
8135            begin.divIdx
8136          );
8137        }
8138
8139        // Match inside new div.
8140        if (!prevEnd || begin.divIdx !== prevEnd.divIdx) {
8141          // If there was a previous div, then add the text at the end.
8142          if (prevEnd !== null) {
8143            appendTextToDiv(prevEnd.divIdx, prevEnd.offset, infinity.offset);
8144          }
8145          // Clear the divs and set the content until the starting point.
8146          beginText(begin);
8147        } else {
8148          appendTextToDiv(prevEnd.divIdx, prevEnd.offset, begin.offset);
8149        }
8150
8151        if (begin.divIdx === end.divIdx) {
8152          appendTextToDiv(
8153            begin.divIdx,
8154            begin.offset,
8155            end.offset,
8156            "highlight" + highlightSuffix
8157          );
8158        } else {
8159          appendTextToDiv(
8160            begin.divIdx,
8161            begin.offset,
8162            infinity.offset,
8163            "highlight begin" + highlightSuffix
8164          );
8165          for (var n0 = begin.divIdx + 1, n1 = end.divIdx; n0 < n1; n0++) {
8166            textDivs[n0].className = "highlight middle" + highlightSuffix;
8167          }
8168          beginText(end, "highlight end" + highlightSuffix);
8169        }
8170        prevEnd = end;
8171      }
8172
8173      if (prevEnd) {
8174        appendTextToDiv(prevEnd.divIdx, prevEnd.offset, infinity.offset);
8175      }
8176    },
8177
8178    updateMatches: function TextLayerBuilder_updateMatches() {
8179      // Only show matches when all rendering is done.
8180      if (!this.renderingDone) {
8181        return;
8182      }
8183
8184      // Clear all matches.
8185      var matches = this.matches;
8186      var textDivs = this.textDivs;
8187      var bidiTexts = this.textContent.items;
8188      var clearedUntilDivIdx = -1;
8189
8190      // Clear all current matches.
8191      for (var i = 0, len = matches.length; i < len; i++) {
8192        var match = matches[i];
8193        var begin = Math.max(clearedUntilDivIdx, match.begin.divIdx);
8194        for (var n = begin, end = match.end.divIdx; n <= end; n++) {
8195          var div = textDivs[n];
8196          div.textContent = bidiTexts[n].str;
8197          div.className = "";
8198        }
8199        clearedUntilDivIdx = match.end.divIdx + 1;
8200      }
8201
8202      if (this.findController === null || !this.findController.active) {
8203        return;
8204      }
8205
8206      // Convert the matches on the page controller into the match format
8207      // used for the textLayer.
8208      var pageMatches, pageMatchesLength;
8209      if (this.findController !== null) {
8210        pageMatches = this.findController.pageMatches[this.pageIdx] || null;
8211        pageMatchesLength = this.findController.pageMatchesLength
8212          ? this.findController.pageMatchesLength[this.pageIdx] || null
8213          : null;
8214      }
8215
8216      this.matches = this.convertMatches(pageMatches, pageMatchesLength);
8217      this.renderMatches(this.matches);
8218    },
8219
8220    /**
8221     * Fixes text selection: adds additional div where mouse was clicked.
8222     * This reduces flickering of the content if mouse slowly dragged down/up.
8223     * @private
8224     */
8225    _bindMouse: function TextLayerBuilder_bindMouse() {
8226      var div = this.textLayerDiv;
8227      var self = this;
8228      div.addEventListener("mousedown", function (e) {
8229        if (self.enhanceTextSelection && self.textLayerRenderTask) {
8230          self.textLayerRenderTask.expandTextDivs(true);
8231          return;
8232        }
8233        var end = div.querySelector(".endOfContent");
8234        if (!end) {
8235          return;
8236        }
8237        // On non-Firefox browsers, the selection will feel better if the height
8238        // of the endOfContent div will be adjusted to start at mouse click
8239        // location -- this will avoid flickering when selections moves up.
8240        // However it does not work when selection started on empty space.
8241        var adjustTop = e.target !== div;
8242        adjustTop =
8243          adjustTop &&
8244          window.getComputedStyle(end).getPropertyValue("-moz-user-select") !==
8245            "none";
8246        if (adjustTop) {
8247          var divBounds = div.getBoundingClientRect();
8248          var r = Math.max(0, (e.pageY - divBounds.top) / divBounds.height);
8249          end.style.top = (r * 100).toFixed(2) + "%";
8250        }
8251        end.classList.add("active");
8252      });
8253      div.addEventListener("mouseup", function (e) {
8254        if (self.enhanceTextSelection && self.textLayerRenderTask) {
8255          self.textLayerRenderTask.expandTextDivs(false);
8256          return;
8257        }
8258        var end = div.querySelector(".endOfContent");
8259        if (!end) {
8260          return;
8261        }
8262        end.style.top = "";
8263        end.classList.remove("active");
8264      });
8265    },
8266  };
8267  return TextLayerBuilder;
8268})();
8269
8270DFLIP.ConvertPageLinks = function () {
8271  var w = arguments[0] / 100,
8272    h = arguments[1] / 100;
8273
8274  var toPercent = function (_x, _y, _w, _h, _dest) {
8275    return {
8276      x: _x / w,
8277      y: _y / h,
8278      w: _w / w,
8279      h: _h / h,
8280      dest: _dest,
8281    };
8282  };
8283
8284  var percents = [];
8285  var input;
8286
8287  for (var index = 2; index < arguments.length; index++) {
8288    input = arguments[index];
8289    percents[index - 2] = toPercent.apply(this, input);
8290  }
8291
8292  return percents;
8293};
8294
8295DFLIP.parseLinks = function (links) {
8296  var _links;
8297  if (links !== void 0 && links.length > 0) {
8298    for (var index = 0; index < links.length; index++) {
8299      _links = links[index];
8300
8301      if (
8302        _links !== void 0 &&
8303        _links[0] !== void 0 &&
8304        _links[0].dest == void 0
8305      ) {
8306        _links = DFLIP.ConvertPageLinks.apply(this, _links);
8307        links[index] = _links;
8308      }
8309    }
8310  }
8311  return links;
8312};
8313
8314/**
8315 * DFLIP.parseBooks
8316 */
8317(function ($) {
8318  //php and javascript interpret booleans differently so we use string checks
8319  function isTrue(val) {
8320    return val == "true" || val == true;
8321  }
8322
8323  function checkValues(options) {
8324    //boolean values
8325    if (options.webgl !== void 0) options.webgl = isTrue(options.webgl);
8326    if (options.enableDownload !== void 0)
8327      options.enableDownload = isTrue(options.enableDownload);
8328    if (options.scrollWheel !== void 0)
8329      options.scrollWheel = isTrue(options.scrollWheel);
8330    if (options.autoEnableOutline !== void 0)
8331      options.autoEnableOutline = isTrue(options.autoEnableOutline);
8332    if (options.autoEnableThumbnail !== void 0)
8333      options.autoEnableThumbnail = isTrue(options.autoEnableThumbnail);
8334    if (options.transparent !== void 0)
8335      options.transparent = isTrue(options.transparent);
8336    if (options.overwritePDFOutline !== void 0)
8337      options.overwritePDFOutline = isTrue(options.overwritePDFOutline);
8338    if (options.soundEnable !== void 0)
8339      options.soundEnable = isTrue(options.soundEnable);
8340    if (options.forceFit !== void 0)
8341      options.forceFit = isTrue(options.forceFit);
8342    if (options.enableAnnotation !== void 0)
8343      options.enableAnnotation = isTrue(options.enableAnnotation);
8344    if (options.webglShadow !== void 0)
8345      options.webglShadow = isTrue(options.webglShadow);
8346
8347    //integer value
8348    if (options.minTopOffset !== void 0)
8349      options.minTopOffset = parseInt(options.minTopOffset, 10);
8350    if (options.zoomRatio !== void 0)
8351      options.zoomRatio = parseFloat(options.zoomRatio, 10);
8352
8353    if (options.pageMode == 0 || options.pageMode == "0")
8354      options.pageMode = void 0;
8355    if (options.singlePageMode == 0 || options.singlePageMode == "0")
8356      options.singlePageMode = void 0;
8357  }
8358
8359  function parseOptions(options) {
8360    //bail out if already parsed or failed
8361    if (options.parsed == true) return;
8362
8363    options.parsed = true;
8364    //options.links are in json format
8365    //{"1":[]}
8366    //convert them to array format
8367    var links = [];
8368    checkValues(options);
8369
8370    if (typeof dFlipWPGlobal !== "undefined" && options.wpOptions == "true") {
8371      try {
8372        for (var key in options.links) {
8373          var _pagelinks = options.links[key];
8374          var pagelink = [100, 100];
8375          for (var l = 0; l < _pagelinks.length; l++) {
8376            var _link = _pagelinks[l];
8377            var _values = _link.substr(1).slice(0, -1).split(",");
8378            var _linkarr = [];
8379            for (var v = 0; v < 5; v++) {
8380              _linkarr[v] = _values[v];
8381            }
8382            pagelink.push(_linkarr);
8383          }
8384          links[parseInt(key, 10) + 1] = pagelink;
8385        }
8386      } catch (error) {
8387        console.error(error.stack);
8388      }
8389      options.links = DFLIP.parseLinks(links);
8390    } else {
8391      options.links = DFLIP.parseLinks(options.links);
8392    }
8393  }
8394
8395  DFLIP.getOptions = function (book) {
8396    book = $(book);
8397
8398    var book_id = book.attr("id");
8399
8400    var options = "option_" + book_id,
8401      source = book.attr("source") || book.attr("df-source");
8402
8403    //verify and optimize the values
8404    options =
8405      options == void 0 || options == "" || window[options] == void 0
8406        ? {}
8407        : window[options];
8408
8409    options.source = source == void 0 || source == "" ? options.source : source;
8410
8411    /*As of 1.2.6 attribute values are also considered as options in some cases*/
8412    var attrOptions = {
8413      webgl: book.attr("webgl"),
8414      height: book.attr("height"),
8415      soundEnable: book.attr("sound"),
8416      transparent: book.attr("transparent"),
8417      enableDownload: book.attr("download"),
8418      duration: book.attr("duration"),
8419      hard: book.attr("hard"),
8420      pageMode: book.attr("pagemode"),
8421      direction: book.attr("direction"),
8422      backgroundColor: book.attr("backgroundcolor"),
8423      scrollWheel: book.attr("scrollwheel"),
8424      backgroundImage: book.attr("backgroundimage"),
8425      minTopOffset: book.attr("mintopoffset"),
8426      wpOptions: book.attr("wpoptions"),
8427    };
8428
8429    options = $.extend(true, {}, options, attrOptions);
8430
8431    parseOptions(options);
8432
8433    return options;
8434  };
8435
8436  DFLIP.parseBooks = function () {
8437    $("._df_button, ._df_thumb, ._df_custom, ._df_book").each(function () {
8438      var book = $(this);
8439
8440      //fetch any existing values
8441      var parsed = book.attr("parsed") || book.attr("df-parsed");
8442
8443      //skip if already parsed or failed
8444      if (parsed !== "true") {
8445        book.attr("df-parsed", "true");
8446
8447        if (book.hasClass("_df_book")) {
8448          var book_id = book.attr("id"),
8449            slug = book.attr("slug");
8450          var options = DFLIP.getOptions(book);
8451          options.id = book_id;
8452          if (slug !== void 0) options.slug = slug;
8453          if (book_id) {
8454            window[book_id.toString()] = $(book).flipBook(
8455              options.source,
8456              options
8457            );
8458          } else {
8459            $(book).flipBook(options.source, options);
8460          }
8461        } else {
8462          book.on("click", function () {
8463            //cache the book element
8464            var book = $(this);
8465
8466            if (!window.dfLightBox) {
8467              window.dfLightBox = new DFLightBox(function () {
8468                if (window.location.hash.indexOf("#dflip-") == 0)
8469                  window.location.hash = "#_";
8470                window.dfActiveLightBoxBook.dispose();
8471                window.dfActiveLightBoxBook = null;
8472              });
8473            }
8474
8475            window.dfLightBox.duration = 500;
8476
8477            if (
8478              window.dfActiveLightBoxBook &&
8479              window.dfActiveLightBoxBook.dispose
8480            ) {
8481              window.dfActiveLightBoxBook.dispose();
8482            } else {
8483              window.dfLightBox.show(function () {
8484                //                            $("body").addClass("df-no-scroll");
8485                var options = DFLIP.getOptions(book);
8486                options.transparent = false;
8487                options.id = book.attr("id");
8488                var slug = book.attr("slug");
8489                if (slug !== void 0) options.slug = slug;
8490                options.isLightBox = true;
8491                window.dfActiveLightBoxBook = $(
8492                  window.dfLightBox.container
8493                ).flipBook(options.source, options);
8494              });
8495            }
8496          });
8497
8498          if (book.hasClass("_df_thumb")) {
8499            var wrapper = $("<div class='_df_book-cover'>");
8500
8501            var text = book.html();
8502            book.html("");
8503            var title = $("<span class='_df_book-title'>")
8504              .html(text)
8505              .appendTo(wrapper);
8506
8507            var thumb = book.attr("thumb") || book.attr("df-thumb"),
8508              tags = book.attr("tags") || book.attr("df-tags");
8509
8510            if (tags) {
8511              tags = tags.split(",");
8512
8513              if (tags.length > 0) {
8514                for (var tagcount = 0; tagcount < tags.length; tagcount++) {
8515                  book.append(
8516                    "<span class='_df_book-tag'>" + tags[tagcount] + "</span>"
8517                  );
8518                }
8519              }
8520            }
8521
8522            if (thumb !== void 0 && thumb.toString().trim() != "") {
8523              wrapper.css({
8524                backgroundImage: "url(" + thumb + ")",
8525              });
8526            } else {
8527              wrapper.addClass("_df_thumb-not-found");
8528            }
8529
8530            book.append(wrapper);
8531          }
8532        }
8533      }
8534    });
8535  };
8536
8537  $(document).ready(function () {
8538    if (typeof dFlipLocation !== "undefined") {
8539      //add ending forward slash trail for safety
8540      if (dFlipLocation.length > 2 && dFlipLocation.slice(-1) !== "/") {
8541        dFlipLocation += "/";
8542      }
8543
8544      //PRESENTATION.defaults.backgroundImage = "blank"; "images/textures/white.jpg";
8545      //PRESENTATION.defaults.textureLoadFallback = dFlipLocation + "images/textures/white.jpg";
8546      DFLIP.defaults.mockupjsSrc = dFlipLocation + "js/libs/mockup.min.js";
8547      DFLIP.defaults.pdfjsSrc = dFlipLocation + "js/libs/pdf.min.js";
8548      DFLIP.defaults.pdfjsCompatibilitySrc =
8549        dFlipLocation + "js/libs/compatibility.js";
8550      DFLIP.defaults.threejsSrc = dFlipLocation + "js/libs/three.min.js";
8551      DFLIP.defaults.pdfjsWorkerSrc =
8552        dFlipLocation + "js/libs/pdf.worker.min.js";
8553      DFLIP.defaults.soundFile = dFlipLocation + "sound/turn2.mp3";
8554      DFLIP.defaults.imagesLocation = dFlipLocation + "images";
8555      if (typeof dFlipWPGlobal !== "undefined") {
8556        checkValues(dFlipWPGlobal);
8557
8558        $.extend(DFLIP.defaults, dFlipWPGlobal);
8559      }
8560    }
8561
8562    DFLIP.preParseHash = window.location.hash;
8563    DFLIP.parseBooks();
8564
8565    //parse hash and check if any exists
8566    if (DFLIP.preParseHash && DFLIP.preParseHash.indexOf("dflip-") >= 0) {
8567      var id = DFLIP.preParseHash.split("dflip-")[1].split("/")[0];
8568      var page = DFLIP.preParseHash.split("dflip-")[1].split("/")[1];
8569      if (page != void 0) {
8570        page = page.split("/")[0];
8571      }
8572      var book;
8573      //first check for slug pattern
8574      book = $("[slug=" + id + "]");
8575      //then id pattern
8576      if (book.length == 0) book = $("#" + id);
8577
8578      if (book.length > 0) {
8579        //var oldHash = window.location.hash;
8580        //window.location.hash = id;
8581        //window.location.hash = DFLIP.preParseHash;
8582
8583        if (page != void 0) {
8584          book.data("page", page);
8585        }
8586
8587        if (book.is("._df_button, ._df_thumb, ._df_custom")) {
8588          book.trigger("click");
8589        }
8590      }
8591    }
8592
8593    $("body").on("click", ".df-ui-sidemenu-close", function () {
8594      var $this = $(this);
8595      $this
8596        .closest(".df-container")
8597        .find(".df-ui-outline.df-active , .df-ui-thumbnail.df-active")
8598        .trigger("click");
8599    });
8600  });
8601})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.