Free javascript Hosting


magalone.js

Uploaded on Feb 13 2022 20:34 by fdcvgf

///#source 1 1 /js/exHelp.js
/// <reference path="_references.js" />

/*!

exHelp Library - Extensible Helper // Version 1.1.0.0
http://www.github.com/xwcg

The MIT License (MIT)

Copyright (c) 2014 Michael Schwarz

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

*/

// FIX for IE
if (!Array.prototype.find) {
Object.defineProperty(Array.prototype, 'find', {
value: function (predicate) {
// 1. Let O be ? ToObject(this value).
if (this == null) {
throw new TypeError('"this" is null or not defined');
}

var o = Object(this);

// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;

// 3. If IsCallable(predicate) is false, throw a TypeError exception.
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}

// 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
var thisArg = arguments[1];

// 5. Let k be 0.
var k = 0;

// 6. Repeat, while k < len
while (k < len) {
// a. Let Pk be ! ToString(k).
// b. Let kValue be ? Get(O, Pk).
// c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
// d. If testResult is true, return kValue.
var kValue = o[k];
if (predicate.call(thisArg, kValue, k, o)) {
return kValue;
}
// e. Increase k by 1.
k++;
}

// 7. Return undefined.
return undefined;
},
});
}

(function InitExHelp(window) {
var exHelpObject = {
_storage: {},
_subscribers: {},

// Object to hold settings

settings: {},

// Information about the current application
info: {
AppName: 'Extensible Helper Class',
Version: '1.1.0.0',
Author: 'Michael Schwarz',
},

addStorage: function (name) {
/// <summary>
/// Creates a new storage (name)
/// </summary>
/// <param name="name" type="String">Name of the storage</param>
/// <returns type="Object">Storage object</returns>

// If the storage is undefined (does not exist)
if (this._storage[name] === undefined) {
// Create it
this._storage[name] = {};
}
// And return it
return this.getStorage(name);
},

getStorage: function (name) {
/// <summary>
/// Get reference to storage (name)
/// </summary>
/// <param name="name" type="String">Name of the Storage</param>
/// <returns type="Object|undefined">Storage object or undefined if it does not exist</returns>

// return the storage
return this._storage[name];
},

storage: function (name) {
/// <summary>
/// Returns a reference to storage (name) and creates it if necessary
/// </summary>
/// <param name="name" type="String">Name of the storage</param>
/// <returns type="Object">Storage object</returns>

// If the storage exists
if (this._storage[name])
// return it
return this._storage[name];
// else: create and return it
else return this.addStorage(name);
},

subscribe: function (name, cb) {
/// <summary>
/// Subscribe a function (cb) to trigger (name)
/// </summary>
/// <param name="name" type="String">Trigger name</param>
/// <param name="cb" type="Function">Callback to execute</param>

// If the trigger has a subscriber list
if (this._subscribers[name])
// Add this callback to it
this._subscribers[name].push(cb);
else {
// Else:
// Create a new list for that trigger
this._subscribers[name] = [];
// And call this function again
this.subscribe(name, cb);
}
},

unsubscribe: function (name, cb) {
/// <summary>
/// Unsubscribe a function (cb) from trigger (name)
/// </summary>
/// <param name="name" type="String">Trigger name</param>
/// <param name="cb" type="Function">Callback to unsubscribe</param>

// If there is a subscriber list for this trigger
if (this._subscribers[name]) {
// Go through all subsribers
for (var i = 0; i < this._subscribers[name].length; i++) {
// If the subscriber is the same as the provided callback
if (this._subscribers[name][i] === cb) {
// Remove it from the subscriber listd
this._subscribers[name].splice(i, 1);

// and step out of the loop since the index is now corrupted
break;
}
}
}
},

clearSubscriptions: function (name) {
/// <summary>
/// Clear all subscribers from trigger (name)
/// </summary>
/// <param name="name" type="String">Trigger name</param>

// If there is a subscriber list for this trigger
if (this._subscribers[name])
// Empty it
this._subscribers[name] = [];
},

// ! Internal Trigger Function
_trigger: function exHelp_Trigger_Internal(name, e) {
// If there is a subscriber list for this trigger
if (this._subscribers[name]) {
// scope = subscriber list
var scope = this._subscribers[name];

// Go through all subscribers
for (var i = 0; i < scope.length; i++) {
// get the current subscriber
var subscriber = scope[i];

// And execute it (window context)
subscriber.apply(window, e);
}
}
},

trigger: function exHelp_Trigger(name, e, clearAfter, immediate) {
/// <signature>
/// <summary>
/// Trigger event (name) with parameters (e)
/// </summary>
/// <param name="name" type="String">Trigger name</param>
/// <param name="e" type="Array">Parameters array for the subscriber callback
/// functions</param>
/// <param name="clearAfter" type="Boolean">If true, will clear all subscribers of
/// this trigger after execution</param>
/// <param name="immediate" type="Boolean">If true, will not be deferred to the end
/// of the execution queue</param> </signature>
///
/// <signature>
/// <summary>
/// Trigger event (name) with parameters (e)
/// </summary>
/// <param name="name" type="String">Trigger name</param>
/// <param name="e" type="Array">Parameters array for the subscriber callback
/// functions</param>
/// <param name="clearAfter" type="Boolean">If true, will clear all subscribers of
/// this trigger after execution</param> </signature>
///
/// <signature>
/// <summary>
/// Trigger event (name) with parameters (e)
/// </summary>
/// <param name="name" type="String">Trigger name</param>
/// <param name="e" type="Array">Parameters array for the subscriber callback
/// functions</param> </signature>

// Get "this" to a local variable for scoping
var $this = this;

// If not immediate
if (!immediate)
// Defer this trigger to the end of the execution stack
this.defer(function exHelp_Trigger_Defer() {
// Trigger it
$this._trigger(name, e);

// If we want to clear the subscribers afterwards, do so
clearAfter && $this.clearSubscriptions(name);
});
else {
// If immediate
// Trigger it
this._trigger(name, e);
// If we want to clear the subscribers afterwards, do so
clearAfter && this.clearSubscriptions(name);
}
},

defer: function exHelp_Defer(e, context, args, time) {
/// <signature>
/// <summary>
/// Puts the function at the end of the execution stack
/// </summary>
/// <param name="e" type="Function">Function to defer</param>
/// <param name="context" type="Object">Context to execute the function in</param>
/// <param name="args" type="Array">Parameter array</param>
/// <param name="time" type="Int">Delay time in ms</param> </signature>
///
/// <signature>
/// <summary>
/// Puts the function at the end of the execution stack
/// </summary>
/// <param name="e" type="Function">Function to defer</param>
/// <param name="context" type="Object">Context to execute the function in</param>
/// <param name="args" type="Array">Parameter array</param> </signature>
///
/// <signature>
/// <summary>
/// Puts the function at the end of the execution stack
/// </summary>
/// <param name="e" type="Function">Function to defer</param>
/// <param name="context" type="Object">Context to execute the function in</param>
/// </signature>
///
/// <signature>
/// <summary>
/// Puts the function at the end of the execution stack
/// </summary>
/// <param name="e" type="Function">Function to defer</param> </signature>

// If the provided callback is actually a function
if (this.is.function(e)) {
// Defer
setTimeout(
function exHelp_Defer_Execution() {
// do we have a context?
if (context)
// Yes, execute it with it
e.apply(context, args);
else if (args) e.apply(undefined, args);
// No, execute locally
else e();
// Timeout specified? Yes, use it, otherwise use 1 for fastest speed
},
time ? time : 1
);
}
},

extend: function (base, branch) {
if (!branch) {
branch = base;
base = this;
}

for (var key in branch) {
if (branch[key] !== undefined) base[key] = branch[key];
}
},

each: function (obj, callback, args) {
if (obj['length'] !== void 0) {
var i = 0,
length = obj.length;
if (args) {
for (; i < length; i++) {
if (callback.apply(obj[i], args) === false) break;
}
} else {
for (; i < length; i++) {
if (callback.call(obj[i], i, obj[i]) === false) break;
}
}
}

return obj;
},

jsonParse: function (str) {
/// <summary>
/// Parses JSON (j) and fails gracefully on error
/// </summary>
/// <param name="str" type="String">JSON to parse</param>
/// <returns type="mixed|null">JSON Parse result or null on error</returns>
try {
return JSON.parse(str);
} catch (e) {
console.error('JSON Parse Error ', e, "While Parsing: '", str, "'");
return null;
}
},
jsonStringify: function (e) {
/// <summary>
/// Stringifies (e) to JSON and fails gracefully on error
/// </summary>
/// <param name="e" type="mixed">Value to stringify into JSON</param>
/// <returns type="String|null">JSON String or null on error</returns>
try {
return JSON.stringify(e);
} catch (e) {
console.error('JSON Stringify Error ', e, 'While Stringifying: ', e);
return null;
}
},

// Helpers for randomization
random: {
//! Internal random string function (letters AND numbers!)
_gen: function (args) {
var ASCII_UPPER = args.upper || 65;
var ASCII_LOWER = args.lower || 90;
var MaxLength = args.len || args.length || 8;

var str = '';

// As long as the string is not the desired length
while (str.length < MaxLength) {
// Decide whether to add a letter or number
if (Math.random() * 100 >= 50) {
// Add a letter (fancy mathemagics)
str += String.fromCharCode(
Math.floor(
Math.random() * (ASCII_UPPER - ASCII_LOWER) + ASCII_LOWER
)
);
} else {
// Add a number (no mathemagics)
str += Math.floor(Math.random() * 9).toString();
}
}

return str;
},

number: function (min, max) {
/// <summary>
/// Returns a random number between (min) and (max)
/// </summary>
/// <param name="min" type="Number">Lower bound</param>
/// <param name="max" type="Number">Upper bound</param>
/// <returns type="Number">Random number</returns>

return Math.random() * (max - min) + min;
},
string: function (len, upper) {
/// <signature>
/// <summary>
/// Returns a random string of length (len)
/// </summary>
/// <param name="len" type="Int">Desired string length</param>
/// <param name="upper" type="Boolean">If true, will return UPPERCASE string</param>
/// <returns type="String">Random string</returns>
/// </signature>
/// <signature>
/// <summary>
/// Returns a random string of length (len)
/// </summary>
/// <param name="len" type="Int">Desired string length</param>
/// <returns type="String">Random string</returns>
/// </signature>

var ASCII_LOWER = 65; // Lower ascii boundary (A)
var ASCII_UPPER = 90; // Upper ascii boundary (Z)

if (upper !== undefined && upper === false) {
ASCII_LOWER = 97; // Lower ascii boundary (a)
ASCII_UPPER = 122; // Upper ascii boundary (z)
}

return this._gen({
upper: ASCII_UPPER,
lower: ASCII_LOWER,
len: len,
});
},
hex: function (len) {
/// <summary>
/// Returns a random HEX string [a-f0-9] of length (len)
/// </summary>
/// <param name="len" type="Int">Desired string length</param>
/// <returns type="String">Random Hex String</returns>

// Basically the same as a random string generator but the ASCII boundaries are limited to a-f and 0-9
var ASCII_LOWER = 97; // Lower ascii boundary (a)
var ASCII_UPPER = 102; // Upper ascii boundary (f)

return this._gen({
upper: ASCII_UPPER,
lower: ASCII_LOWER,
len: len,
});
},
guid: function () {
/// <summary>
/// Returns a pseudorandom GUID [a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}
/// </summary>
/// <returns type="String">GUID</returns>
return '{0}-{1}-{2}-{3}-{4}'.format(
this.hex(8),
this.hex(4),
this.hex(4),
this.hex(4),
this.hex(12)
);
},
hexColor: function () {
/// <summary>
/// Returns a random hex colour
/// </summary>
/// <returns type="String">Hex Colour</returns>
return '#' + this.hex(6);
},
date: function (min, max) {
/// <summary>
/// Returns a random date between (min) and (max)
/// NOTE: Requires exHelp Date Extension!
/// </summary>
/// <param name="min" type="Date">Lower bound date</param>
/// <param name="max" type="Date">Upper bound date</param>
/// <returns type="Date">Random date</returns>

// We need the date extension, so check for it
if (!exHelpObject.date)
return console.error('exHelp: Date Extension not found!');

// Get timestamps
var mmax = exHelpObject.date.fix(max).getTime();
var mmin = exHelpObject.date.fix(min).getTime();

// Make a new date object by using mathemagics with the timestamps
return exHelpObject.date.fix(Math.random() * (mmax - mmin) + mmin);
},
},

// Array helpers
array: {
clone: function (a) {
/// <summary>
/// Clones an array (No references!)
/// </summary>
/// <param name="a" type="Array">Array to be cloned</param>
/// <returns type="Array">Cloned array</returns>

// By stringyfing the object to JSON and back we avoid pesky references
return exHelpObject.jsonParse(exHelpObject.jsonStringify(a));
},

sieve: function (e) {
/// <summary>
/// Cleans an array by removing empty values ("", null, undefined) and trimming all strings
/// </summary>
/// <param name="e" type="Array">Array to be cleaned</param>
/// <returns type="Array">Cleaned array</returns>

var temp = e;

var fncSieve = function (a) {
for (var key in a) {
var value = a[key];
if (exHelpObject.isString(value)) {
a[key] = value = value.trim();
if (value.trim().length == 0) {
a.splice(key, 1);
return fncSieve(a);
}
} else {
if (value === null || value === undefined) {
a.splice(key, 1);
return fncSieve(a);
}
}
}
return a;
};

return fncSieve(temp);
},

contains: function (arr, value) {
return arr.indexOf(value) !== -1;
},
},
// Math helpers
math: {
rect: function (t, l, b, r) {
return {
top: t ? t : 0,
left: l ? l : 0,
right: r ? r : 0,
bottom: b ? b : 0,
get width() {
return this.right - this.left;
},
get height() {
return this.bottom - this.top;
},
set width(val) {
this.right = this.left + val;
},
set height(val) {
this.bottom = this.top + val;
},
moveTopBy: function (val) {
(this.top += val), (this.bottom += val);
},
moveTopTo: function (val) {
var h = this.height;
(this.top = val), (this.bottom = this.top + h);
},
moveLeftBy: function (val) {
(this.left += val), (this.right += val);
},
moveLeftTo: function (val) {
var w = this.width;
(this.left = val), (this.right = this.left + w);
},
intersects: function (rect) {
return (
this.left <= rect.right &&
rect.left <= this.right &&
this.top <= rect.bottom &&
rect.top <= this.bottom
);
},
contains: function (rect) {
return (
rect.left <= this.right &&
rect.left >= this.left &&
rect.top <= this.bottom &&
rect.top >= this.top &&
rect.right <= this.right &&
rect.right >= this.left &&
rect.bottom <= this.bottom &&
rect.bottom >= this.top
);
},
};
},
easing: {
linearTween: function (t, b, c, d) {
/// <summary>
/// simple linear tweening - no easing, no acceleration
/// </summary>
/// <param name="t">current time</param>
/// <param name="b">start value</param>
/// <param name="c">change in value</param>
/// <param name="d">duration</param>
/// <returns type="float">new value</returns>
return (c * t) / d + b;
},
easeInQuad: function (t, b, c, d) {
/// <summary>
/// quadratic easing in - accelerating from zero velocity
/// </summary>
/// <param name="t">current time</param>
/// <param name="b">start value</param>
/// <param name="c">change in value</param>
/// <param name="d">duration</param>
/// <returns type="float">new value</returns>
t /= d;
return c * t * t + b;
},
easeOutQuad: function (t, b, c, d) {
/// <summary>
/// quadratic easing out - decelerating to zero velocity
/// </summary>
/// <param name="t">current time</param>
/// <param name="b">start value</param>
/// <param name="c">change in value</param>
/// <param name="d">duration</param>
/// <returns type="float">new value</returns>
t /= d;
return -c * t * (t - 2) + b;
},
easeInOutQuad: function (t, b, c, d) {
/// <summary>
/// quadratic easing in/out - acceleration until halfway, then deceleration
/// </summary>
/// <param name="t">current time</param>
/// <param name="b">start value</param>
/// <param name="c">change in value</param>
/// <param name="d">duration</param>
/// <returns type="float">new value</returns>
t /= d / 2;
if (t < 1) return (c / 2) * t * t + b;
t--;
return (-c / 2) * (t * (t - 2) - 1) + b;
},
easeInCubic: function (t, b, c, d) {
/// <summary>
/// cubic easing in - accelerating from zero velocity
/// </summary>
/// <param name="t">current time</param>
/// <param name="b">start value</param>
/// <param name="c">change in value</param>
/// <param name="d">duration</param>
/// <returns type="float">new value</returns>
t /= d;
return c * t * t * t + b;
},
easeOutCubic: function (t, b, c, d) {
/// <summary>
/// cubic easing out - decelerating to zero velocity
/// </summary>
/// <param name="t">current time</param>
/// <param name="b">start value</param>
/// <param name="c">change in value</param>
/// <param name="d">duration</param>
/// <returns type="float">new value</returns>
t /= d;
t--;
return c * (t * t * t + 1) + b;
},
easeInOutCubic: function (t, b, c, d) {
/// <summary>
/// cubic easing in/out - acceleration until halfway, then deceleration
/// </summary>
/// <param name="t">current time</param>
/// <param name="b">start value</param>
/// <param name="c">change in value</param>
/// <param name="d">duration</param>
/// <returns type="float">new value</returns>
t /= d / 2;
if (t < 1) return (c / 2) * t * t * t + b;
t -= 2;
return (c / 2) * (t * t * t + 2) + b;
},
easeInQuart: function (t, b, c, d) {
/// <summary>
/// quartic easing in - accelerating from zero velocity
/// </summary>
/// <param name="t">current time</param>
/// <param name="b">start value</param>
/// <param name="c">change in value</param>
/// <param name="d">duration</param>
/// <returns type="float">new value</returns>
t /= d;
return c * t * t * t * t + b;
},
easeOutQuart: function (t, b, c, d) {
/// <summary>
/// quartic easing out - decelerating to zero velocity
/// </summary>
/// <param name="t">current time</param>
/// <param name="b">start value</param>
/// <param name="c">change in value</param>
/// <param name="d">duration</param>
/// <returns type="float">new value</returns>
t /= d;
t--;
return -c * (t * t * t * t - 1) + b;
},
easeInOutQuart: function (t, b, c, d) {
/// <summary>
/// quartic easing in/out - acceleration until halfway, then deceleration
/// </summary>
/// <param name="t">current time</param>
/// <param name="b">start value</param>
/// <param name="c">change in value</param>
/// <param name="d">duration</param>
/// <returns type="float">new value</returns>
t /= d / 2;
if (t < 1) return (c / 2) * t * t * t * t + b;
t -= 2;
return (-c / 2) * (t * t * t * t - 2) + b;
},
easeInQuint: function (t, b, c, d) {
/// <summary>
/// quintic easing in - accelerating from zero velocity
/// </summary>
/// <param name="t">current time</param>
/// <param name="b">start value</param>
/// <param name="c">change in value</param>
/// <param name="d">duration</param>
/// <returns type="float">new value</returns>
t /= d;
return c * t * t * t * t * t + b;
},
easeOutQuint: function (t, b, c, d) {
/// <summary>
/// quintic easing out - decelerating to zero velocity
/// </summary>
/// <param name="t">current time</param>
/// <param name="b">start value</param>
/// <param name="c">change in value</param>
/// <param name="d">duration</param>
/// <returns type="float">new value</returns>
t /= d;
t--;
return c * (t * t * t * t * t + 1) + b;
},
easeInOutQuint: function (t, b, c, d) {
/// <summary>
/// quintic easing in/out - acceleration until halfway, then deceleration
/// </summary>
/// <param name="t">current time</param>
/// <param name="b">start value</param>
/// <param name="c">change in value</param>
/// <param name="d">duration</param>
/// <returns type="float">new value</returns>
t /= d / 2;
if (t < 1) return (c / 2) * t * t * t * t * t + b;
t -= 2;
return (c / 2) * (t * t * t * t * t + 2) + b;
},
easeInSine: function (t, b, c, d) {
/// <summary>
/// sinusoidal easing in - accelerating from zero velocity
/// </summary>
/// <param name="t">current time</param>
/// <param name="b">start value</param>
/// <param name="c">change in value</param>
/// <param name="d">duration</param>
/// <returns type="float">new value</returns>
return -c * Math.cos((t / d) * (Math.PI / 2)) + c + b;
},
easeOutSine: function (t, b, c, d) {
/// <summary>
/// sinusoidal easing out - decelerating to zero velocity
/// </summary>
/// <param name="t">current time</param>
/// <param name="b">start value</param>
/// <param name="c">change in value</param>
/// <param name="d">duration</param>
/// <returns type="float">new value</returns>
return c * Math.sin((t / d) * (Math.PI / 2)) + b;
},
easeInOutSine: function (t, b, c, d) {
/// <summary>
/// sinusoidal easing in/out - accelerating until halfway, then decelerating
/// </summary>
/// <param name="t">current time</param>
/// <param name="b">start value</param>
/// <param name="c">change in value</param>
/// <param name="d">duration</param>
/// <returns type="float">new value</returns>
return (-c / 2) * (Math.cos((Math.PI * t) / d) - 1) + b;
},
easeInExpo: function (t, b, c, d) {
/// <summary>
/// exponential easing in - accelerating from zero velocity
/// </summary>
/// <param name="t">current time</param>
/// <param name="b">start value</param>
/// <param name="c">change in value</param>
/// <param name="d">duration</param>
/// <returns type="float">new value</returns>
return c * Math.pow(2, 10 * (t / d - 1)) + b;
},
easeOutExpo: function (t, b, c, d) {
/// <summary>
/// exponential easing out - decelerating to zero velocity
/// </summary>
/// <param name="t">current time</param>
/// <param name="b">start value</param>
/// <param name="c">change in value</param>
/// <param name="d">duration</param>
/// <returns type="float">new value</returns>
return c * (-Math.pow(2, (-10 * t) / d) + 1) + b;
},
easeInOutExpo: function (t, b, c, d) {
/// <summary>
/// exponential easing in/out - accelerating until halfway, then decelerating
/// </summary>
/// <param name="t">current time</param>
/// <param name="b">start value</param>
/// <param name="c">change in value</param>
/// <param name="d">duration</param>
/// <returns type="float">new value</returns>
t /= d / 2;
if (t < 1) return (c / 2) * Math.pow(2, 10 * (t - 1)) + b;
t--;
return (c / 2) * (-Math.pow(2, -10 * t) + 2) + b;
},
easeInCirc: function (t, b, c, d) {
/// <summary>
/// circular easing in - accelerating from zero velocity
/// </summary>
/// <param name="t">current time</param>
/// <param name="b">start value</param>
/// <param name="c">change in value</param>
/// <param name="d">duration</param>
/// <returns type="float">new value</returns>
t /= d;
return -c * (Math.sqrt(1 - t * t) - 1) + b;
},
easeOutCirc: function (t, b, c, d) {
/// <summary>
/// circular easing out - decelerating to zero velocity
/// </summary>
/// <param name="t">current time</param>
/// <param name="b">start value</param>
/// <param name="c">change in value</param>
/// <param name="d">duration</param>
/// <returns type="float">new value</returns>
t /= d;
t--;
return c * Math.sqrt(1 - t * t) + b;
},
easeInOutCirc: function (t, b, c, d) {
/// <summary>
/// circular easing in/out - acceleration until halfway, then deceleration
/// </summary>
/// <param name="t">current time</param>
/// <param name="b">start value</param>
/// <param name="c">change in value</param>
/// <param name="d">duration</param>
/// <returns type="float">new value</returns>
t /= d / 2;
if (t < 1) return (-c / 2) * (Math.sqrt(1 - t * t) - 1) + b;
t -= 2;
return (c / 2) * (Math.sqrt(1 - t * t) + 1) + b;
},
},
// Percentage helpers
Percentage: {
XofY: function (current, max) {
/// <summary>
/// Calculates X% of Y
/// </summary>
/// <param name="current" type="Number">Current Value</param>
/// <param name="max" type="Number">Maximum Value</param>
/// <returns type="Number">Percentage</returns>
return (current / max) * 100;
},
},
Dist2D: function (a, b) {
if (
a &&
a.x != undefined &&
a.y != undefined &&
b &&
b.x != undefined &&
b.y != undefined
) {
var xd = b.x - a.x;
var yd = b.y - a.y;
return Math.sqrt(xd * xd + yd * yd);
}

return 0;
},
Midpoint2D: function (a, b) {
if (
a &&
a.x != undefined &&
a.y != undefined &&
b &&
b.x != undefined &&
b.y != undefined
) {
// return Point((p1.x+p2.x)/2, (p1.y+p2.y)/2)
return {
x: (a.x + b.x) / 2,
y: (a.y + b.y) / 2,
};
}
return {
x: 0,
y: 0,
};
},
Dist3D: function (a, b) {
if (
a &&
a.x != undefined &&
a.y != undefined &&
b &&
b.x != undefined &&
b.y != undefined
) {
var xd = b.x - a.x;
var yd = b.y - a.y;
var zd = b.z - a.z;
return Math.sqrt(xd * xd + yd * yd + zd * zd);
}

return 0;
},
},
// Color functions
color: {
// Internal: converts 0-255 to hex equivalent
_component: function (c) {
var hex = c.toString(16);
return hex.length === 1 ? '0' + hex : hex;
},
HexToRGB: function (hex) {
/// <summary>
/// Converts a HEX string to an RGB Object
/// </summary>
/// <param name="hex" type="String">Valid Hex String (#[a-f0-9]{6})</param>
/// <returns type="Object">RGB object { r, g, b }</returns>

var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16),
};
},
HexToHSV: function (hex) {
/// <summary>
/// Converts a HEX string to an HSV Object
/// </summary>
/// <param name="hex" type="String">Valid Hex String (#[a-f0-9]{6})</param>
/// <returns type="Object">HSV object { h, s, v }</returns>

var rgb = this.HexToRGB(hex);
return this.RGBToHSV(rgb.r, rgb.g, rgb.b);
},
RGBToHex: function (cr, cg, cb) {
/// <signature>
/// <summary>
/// Converts RGB to Hex String
/// </summary>
/// <param name="cr" type="Number">Red</param>
/// <param name="cg" type="Number">Green</param>
/// <param name="cb" type="Number">Blue</param>
/// <returns type="String">Hex String</returns>
/// </signature>
///
/// <signature>
/// <summary>
/// Converts RGB Object to Hex String
/// </summary>
/// <param name="cr" type="Object">RGB object { r, g, b }</param>
/// <returns type="String">Hex String</returns>
/// </signature>

if (cr && !cg && !cb && exHelpObject.is.object(cr)) {
var r = cr.r;
var g = cr.g;
var b = cr.b;
} else {
var r = cr;
var g = cg;
var b = cb;
}

return (
'#' + this._component(r) + this._component(g) + this._component(b)
);
},
RGBToHSV: function () {
/// <summary>
/// Converts RGB Arguments to HSV Object { h, s, v }
/// </summary>
/// <param name="red" type="Number">Red</param>
/// <param name="green" type="Number">Green</param>
/// <param name="blue" type="Number">Blue</param>
/// <returns type="Object">HSV object { h, s, v }</returns>

// http://stackoverflow.com/questions/8022885/rgb-to-hsv-color-in-javascript
var rr,
gg,
bb,
r = arguments[0] / 255,
g = arguments[1] / 255,
b = arguments[2] / 255,
h,
s,
v = Math.max(r, g, b),
diff = v - Math.min(r, g, b),
diffc = function (c) {
return (v - c) / 6 / diff + 1 / 2;
};

if (diff == 0) {
h = s = 0;
} else {
s = diff / v;
rr = diffc(r);
gg = diffc(g);
bb = diffc(b);

if (r === v) {
h = bb - gg;
} else if (g === v) {
h = 1 / 3 + rr - bb;
} else if (b === v) {
h = 2 / 3 + gg - rr;
}
if (h < 0) {
h += 1;
} else if (h > 1) {
h -= 1;
}
}
return {
h: Math.round(h * 360),
s: Math.round(s * 100),
v: Math.round(v * 100),
};
},
// Converts H,S,V arguments to RGB Object {r, g, b}
HSVToRGB: function (h, s, v) {
/// <summary>
/// Converts HSV arguments to RGB Object
/// </summary>
/// <param name="h" type="Number">Hue</param>
/// <param name="s" type="Number">Saturation</param>
/// <param name="v" type="Number">Value</param>
/// <returns type="Object">RGB Object {r, g, b}</returns>

// http://snipplr.com/view/14590
var r, g, b;
var i;
var f, p, q, t;

h = Math.max(0, Math.min(360, h));
s = Math.max(0, Math.min(100, s));
v = Math.max(0, Math.min(100, v));
s /= 100;
v /= 100;

if (s == 0) {
r = g = b = v;
return [
Math.round(r * 255),
Math.round(g * 255),
Math.round(b * 255),
];
}

h /= 60; // sector 0 to 5
i = Math.floor(h);
f = h - i; // factorial part of h
p = v * (1 - s);
q = v * (1 - s * f);
t = v * (1 - s * (1 - f));

switch (i) {
case 0:
r = v;
g = t;
b = p;
break;

case 1:
r = q;
g = v;
b = p;
break;

case 2:
r = p;
g = v;
b = t;
break;

case 3:
r = p;
g = q;
b = v;
break;

case 4:
r = t;
g = p;
b = v;
break;

default:
// case 5:
r = v;
g = p;
b = q;
}

return {
r: Math.round(r * 255),
g: Math.round(g * 255),
b: Math.round(b * 255),
};
},
HSVToHex: function (h, s, v) {
/// <summary>
/// Converts HSV arguments to Hex String
/// </summary>
/// <param name="h" type="Number">Hue</param>
/// <param name="s" type="Number">Saturation</param>
/// <param name="v" type="Number">Value</param>
/// <returns type="String">Hex String</returns>

var rgb = this.HSVToRGB(h, s, v);
return this.RGBToHex(rgb);
},
Saturate: function (c, i) {
/// <summary>
/// Changes Saturation
/// </summary>
/// <param name="c" type="HexString|HSVObject|RGBObject">Color to change</param>
/// <param name="i" type="Number">Saturation 0-100</param>
/// <returns type="HexString|HSVObject|RGBObject">Color with changed saturation in input format</returns>

var originalColor = 0;
var intensity = i || 100;

// Check which color type we have been given
if (exHelpObject.is.object(c)) {
if (c.h && c.s && c.v) originalColor = 'HSV';
else if (c.r && c.g && c.b) originalColor = 'RGB';
} else if (c.startsWith('#')) originalColor = 'HEX';

// No type detected
if (originalColor === 0) return c; // Do nothing and return original color

var hsv = 0;

// Convert input color to HSV
switch (originalColor) {
case 'HSV':
hsv = c;
break;
case 'RGB':
hsv = this.RGBToHSV(c.r, c.g, c.b);
break;
case 'HEX':
hsv = this.HexToHSV(c);
break;
}

// Set the saturation
hsv.s = intensity;

// Convert back to original color and return it
switch (originalColor) {
case 'HSV':
return hsv;
case 'RGB':
return this.HSVToRGB(hsv.h, hsv.s, hsv.v);
case 'HEX':
return this.HSVToHex(hsv.h, hsv.s, hsv.v);
}
},
Lightness: function (c, i) {
/// <summary>
/// Changes Light-/Brightness
/// </summary>
/// <param name="c" type="HexString|HSVObject|RGBObject">Color to change</param>
/// <param name="i" type="Number">Lightness 0-100</param>
/// <returns type="HexString|HSVObject|RGBObject">Color with changed lightness in input format</returns>

var originalColor = 0;
var intensity = i || 100;

if (exHelpObject.is.object(c)) {
if (c.h && c.s && c.v) originalColor = 'HSV';
else if (c.r && c.g && c.b) originalColor = 'RGB';
} else if (c.startsWith('#')) originalColor = 'HEX';

if (originalColor === 0) return c;

var hsv = 0;

switch (originalColor) {
case 'HSV':
hsv = c;
break;
case 'RGB':
hsv = this.RGBToHSV(c.r, c.g, c.b);
break;
case 'HEX':
hsv = this.HexToHSV(c);
break;
}

hsv.v = intensity;

switch (originalColor) {
case 'HSV':
return hsv;
case 'RGB':
return this.HSVToRGB(hsv.h, hsv.s, hsv.v);
case 'HEX':
return this.HSVToHex(hsv.h, hsv.s, hsv.v);
}
},
},
// Cookie Helpers
cookies: {
cookies: [],

Read: function () {
/// <summary>
/// Read cookies into the this.cookies array
/// </summary>
this.cookies = [];
var $cookieStr = document.cookie;
var $cookieList = $cookieStr.split(';');
for (var i = 0; i < $cookieList.length; i++) {
var $csplit = $cookieList[i].split('=');
var $cookie = {
name: $csplit[0],
value: $csplit[1],
};
this.cookies.push($cookie);
}
},

Clear: function () {
/// <summary>
/// Sets all current cookies for this domain to expire
/// </summary>

this.Read();

for (var i = 0; i < this.cookies.length; i++) {
$cookie = this.cookies[i];
document.cookie = '{0}=; expires={1}'.format(
$cookie.name,
new Date(0).toUTCString()
);
}
},
},

// String Helpers
string: {
pad: function (str, char, num) {
/// <summary>
/// Pads a string to a specified minimum length
/// </summary>
/// <param name="str" type="mixed">string to be padded</param>
/// <param name="char" type="String">char to fill the size</param>
/// <param name="num" type="Integer">minimum length</param>
/// <returns type="String">Padded string</returns>

if (!char || char === '' || char.length === 0) char = ' ';
if (!num) num = 2;

var s = '' + str;
while (str.length < num) s = char + s;
return s;
},
},

// HTML5 Fullscreen API Helpers
fullscreen: {
_fromUser: false,
get isFullscreen() {
return !(
!document.fullscreenElement &&
!document.mozFullScreenElement &&
!document.webkitFullscreenElement &&
!document.msFullscreenElement
);
},
get isUserFullScreen() {
return this.isFullscreen && this._fromUser;
},
enter: function (from) {
if (!from) from = document.documentElement;
if (!this.isFullscreen) {
if (from.requestFullscreen) {
from.requestFullscreen();
} else if (from.msRequestFullscreen) {
from.msRequestFullscreen();
} else if (from.mozRequestFullScreen) {
from.mozRequestFullScreen();
} else if (from.webkitRequestFullscreen) {
from.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
}
}

this._fromUser = true;
},
exit: function () {
if (this.isFullscreen) {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
}
}

this._fromUser = false;
},
},

// Browser and Feature Detection Helpers
browser: {
// Returns true<bool> if browser is on a mobile device
get isMobile() {
// for some reason, 1000x more reliable than checking the user agent (also faster)
// iPhone 5 landscape reports 568px width, rounded to 570
if (window.innerWidth <= 1024) return true;

return false;
},
// Returns true<bool> if browser is in portrait
get isPortrait() {
if (window.innerWidth < window.innerHeight) return true;

return false;
},

// Returns true<bool> if touch input is used
get isTouch() {
return 'ontouchstart' in window;
},

// Returns true<bool> if browser is Mozilla Firefox
get isFirefox() {
return navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
},

// Returns true<bool> if browser is Google Chrome
get isChrome() {
return navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
},

// Returns true<bool> if browser is Apple Safari
get isSafari() {
return (
(navigator.userAgent.toLowerCase().indexOf('safari') > -1 &&
!this.isChrome) ||
(navigator.userAgent.toLowerCase().indexOf('applewebkit') > -1 &&
!this.isChrome)
);
},

// Returns true<bool> if browser is Opera
get isOpera() {
return navigator.userAgent.toLowerCase().indexOf('opera') > -1;
},

// Returns true<bool> if browser is Microsoft Internet Explorer
get isMSIE() {
return navigator.userAgent.toLowerCase().indexOf('trident') > -1;
},

// Returns true<bool> if browser is Microsoft Edge
get isEdge() {
return navigator.userAgent.toLowerCase().indexOf('edge/') > -1;
},

// Returns true<bool> if browser is Microsoft IE Mobile
get isIEMobile() {
return navigator.userAgent.toLowerCase().indexOf('iemobile') > -1;
},

// Returns true<bool> if browser is on a Windows Phone
get isWindowsPhone() {
return navigator.userAgent.toLowerCase().indexOf('windows phone') > -1;
},

// Returns true<bool> if browser uses Webkit
get isWebkit() {
return navigator.userAgent.toLowerCase().indexOf('webkit') > -1;
},

// Returns true<bool> if the system is iOS
get isiOS() {
return this.isSafari && this.isTouch;
},

// Returns true<bool> if the system is iOS 7
get isiOS7() {
return (
this.isiOS && navigator.userAgent.toLowerCase().indexOf('os 7') > -1
);
},

get supportsHistoryAPI() {
return !!(window.history && history.pushState);
},
},

// Networking Helpers
net: {
request: function (url, options) {
var baseOptions = {
method: 'GET',
data: null,
progress: null,
load: null,
error: null,
abort: null,
finished: null,
};

exHelp.extend(baseOptions, options);

var xhr = new XMLHttpRequest();

var onProgress = function WrappedOnProgress(e) {
if (baseOptions.progress && exHelp.is.function(baseOptions.progress))
baseOptions.progress(e);
};
var onLoad = function WrappedOnLoad(e) {
if (baseOptions.load && exHelp.is.function(baseOptions.load))
baseOptions.load(e);
};
var onError = function WrappedOnError(e) {
if (baseOptions.error && exHelp.is.function(baseOptions.error))
baseOptions.error(e);
};
var onAbort = function WrappedOnAbort(e) {
if (baseOptions.abort && exHelp.is.function(baseOptions.abort))
baseOptions.abort(e);
};
var onReadyState = function WrappedOnReadyState(e) {
switch (xhr.readyState) {
case XMLHttpRequest.OPENED:
case XMLHttpRequest.HEADERS_RECEIVED:
case XMLHttpRequest.LOADING:
case XMLHttpRequest.UNSENT:
break;
case XMLHttpRequest.DONE:
var success = xhr.status == 200;
if (
baseOptions.finished &&
exHelp.is.function(baseOptions.finished)
)
baseOptions.finished(success, xhr.responseText, xhr);
break;
}
};

xhr.onprogress = onProgress;
xhr.onabort = onAbort;
xhr.onerror = onError;
xhr.onload = onLoad;
xhr.onreadystatechange = onReadyState;

xhr.open(baseOptions.method, url);

if (baseOptions.data && baseOptions.method == 'POST') {
var datastring = '';

// http://stackoverflow.com/questions/1714786/querystring-encoding-of-a-javascript-object
var encode = function (obj, prefix) {
var str = [];
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
var k = prefix ? prefix + '[' + p + ']' : p,
v = obj[p];
str.push(
typeof v == 'object'
? encode(v, k)
: encodeURIComponent(k) + '=' + encodeURIComponent(v)
);
}
}
return str.join('&');
};

datastring = encode(baseOptions.data);
xhr.setRequestHeader(
'Content-type',
'application/x-www-form-urlencoded'
);
xhr.send(datastring);
} else {
xhr.send();
}
},
},

//! Other checking functions

is: {
string: function (e) {
return !!(typeof e == 'string' || e instanceof String);
},
function: function (e) {
return !!(typeof e === 'function' || e instanceof Function);
},
object: function (e) {
return !!(typeof e === 'object' || e instanceof Object);
},
array: Array.isArray,
arraylike: function (e) {
return e !== void 0 && e['length'] !== void 0;
},
number: function (e) {
return (
!isNaN(e) &&
isFinite(e) &&
e !== false &&
e !== true &&
e !== null &&
e !== undefined
);
},
mouse_event: function (e) {
return !!(typeof e === 'MouseEvent' || e instanceof MouseEvent);
},
keyboard_event: function (e) {
return !!(typeof e === 'KeyboardEvent' || e instanceof KeyboardEvent);
},
},

// HTML5 Notifications
browserNotification: {
_mode: 0,
_permission: 1,
_api: null,
_counter: 0,

// Permission Constants<int>
permissions: {
// Permission to show notifications has been requested and granted
get ALLOWED() {
return 0;
},
// Permission to show notifications has not been requested
get NOT_ALLOWED() {
return 1;
},
// Permission to show notifications has been requested and denied
get DENIED() {
return 2;
},
},

// Mode Constants<int>
modes: {
// HTML5 Notifications are not supported
get NONE() {
return 0;
},
// HTML5 Notifications are supported according to the W3C Standard
get W3C() {
return 1;
},
// HTML5 Notifications are supported with the Webkit Implementation
get WEBKIT() {
return 2;
},
},
_list: [],

Init: function () {
/// <summary>
/// Initialize HTML5 Notifications
/// Call via click event to request permissions
/// </summary>

if (this.Check_Support(true)) {
switch (this.Permission.Check(true)) {
case this.permissions.ALLOWED:
break;
case this.permissions.NOT_ALLOWED:
this.Permission.Request();
p.browserNotification.Init();
break;
case this.permissions.DENIED:
break;
}
}
},

Check_Support: function (set) {
/// <signature>
/// <summary>
/// Check if the current browser supports HTML5 Notifications
/// </summary>
/// <param name="set" type="Boolean">If true, the value will be set internally as well</param>
/// <returns type="Boolean">Whether or not notifications are supported</returns>
/// </signature>
///
/// <signature>
/// <summary>
/// Check if the current browser supports HTML5 Notifications
/// </summary>
/// <returns type="Boolean">Whether or not notifications are supported</returns>
/// </signature>
///

if (exHelpObject.isSafari) {
this._api = null;
return false;
}

var isValid = function (e) {
if (
!e ||
!e.checkPermission ||
!e.createNotification ||
!e.requestPermission
)
return false;

return true;
};

if (isValid(window.Notification)) {
set && (this._api = window.Notification);
}
if (isValid(window.webkitNotifications)) {
set && (this._api = window.webkitNotifications);
}

if (set) return !!this._api;
else
return (
isValid(window.Notification) || isValid(window.webkitNotifications)
);
},
// HTML5 Notifications Permission Handling
Permission: {
// Check if HTML5 Notifications are permitted
Check: function (set) {
/// <signature>
/// <summary>
/// Check if HTML5 Notifications are permitted
/// </summary>
/// <param name="set" type="Boolean">If true, the value will be set internally as well</param>
/// <returns type="Boolean">Whether or not notifications are permitted</returns>
/// </signature>
///
/// <signature>
/// <summary>
/// Check if HTML5 Notifications are permitted
/// </summary>
/// <returns type="Boolean">Whether or not notifications are permitted</returns>
/// </signature>
///

if (!exHelpObject.browserNotification._api)
if (!exHelpObject.browserNotification.Check_Support(true)) return;

var result = exHelpObject.browserNotification._api.checkPermission();
set && (exHelpObject.browserNotification._permission = result);
return result;
},

// Request permission to show HTML5 Notifications
// NOTE: This has to be executed on a click handler
Request: function () {
/// <summary>
/// Request permission to show HTML5 Notifications
/// NOTE: This has to be executed on a click handler
/// </summary>
/// <returns type="Boolean">Whether or not notifications have been granted or denied</returns>

return p.browserNotification._api.requestPermission();
},
},
_Push_Basic: function ($opts) {
if (
!exHelpObject.settings.useNativeNotifications ||
!this.Check_Support() ||
this.Permission.Check() !== this.permissions.ALLOWED
)
return;

var $title = $opts.title || exHelpObject.info.AppName;
var $content =
$opts.content ||
$opts.msg ||
$opts.message ||
$opts.txt ||
$opts.text;
var $img = $opts.img || $opts.pic || 'favicon.png';

var $onShow =
$opts.show ||
$opts.onshow ||
$opts.onShow ||
$opts.display ||
$opts.ondisplay ||
$opts.onDisplay;
var $onClose =
$opts.close || $opts.onClose || $opts.hide || $opts.onHide;

var $notification = this._api.createNotification(
$img,
$title,
$content
);
$onShow &&
exHelp.is.isFunction($onShow) &&
($notification.ondisplay = $onShow);
$onClose &&
exHelp.is.isFunction($onClose) &&
($notification.onclose = $onClose);

$notification.show();

this._list[this._counter.toString()] = $notification;
//this._counter++;

return {
notification: $notification,
id: this._counter++,
};
},

Push: function (title, message) {
/// <summary>
/// Push a notification
/// </summary>
/// <param name="title" type="String">Title of the notification</param>
/// <param name="message" type="String">Message of the notification</param>
/// <returns type="Object">Notification wrapper object { notification, id }</returns>

return this._Push_Basic({
title: title,
content: message,
});
},

PushWithImage: function (title, message, pic) {
/// <summary>
/// Push a notification with a custom image
/// </summary>
/// <param name="title" type="String">Title of the notification</param>
/// <param name="message" type="String">Message of the notification</param>
/// <param name="pic" type="String">URL of the image of the notification</param>
/// <returns type="Object">Notification wrapper object { notification, id }</returns>

return this._Push_Basic({
title: title,
content: message,
img: pic,
});
},

PushAdvanced: function (options) {
/// <summary>
/// Push a notification with (options) (For advanced users only)
/// </summary>
/// <param name="options" type="Object">Settings object { title, txt, img, show, close }</param>
/// <returns type=""></returns>

return this._Push_Basic(options);
},
},

locale: {
_locale: 'en',
set: function (l) {
this._locale = l;
},
getString: function (str) {
var store = exHelpObject.storage('locale');
if (store[this._locale] && store[this._locale][str])
return store[this._locale][str];

return str;
},
},
};

var exHelpExtend = function (e) {
exHelpObject.extend(e);
};

window.exHelp = exHelpObject;
window.exHelpExtend = exHelpExtend;
})(window);

// C# Style String.Format
// http://stackoverflow.com/questions/1038746/equivalent-of-string-format-in-jquery
String.prototype.format = function () {
var a = arguments;
return this.replace(/{(\d+)}/g, function (c, d) {
return 'undefined' != typeof a[d] ? a[d] : c;
});
};

// http://stackoverflow.com/questions/646628/javascript-startswith
String.prototype.startsWith = function (str) {
/// <summary>
/// Check if this string starts with (str)
/// </summary>
/// <param name="str" type="String">Needle to check</param>
/// <returns type="Boolean">True if this string starts with (str)</returns>
return this.slice(0, str.length) == str;
};

// http://stackoverflow.com/questions/646628/javascript-startswith
String.prototype.endsWith = function (str) {
/// <summary>
/// Check if this string ends with (str)
/// </summary>
/// <param name="str" type="String">Needle to check</param>
/// <returns type="Boolean">True if this string ends with (str)</returns>
return this.slice(-str.length) == str;
};

String.prototype.contains = function (str) {
return this.indexOf(str) !== -1;
};

// http://stackoverflow.com/questions/202605/repeat-string-javascript
String.prototype.repeat = function (n) {
/// <summary>
/// Repeats this string (n) times
/// </summary>
/// <param name="n" type="Integer">How often to repeat this string</param>
/// <returns type="String">Repeated string</returns>
var x = this;
var s = '';
for (;;) {
if (n & 1) s += x;
n >>= 1;
if (n) x += x;
else break;
}
return s;
};

// http://stackoverflow.com/a/5047712
//String.prototype.width = function (font)
//{
// var f = font || '12px arial',
// o = $('<div>' + this + '</div>')
// .css({ 'position': 'absolute', 'float': 'left', 'white-space': 'nowrap', 'visibility': 'hidden', 'font': f })
// .appendTo($('body')),
// w = o.width();

// o.remove();

// return w;
//}
///#source 1 1 /js/exHelp_Element.js
/// <reference path="_references.js" />

/*!

exHelp Library - Element Helper Plugin // Version 1.0.0.0
http://www.github.com/xwcg

The MIT License (MIT)

Copyright (c) 2016 Michael Schwarz

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

*/

(function InitExHelp_ElementPlugin(window) {
if (window['exHelp'] == void 0 || window['exHelpExtend'] == void 0) {
return setTimeout(InitExHelp_ElementPlugin, 100, window);
}

var exElement = function (selector, options) {
return new exElement.functions.init(selector, options);
};

var exHelpElement = {
e: exElement,
isExElement: function (e) {
return !!(e instanceof exHelp.e);
},
};

var domReadySusbcriberTopic = '_dom_ready';
var onDomReady = function () {
document.removeEventListener('DOMContentLoaded', onDomReady);
window.removeEventListener('load', onDomReady);

exHelp.trigger(domReadySusbcriberTopic);
};

document.addEventListener('DOMContentLoaded', onDomReady);
window.addEventListener('load', onDomReady);

exElement.functions = exElement.prototype = {
constructor: exElement,
init: function (selector, options) {
if (!selector) return this;

var matches = [];

if (exHelp.is.string(selector)) {
if (
selector.charAt(0) == '<' &&
selector.length >= 3 &&
selector.charAt(selector.length - 1) == '>'
) {
var tempElement = window.document.createElement('div');
tempElement.innerHTML = selector;
matches = tempElement.childNodes;

return new exElement(matches, options);
} else {
matches = window.document.querySelectorAll(selector);
for (var i = 0; i < matches.length; i++) this[i] = matches[i];

this.length = matches.length;
}
} else if (exHelp.is.arraylike(selector)) {
var tempmatch,
length = selector.length,
i = 0;
for (; i < length; i++) {
if (selector[i] instanceof exHelp.e) tempmatch = selector[i];
else tempmatch = new exElement(selector[i], options);

if (tempmatch.length > 0) matches.push(tempmatch[0]);
}

length = matches.length;
for (i = 0; i < length; i++) this[i] = matches[i];

this.length = matches.length;
} else if (exHelp.is.object(selector)) {
if (selector instanceof exHelp.e) return selector;

this.context = this[0] = selector;
this.length = 1;
}

this._applyOptions(options);

return this;
},

length: 0,

each: function (callback) {
//exHelp.each(this, callback);
for (var i = 0; i < this.length; i++)
if (callback.call(this[i], i, this[i]) === false) return false;

return true;
},

// Internal

_applyOptions: function (options) {
var key, value;
for (key in options) {
value = options[key];
switch (key.toLowerCase()) {
case 'html':
if (value.startsWith('__LOCALE__:')) {
var localeKey = value.split(':')[1];
this.setHtml(exHelp.locale.getString(localeKey));
} else this.setHtml(value);
break;

case 'class':
this.addClass(value);
break;

case 'width':
case 'height':
case 'top':
case 'left':
case 'right':
case 'bottom':
case 'position':
this.setStyle(key, value);
break;

default:
this.setAttr(key, value);
break;
}
}
},

// Basic DOM Functions

setAttr: function (name, value) {
this.each(function () {
if (this['setAttribute'] !== void 0) this.setAttribute(name, value);
//try { this.setAttribute(name, value); } catch (ex) { this[name] = value; }
});
return this;
},
getAttr: function (name) {
var ret = null;
this.each(function () {
if (this['getAttribute'] !== void 0) ret = this.getAttribute(name);

if (ret == null) {
// Sometimes getAttribute returns null even though the attribute definitely exists
// and definitely has a value. I don't know why, it just does.
// Thus: Go through the attributes list and find the attribute...
var attrList = this.attributes,
l = attrList.length,
i = 0;
for (; i < l; i++) {
var $this = attrList[i],
n = $this.name || $this.nodeName,
v = $this.value || $this.nodeValue || $this.textContent;
if (n == name) {
ret = v;
break;
}
}
}
});
return ret;
},

setHtml: function (value) {
this.each(function () {
if (this['innerHTML'] !== void 0) {
this.innerHTML = value;
} else if (this['textContent'] !== void 0) {
this.textContent = value;
}
});

return this;
},

getHtml: function () {
var ret = null;
this.each(function () {
if (this['innerHTML'] !== void 0) {
ret = this.innerHTML;
} else if (this['textContent'] !== void 0) {
ret = this.textContent;
}
});
return ret;
},

empty: function () {
return this.setHtml('');
},

remove: function () {
this.each(function () {
this.parentNode.removeChild(this);
});

return this;
},

children: function () {
var ret = [];
this.each(function () {
var i = 0,
children = this.childNodes,
length = children.length;
for (; i < length; i++) ret.push(children[i]);
});

return new exElement(ret);
},
find: function (query) {
if (!query) return new exElement([]);

var ret = [],
ele,
isClass = query.charAt(0) == '.',
isId = query.charAt(0) == '#',
pureName = isClass || isId ? query.substr(1) : query,
i,
length;

this.each(function exElement_FindIterator() {
ele = new exElement(this);
if (
(isClass && ele.hasClass(pureName)) ||
(isId && ele.getAttr('id') == pureName) ||
(!isClass &&
!isId &&
ele[0].nodeName.toLowerCase() == pureName.toLowerCase())
) {
ret.push(this);
}

if (this.childNodes.length > 0) {
ele = ele.children().find(query);
length = ele.length;
if (length > 0) {
for (i = 0; i < length; i++) ret.push(ele[i]);
}
}
});

return new exElement(ret);
},
exclusive: function (query) {
var ret = [],
ele,
isClass = query.charAt(0) == '.',
isId = query.charAt(0) == '#',
pureName = isClass || isId ? query.substr(1) : query,
i,
length;

this.each(function exElement_ExclusiveIterator() {
ele = new exElement(this);
if (
(isClass && ele.hasClass(pureName)) ||
(isId && ele.getAttr('id') == pureName) ||
(!isClass &&
!isId &&
ele[0].nodeName.toLowerCase() == pureName.toLowerCase())
) {
ret.push(this);
}
});

return new exElement(ret);
},

getWidth: function () {
return parseFloat(this.getComputedStyle('width'));
},
getHeight: function () {
return parseFloat(this.getComputedStyle('height'));
},

getParents: function (until) {
var parents = [],
hasUntil = until !== undefined,
untilIsClass = hasUntil && until.startsWith('.'),
untilIsId = hasUntil && until.startsWith('#');

var gp = function (e) {
if (e) {
var $e = new exElement(e);
parents.push(e);
if (hasUntil) {
if (
(untilIsClass && $e.hasClass(until)) ||
(untilIsId && $e.getAttr('id') == until)
)
return false;
}

if (e.parentNode) {
return gp(e.parentNode);
}
}
};

this.each(function () {
if (this) {
gp(this.parentNode);
}
});

return new exElement(parents);
},

getPageXY: function () {
var fullscreenElement =
document.fullScreenElement ||
document.msFullscreenElement ||
document.mozFullScreenElement ||
document.webkitFullscreenElement;
var offset = {
x: 0,
y: 0,
};
var getOffset = function (e) {
if (exHelp.fullscreen.isFullscreen && fullscreenElement == e) return;

offset.x += e.offsetLeft;
offset.y += e.offsetTop;

if (e.offsetParent) getOffset(e.offsetParent);
};

this.each(function () {
getOffset(this);
});

return offset;
},

getPageBounds: function () {
var xy = this.getPageXY();
var bounds = {
left: xy.x,
top: xy.y,
right: xy.x + this.getWidth(),
bottom: xy.y + this.getHeight(),
};

return bounds;
},

getRelativeXY: function (until) {
var offset = {
x: 0,
y: 0,
},
isClass = until.charAt(0) == '.',
isId = until.charAt(0) == '#',
pureName = isClass || isId ? until.substr(1) : until;

var getOffset = function (e) {
var ele = new exElement(e);
if (
(isClass && ele.hasClass(pureName)) ||
(isId && ele.getAttr('id') == pureName) ||
(!isClass &&
!isId &&
ele[0].nodeName.toLowerCase() == pureName.toLowerCase())
)
return false;

offset.x += e.offsetLeft;
offset.y += e.offsetTop;

if (e.offsetParent) getOffset(e.offsetParent);
};

this.each(function () {
getOffset(this);
});

return offset;
},

getRelativeBounds: function (until) {
var xy = this.getRelativeXY(until);
var bounds = {
left: xy.x,
top: xy.y,
right: xy.x + this.getWidth(),
bottom: xy.y + this.getHeight(),
};

return bounds;
},

getRelativeBoundingClientRect: function () {
var boundingRect = null;
var relBounds = this.getPageBounds();
this.each(function () {
boundingRect = this.getBoundingClientRect();
});

if (boundingRect != null) {
var outRect = {
top: boundingRect.top - relBounds.top,
left: boundingRect.left - relBounds.left,
right: boundingRect.right - relBounds.right,
bottom: boundingRect.bottom - relBounds.bottom,
width: boundingRect.width,
height: boundingRect.height,
};

return outRect;
}

return relBounds;
},

getComputedStyle: function (prop) {
var ret = null;

this.each(function () {
if (window.getComputedStyle) {
ret = window.getComputedStyle(this, null).getPropertyValue(prop);
} else if (this.currentStyle) {
ret = this.currentStyle[prop];
} else {
ret = this.style[prop];
}
});

return ret;
},

addClass: function (value) {
var values = value.split(' ');
this.each(function () {
var classes = this.className.split(' ');
for (var i = 0; i < values.length; i++)
if (!exHelp.array.contains(classes, values[i])) {
classes.push(values[i]);
}
this.className = classes.join(' ').trim();
});
return this;
},

removeClass: function (value) {
var values = value.split(' ');
this.each(function () {
var classes = this.className.split(' ');
for (var i = 0; i < values.length; i++)
if (exHelp.array.contains(classes, values[i])) {
classes.splice(classes.indexOf(values[i]), 1);
}
this.className = classes.join(' ').trim();
});
return this;
},

toggleClass: function (value) {
var values = value.split(' ');
this.each(function () {
var classes = this.className.split(' ');
for (var i = 0; i < values.length; i++)
if (exHelp.array.contains(classes, values[i])) {
classes.splice(classes.indexOf(values[i]), 1);
} else {
classes.push(values[i]);
}
this.className = classes.join(' ').trim();
});
return this;
},

hasClass: function (value) {
var ret = false;
this.each(function () {
var classes = this.className ? this.className.split(' ') : [];
if (exHelp.array.contains(classes, value)) {
ret = true;
return false;
}
});
return ret;
},

setStyle: function (name, value) {
this.each(function () {
this.style[name] = value;
});
},

appendTo: function (target) {
target = new exElement(target);
this.each(function () {
var $this = this;
target.each(function () {
this.appendChild($this);
});
});
return this;
},

prependTo: function (target) {
target = new exElement(target);
this.each(function () {
var $this = this;
target.each(function () {
this.insertBefore($this, this.firstChild);
});
});
return this;
},

// Event handling

_evtQueue: function () {
var queue = [];

this.add = function (e) {
queue.push(e);
};

this.call = function (context) {
for (var i = 0, l = queue.length; i < l; i++) {
queue[i].call(context);
}
};

this.remove = function (e) {
var newQueue = [];
for (var i = 0, l = queue.length; i < l; i++) {
if (queue[i] !== e) newQueue.push(queue[i]);
}
};

this.length = function () {
return queue.length;
};
},

on: function (events, callback) {
var evts = [],
$this = this;
if (exHelp.is.string(events)) {
if (events.contains(' ')) evts = events.split(' ');
else if (events.contains(',')) {
evts = events.split(',');
for (var i = 0; i < evts.length; i++) evts[i] = evts[i].trim();
} else evts.push(events);
}

var i = 0,
length = evts.length,
e;
for (; i < length; i++) {
e = evts[i];

switch (e) {
case 'ready':
exHelp.subscribe(domReadySusbcriberTopic, callback);
break;

case 'tap':
var tapHandler = function (element) {
var isDown = false,
ignoreUntilNew = false,
xe = new exElement(element);

element.addEventListener(
'touchstart',
function (e) {
//exHelp.reader.dbg("start");
ignoreUntilNew = false;
isDown = true;
xe.addClass('pressed');
},
{
passive: true,
}
);

element.addEventListener(
'touchcancel',
function (e) {
if (!ignoreUntilNew) {
//exHelp.reader.dbg("cancel");
ignoreUntilNew = true;
isDown = false;
xe.removeClass('pressed');
}
},
{
passive: true,
}
);

element.addEventListener(
'touchmove',
function (e) {
if (!ignoreUntilNew) {
var bounds = new exElement(element).getPageBounds();

if (e && e.touches && e.touches.length > 0) {
var touch = e.touches[0];
if (
touch.pageX < bounds.left ||
touch.pageX > bounds.right ||
touch.pageY < bounds.top ||
touch.pageY > bounds.bottom
) {
isDown = false;
element.dispatchEvent(new TouchEvent('touchcancel'));
}
}
}
},
{
passive: true,
}
);

element.addEventListener('touchend', function (e) {
if (!ignoreUntilNew) {
if (isDown) {
// Prevent double triggering of tap and click
if (e && e.preventDefault) e.preventDefault();
if (e && e.stopPropagation) e.stopPropagation();

//exHelp.reader.dbg("end");
element._ehe_queue_tap.call(element);
isDown = false;
xe.removeClass('pressed');
}
}
});
};

this.each(function () {
if (!this._ehe_queue_tap)
this._ehe_queue_tap = new $this._evtQueue();

if (!this._ehe_taphandler)
this._ehe_taphandler = new tapHandler(this);

this._ehe_queue_tap.add(callback);
});
break;

case 'resize':
var resizeAttacher = function () {
if (this instanceof Element) {
if (this._ehe_resize_handler) {
this._ehe_queue_resize.add(callback);
} else {
if (!this._ehe_queue_resize)
this._ehe_queue_resize =
new exElement.functions._evtQueue();

this._ehe_queue_resize.add(callback);
this._ehe_resize_handler = document.createElement('div');

var $this = this;
var style =
'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden; z-index: -1; visibility: hidden;';
var styleChild =
'position: absolute; left: 0; top: 0; transition: 0s;';

this._ehe_resize_handler.className = 'ehe-resize-event-dummy';
this._ehe_resize_handler.style.cssText = style;
this._ehe_resize_handler.innerHTML =
'<div class="resize-sensor-expand" style="{0}"><div style="{1}"></div></div><div class="resize-sensor-shrink" style="{0}"><div style="{1} width: 200%; height: 200%"></div></div>'.format(
style,
styleChild
);

this.appendChild(this._ehe_resize_handler);

var expand = this._ehe_resize_handler.childNodes[0];
var expandChild = expand.childNodes[0];
var shrink = this._ehe_resize_handler.childNodes[1];

var reset = function () {
expandChild.style.width = 100000 + 'px';
expandChild.style.height = 100000 + 'px';

expand.scrollLeft = 100000;
expand.scrollTop = 100000;

shrink.scrollLeft = 100000;
shrink.scrollTop = 100000;
};

reset();

var lastWidth, lastHeight;
var cachedWidth, cachedHeight; //useful to not query offsetWidth twice

var onScroll = function () {
if (
(cachedWidth = $this.offsetWidth) != lastWidth ||
(cachedHeight = $this.offsetHeight) != lastHeight
) {
$this._ehe_queue_resize.call(this);

lastWidth = cachedWidth;
lastHeight = cachedHeight;
}
reset();
};

expand.addEventListener('scroll', onScroll);
shrink.addEventListener('scroll', onScroll);
}

return false;
}
};

if (this.each(resizeAttacher) === false) break;

default:
this.each(function () {
this.addEventListener(e, callback);
});
break;
}
}

return this;
},
off: function (events, callback) {
var evts = [],
$this = this;
if (exHelp.is.string(events)) {
if (events.contains(' ')) evts = events.split(' ');
else if (events.contains(',')) {
evts = events.split(',');
for (var i = 0; i < evts.length; i++) evts[i] = evts[i].trim();
} else evts.push(events);
}

var i = 0,
length = evts.length,
e;
for (; i < length; i++) {
e = evts[i];

switch (e) {
case 'ready':
exHelp.unsubscribe(domReadySusbcriberTopic, callback);
break;

case 'tap':
this.each(function () {
if (this._ehe_queue_tap) this._ehe_queue_tap.remove(callback);
});
break;

case 'resize':
var resizeAttacher = function () {
if (this instanceof Element) {
if (this._ehe_queue_resize) {
this._ehe_queue_resize.remove(callback);
}
}
};

if (this.each(resizeAttacher) === false) break;

default:
this.each(function () {
this.removeEventListener(e, callback);
});
break;
}
}

return this;
},
};

exElement.functions.init.prototype = exElement.functions;
exElement.extend = exElement.functions.extend = function (e) {
exHelp.extend(this, e);
};

// Extend exHelp
window.exHelpExtend(exHelpElement);
})(window);
///#source 1 1 /js/init.js
/// <reference path="_references.js" />

(function InitReader(window) {
if (
window['exHelp'] == void 0 ||
window['exHelpExtend'] == void 0 ||
window['exHelp']['e'] == void 0
) {
return setTimeout(InitReader, 100, window);
}

// Create shorthand
var p = exHelp;

var reader = {
reader: {
container: null,
path: null,
render_canvas: null,
sound: null,

dbg_log: [],
dbg: function (a) {
/*
var $this = p.reader;
$this.dbg_log.push(a);

if ($this.dbg_log.length > 5)
$this.dbg_log.splice(0, 1);

var ele = p.e("#dbgcontainer");
if (!ele || ele.length == 0)
{
ele = p.e("<div>", { "id": "dbgcontainer" }).appendTo($this.container);
}

ele.setHtml("<p>" + $this.dbg_log.join("</p><p>") + "</p>");
*/
},

settings: {
language: 'en',

show_go_to_page: false,

preload: false,

custom_background: null,
custom_backgound_mode: null,

start_page: 1,
no_pdf: false,

slideshow_mode: false,
slideshow_timing: 5,
slideshow_controls: false,
slideshow_pdf: false,

page_mode: 'auto',
page_sound: 0,
page_sound_volume: 1.0,

show_zoom: true,
show_print: false,
enable_pinching: false,
enable_double_tapping: false,
enable_mousewheel_zoom: false,
zoom_max: 2,
/*zoom_min: "auto",
zoom_doubleclick: 1.0,
zoom_wheel_step: 0.1,
zoom_button_step:1.0,*/

zoom_min: 'auto',
zoom_doubleclick: 1.0,
zoom_wheel_step: 0.5,
zoom_button_step: 0.5,

enable_dragging: true,
enable_scrollbars: false,

show_fullscreen: true,
hide_in_fullscreen: true,

show_invert: false,
show_download: false,

show_overview: true,
overview_direction: 'bottom',
overview_overlay: false,
overview_size: 150,
overview_start_open: false,

enable_keyboard_navigation: false,
enable_swiping: false,
enable_arrows: false,

social_twitter: null,
social_facebook: null,
social_google: null,
social_email: false,

enable_printing: false,

small_controls: false,
},

control_assignments: {
overview: 'bottomright-ver',
fullscreen: 'bottomright-ver',
invert: 'topright-hor',
'zoom-in': 'topright-hor',
print: 'topright-hor',
'zoom-out': 'topright-hor',
'go-back': 'left',
'go-fwd': 'right',
download: 'bottomleft-hor',
goto: 'bottomleft-hor',
'ss-back': 'bottom',
'ss-play': 'bottom',
'ss-pause': 'bottom',
'ss-fwd': 'bottom',
},

elements: [
{
selector: '.content',
construct: '<div>',
options: {
class: 'content',
tabindex: 0,
},

children: [
{
selector: '.pages',
options: {
class: 'pages',
},
children: [
{
selector: '.overlayer',
options: {
class: 'overlayer',
},
},
],
},
],
},

{
selector: '.controls',
options: {
class: 'controls',
},
children: [
{
selector: '.topleft',
options: {
class: 'topleft',
},
children: [
{
selector: '.horizontal',
options: {
class: 'horizontal flex',
},
},
{
selector: '.vertical',
options: {
class: 'vertical flex',
},
},
],
},
{
selector: '.topright',
options: {
class: 'topright',
},
children: [
{
selector: '.horizontal',
options: {
class: 'horizontal flex',
},
},
{
selector: '.vertical',
options: {
class: 'vertical flex',
},
},
],
},
{
selector: '.bottomleft',
options: {
class: 'bottomleft',
},
children: [
{
selector: '.horizontal',
options: {
class: 'horizontal flex',
},
},
{
selector: '.vertical',
options: {
class: 'vertical flex',
},
},
],
},
{
selector: '.bottomright',
options: {
class: 'bottomright',
},
children: [
{
selector: '.horizontal',
options: {
class: 'horizontal flex',
},
},
{
selector: '.vertical',
options: {
class: 'vertical flex',
},
},
],
},

{
selector: '.top',
options: {
class: 'top flex horizontal center-content',
},
},

{
selector: '.left',
options: {
class: 'left flex vertical center-content',
},
},

{
selector: '.bottom',
options: {
class: 'bottom flex horizontal center-content',
},
},

{
selector: '.right',
options: {
class: 'right flex vertical center-content',
},
},
],
},

{
selector: '.overviews',
options: {
class: 'overviews',
},
},

{
selector: '.main-loader',
options: {
class: 'main-loader loader',
},
},

{
selector: '.status',
options: {
class: 'status flex horizontal',
},
children: [
{
selector: '.loader',
options: {
class: 'loader',
},
children: [
{
selector: '.spinner',
options: {
class: 'spinner',
},
},
],
},
{
selector: '.text',
options: {
class: 'text',
html: '__LOCALE__:LOADING',
},
},
{
selector: '.finished-overlay',
options: {
class: 'finished-overlay hidden',
html: '__LOCALE__:LOADING_FINISHED',
},
},
{
selector: '.error-overlay',
options: {
class: 'error-overlay hidden',
html: '__LOCALE__:LOADING_ERROR',
},
},
],
},
{
selector: '.render-canvas',
construct: '<canvas>',
options: {
class: 'render-canvas',
},
},
],

checkFileExists: function (path, callback) {
callback(true);
},

makeMessage: function (title, text, onButton) {
var box = p.e('<div>', {
class: 'message',
});
var eTitle = p.e('<div>', {
class: 'title',
html: title,
});
var eText = p.e('<div>', {
class: 'text',
html: text,
});
var eButton = p.e('<div>', {
class: 'button',
html: 'OK',
});
eTitle.appendTo(box);
eText.appendTo(box);
eButton.appendTo(box);

eButton.on('click', function () {
box.remove();

if (onButton && p.is.function(onButton)) {
onButton();
}
});

return box;
},

loadPdfProcessor: function (callback) {
var scriptTags = p.e('script');
var currentScript = null;
scriptTags.each(function () {
if (this.src.contains('magalone.')) {
currentScript = this.src;
return false;
}
});

if (currentScript != null) {
p.pager.current_script = currentScript;
var currentPath = p.pager.current_script.substr(
0,
p.pager.current_script.lastIndexOf('/')
);
var pdfProcessorPath =
currentPath +
'/processing' +
(p.pager.current_script.contains('.min') ? '.min' : '') +
'.js';

var pdfProcessorScriptElement = document.createElement('script');
var pdfProcessorLoaded = false;
pdfProcessorScriptElement.onload = function () {
if (!pdfProcessorLoaded) {
callback();
}

pdfProcessorLoaded = true;
};
pdfProcessorScriptElement.setAttribute('src', pdfProcessorPath);
document
.getElementsByTagName('head')[0]
.appendChild(pdfProcessorScriptElement);
}
},

loadLocale: function (callback) {
var scriptTags = p.e('script');
var currentScript = null;
scriptTags.each(function () {
if (this.src.contains('magalone')) {
currentScript = this.src;
return false;
}
});

if (currentScript != null) {
p.pager.current_script = currentScript;
var currentPath = p.pager.current_script.substr(
0,
p.pager.current_script.lastIndexOf('/')
);
var localePath =
currentPath +
'/locale/' +
p.reader.settings.language +
(p.pager.current_script.contains('.min') ? '.min' : '') +
'.js';

var localeScriptElement = document.createElement('script');
var localeLoaded = false;
localeScriptElement.onload = function () {
if (!localeLoaded) {
callback();
}

localeLoaded = true;
};
localeScriptElement.setAttribute('src', localePath);
document
.getElementsByTagName('head')[0]
.appendChild(localeScriptElement);
}
},

loadAudioPath: function () {
var scriptTags = p.e('script');
var currentScript = null;
scriptTags.each(function () {
if (this.src.contains('magalone.')) {
currentScript = this.src;
return false;
}
});

if (currentScript != null) {
p.pager.current_script = currentScript;
var currentPath =
p.pager.current_script.substr(
0,
p.pager.current_script.lastIndexOf('/') - 3
) + '/sound/page-flip-';
return currentPath;
}

return './';
},

svgLoaded: false,
loadSvgFilters: function () {
var invertFilter =
'<svg version="1.1" xmlns:svg="http://www.w3.org/2000/svg" height="0"><filter id="invert"><feComponentTransfer><feFuncR type="table" tableValues="1 0"></feFuncR><feFuncG type="table" tableValues="1 0"></feFuncG><feFuncB type="table" tableValues="1 0"></feFuncB></feComponentTransfer></filter></svg>';
p.e(invertFilter, {
style: 'display:none;',
}).appendTo('body');
this.svgLoaded = true;
},

playPageSound: function () {
if (p.reader.sound != null) {
p.reader.sound[0].pause();
p.reader.sound[0].currentTime = 0;
p.reader.sound[0].play();
}
},

get: function (e, defaultValue) {
var v = p.reader.container.getAttr('data-' + e);
var d = defaultValue === undefined ? null : defaultValue;
return v == null ? d : v;
},

getBoolean: function (e, defaultValue) {
var v = this.get(e);
var d = defaultValue === undefined ? false : defaultValue;
return v == null ? d : v == 'true';
},

lastFullscreenElement: null,
onFullscreenChange: function (evt) {
var fullscreenElement =
document.fullScreenElement ||
document.msFullscreenElement ||
document.mozFullScreenElement ||
document.webkitFullscreenElement;
var type = '';
if (p.reader.lastFullscreenElement == null) {
type = 'enter';
} else {
type = 'exit';
}

p.trigger('fullscreen', [
type,
fullscreenElement || p.reader.lastFullscreenElement,
]);
p.reader.lastFullscreenElement = fullscreenElement;
},

init: function () {
var $this = this,
temp;
this.container = p.e('#reader-container');

if (this.container.length > 0) {
this.path = this.get('path');
}

if (
this.container.length > 0 &&
this.path != null &&
this.path.length > 0
) {
// Get Config
this.settings.language = this.get('language', 'en');
p.locale.set(this.settings.language);

this.settings.start_page = parseInt(this.get('start-page', '1'));
this.settings.no_pdf = this.getBoolean('no-pdf', false);

this.settings.show_fullscreen = this.getBoolean(
'show-fullscreen',
true
);
this.settings.hide_in_fullscreen = this.getBoolean(
'immersive-fullscreen',
false
);
this.settings.show_invert = this.getBoolean('show-invert');

this.settings.show_overview = this.getBoolean('show-thumbnails');
this.settings.overview_overlay =
this.getBoolean('thumbnails-overlay');
this.settings.overview_direction = this.get(
'thumbnails-direction',
'bottom'
);
this.settings.overview_size = parseInt(
this.get('thumbnails-size', '150')
);
this.settings.overview_start_open = this.getBoolean(
'thumbnails-start-open'
);

this.settings.show_zoom = this.getBoolean('show-zoom');
this.settings.show_print = this.getBoolean('show-print');
this.settings.enable_pinching = this.getBoolean('enable-pinching');
this.settings.enable_double_tapping = this.getBoolean(
'enable-double-click'
);
this.settings.enable_mousewheel_zoom =
this.getBoolean('enable-mouse-wheel');
this.settings.zoom_wheel_step =
parseInt(this.get('zoom-wheel', '10')) / 100;
this.settings.zoom_max = parseInt(this.get('zoom-max', '280')) / 100;
this.settings.zoom_min =
(temp = this.get('zoom-min', 'auto')) == 'auto'
? 'auto'
: parseInt(temp) / 100;
this.settings.zoom_doubleclick =
parseInt(this.get('zoom-doubleclick', '200')) / 100;

this.settings.enable_keyboard_navigation = this.getBoolean(
'enable-keyboard',
true
);
this.settings.enable_swiping = this.getBoolean(
'enable-swiping',
true
);
this.settings.enable_arrows = this.getBoolean('enable-arrows', true);

this.settings.preload = this.getBoolean('preload', true); //!
this.settings.show_download = this.getBoolean('show-download', false);
this.settings.show_go_to_page = this.getBoolean(
'show-go-to-page',
false
); //!

this.settings.slideshow_mode = this.getBoolean('slideshow', false);
this.settings.slideshow_timing = parseFloat(
this.get('slideshow-time', '5')
);
this.settings.slideshow_controls = this.getBoolean(
'slideshow-show-controls',
false
);
this.settings.slideshow_pdf = this.getBoolean(
'slideshow-use-pdf',
false
);

this.settings.small_controls = this.getBoolean(
'small-controls',
false
);

this.settings.page_sound = parseInt(this.get('page-sound', '0'));
this.settings.page_sound_volume =
parseInt(this.get('page-sound-volume', '100')) / 100;

this.settings.page_mode = this.get('page-mode', 'auto');
if (this.settings.page_mode != 'auto') {
if (this.settings.page_mode == 'single') {
p.pager.current_mode_manual = true;
p.pager.current_mode = p.pager.constant.SINGLE;
} else if (this.settings.page_mode == 'double') {
p.pager.current_mode_manual = true;
p.pager.current_mode = p.pager.constant.DOUBLE;
}
}

//this.settings.enable_dragging = this.getBoolean("enable-dragging", true);//!
//this.settings.enable_scrollbars = this.getBoolean("enable-scrollbars");//!
/*

custom_background: null,
custom_backgound_mode: null,

social_twitter: null,
social_facebook: null,
social_google: null,
social_email: false,

enable_printing: false,
*/

// Do inits
this.loadLocale(function () {
$this.prepareElements();
p.overlays.init();
document.addEventListener(
'fullscreenchange',
p.reader.onFullscreenChange
);
document.addEventListener(
'mozfullscreenchange',
p.reader.onFullscreenChange
);
document.addEventListener(
'webkitfullscreenchange',
p.reader.onFullscreenChange
);
document.addEventListener(
'MSFullscreenChange',
p.reader.onFullscreenChange
); // CASE SENSITIVE, yes I am serious

$this.render_canvas = $this.container.find('.render-canvas');

if ($this.settings.enable_scrollbars) {
$this.container.find('.content').addClass('scrollbars');
}
if ($this.settings.small_controls)
$this.container.find('.controls').addClass('small');

if ($this.settings.slideshow_mode) {
p.pager.current_mode_manual = true;
p.pager.current_mode = p.pager.constant.SINGLE;
}
if (
$this.settings.page_sound > 0 &&
$this.settings.page_sound <= 20
) {
try {
$this.sound = p.e('<audio>', {
preload: 'auto',
});
} catch (ex) {
$this.sound = p.e('<audio>');
}
if ($this.sound != null) {
var path = $this.loadAudioPath();

if ($this.sound[0].canPlayType('audio/mp3'))
var mp3 = p
.e('<source>', {
src: path + $this.settings.page_sound + '.mp3',
type: 'audio/mp3',
})
.appendTo($this.sound);
if ($this.sound[0].canPlayType('audio/aac'))
var aac = p
.e('<source>', {
src: path + $this.settings.page_sound + '.aac',
type: 'audio/aac',
})
.appendTo($this.sound);
if ($this.sound[0].canPlayType('audio/ogg'))
var ogg = p
.e('<source>', {
src: path + $this.settings.page_sound + '.ogg',
type: 'audio/ogg',
})
.appendTo($this.sound);
if ($this.sound[0].canPlayType('audio/wav'))
var wav = p
.e('<source>', {
src: path + $this.settings.page_sound + '.wav',
type: 'audio/wav',
})
.appendTo($this.sound);

$this.sound.appendTo($this.container);
try {
$this.sound[0].volume = $this.settings.page_sound_volume;
} catch (ex) {
console.error('AUDIO is not supported by browser');
$this.sound = null;
}
}
}

$this.checkFileExists(
'<?php echo $file_path; ?>/thumb/cover_small.jpg',
function (success) {
if (success) {
// $this.prepareCover();
$this.prepareData();
$this.prepareControls();
}
}
);
});
}
},

setProgress: function (e) {
var status = p.e('div.status .text');
if (e < 0) {
status.setHtml(p.locale.getString('LOADING'));
} else if (e >= 0 && e < 100) {
status.setHtml(e.toFixed(0) + '%');
} else if (e == 'error') {
p.e('.error-overlay').removeClass('hidden');
setTimeout(function () {
p.e('.status').addClass('gone');
}, 1000);
} else {
p.e('.finished-overlay').removeClass('hidden');
setTimeout(function () {
p.e('.status').addClass('gone');
}, 1000);
}
},

prepareControls: function () {
// Make Controls
var ctrl_initializers = {
fullscreen: {
selector: '.ctrl.btn.fullscreen',
options: {
class: 'ctrl btn fullscreen',
},
children: [
{
selector: '.icon.on',
options: {
class: 'icon on',
html: 'fullscreen_exit',
},
},
{
selector: '.icon.off',
options: {
class: 'icon off',
html: 'fullscreen',
},
},
],
},
overview: {
selector: '.ctrl.btn.overview',
options: {
class: 'ctrl btn overview',
},
children: [
{
selector: '.icon',
options: {
class: 'icon',
html: 'view_module',
},
},
],
},
invert: {
selector: '.ctrl.btn.invert',
options: {
class: 'ctrl btn invert',
},
children: [
{
selector: '.icon',
options: {
class: 'icon',
html: 'invert_colors',
},
},
],
},
'zoom-in': {
selector: '.ctrl.btn.zoom-in',
options: {
class: 'ctrl btn zoom-in',
},
children: [
{
selector: '.icon',
options: {
class: 'icon',
html: 'zoom_in',
},
},
],
},
print: {
selector: '.ctrl.btn.print',
options: {
class: 'ctrl btn print',
},
children: [
{
selector: '.icon',
options: {
class: 'icon',
html: 'print',
},
},
],
},
'zoom-out': {
selector: '.ctrl.btn.zoom-out',
options: {
class: 'ctrl btn zoom-out',
},
children: [
{
selector: '.icon',
options: {
class: 'icon',
html: 'zoom_out',
},
},
],
},
'go-back': {
selector: '.ctrl.btn.go-back',
options: {
class: 'ctrl btn go-back',
},
children: [
{
selector: '.icon',
options: {
class: 'icon',
html: 'keyboard_arrow_left',
},
},
],
},
'go-fwd': {
selector: '.ctrl.btn.go-fwd',
options: {
class: 'ctrl btn go-fwd',
},
children: [
{
selector: '.icon',
options: {
class: 'icon',
html: 'keyboard_arrow_right',
},
},
],
},
/*,
"download": {
construct: "<a>",
selector: ".ctrl.btn.download",
options: { "class": "ctrl btn download", href: p.pager.getPDFPath(), "target": "_blank" },
children:
[
{ selector: ".icon", options: { "class": "icon", html: "file_download" } }
]
}*/
goto: {
selector: '.ctrl.btn.goto',
options: {
class: 'ctrl btn goto',
},
children: [
{
selector: '.icon',
options: {
class: 'icon',
html: 'input',
},
},
],
},

/// SLIDESHOW
'ss-back': {
selector: '.ctrl.btn.ss-back',
options: {
class: 'ctrl btn ss-back',
},
children: [
{
selector: '.icon',
options: {
class: 'icon',
html: 'skip_previous',
},
},
],
},
'ss-play': {
selector: '.ctrl.btn.ss-play',
options: {
class: 'ctrl btn ss-play',
},
children: [
{
selector: '.icon',
options: {
class: 'icon',
html: 'play_arrow',
},
},
],
},
'ss-pause': {
selector: '.ctrl.btn.ss-pause',
options: {
class: 'ctrl btn ss-pause',
},
children: [
{
selector: '.icon',
options: {
class: 'icon',
html: 'pause',
},
},
],
},
'ss-fwd': {
selector: '.ctrl.btn.ss-fwd',
options: {
class: 'ctrl btn ss-fwd',
},
children: [
{
selector: '.icon',
options: {
class: 'icon',
html: 'skip_next',
},
},
],
},
};

var containers = {
'topleft-hor': p.e('.controls .topleft .horizontal'),
'topright-hor': p.e('.controls .topright .horizontal'),
'bottomleft-hor': p.e('.controls .bottomleft .horizontal'),
'bottomright-hor': p.e('.controls .bottomright .horizontal'),
'topleft-ver': p.e('.controls .topleft .vertical'),
'topright-ver': p.e('.controls .topright .vertical'),
'bottomleft-ver': p.e('.controls .bottomleft .vertical'),
'bottomright-ver': p.e('.controls .bottomright .vertical'),

top: p.e('.controls .top'),
left: p.e('.controls .left'),
right: p.e('.controls .right'),
bottom: p.e('.controls .bottom'),
};

var tabindex = 1;

for (var ctrl in ctrl_initializers) {
var target =
containers[this.control_assignments[ctrl]] ||
containers['topleft-hor'];
this._prepareElement(ctrl_initializers[ctrl], target).setAttr(
'tabindex',
tabindex++
);
}

// FULLLSCREEN BUTTON
if (this.settings.show_fullscreen) {
p.e('.ctrl.btn.fullscreen').on('click', function (e) {
ga('send', 'event', {
eventCategory: 'Web-Reader',
eventAction: 'Fullscreen',
eventLabel: 'clicked',
});

if (e && e.preventDefault) e.preventDefault();
if (e && e.stopPropagation) e.stopPropagation();

if (p.is.keyboard_event(e)) {
if (e.keyCode != 13 && e.keyCode != 32) {
return;
}
}

if (p.fullscreen.isFullscreen) {
p.fullscreen.exit();
} else {
p.fullscreen.enter(p.reader.container[0]);
}
});

if (p.fullscreen.isFullscreen) {
p.e('.ctrl.btn.fullscreen').addClass('on').removeClass('off');
} else {
p.e('.ctrl.btn.fullscreen').addClass('off').removeClass('on');
}

var readerFullscreenChange = function (type, element) {
//console.log(type, element);
if (p.e(element).getAttr('id') == 'reader-container') {
if (type == 'exit') {
p.e('.ctrl.btn:not(.fullscreen)').removeClass('immersive');
p.reader.container.removeClass('fullscreen');
p.pager.adjust({
reload: true,
});
p.e('.ctrl.btn.fullscreen').addClass('off').removeClass('on');
} else {
if (p.reader.settings.hide_in_fullscreen)
p.e('.ctrl.btn:not(.fullscreen)').addClass('immersive');
p.reader.container.addClass('fullscreen');
p.pager.adjust({
reload: true,
});
p.e('.ctrl.btn.fullscreen').addClass('on').removeClass('off');
}

p.pager.calculateAutozoom();
}
};

p.subscribe('fullscreen', readerFullscreenChange);
} else {
p.e('.ctrl.btn.fullscreen').addClass('gone');
}

// OVERVIEW
if (this.settings.show_overview) {
p.e('.ctrl.btn.overview').on('click tap', function (e) {
ga('send', 'event', {
eventCategory: 'Web-Reader',
eventAction: 'Overview',
eventLabel: 'clicked',
});

if (e && e.preventDefault) e.preventDefault();
if (e && e.stopPropagation) e.stopPropagation();

p.reader.overview.toggle();
});
} else {
p.e('.ctrl.btn.overview').addClass('gone');
}

// INVERT

if (this.settings.show_invert && !p.browser.isMSIE) {
p.e('.ctrl.btn.invert').on('click tap', function (e) {
ga('send', 'event', {
eventCategory: 'Web-Reader',
eventAction: 'Invert',
eventLabel: 'clicked',
});

if (e && e.preventDefault) e.preventDefault();
if (e && e.stopPropagation) e.stopPropagation();

p.reader.toggleInvert();
});
} else {
p.e('.ctrl.btn.invert').addClass('gone');
}

// ZOOM

if (this.settings.show_zoom) {
p.e('.ctrl.btn.zoom-in').on('click tap', function (e) {
ga('send', 'event', {
eventCategory: 'Web-Reader',
eventAction: 'Zoom In',
eventLabel: 'clicked',
});

if (e && e.preventDefault) e.preventDefault();
if (e && e.stopPropagation) e.stopPropagation();

p.pager.setZoom(
p.pager.current_zoom + p.reader.settings.zoom_button_step
);
p.pager.adjust({
reload: true,
});
});
p.e('.ctrl.btn.zoom-out').on('click tap', function (e) {
ga('send', 'event', {
eventCategory: 'Web-Reader',
eventAction: 'Zoom Out',
eventLabel: 'clicked',
});

if (e && e.preventDefault) e.preventDefault();
if (e && e.stopPropagation) e.stopPropagation();

p.pager.setZoom(
p.pager.current_zoom - p.reader.settings.zoom_button_step
);
p.pager.adjust({
reload: true,
});
});
} else {
p.e(['.ctrl.btn.zoom-in', '.ctrl.btn.zoom-out']).addClass('gone');
}

if (this.settings.show_print) {
p.e('.ctrl.btn.print').on('click tap', function (e) {
print();
});
} else {
p.e(['.ctrl.btn.print']).addClass('gone');
}

if (this.settings.enable_arrows) {
//var tapLock = false;
p.e('.ctrl.btn.go-fwd').on('click tap', function (e) {
console.log('local Magalone.js');

ga('send', 'event', {
eventCategory: 'Web-Reader',
eventAction: 'Next',
eventLabel: 'clicked',
});
if (p.ads.showAds()) {
return false;
}
//if (!tapLock)
//{
// tapLock = true;

if (e && e.preventDefault) e.preventDefault();
if (e && e.stopPropagation) e.stopPropagation();

//p.reader.dbg("fwd-tap");

if (p.pager.current_animator == null) p.pager.goForward();
else p.pager.current_animator.doFullAnimationNext();

// setTimeout(function () { tapLock = false; }, 50);
//}
});
p.e('.ctrl.btn.go-back').on('click tap', function (e) {
ga('send', 'event', {
eventCategory: 'Web-Reader',
eventAction: 'Previous',
eventLabel: 'clicked',
});
if (p.ads.showAds()) {
return false;
}
//if (!tapLock)
//{
// tapLock = true;

if (e && e.preventDefault) e.preventDefault();
if (e && e.stopPropagation) e.stopPropagation();

//p.reader.dbg("back-tap");

if (p.pager.current_animator == null) p.pager.goBack();
else p.pager.current_animator.doFullAnimationPrev();

// setTimeout(function () { tapLock = false; }, 50);
//}
});
} else {
p.e(['.ctrl.btn.go-fwd', '.ctrl.btn.go-back']).addClass('gone');
}

if (this.settings.show_download) {
p.e('.ctrl.btn.download').on('click tap', function (e) {
//if (e && e.preventDefault) e.preventDefault();
if (e && e.stopPropagation) e.stopPropagation();

//window.location.assign(p.pager.getPDFPath());
});
} else {
p.e('.ctrl.btn.download').addClass('gone');
}

if (this.settings.show_go_to_page) {
p.e('.ctrl.btn.goto').on('click tap', function (e) {
if (e && e.preventDefault) e.preventDefault();
if (e && e.stopPropagation) e.stopPropagation();
});
} else {
p.e('.ctrl.btn.goto').addClass('gone');
}

if (this.settings.slideshow_mode && this.settings.slideshow_controls) {
p.e('.ctrl.btn.ss-back').on('click tap', function (e) {
if (e && e.preventDefault) e.preventDefault();
if (e && e.stopPropagation) e.stopPropagation();

p.reader.slideshow.prev_manual();
});
p.e('.ctrl.btn.ss-fwd').on('click tap', function (e) {
if (e && e.preventDefault) e.preventDefault();
if (e && e.stopPropagation) e.stopPropagation();

p.reader.slideshow.next_manual();
});

p.e('.ctrl.btn.ss-pause').on('click tap', function (e) {
if (e && e.preventDefault) e.preventDefault();
if (e && e.stopPropagation) e.stopPropagation();

p.reader.slideshow.pause();
});
p.e('.ctrl.btn.ss-play').on('click tap', function (e) {
if (e && e.preventDefault) e.preventDefault();
if (e && e.stopPropagation) e.stopPropagation();

p.reader.slideshow.play();
});

p.e('.ctrl.btn.ss-play').addClass('gone');
} else {
p.e([
'.ctrl.btn.ss-back',
'.ctrl.btn.ss-pause',
'.ctrl.btn.ss-play',
'.ctrl.btn.ss-fwd',
]).addClass('gone');
}
},

slideshow: {
timeout: null,
play_timeout: function () {
p.pager.goForward(function () {
p.reader.slideshow.timeout = setTimeout(
p.reader.slideshow.play_timeout,
p.reader.settings.slideshow_timing * 1000
);
if (p.pager.current_page == p.pager.page_count)
p.pager.current_page = 0;
});
},
play: function () {
p.e('.ctrl.btn.ss-play').addClass('gone');
p.e('.ctrl.btn.ss-pause').removeClass('gone');
p.reader.slideshow.timeout = setTimeout(
p.reader.slideshow.play_timeout,
p.reader.settings.slideshow_timing * 1000
);
},
pause: function () {
p.e('.ctrl.btn.ss-pause').addClass('gone');
p.e('.ctrl.btn.ss-play').removeClass('gone');
clearTimeout(p.reader.slideshow.timeout);
},
next_manual: function () {
p.reader.slideshow.pause();
p.pager.goForward();
},
prev_manual: function () {
p.reader.slideshow.pause();
p.pager.goBack();
},
},

overview: {
isInited: false,
isFirstOpen: true,
isOpen: false,
container: null,
thumbs: [],
delta: 0,
interval: null,

ensureInit: function () {
if (!this.isInited) {
var $this = this,
requestFrame =
window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame,
cancelFrame =
window.cancelAnimationFrame || window.mozCancelAnimationFrame;

this.container = p.e('#reader-container .overviews');
this.container.addClass(
p.reader.settings.overview_direction +
(p.reader.settings.overview_overlay ? ' float' : ' solid')
);
this.container.addClass('hidden');

switch (p.reader.settings.overview_direction) {
case 'left':
case 'right':
this.container.setAttr(
'style',
'width: {0}px'.format(p.reader.settings.overview_size)
);
break;
case 'top':
case 'bottom':
this.container.setAttr(
'style',
'height: {0}px'.format(p.reader.settings.overview_size)
);
break;
}

this.container.on('wheel', function (e) {
if (e && e.preventDefault) e.preventDefault();
if (e && e.stopPropagation) e.stopPropagation();

switch (p.reader.settings.overview_direction) {
case 'left':
case 'right':
$this.container[0].scrollTop += e.deltaY;
break;
case 'top':
case 'bottom':
$this.container[0].scrollLeft += e.deltaY;
break;
}
});

var isScrolling = false;
var lastPos = null;
var currentPos = null;
var momentumStep = 1;

var fncGetPos = function (event) {
if (event.type.startsWith('touch')) {
if (event.touches.length == 1) {
return {
x: event.touches[0].pageX,
y: event.touches[0].pageY,
};
} else if (event.touches.length == 2) {
var a = {
x: event.touches[0].pageX,
y: event.touches[0].pageY,
},
b = {
x: event.touches[1].pageX,
y: event.touches[1].pageY,
},
midpoint = p.math.Midpoint2D(a, b);

return {
x: midpoint.x,
y: midpoint.y,
dist: p.math.Dist2D(a, b),
};
}
} else {
return {
x: event.pageX,
y: event.pageY,
};
}
};

this.container.on('touchstart mousedown', function (e) {
if (e && e.preventDefault) e.preventDefault();
if (e && e.stopPropagation) e.stopPropagation();

p.reader.overview.delta = 0;
isScrolling = true;
lastPos = fncGetPos(e);
clearInterval(p.reader.overview.interval);
clearTimeout(p.reader.overview.scrollTimeout);
});
this.container.on('touchmove mousemove', function (e) {
if (e && e.preventDefault) e.preventDefault();
if (e && e.stopPropagation) e.stopPropagation();

//clearInterval(p.reader.overview.interval);
//clearTimeout(p.reader.overview.scrollTimeout);
if (isScrolling) {
currentPos = fncGetPos(e);

switch (p.reader.settings.overview_direction) {
case 'left':
case 'right':
p.reader.overview.delta = lastPos.y - currentPos.y;
$this.container[0].scrollTop += p.reader.overview.delta;
break;

case 'top':
case 'bottom':
p.reader.overview.delta = lastPos.x - currentPos.x;
$this.container[0].scrollLeft += p.reader.overview.delta;
break;
}

//console.log(delta);

//console.log(lastPos, currentPos);
lastPos = currentPos;
//console.log(lastPos, currentPos);
}
});
this.container.on('touchend mouseup mouseleave', function (e) {
if (e && e.preventDefault) e.preventDefault();
if (e && e.stopPropagation) e.stopPropagation();
//console.log("end");

isScrolling = false;
if (Math.abs(p.reader.overview.delta) >= 10) {
momentumStep =
Math.abs(p.reader.overview.delta) /
(p.pager.is_mobile ? 30 : 60);

var animationCallback = function () {
if (Math.abs(p.reader.overview.delta) > 1) {
switch (p.reader.settings.overview_direction) {
case 'left':
case 'right':
$this.container[0].scrollTop += p.reader.overview.delta;
break;

case 'top':
case 'bottom':
$this.container[0].scrollLeft +=
p.reader.overview.delta;
break;
}

if (p.reader.overview.delta > 0)
p.reader.overview.delta -= momentumStep;
else p.reader.overview.delta += momentumStep;

//console.log(delta);
//delta = delta / 4;
p.reader.overview.interval =
requestFrame(animationCallback);
} else {
//clearInterval(p.reader.overview.interval);
cancelFrame(p.reader.overview.interval);
}
};

p.reader.overview.interval = requestFrame(animationCallback);

/*clearInterval(p.reader.overview.interval);
clearTimeout(p.reader.overview.scrollTimeout);
p.reader.overview.interval = setInterval(function ()
{
if (Math.abs(p.reader.overview.delta) > 1)
{
switch (p.reader.settings.overview_direction)
{
case "left":
case "right":
$this.container[0].scrollTop += p.reader.overview.delta;
break;

case "top":
case "bottom":
$this.container[0].scrollLeft += p.reader.overview.delta;
break;
}

if (p.reader.overview.delta > 0)
p.reader.overview.delta -= momentumStep;
else
p.reader.overview.delta += momentumStep;

//console.log(delta);
//delta = delta / 4;
}
else
{
clearInterval(p.reader.overview.interval);
}
}, 1000 / (p.pager.is_mobile ? 30 : 60));
*/
}
});
}
},

open: function () {
this.ensureInit();

if (this.isFirstOpen) {
this.isFirstOpen = false;
var pageSize = p.pager.getPageSize(1, true);
var overviewMargin = 8;
var scaleFactor;
switch (p.reader.settings.overview_direction) {
case 'left':
case 'right':
scaleFactor =
(p.reader.settings.overview_size - overviewMargin * 2) /
pageSize.width;
break;
case 'top':
case 'bottom':
scaleFactor =
(p.reader.settings.overview_size - overviewMargin * 2) /
pageSize.height;
break;
}
var thumbSize = {
width: pageSize.width * scaleFactor,
height: pageSize.height * scaleFactor,
};

var thumbFnc = function () {
if (Math.abs(p.reader.overview.delta) < 10) {
p.pager.current_page = parseInt(p.e(this).getAttr('data-page'));
p.pager.goToPage(p.pager.current_page);
}
};

let left_to_right = $('#left_to_right').val() == 'true';

for (var i = 0; i < p.pager.page_count; i++) {
var curpg = p.pager.current_page;
var thumb = p.e('<div>', {
class: 'thumb',
'data-page': i + 1,
});

let p_no = i + 1;

let toDisplay = p_no;

if (left_to_right) {
toDisplay = p.pager.page_count - p_no + 1;
}

var thumb1 = p.e('<div><span>' + toDisplay + '</span></div>', {
class: 'thumb1',
});

var loader = p.reader.stageLoader();
loader.load([p.pager.getThumbPath(i + 1)]);

loader.appendTo(thumb);
thumb.setAttr(
'style',
'width: {0}px; height: {1}px;'.format(
thumbSize.width,
thumbSize.height
)
);
thumb.appendTo(this.container);

thumb1.appendTo(thumb);

var waitingForClick = false;

var thumbOnDown = function () {
waitingForClick = true;
};
var thumbOnUp = function () {
if (p.ads.hideAds()) {
return false;
}
if (waitingForClick) {
p.pager.current_page = parseInt(
p.e(this).getAttr('data-page')
);
p.pager.goToPage(p.pager.current_page);
waitingForClick = false;
}
};
var thumbOnCancel = function () {
waitingForClick = false;
};

//thumb.on("click tap", thumbFnc);
thumb.on('mousedown touchstart', thumbOnDown);
thumb.on('mouseup touchend', thumbOnUp);
thumb.on(
'mousemove mousecancel touchmove touchcancel',
thumbOnCancel
);
}
}

this.container.removeClass('hidden');
p.e('#reader-container .controls').setAttr(
'style',
'{0}: {1}px;'.format(
p.reader.settings.overview_direction,
p.reader.settings.overview_size
)
);
if (!p.reader.settings.overview_overlay)
p.pager.content_container.setAttr(
'style',
'{0}: {1}px;'.format(
p.reader.settings.overview_direction,
p.reader.settings.overview_size
)
);

this.scrollToCurrentPage();

this.isOpen = true;
},
scrollTimeout: null,
scrollToCurrentPage: function () {
var currentThumb = p.e(
".thumb[data-page='{0}']".format(p.pager.current_page_firstvalid)
),
requestFrame =
window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame,
cancelFrame =
window.cancelAnimationFrame || window.mozCancelAnimationFrame;
if (currentThumb && currentThumb.length > 0) {
p.e('.thumb').removeClass('active');

if (
p.pager.current_mode == p.pager.constant.SINGLE ||
p.pager.current_mode == p.pager.constant.SINGLE_REVERSE
)
currentThumb.addClass('active');
else
p.e(
".thumb[data-page='{0}'], .thumb[data-page='{1}']".format(
p.pager.current_page_left,
p.pager.current_page_right
)
).addClass('active');

if (
p.reader.settings.overview_direction == 'left' ||
p.reader.settings.overview_direction == 'right'
)
var target =
currentThumb[0].offsetTop -
(currentThumb[0].offsetHeight +
this.container[0].offsetHeight) /
2 +
currentThumb[0].offsetHeight;
else
var target =
currentThumb[0].offsetLeft -
(currentThumb[0].offsetWidth + this.container[0].offsetWidth) /
2 +
currentThumb[0].offsetWidth;

if (
p.pager.current_mode == p.pager.constant.DOUBLE ||
p.pager.current_mode == p.pager.constant.DOUBLE_REVERSE
)
target +=
(p.reader.settings.overview_direction == 'left' ||
p.reader.settings.overview_direction == 'right'
? currentThumb[0].offsetHeight / 2
: currentThumb[0].offsetWidth / 2) + 16;

var now = 0,
max = 60,
step = Math.abs(this.container[0].scrollTop - target) / max,
$this = this,
dist = target - this.container[0].scrollTop,
start = this.container[0].scrollTop;

if (
p.reader.settings.overview_direction == 'top' ||
p.reader.settings.overview_direction == 'bottom'
) {
dist = target - this.container[0].scrollLeft;
start = this.container[0].scrollLeft;
}

var easeInOutQuad = function (tCurrent, start, change, duration) {
tCurrent /= duration / 2;
if (tCurrent < 1)
return (change / 2) * tCurrent * tCurrent + start;
tCurrent--;
return (-change / 2) * (tCurrent * (tCurrent - 2) - 1) + start;
};

//console.log(dist, start, this.container[0].scrollLeft);

var stepFnc = function () {
if (
p.reader.settings.overview_direction == 'left' ||
p.reader.settings.overview_direction == 'right'
) {
$this.container[0].scrollTop = easeInOutQuad(
now,
start,
dist,
max
);
} else {
$this.container[0].scrollLeft = easeInOutQuad(
now,
start,
dist,
max
);
}

now++;
if (now < max) $this.scrollTimeout = requestFrame(stepFnc);
else cancelFrame($this.scrollTimeout);
};

cancelFrame(this.scrollTimeout);
this.scrollTimeout = requestFrame(stepFnc);
}
},
close: function () {
this.ensureInit();

this.container.addClass('hidden');
p.pager.content_container.setAttr('style', '');
p.e('#reader-container .controls').setAttr('style', '');

this.isOpen = false;
},
toggle: function () {
if (this.isOpen) this.close();
else this.open();
},
},

prepareData: function () {
let raw = raw_data;
let parse = {};
let count = 1;
let keys = Object.keys(raw);

let left_to_right = $('#left_to_right').val() == 'true';
p.pager.last_page = Object.keys(raw).length - 1;

let preview_page = $('#preview_page').val();
let l_p = keys.length;

if (preview_page && preview_page != '') {
let temp1 = {};
keys.forEach(function (k) {
temp1[raw[k].page_content] = raw[k];
});
let temp = {};
let p_pages = preview_page.split(',').map(function (v) {
return parseInt(v);
});
let c = 1;
p_pages.forEach(function (i) {
temp[c] = temp1[i];
c++;
});
raw = temp;

p.pager.last_page_no = l_p + 1;
if (left_to_right && l_p % 2 == 0) {
p.pager.last_page_no--;
}
raw[p.pager.last_page_no] = {
page_content: p.pager.last_page_no,
page_name: 'last_page.php',
ref_size: {
width: raw[keys.length - 1].ref_size.width,
height: raw[keys.length - 1].ref_size.height,
},
};
if (left_to_right) {
p.pager.last_page_no = 1;
}
}
l_p = Object.keys(raw).length;
Object.keys(raw).forEach(function (k) {
if (!left_to_right) {
parse[count] = raw[k];
} else {
parse[count] = raw[l_p - (k - 1)];
}

count++;
});

p.pager.pages = parse;
//p.e(".finished-overlay").removeClass("hidden");

p.pager.init();
if (left_to_right) {
p.pager.goToPage((p.pager.current_page = l_p));
}

Hash.on('^page/([0-9]*)$', {
yep: function (path, parts) {
var page = parts[1];
if (page !== undefined) {
page = parseInt(page);
if (page >= 1 && page <= exHelp.pager.last_page) {
if (
exHelp.pager.current_mode == exHelp.pager.constant.SINGLE ||
exHelp.pager.current_mode ==
exHelp.pager.constant.SINGLE_REVERSE
) {
page = page;
} else {
page = (page / 2) * 2;
}
exHelp.pager.goToPage((exHelp.pager.current_page = page));
setTimeout(function () {}, 100);
} else {
location.href =
'#page/' +
(exHelp.pager.current_page ? exHelp.pager.current_page : 1);
}
}
},
nop: function (path) {
exHelp.pager.goToPage((exHelp.pager.current_page = 1));
},
});
},
prepareCover: function () {
var coverLoader = this.stageLoader();
coverLoader.addClass('cover-loader');
coverLoader.appendTo('.main-loader');
coverLoader.load([
this.path + '/cover_small.jpg',
this.path + '/cover_medium.jpg',
this.path + '/cover_big.jpg',
]);
},
prepareElements: function () {
for (var key in this.elements) {
this._prepareElement(this.elements[key], this.container);
}
},
_prepareElement: function (e, parent) {
var ele,
key,
$this = this;
ele = parent.find(e.selector);
if (ele.length == 0) {
ele = p.e(e.construct || '<div>', e.options);
ele.appendTo(parent);
}

if (e['children'] !== void 0) {
for (key in e.children) this._prepareElement(e.children[key], ele);
}

return ele;
},

make_slider: function (options, fullscreenCheckId) {
var slider = p.e('<div>', {
class: 'slider',
value: 50,
});
var track = p
.e('<div>', {
class: 'track',
})
.appendTo(slider);
var fill = p
.e('<div>', {
class: 'fill',
})
.appendTo(track);
var thumb = p
.e('<div>', {
class: 'thumb',
})
.appendTo(slider);
var buffer = p.e('<div>', {
class: 'buffer',
});

var callback = null;
var displayCallback = null;
var vertical = false;

var fncs = {
slider: {
max: options.max || 100,
min: options.min || 0,
value: options.value || 50,
sigfigs: options.sigfigs != undefined ? options.sigfigs : -1,
dragging: false,
update: function (nocallback, fromUser) {
var $this = fncs.slider;
var percent = p.math.Percentage.XofY($this.value, $this.max);
if (vertical) {
fill.setStyle('height', percent + '%');
thumb.setStyle('bottom', percent + '%');
} else {
fill.setStyle('width', percent + '%');
thumb.setStyle('left', percent + '%');
}

var displayValue = $this.value + 0;
if (displayCallback && p.is.function(displayCallback))
displayValue = displayCallback(displayValue);

thumb.setAttr('value', $this.value);

slider.setAttr('value', $this.value);
slider.setAttr('max', $this.max);
slider.setAttr('min', $this.min);

if (!nocallback && callback && p.is.function(callback))
callback($this.value, !!fromUser);
},
set: function (val) {
var $this = fncs.slider;
$this.value = val;
$this.update;
},
setBuffer: function (perc) {
buffer.setStyle('width', 100 - perc + '%');
},
onStart: function () {
var $this = fncs.slider;
$this.dragging = true;
thumb.addClass('pressed');
},
onEnd: function () {
var $this = fncs.slider;
$this.dragging = false;
thumb.removeClass('pressed');
},
onDrag: function (e) {
var $this = fncs.slider;
if ($this.dragging) {
var pos = $this.getPos(e);
if (vertical) {
var height = slider.getHeight();
$this.value =
(p.math.Percentage.XofY(height - pos.y, height) / 100) *
$this.max +
$this.min;
} else {
var width = slider.getWidth();
$this.value =
(p.math.Percentage.XofY(pos.x, width) / 100) * $this.max +
$this.min;
}

if ($this.sigfigs != -1) {
$this.value = $this.value.toFixed($this.sigfigs);
}

$this.value = Math.min(
$this.max,
Math.max($this.min, $this.value)
);
$this.update(undefined, true);
}
},
getPos: function (event) {
//debugger;
var offset = slider.getPageXY();
if (event.type.startsWith('touch')) {
if (event.touches.length == 1) {
return {
x: event.touches[0].pageX - offset.x,
y: event.touches[0].pageY - offset.y,
};
}
} else {
return {
x: event.pageX - offset.x,
y: event.pageY - offset.y,
};
}
},
},
};

if (options) {
if (options.dark) slider.addClass('dark');
if (options.discrete) slider.addClass('discrete');
if (options.callback) callback = options.callback;
if (options.displayCallback)
displayCallback = options.displayCallback;
if (options.vertical) vertical = true;
if (options.buffering) buffer.appendTo(track);
if (options.buffer) fncs.setBuffer(options.buffer);
}

if (vertical) slider.addClass('vertical');

slider.extend(fncs);
slider.slider.update();
thumb.on('mousedown touchstart', fncs.slider.onStart);
slider.on('mousemove touchmove', fncs.slider.onDrag);
p.e('body').on('mouseup touchend', fncs.slider.onEnd);
return slider;
},

stageLoaderId: 0,
stageLoader: function () {
var ele = p.e('<div>', {
class: 'loader',
}),
spinner = p
.e('<div>', {
class: 'spinner',
})
.appendTo(ele);
var thisId = ++p.reader.stageLoaderId;

var c = {
currentStage: -1,
instanceId: 0,
sources: [],
elements: [],
spinner: null,
callback: null,
loadInstance: null,

load: function (sources, callback, suppressLoading) {
//CallTrace(arguments, thisId + "/SL" + (c.instanceId + 1));
//console.log("stageLoader", "load");
suppressLoading = true;
if (sources) {
var allsame = true;

for (var i = 0; i < sources.length; i++)
if (sources[i] != c.sources[i]) {
allsame = false;
//console.log("stageLoader", "new sources");
//console.log("not all same");
//if (c.callback && p.is.function(c.callback))
//{
// c.callback();
// c.callback = null;
//}
break;
}

if (allsame) {
//Trace(["done (same sources)"], "SL");
//console.log("stageLoader", "same sources");
//console.log("all same");
if (callback && p.is.function(callback)) {
callback();
}
return;
}

c.sources = sources;
c.spinner.removeClass('hidden');

for (var i = 0; i < c.elements.length; i++)
c.elements[i].remove();

c.elements = [];
let id = Math.random() * 100000000;

for (var i = 0; i < c.sources.length; i++) {
if (c.sources[i].endsWith('last_page')) {
var last = document.getElementById('lastpage').innerHTML;
c.elements[i] = p
.e(last, {
class: suppressLoading ? '' : 'loading',
})
.appendTo(ele);
setTimeout(function () {
var thumb = document.getElementById(id);
if (thumb) {
thumb.style.visibility = 'hidden';
}
}, 100);
} else if (c.sources[i].endsWith('thumb.jpg')) {
c.elements[i] = p
.e(
"<img style='visibility: visible;' id='" + id + "_t' >",
{
class: suppressLoading ? '' : 'loading',
}
)
.appendTo(ele);
} else {
if (c.sources[i].endsWith('svg')) {
c.elements[i] = p
.e(
"<embed style='visibility: hidden;' class='mainsvg' id='" +
id +
"' type='image/svg+xml'>",
{
class: suppressLoading ? '' : 'loading',
}
)
.appendTo(ele);
} else {
c.elements[i] = p
.e(
"<img style='visibility: hidden;' class='mainsvg' id='" +
id +
"' type='image/jpg'>",
{
class: suppressLoading ? '' : 'loading',
}
)
.appendTo(ele);
}
var svgholder = document.getElementById(id);

svgholder.onload = function () {
var svgholder = document.getElementById(id);
if (svgholder) {
svgholder.style.visibility = 'visible';
}
setTimeout(function () {
var thumb = document.getElementById(id + '_t');
if (thumb) {
thumb.style.visibility = 'hidden';
}
}, 100);
};
}
}
}
c.callback = callback;
//Trace([c.callback, "assigned", callback], thisId + "/SL" + (c.instanceId + 1));
//c.onLoad();

c.loadInstance = new c.loadEvent(++c.instanceId);
c.currentStage = -1;
c.loadInstance.onLoad();
},

loadThumb: function (sources, callback, suppressLoading) {
//CallTrace(arguments, thisId + "/SL" + (c.instanceId + 1));
//console.log("stageLoader", "load");
if (sources) {
var allsame = true;

for (var i = 0; i < sources.length; i++)
if (sources[i] != c.sources[i]) {
allsame = false;
//console.log("stageLoader", "new sources");
//console.log("not all same");
//if (c.callback && p.is.function(c.callback))
//{
// c.callback();
// c.callback = null;
//}
break;
}

if (allsame) {
//Trace(["done (same sources)"], "SL");
//console.log("stageLoader", "same sources");
//console.log("all same");
if (callback && p.is.function(callback)) {
callback();
}
return;
}

c.sources = sources;
c.spinner.removeClass('hidden');
for (var i = 0; i < c.elements.length; i++)
c.elements[i].remove();

c.elements = [];

for (var i = 0; i < c.sources.length; i++)
c.elements[i] = p
.e("<img class='thumbImg'>", {
class: suppressLoading && i == 0 ? '' : 'loading',
})
.appendTo(ele);
}
c.callback = callback;
//Trace([c.callback, "assigned", callback], thisId + "/SL" + (c.instanceId + 1));
//c.onLoad();

c.loadInstance = new c.loadEvent(++c.instanceId);
c.currentStage = -1;
c.loadInstance.onLoad();
},
loadEvent: function (iid) {
var $this = this;
this.id = iid;
this.onLoad = function () {
//Trace([$this.id, "onload"], thisId + "/SL");
//Trace([$this.id, "onLoad"], "SL");
if ($this.id != c.instanceId) {
return;
}
if (c.currentStage >= 0) {
c.spinner.addClass('hidden');
if (c.elements[c.currentStage])
c.elements[c.currentStage].removeClass('loading');
}

c.currentStage++;

if (c.currentStage < c.sources.length) {
c.elements[c.currentStage].on('load', $this.onLoad);
c.elements[c.currentStage].setAttr(
'src',
c.sources[c.currentStage]
);
if (c.sources[c.currentStage].endsWith('svg')) {
c.elements[c.currentStage].each(function () {
if (this['parentNode']) {
let parentSvg = this.parentNode;
parentSvg.removeChild(this);
parentSvg.appendChild(this);
}
});
}
} else {
//Trace([$this.id, "done", c.callback], thisId + "/SL");
if (c.callback && p.is.function(c.callback)) {
if ($this.id != c.instanceId) {
return;
}
c.callback();
c.callback = null;
//Trace([$this.id, "unassigned callback", c.callback], thisId + "/SL");
}
}
};
}, //,
//onLoad: function (iid)
//{
// if (c.currentStage >= 0)
// {
// c.spinner.addClass("hidden");
// if (c.elements[c.currentStage])
// c.elements[c.currentStage].removeClass("loading");
// }

// c.currentStage++;

// if (c.currentStage < c.sources.length)
// {
// c.elements[c.currentStage].setAttr("src", c.sources[c.currentStage]);
// c.elements[c.currentStage].on("load", c.onLoad);
// }
// else
// {
// if (c.callback && p.is.function(c.callback))
// {
// c.callback();
// c.callback = null;
// }
// }
//}
};
c.spinner = spinner;
exHelp.extend(ele, c);
return ele;
},

isInvertOn: false,
toggleInvert: function () {
if (this.isInvertOn) {
//p.reader.container.setStyle("filter", "");
p.reader.container.removeClass('invert');
this.isInvertOn = false;
} else {
//if (p.browser.isMSIE)
//{
// if (!this.svgLoaded)
// this.loadSvgFilters();

// p.reader.container.setStyle("filter", "url(#invert)");
//}
//else
//{
//p.reader.container.setStyle("filter", "invert(100%)");
//}
p.reader.container.addClass('invert');
this.isInvertOn = true;
}
},
},

swipe_animator: {
listen: true,
dragging: false,
dragged: null,
revealed: null,
moveStart: null,
size: null,
last: null,
target: null,
direction: 'none',
animationTimeout: null,

init: function () {
p.e(document).on('mousedown touchstart', this.listenerStart);
p.e(document).on('mousemove touchmove', this.listenerMove);
p.e(document).on(
'mouseup touchend mouseleave touchleave',
this.listenerEnd
);
},

destruct: function () {
p.e(document).off('mousedown touchstart', this.listenerStart);
p.e(document).off('mousemove touchmove', this.listenerMove);
p.e(document).off(
'mouseup touchend mouseleave touchleave',
this.listenerEnd
);
},

intersects: function (pos, rect) {
return (
pos.x > rect.left &&
pos.x < rect.right &&
pos.y > rect.top &&
pos.y < rect.bottom
);
},

posFromEvent: function (event) {
if (event.type.startsWith('touch')) {
if (event.touches.length == 1) {
return {
x: event.touches[0].pageX,
y: event.touches[0].pageY,
};
} else if (event.touches.length == 2) {
var a = {
x: event.touches[0].pageX,
y: event.touches[0].pageY,
},
b = {
x: event.touches[1].pageX,
y: event.touches[1].pageY,
},
midpoint = p.math.Midpoint2D(a, b);

return {
x: midpoint.x,
y: midpoint.y,
dist: p.math.Dist2D(a, b),
};
}
} else {
return {
x: event.pageX,
y: event.pageY,
};
}
},

animateRight: function (dist) {
var $this = p.swipe_animator,
CONST = p.pager.constant;

// Calculations
var fullHidden =
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
? $this.size.width * 2
: $this.size.width;
var fullVisible = 0;
var current = fullHidden - dist;

var proz = Math.min(1.0, dist / fullHidden);
var eased = p.math.easing.easeOutQuad(proz * 100, 0, 100, 100) / 100;

// Ensure style
clearTimeout($this.animationTimeout);
if (
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
) {
($this.revealed = p.e([
p.pager.holders[CONST.CUR_LEFT],
p.pager.holders[CONST.CUR_RIGHT],
])),
($this.dragged = p.e([
p.pager.holders[CONST.NEXT_LEFT],
p.pager.holders[CONST.NEXT_RIGHT],
]));
p.e([
p.pager.holders[CONST.PREV_LEFT],
p.pager.holders[CONST.PREV_LEFT],
]).addClass('hidden');

if (p.pager.showPage(p.pager.current_page_left + 2))
p.e(p.pager.holders[CONST.NEXT_LEFT]).removeClass('hidden');
else p.e(p.pager.holders[CONST.NEXT_LEFT]).addClass('hidden');

if (p.pager.showPage(p.pager.current_page_right + 2))
p.e(p.pager.holders[CONST.NEXT_RIGHT]).removeClass('hidden');
else p.e(p.pager.holders[CONST.NEXT_RIGHT]).addClass('hidden');

if (p.pager.showPage(p.pager.current_page_left))
p.e(p.pager.holders[CONST.CUR_LEFT]).removeClass('hidden');
else p.e(p.pager.holders[CONST.CUR_LEFT]).addClass('hidden');

if (p.pager.showPage(p.pager.current_page_right))
p.e(p.pager.holders[CONST.CUR_RIGHT]).removeClass('hidden');
else p.e(p.pager.holders[CONST.CUR_RIGHT]).addClass('hidden');
} else {
($this.revealed = p.pager.holders[CONST.CUR]),
($this.dragged = p.pager.holders[CONST.NEXT]);
p.pager.holders[CONST.PREV].addClass('hidden');
p.pager.holders[CONST.NEXT].removeClass('hidden');
}

$this.dragged.addClass('animate');
$this.revealed.addClass('wait');
p.overlays.setHidden(true);

// Animate
$this.dragged.setStyle(
'transform',
'translate({0}px, 0)'.format(fullHidden - fullHidden * eased)
);
$this.revealed.setStyle(
'transform',
'translate(-{0}%, 0)'.format(20 * eased)
);

$this.dragged.setStyle(
'opacity',
1 * p.math.easing.easeOutExpo(proz * 1000, 0, 1, 100)
);
$this.revealed.setStyle(
'opacity',
10 - p.math.easing.easeOutExpo(proz * 100, 0, 10, 100)
);
},
animateLeft: function (dist) {
var $this = p.swipe_animator,
CONST = p.pager.constant;

// Calculations
var fullHidden =
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
? $this.size.width * 2
: $this.size.width;
var fullVisible = 0;
var current = fullHidden - dist;

var proz = Math.min(1.0, dist / fullHidden);
var eased = p.math.easing.easeOutQuad(proz * 100, 0, 100, 100) / 100;

// Ensure style
clearTimeout($this.animationTimeout);
if (
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
) {
($this.revealed = p.e([
p.pager.holders[CONST.CUR_LEFT],
p.pager.holders[CONST.CUR_RIGHT],
])),
($this.dragged = p.e([
p.pager.holders[CONST.PREV_LEFT],
p.pager.holders[CONST.PREV_RIGHT],
]));
p.e([
p.pager.holders[CONST.NEXT_LEFT],
p.pager.holders[CONST.NEXT_RIGHT],
]).addClass('hidden');
} else {
($this.dragged = p.pager.holders[CONST.PREV]),
($this.revealed = p.pager.holders[CONST.CUR]);
p.pager.holders[CONST.PREV].removeClass('hidden');
p.pager.holders[CONST.NEXT].addClass('hidden');
}

$this.dragged.addClass('animate').removeClass('hidden');
$this.revealed.addClass('wait').removeClass('hidden');
p.overlays.setHidden(true);

// Animate
$this.dragged.setStyle(
'transform',
'translate(-{0}px, 0)'.format(fullHidden - fullHidden * eased)
);
$this.revealed.setStyle(
'transform',
'translate({0}%, 0)'.format(20 * eased)
);

$this.dragged.setStyle(
'opacity',
1 * p.math.easing.easeOutExpo(proz * 1000, 0, 1, 100)
);
$this.revealed.setStyle(
'opacity',
10 - p.math.easing.easeOutExpo(proz * 100, 0, 10, 100)
);
},
animateRightTo: function (from, to, callback) {
var $this = p.swipe_animator,
CONST = p.pager.constant,
t = 0,
max = 30,
requestFrame =
window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame,
cancelFrame =
window.cancelAnimationFrame || window.mozCancelAnimationFrame;
var fnc = function () {
$this.animateRight(
p.math.easing.easeInOutQuad(t++, from, to - from, max)
);
if (t < max) $this.animationTimeout = requestFrame(fnc);
else if (p.is.function(callback)) {
callback();
cancelFrame($this.animationTimeout);
}
};

cancelFrame($this.animationTimeout);
$this.animationTimeout = requestFrame(fnc);
},
animateLeftTo: function (from, to, callback) {
var $this = p.swipe_animator,
CONST = p.pager.constant,
t = 0,
max = 30,
requestFrame =
window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame,
cancelFrame =
window.cancelAnimationFrame || window.mozCancelAnimationFrame;
var fnc = function () {
$this.animateLeft(
p.math.easing.easeInOutQuad(t++, from, to - from, max)
);
if (t < max) $this.animationTimeout = requestFrame(fnc);
else if (p.is.function(callback)) {
callback();
cancelFrame($this.animationTimeout);
}
};

cancelFrame($this.animationTimeout);
$this.animationTimeout = requestFrame(fnc);
},

listenerStart: function (e) {
var $this = p.swipe_animator,
CONST = p.pager.constant;

if (!$this.lockAnimation && !p.pager.touchBlocked) {
if (p.pager.current_animation == CONST.SWIPE) {
if (
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
) {
var rectLeft =
p.pager.holders[CONST.CUR_LEFT][0].getBoundingClientRect(),
rectRight =
p.pager.holders[CONST.CUR_RIGHT][0].getBoundingClientRect(),
targetRectLeft = {
top: rectLeft.top,
left: rectLeft.left,
right: rectLeft.left + rectLeft.width * 0.1,
bottom: rectLeft.bottom,
},
targetRectRight = {
top: rectRight.top,
left: rectRight.right - rectRight.width * 0.1,
right: rectRight.right,
bottom: rectRight.bottom,
},
pos = $this.posFromEvent(e);

if ($this.intersects(pos, targetRectRight)) {
// One time calculation
$this.size = {
width: rectLeft.width || rectRight.width,
height: rectLeft.height || rectRight.height,
};
$this.target =
p.pager.page_container[0].getBoundingClientRect();
$this.target = {
top: $this.target.top + p.pager.current_padding,
left: $this.target.left + p.pager.current_padding,
right: $this.target.right - p.pager.current_padding,
bottom: $this.target.bottom - p.pager.current_padding,
};
$this.moveStart = pos;

p.pager.paging_handled_by_animator = true;

$this.startDragRight();
} else if ($this.intersects(pos, targetRectLeft)) {
// One time calculation
$this.size = {
width: rectLeft.width || rectRight.width,
height: rectLeft.height || rectRight.height,
};
$this.target =
p.pager.page_container[0].getBoundingClientRect();
$this.target = {
top: $this.target.top + p.pager.current_padding,
left: $this.target.left + p.pager.current_padding,
right: $this.target.right - p.pager.current_padding,
bottom: $this.target.bottom - p.pager.current_padding,
};
$this.moveStart = pos;

p.pager.paging_handled_by_animator = true;

$this.startDragLeft();
}
} else {
var rect = p.pager.holders[CONST.CUR][0].getBoundingClientRect(),
targetRectLeft = {
top: rect.top,
left: rect.left,
right: rect.left + rect.width * 0.1,
bottom: rect.bottom,
},
targetRectRight = {
top: rect.top,
left: rect.right - rect.width * 0.1,
right: rect.right,
bottom: rect.bottom,
},
pos = $this.posFromEvent(e);

// One time calculation
$this.size = {
width: rect.width,
height: rect.height,
};
$this.target = p.pager.page_container[0].getBoundingClientRect();
$this.target = {
top: $this.target.top + p.pager.current_padding,
left: $this.target.left + p.pager.current_padding,
right: $this.target.right - p.pager.current_padding,
bottom: $this.target.bottom - p.pager.current_padding,
};
$this.moveStart = pos;

if ($this.intersects(pos, targetRectRight)) {
p.pager.paging_handled_by_animator = true;
$this.startDragRight();
} else if ($this.intersects(pos, targetRectLeft)) {
p.pager.paging_handled_by_animator = true;
$this.startDragLeft();
}
}
}
}
},
listenerMove: function (e) {
var $this = p.swipe_animator,
CONST = p.pager.constant;
if (!$this.lockAnimation && $this.dragging) {
var pos = $this.posFromEvent(e);
$this.last = pos;
if ($this.direction == 'right') {
var distX = Math.abs($this.target.right - pos.x);

$this.animateRight(distX);
} else if ($this.direction == 'left') {
var distX = Math.abs($this.target.left - pos.x);

$this.animateLeft(distX);
}
}
},
listenerEnd: function (e) {
var $this = p.swipe_animator,
CONST = p.pager.constant;

if (!$this.lockAnimation && $this.dragging) {
p.reader.playPageSound();
var pos = $this.last,
finish = function () {
$this.dragged.removeClass('animate');
$this.revealed.removeClass('wait');
$this.dragged.setStyle('transform', '');
$this.revealed.setStyle('transform', '');
p.pager.paging_handled_by_animator = false;
$this.last = null;
$this.lockAnimation = false;
p.overlays.setHidden(false);
};

if ($this.direction == 'right') {
var distX = pos != null ? Math.abs($this.target.right - pos.x) : 0;
var finalDistance =
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
? $this.size.width * 2
: $this.size.width;
var triggerDistance = finalDistance / 10;

if (distX < finalDistance) {
if (distX >= triggerDistance) {
$this.animateRightTo(distX, finalDistance, function () {
p.pager.goForward(function () {
finish();
});
});
} else {
$this.animateRightTo(distX, 0, function () {
finish();
});
}
} else {
p.pager.goForward(function () {
finish();
});
}
} else if ($this.direction == 'left') {
var distX = pos != null ? Math.abs($this.target.left - pos.x) : 0;
var finalDistance =
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
? $this.size.width * 2
: $this.size.width;
var triggerDistance = finalDistance / 8;

if (distX < finalDistance) {
if (distX >= triggerDistance) {
$this.animateLeftTo(distX, finalDistance, function () {
p.pager.goBack(function () {
finish();
});
});
} else {
$this.animateLeftTo(distX, 0, function () {
finish();
});
}
} else {
p.pager.goBack(function () {
finish();
});
}
}
}

$this.dragging = false;
},

lockAnimation: false,

doFullAnimationNext: function (callback) {
var $this = p.swipe_animator,
CONST = p.pager.constant;

if (!$this.lockAnimation && p.pager.can_go_forward) {
$this.lockAnimation = true;

p.reader.playPageSound();

var pos = $this.last,
finish = function () {
$this.dragged.removeClass('animate');
$this.revealed.removeClass('wait');
$this.dragged.setStyle('transform', '');
$this.revealed.setStyle('transform', '');

if (callback && p.is.function(callback)) callback();

$this.lockAnimation = false;
p.pager.paging_handled_by_animator = false;
$this.last = null;
p.overlays.setHidden(false);
},
rectLeft =
p.pager.holders[CONST.CUR_LEFT][0].getBoundingClientRect(),
rectRight =
p.pager.holders[CONST.CUR_RIGHT][0].getBoundingClientRect();

$this.size = {
width: rectLeft.width || rectRight.width,
height: rectLeft.height || rectRight.height,
};
$this.target = p.pager.page_container[0].getBoundingClientRect();
$this.target = {
top: $this.target.top + p.pager.current_padding,
left: $this.target.left + p.pager.current_padding,
right: $this.target.right - p.pager.current_padding,
bottom: $this.target.bottom - p.pager.current_padding,
};

var finalDistance =
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
? $this.size.width * 2
: $this.size.width;

$this.direction = 'right';

$this.animateRightTo(0, finalDistance, function () {
p.pager.goForward(null, function () {
finish();
});
});
}
},
doFullAnimationPrev: function (callback) {
var $this = p.swipe_animator,
CONST = p.pager.constant;

if (!$this.lockAnimation && p.pager.can_go_back) {
$this.lockAnimation = true;

p.reader.playPageSound();

var pos = $this.last,
finish = function () {
$this.dragged.removeClass('animate');
$this.revealed.removeClass('wait');
$this.dragged.setStyle('transform', '');
$this.revealed.setStyle('transform', '');

if (callback && p.is.function(callback)) callback();

$this.lockAnimation = false;
p.pager.paging_handled_by_animator = false;
$this.last = null;
p.overlays.setHidden(false);
},
rectLeft =
p.pager.holders[CONST.CUR_LEFT][0].getBoundingClientRect(),
rectRight =
p.pager.holders[CONST.CUR_RIGHT][0].getBoundingClientRect();

$this.size = {
width: rectLeft.width || rectRight.width,
height: rectLeft.height || rectRight.height,
};
$this.target = p.pager.page_container[0].getBoundingClientRect();
$this.target = {
top: $this.target.top + p.pager.current_padding,
left: $this.target.left + p.pager.current_padding,
right: $this.target.right - p.pager.current_padding,
bottom: $this.target.bottom - p.pager.current_padding,
};

var finalDistance =
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
? $this.size.width * 2
: $this.size.width;

$this.direction = 'left';

$this.animateLeftTo(0, finalDistance, function () {
p.pager.goBack(null, function () {
finish();
});
});
}
},

startDragRight: function (e) {
var $this = p.swipe_animator,
CONST = p.pager.constant,
cancelFrame =
window.cancelAnimationFrame || window.mozCancelAnimationFrame;

$this.dragging = true;
cancelFrame($this.animationTimeout);

if (
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
) {
($this.revealed = p.e([
p.pager.holders[CONST.CUR_LEFT],
p.pager.holders[CONST.CUR_RIGHT],
])),
($this.dragged = p.e([
p.pager.holders[CONST.NEXT_LEFT],
p.pager.holders[CONST.NEXT_RIGHT],
]));
p.e([
p.pager.holders[CONST.PREV_LEFT],
p.pager.holders[CONST.PREV_LEFT],
]).addClass('hidden');

if (p.pager.showPage(p.pager.current_page_left + 2))
p.e(p.pager.holders[CONST.NEXT_LEFT]).removeClass('hidden');
else p.e(p.pager.holders[CONST.NEXT_LEFT]).addClass('hidden');

if (p.pager.showPage(p.pager.current_page_right + 2))
p.e(p.pager.holders[CONST.NEXT_RIGHT]).removeClass('hidden');
else p.e(p.pager.holders[CONST.NEXT_RIGHT]).addClass('hidden');

if (p.pager.showPage(p.pager.current_page_left))
p.e(p.pager.holders[CONST.CUR_LEFT]).removeClass('hidden');
else p.e(p.pager.holders[CONST.CUR_LEFT]).addClass('hidden');

if (p.pager.showPage(p.pager.current_page_right))
p.e(p.pager.holders[CONST.CUR_RIGHT]).removeClass('hidden');
else p.e(p.pager.holders[CONST.CUR_RIGHT]).addClass('hidden');
} else {
($this.revealed = p.pager.holders[CONST.CUR]),
($this.dragged = p.pager.holders[CONST.NEXT]);
p.pager.holders[CONST.PREV].addClass('hidden');
}

$this.dragged.addClass('animate');
$this.revealed.addClass('wait');

//$this.dragged.setStyle("opacity", "0");
$this.dragged.setStyle('transform', 'translate(200%, 0)');
$this.revealed.setStyle('transform', 'translate(0%, 0)');

$this.direction = 'right';
},
startDragLeft: function (e) {
var $this = p.swipe_animator,
CONST = p.pager.constant,
cancelFrame =
window.cancelAnimationFrame || window.mozCancelAnimationFrame;

$this.dragging = true;
cancelFrame($this.animationTimeout);

if (
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
) {
($this.revealed = p.e([
p.pager.holders[CONST.CUR_LEFT],
p.pager.holders[CONST.CUR_RIGHT],
])),
($this.dragged = p.e([
p.pager.holders[CONST.PREV_LEFT],
p.pager.holders[CONST.PREV_RIGHT],
]));
p.e([
p.pager.holders[CONST.NEXT_LEFT],
p.pager.holders[CONST.NEXT_RIGHT],
]).addClass('hidden');
} else {
($this.dragged = p.pager.holders[CONST.PREV]),
($this.revealed = p.pager.holders[CONST.CUR]);
p.pager.holders[CONST.NEXT].addClass('hidden');
}

$this.dragged.addClass('animate').removeClass('hidden');
$this.revealed.addClass('wait').removeClass('hidden');

//$this.dragged.setStyle("opacity", "0");
$this.dragged.setStyle('transform', 'translate(-200%, 0)');
$this.revealed.setStyle('transform', 'translate(0%, 0)');

$this.direction = 'left';
},
},

flip_animator: {
listen: true,
dragging: false,
dragged: null,
revealed: null,
hidden: null,
fullhidden: null,
moveStart: null,
size: null,
last: null,
target: null,
direction: 'none',
animationTimeout: null,

init: function () {
p.e(document).on('mousedown touchstart', this.listenerStart);
p.e(document).on('mousemove touchmove', this.listenerMove);
p.e(document).on(
'mouseup touchend mouseleave touchleave',
this.listenerEnd
);
},

destruct: function () {
p.e(document).off('mousedown touchstart', this.listenerStart);
p.e(document).off('mousemove touchmove', this.listenerMove);
p.e(document).off(
'mouseup touchend mouseleave touchleave',
this.listenerEnd
);
},

intersects: function (pos, rect) {
return (
pos.x > rect.left &&
pos.x < rect.right &&
pos.y > rect.top &&
pos.y < rect.bottom
);
},

posFromEvent: function (event) {
if (event.type.startsWith('touch')) {
if (event.touches.length == 1) {
return {
x: event.touches[0].pageX,
y: event.touches[0].pageY,
};
} else if (event.touches.length == 2) {
var a = {
x: event.touches[0].pageX,
y: event.touches[0].pageY,
},
b = {
x: event.touches[1].pageX,
y: event.touches[1].pageY,
},
midpoint = p.math.Midpoint2D(a, b);

return {
x: midpoint.x,
y: midpoint.y,
dist: p.math.Dist2D(a, b),
};
}
} else {
return {
x: event.pageX,
y: event.pageY,
};
}
},

animateRight: function (dist) {
var $this = p.flip_animator,
CONST = p.pager.constant;
$this.dragged.addClass('animate');
$this.revealed.addClass('wait');
p.overlays.setHidden(true);

if (
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
) {
// Ensure style
if (p.pager.showPage(p.pager.current_page_left + 2))
$this.dragged.removeClass('hidden');
else $this.dragged.addClass('hidden');

if (p.pager.showPage(p.pager.current_page_right + 2))
$this.revealed.removeClass('hidden');
else $this.revealed.addClass('hidden');

$this.fullhidden.addClass('hidden');

$this.dragged.setStyle('left', 'auto');

$this.revealed.setStyle('left', 'auto');
$this.revealed.setStyle('right', p.pager.current_padding + 'px');
$this.revealed.find('.wrapper').setStyle('left', 'auto');
$this.revealed
.find('.wrapper')
.setStyle('width', $this.size.width + 'px');
$this.dragged.find('.wrapper').setStyle('right', 'auto');
$this.dragged
.find('.wrapper')
.setStyle('width', $this.size.width + 'px');
$this.hidden.find('.wrapper').setStyle('right', 'auto');
$this.hidden
.find('.wrapper')
.setStyle('width', $this.size.width + 'px');

// Animate
$this.dragged.setStyle(
'right',
Math.min(
p.pager.current_padding + dist / 2,
$this.size.width + p.pager.current_padding
) + 'px'
);
$this.dragged.setStyle(
'width',
Math.min(dist / 2, $this.size.width) + 'px'
);

$this.hidden.setStyle(
'width',
Math.max(0, $this.size.width - dist) + 'px'
);

$this.revealed.setStyle(
'width',
Math.min(dist / 2, $this.size.width) + 'px'
);
} else {
// Ensure style
if (p.pager.showPage(p.pager.current_page + 1))
$this.revealed.removeClass('hidden');

$this.dragged.find('.wrapper').setStyle('left', 'auto');
$this.dragged
.find('.wrapper')
.setStyle('width', $this.size.width + 'px');

// Animate
$this.dragged.setStyle(
'right',
Math.min(
p.pager.current_padding + dist,
$this.size.width + p.pager.current_padding
) + 'px'
);
$this.dragged.setStyle(
'width',
Math.max($this.size.width - dist, 0) + 'px'
);
}
},
animateLeft: function (dist) {
var $this = p.flip_animator,
CONST = p.pager.constant;

$this.dragged.addClass('animate');
$this.revealed.addClass('wait');
p.overlays.setHidden(true);

if (
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
) {
// Ensure Style
if (p.pager.showPage(p.pager.current_page_left - 2))
$this.revealed.removeClass('hidden');
else $this.revealed.addClass('hidden');

if (p.pager.showPage(p.pager.current_page_right - 2))
$this.dragged.removeClass('hidden');
else $this.dragged.addClass('hidden');

$this.dragged.setStyle('right', 'auto');
$this.dragged.find('.wrapper').setStyle('left', 'auto');
$this.dragged
.find('.wrapper')
.setStyle('width', $this.size.width + 'px');
$this.revealed.find('.wrapper').setStyle('right', 'auto');
$this.revealed
.find('.wrapper')
.setStyle('width', $this.size.width + 'px');
$this.hidden.find('.wrapper').setStyle('left', 'auto');
$this.hidden
.find('.wrapper')
.setStyle('width', $this.size.width + 'px');

$this.revealed.setStyle('right', 'auto');
$this.revealed.setStyle('left', p.pager.current_padding + 'px');

// Animate
$this.dragged.setStyle(
'left',
Math.min(
p.pager.current_padding + dist / 2,
$this.size.width + p.pager.current_padding
) + 'px'
);
$this.dragged.setStyle(
'width',
Math.min(dist / 2, $this.size.width) + 'px'
);

$this.hidden.setStyle(
'width',
Math.max(0, $this.size.width - dist) + 'px'
);

$this.revealed.setStyle(
'width',
Math.min(dist / 2, $this.size.width) + 'px'
);
} else {
// Ensure Style
if (p.pager.showPage(p.pager.current_page - 1))
$this.revealed.removeClass('hidden');
else $this.revealed.addClass('hidden');

$this.dragged.setStyle('right', p.pager.current_padding + 'px');
$this.dragged.find('.wrapper').setStyle('left', 'auto');
$this.dragged
.find('.wrapper')
.setStyle('width', $this.size.width + 'px');
$this.revealed.find('.wrapper').setStyle('left', 'auto');
$this.revealed
.find('.wrapper')
.setStyle('width', $this.size.width + 'px');

// Animate
$this.dragged.setStyle(
'left',
Math.min(
p.pager.current_padding + dist,
$this.size.width + p.pager.current_padding
) + 'px'
);
$this.dragged.setStyle(
'width',
Math.max(0, $this.size.width - dist) + 'px'
);
$this.revealed.setStyle(
'width',
Math.min(dist, $this.size.width) + 'px'
);
}
},
animateRightTo: function (from, to, callback) {
var $this = p.flip_animator,
CONST = p.pager.constant,
t = 0,
max = 30,
requestFrame =
window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame,
cancelFrame =
window.cancelAnimationFrame || window.mozCancelAnimationFrame;
var fnc = function () {
$this.animateRight(
p.math.easing.easeInOutQuad(t++, from, to - from, max)
);
if (t < max) $this.animationTimeout = requestFrame(fnc);
else if (p.is.function(callback)) {
callback();
cancelFrame($this.animationTimeout);
}
};

cancelFrame($this.animationTimeout);
$this.animationTimeout = requestFrame(fnc);
},
animateLeftTo: function (from, to, callback) {
var $this = p.flip_animator,
CONST = p.pager.constant,
t = 0,
max = 30,
requestFrame =
window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame,
cancelFrame =
window.cancelAnimationFrame || window.mozCancelAnimationFrame;
var fnc = function () {
$this.animateLeft(
p.math.easing.easeInOutQuad(t++, from, to - from, max)
);
if (t < max) $this.animationTimeout = requestFrame(fnc);
//$this.animationTimeout = setTimeout(fnc, 300 / max);
else if (p.is.function(callback)) {
callback();
cancelFrame($this.animationTimeout);
}
};

//clearTimeout($this.animationTimeout);
//fnc();
cancelFrame($this.animationTimeout);
$this.animationTimeout = requestFrame(fnc);
},

listenerStart: function (e) {
var $this = p.flip_animator,
CONST = p.pager.constant;
if (!$this.lockAnimation && !p.pager.touchBlocked) {
if (p.pager.current_animation == CONST.FLIP) {
if (
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
) {
var rectLeft =
p.pager.holders[CONST.CUR_LEFT][0].getBoundingClientRect(),
rectRight =
p.pager.holders[CONST.CUR_RIGHT][0].getBoundingClientRect(),
targetRectLeft = {
top: rectLeft.top,
left: rectLeft.left,
right: rectLeft.left + rectLeft.width * 0.1,
bottom: rectLeft.bottom,
},
targetRectRight = {
top: rectRight.top,
left: rectRight.right - rectRight.width * 0.1,
right: rectRight.right,
bottom: rectRight.bottom,
},
pos = $this.posFromEvent(e);

if (
$this.intersects(pos, targetRectRight) &&
p.pager.showPage(p.pager.current_page_left + 2)
) {
// One time calculation
$this.size = {
width: rectLeft.width || rectRight.width,
height: rectLeft.height || rectRight.height,
};
$this.target =
p.pager.page_container[0].getBoundingClientRect();
$this.target = {
top: $this.target.top + p.pager.current_padding,
left: $this.target.left + p.pager.current_padding,
right: $this.target.right - p.pager.current_padding,
bottom: $this.target.bottom - p.pager.current_padding,
};
$this.moveStart = pos;

p.pager.paging_handled_by_animator = true;

$this.startDragRight();
} else if (
$this.intersects(pos, targetRectLeft) &&
p.pager.showPage(p.pager.current_page_right - 2)
) {
// One time calculation
$this.size = {
width: rectLeft.width || rectRight.width,
height: rectLeft.height || rectRight.height,
};
$this.target =
p.pager.page_container[0].getBoundingClientRect();
$this.target = {
top: $this.target.top + p.pager.current_padding,
left: $this.target.left + p.pager.current_padding,
right: $this.target.right - p.pager.current_padding,
bottom: $this.target.bottom - p.pager.current_padding,
};
$this.moveStart = pos;

p.pager.paging_handled_by_animator = true;

$this.startDragLeft();
}
} else {
var rect = p.pager.holders[CONST.CUR][0].getBoundingClientRect(),
targetRectLeft = {
top: rect.top,
left: rect.left,
right: rect.left + rect.width * 0.1,
bottom: rect.bottom,
},
targetRectRight = {
top: rect.top,
left: rect.right - rect.width * 0.1,
right: rect.right,
bottom: rect.bottom,
},
pos = $this.posFromEvent(e);

// One time calculation
$this.size = {
width: rect.width,
height: rect.height,
};
$this.target = p.pager.page_container[0].getBoundingClientRect();
$this.target = {
top: $this.target.top + p.pager.current_padding,
left: $this.target.left + p.pager.current_padding,
right: $this.target.right - p.pager.current_padding,
bottom: $this.target.bottom - p.pager.current_padding,
};
$this.moveStart = pos;

if (
$this.intersects(pos, targetRectRight) &&
p.pager.showPage(p.pager.current_page + 1)
) {
p.pager.paging_handled_by_animator = true;
$this.startDragRight();
} else if (
$this.intersects(pos, targetRectLeft) &&
p.pager.showPage(p.pager.current_page - 1)
) {
p.pager.paging_handled_by_animator = true;
$this.startDragLeft();
}
}
}
}
},
listenerMove: function (e) {
var $this = p.flip_animator,
CONST = p.pager.constant;
if (!$this.lockAnimation && $this.dragging) {
var pos = $this.posFromEvent(e);
$this.last = pos;
if ($this.direction == 'right') {
var distX = Math.abs($this.target.right - pos.x);

$this.animateRight(distX);
} else if ($this.direction == 'left') {
var distX = Math.abs($this.target.left - pos.x);

$this.animateLeft(distX);
}
}
},
listenerEnd: function (e) {
var $this = p.flip_animator,
CONST = p.pager.constant;

if (!$this.lockAnimation && $this.dragging) {
p.reader.playPageSound();
var pos = $this.last,
finish = function () {
$this.dragged.removeClass('animate');
$this.revealed.removeClass('wait');

$this.dragged.find('.wrapper').setAttr('style', '');
$this.revealed.find('.wrapper').setAttr('style', '');
$this.hidden.find('.wrapper').setAttr('style', '');
$this.dragged.find('.loader').setAttr('style', '');
$this.revealed.find('.loader').setAttr('style', '');
p.pager.paging_handled_by_animator = false;
$this.last = null;
$this.lockAnimation = false;
p.overlays.setHidden(false);
};

if ($this.direction == 'right') {
var distX = pos != null ? Math.abs($this.target.right - pos.x) : 0;
var finalDistance =
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
? $this.size.width * 2
: $this.size.width;
var triggerDistance = finalDistance / 10;

if (distX < finalDistance) {
if (distX >= triggerDistance) {
$this.animateRightTo(distX, finalDistance, function () {
p.pager.goForward(null, function () {
finish();
});
});
} else {
$this.animateRightTo(distX, 0, function () {
finish();
});
}
} else {
p.pager.goForward(null, function () {
finish();
});
}
} else if ($this.direction == 'left') {
var distX = pos != null ? Math.abs($this.target.left - pos.x) : 0;
var finalDistance =
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
? $this.size.width * 2
: $this.size.width;
var triggerDistance = finalDistance / 10;

if (distX < finalDistance) {
if (distX >= triggerDistance) {
$this.animateLeftTo(distX, finalDistance, function () {
p.pager.goBack(function () {
finish();
});
});
} else {
$this.animateLeftTo(distX, 0, function () {
finish();
});
}
} else {
p.pager.goBack(function () {
finish();
});
}
}
}

$this.dragging = false;
},

lockAnimation: false,

doFullAnimationNext: function (callback) {
var $this = p.flip_animator,
CONST = p.pager.constant;

//p.reader.dbg("anim-try-next");

if (!$this.lockAnimation && p.pager.can_go_forward) {
$this.lockAnimation = true;

//p.reader.dbg("anim-do-next");

p.reader.playPageSound();

var pos = $this.last,
finish = function () {
$this.dragged.removeClass('animate');
$this.revealed.removeClass('wait');

$this.dragged.find('.wrapper').setAttr('style', '');
$this.revealed.find('.wrapper').setAttr('style', '');
$this.hidden.find('.wrapper').setAttr('style', '');
$this.dragged.find('.loader').setAttr('style', '');
$this.revealed.find('.loader').setAttr('style', '');

if (callback && p.is.function(callback)) callback();

$this.lockAnimation = false;
p.pager.paging_handled_by_animator = false;
$this.last = null;
p.overlays.setHidden(false);
};

if (
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
) {
var rectLeft =
p.pager.holders[CONST.CUR_LEFT][0].getBoundingClientRect(),
rectRight =
p.pager.holders[CONST.CUR_RIGHT][0].getBoundingClientRect();

$this.size = {
width: rectLeft.width || rectRight.width,
height: rectLeft.height || rectRight.height,
};
} else {
var rect = p.pager.holders[CONST.CUR][0].getBoundingClientRect();
$this.size = {
width: rect.width,
height: rect.height,
};
}

$this.target = p.pager.page_container[0].getBoundingClientRect();
$this.target = {
top: $this.target.top + p.pager.current_padding,
left: $this.target.left + p.pager.current_padding,
right: $this.target.right - p.pager.current_padding,
bottom: $this.target.bottom - p.pager.current_padding,
};

var finalDistance =
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
? $this.size.width * 2
: $this.size.width;

if (
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
) {
($this.dragged = p.pager.holders[CONST.NEXT_LEFT]),
($this.revealed = p.pager.holders[CONST.NEXT_RIGHT]);
$this.hidden = p.pager.holders[CONST.CUR_RIGHT];
$this.fullhidden = p.e([
p.pager.holders[CONST.PREV_LEFT],
p.pager.holders[CONST.PREV_RIGHT],
]);

if (p.pager.showPage(p.pager.current_page_left + 2))
$this.dragged.removeClass('hidden');
if (p.pager.showPage(p.pager.current_page_right + 2))
$this.revealed.removeClass('hidden');

$this.fullhidden.addClass('hidden');
} else {
($this.dragged = p.pager.holders[CONST.CUR]),
($this.revealed = p.pager.holders[CONST.NEXT]);
$this.hidden = p.e();
$this.fullhidden = p.pager.holders[CONST.PREV];

if (p.pager.showPage(p.pager.current_page + 1))
$this.revealed.removeClass('hidden');
}

$this.dragged.addClass('animate');
$this.revealed.addClass('wait');

if (
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
) {
$this.dragged.setStyle('left', 'auto');
$this.dragged.setStyle('right', p.pager.current_padding + 'px');
$this.dragged.setStyle('width', '0px');

$this.revealed.setStyle('left', 'auto');
$this.revealed.setStyle('right', p.pager.current_padding + 'px');
$this.revealed.setStyle('width', '0px');
$this.revealed.find('.wrapper').setStyle('left', 'auto');
$this.revealed
.find('.wrapper')
.setStyle('width', $this.size.width + 'px');
} else {
$this.dragged.setStyle('right', p.pager.current_padding + 'px');
$this.dragged.setStyle('width', $this.size.width);
$this.dragged.find('.wrapper').setStyle('left', 'auto');
$this.dragged
.find('.wrapper')
.setStyle('width', $this.size.width + 'px');
}

$this.direction = 'right';

$this.animateRightTo(0, finalDistance, function () {
p.pager.goForward(null, function () {
finish();
});
});
}
},
doFullAnimationPrev: function (callback) {
var $this = p.flip_animator,
CONST = p.pager.constant;

if (!$this.lockAnimation && p.pager.can_go_back) {
$this.lockAnimation = true;

p.reader.playPageSound();

var pos = $this.last,
finish = function () {
$this.dragged.removeClass('animate');
$this.revealed.removeClass('wait');

$this.dragged.find('.wrapper').setAttr('style', '');
$this.revealed.find('.wrapper').setAttr('style', '');
$this.hidden.find('.wrapper').setAttr('style', '');
$this.dragged.find('.loader').setAttr('style', '');
$this.revealed.find('.loader').setAttr('style', '');

if (callback && p.is.function(callback)) callback();

$this.lockAnimation = false;
p.pager.paging_handled_by_animator = false;
$this.last = null;
p.overlays.setHidden(false);
};

if (
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
) {
var rectLeft =
p.pager.holders[CONST.CUR_LEFT][0].getBoundingClientRect(),
rectRight =
p.pager.holders[CONST.CUR_RIGHT][0].getBoundingClientRect();

$this.size = {
width: rectLeft.width || rectRight.width,
height: rectLeft.height || rectRight.height,
};
} else {
var rect = p.pager.holders[CONST.CUR][0].getBoundingClientRect();
$this.size = {
width: rect.width,
height: rect.height,
};
}

$this.target = p.pager.page_container[0].getBoundingClientRect();
$this.target = {
top: $this.target.top + p.pager.current_padding,
left: $this.target.left + p.pager.current_padding,
right: $this.target.right - p.pager.current_padding,
bottom: $this.target.bottom - p.pager.current_padding,
};

var finalDistance =
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
? $this.size.width * 2
: $this.size.width;

if (
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
) {
($this.dragged = p.pager.holders[CONST.PREV_RIGHT]),
($this.revealed = p.pager.holders[CONST.PREV_LEFT]);
$this.hidden = p.pager.holders[CONST.CUR_LEFT];
$this.fullhidden = p.e([
p.pager.holders[CONST.NEXT_LEFT],
p.pager.holders[CONST.NEXT_RIGHT],
]);

if (p.pager.showPage(p.pager.current_page_left - 2))
$this.revealed.removeClass('hidden');
if (p.pager.showPage(p.pager.current_page_right - 2))
$this.dragged.removeClass('hidden');

$this.fullhidden.addClass('hidden');
} else {
($this.dragged = p.pager.holders[CONST.CUR]),
($this.revealed = p.pager.holders[CONST.PREV]);
$this.hidden = p.e();
$this.fullhidden = p.pager.holders[CONST.NEXT];

if (p.pager.showPage(p.pager.current_page - 1))
$this.revealed.removeClass('hidden');

$this.dragged.removeClass('hidden');
}

$this.dragged.addClass('animate');
$this.revealed.addClass('wait');

if (
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
) {
$this.dragged.setStyle('right', 'auto');
$this.dragged.setStyle('left', p.pager.current_padding + 'px');
$this.dragged.setStyle('width', '0px');
$this.dragged.find('.wrapper').setStyle('left', 'auto');
$this.dragged
.find('.wrapper')
.setStyle('width', $this.size.width + 'px');

$this.revealed.setStyle('right', 'auto');
$this.revealed.setStyle('left', p.pager.current_padding + 'px');
$this.revealed.setStyle('width', '0px');
} else {
$this.dragged.setStyle('right', p.pager.current_padding + 'px');
$this.dragged.find('.wrapper').setStyle('left', 'auto');
$this.dragged
.find('.wrapper')
.setStyle('width', $this.size.width + 'px');
$this.revealed.find('.wrapper').setStyle('left', 'auto');
$this.revealed
.find('.wrapper')
.setStyle('width', $this.size.width + 'px');
}

$this.direction = 'left';

$this.animateLeftTo(0, finalDistance, function () {
p.pager.goBack(null, function () {
finish();
});
});
}
},

startDragRight: function (e) {
var $this = p.flip_animator,
CONST = p.pager.constant,
requestFrame =
window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame,
cancelFrame =
window.cancelAnimationFrame || window.mozCancelAnimationFrame;

$this.dragging = true;
cancelFrame($this.animationTimeout);
//p.pager.renderStop();

if (
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
) {
($this.dragged = p.pager.holders[CONST.NEXT_LEFT]),
($this.revealed = p.pager.holders[CONST.NEXT_RIGHT]);
$this.hidden = p.pager.holders[CONST.CUR_RIGHT];
$this.fullhidden = p.e([
p.pager.holders[CONST.PREV_LEFT],
p.pager.holders[CONST.PREV_RIGHT],
]);

if (p.pager.showPage(p.pager.current_page_left + 2))
$this.dragged.removeClass('hidden');
if (p.pager.showPage(p.pager.current_page_right + 2))
$this.revealed.removeClass('hidden');

$this.fullhidden.addClass('hidden');
} else {
($this.dragged = p.pager.holders[CONST.CUR]),
($this.revealed = p.pager.holders[CONST.NEXT]);
$this.hidden = p.e();
$this.fullhidden = p.pager.holders[CONST.PREV];

if (p.pager.showPage(p.pager.current_page + 1))
$this.revealed.removeClass('hidden');
}

$this.dragged.addClass('animate');
$this.revealed.addClass('wait');

if (
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
) {
$this.dragged.setStyle('left', 'auto');
$this.dragged.setStyle('right', p.pager.current_padding + 'px');
$this.dragged.setStyle('width', '0px');

$this.revealed.setStyle('left', 'auto');
$this.revealed.setStyle('right', p.pager.current_padding + 'px');
$this.revealed.setStyle('width', '0px');
$this.revealed.find('.wrapper').setStyle('left', 'auto');
$this.revealed
.find('.wrapper')
.setStyle('width', $this.size.width + 'px');
} else {
$this.dragged.setStyle('right', p.pager.current_padding + 'px');
$this.dragged.setStyle('width', $this.size.width);
$this.dragged.find('.wrapper').setStyle('left', 'auto');
$this.dragged
.find('.wrapper')
.setStyle('width', $this.size.width + 'px');
}

$this.direction = 'right';
},
startDragLeft: function (e) {
var $this = p.flip_animator,
CONST = p.pager.constant,
requestFrame =
window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame,
cancelFrame =
window.cancelAnimationFrame || window.mozCancelAnimationFrame;

$this.dragging = true;
cancelFrame($this.animationTimeout);
//p.pager.renderStop();

if (
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
) {
($this.dragged = p.pager.holders[CONST.PREV_RIGHT]),
($this.revealed = p.pager.holders[CONST.PREV_LEFT]);
$this.hidden = p.pager.holders[CONST.CUR_LEFT];
$this.fullhidden = p.e([
p.pager.holders[CONST.NEXT_LEFT],
p.pager.holders[CONST.NEXT_RIGHT],
]);

if (p.pager.showPage(p.pager.current_page_left - 2))
$this.revealed.removeClass('hidden');
if (p.pager.showPage(p.pager.current_page_right - 2))
$this.dragged.removeClass('hidden');

$this.fullhidden.addClass('hidden');
} else {
($this.dragged = p.pager.holders[CONST.CUR]),
($this.revealed = p.pager.holders[CONST.PREV]);
$this.hidden = p.e();
$this.fullhidden = p.pager.holders[CONST.NEXT];

if (p.pager.showPage(p.pager.current_page - 1))
$this.revealed.removeClass('hidden');

$this.dragged.removeClass('hidden');
}

$this.dragged.addClass('animate');
$this.revealed.addClass('wait');

if (
p.pager.current_mode == CONST.DOUBLE ||
p.pager.current_mode == CONST.DOUBLE_REVERSE
) {
$this.dragged.setStyle('right', 'auto');
$this.dragged.setStyle('left', p.pager.current_padding + 'px');
$this.dragged.setStyle('width', '0px');
$this.dragged.find('.wrapper').setStyle('left', 'auto');
$this.dragged
.find('.wrapper')
.setStyle('width', $this.size.width + 'px');

$this.revealed.setStyle('right', 'auto');
$this.revealed.setStyle('left', p.pager.current_padding + 'px');
$this.revealed.setStyle('width', '0px');
} else {
$this.dragged.setStyle('right', p.pager.current_padding + 'px');
$this.dragged.find('.wrapper').setStyle('left', 'auto');
$this.dragged
.find('.wrapper')
.setStyle('width', $this.size.width + 'px');
$this.revealed.find('.wrapper').setStyle('left', 'auto');
$this.revealed
.find('.wrapper')
.setStyle('width', $this.size.width + 'px');
}

$this.direction = 'left';
},
},

overlays: {
elements: [],
objects: [],
container: null,
lastRenderPage: -1,
lastRenderZoom: -1,
lastRenderMode: -1,

init: function () {
this.container = p.e('#reader-container .overlayer');
var elements = p.reader.container.find('.overlay'),
i = 0,
l = elements.length;
for (; i < l; i++) {
this.parse(elements[i]);
}
elements.remove();
},

setHidden: function (hidden) {
var $this = p.overlays;

if (hidden) $this.container.addClass('hidden');
else $this.container.removeClass('hidden');
},

parse: function (e) {
var ele = p.e(e);

var data = {
html: ele.getHtml().trim(),
display: ele.getAttr('data-display'),
type: ele.getAttr('data-type'),
x: parseInt(ele.getAttr('data-x')),
y: parseInt(ele.getAttr('data-y')),
width: parseInt(ele.getAttr('data-width')),
height: parseInt(ele.getAttr('data-height')),
page: parseInt(ele.getAttr('data-page')),
openWidth: parseInt(ele.getAttr('data-open-width')),
openHeight: parseInt(ele.getAttr('data-open-height')),
icon: ele.getAttr('data-icon'),
};

this.elements.push(data);
},

render: function () {
var $this = p.overlays,
i = 0,
l = $this.elements.length,
CONST = p.pager.constant,
pgr = p.pager;

if (
$this.lastRenderMode != pgr.current_mode ||
$this.lastRenderPage != pgr.current_page ||
$this.lastRenderZoom != pgr.current_zoom
) {
//console.log("Render");
if (!showHighlight) {
showHighlight =
$this.lastRenderPage != pgr.current_page &&
$this.lastRenderZoom == pgr.current_zoom;
}

$this.lastRenderMode = pgr.current_mode;
$this.lastRenderPage = pgr.current_page;
$this.lastRenderZoom = pgr.current_zoom;
$this.prepare();
$this.objects = [];

if (p.pager.current_mode == CONST.SINGLE) {
var c = $this.container.find('.page');
//console.log(c);
} else if (p.pager.current_mode == CONST.DOUBLE) {
var left = $this.container.find('.left');
var right = $this.container.find('.right');
}

for (; i < l; i++) {
var e = $this.elements[i];
// `` console.log(JSON.stringify(e))
var o;
//console.log(e);

if (p.pager.current_mode == CONST.SINGLE) {
if (e.page == p.pager.current_page) {
o = $this.make(e).appendTo(c);
}
} else if (p.pager.current_mode == CONST.DOUBLE) {
if (e.page == p.pager.current_page_left) {
o = $this.make(e).appendTo(left);
} else if (e.page == p.pager.current_page_right) {
o = $this.make(e).appendTo(right);
}
}

if (o) {
$this.objects.push(o);
//console.log($this.objects);
}
}
console.log(pgr.current_page, pgr.current_page % 30);

if (user_id && pgr.current_page > 1 && pgr.current_page % 30 == 0) {
let e = {
html: user_id,
display: 'pin',
type: 'show_user',
x: 5,
y: 5,
width: 50,
height: 10,
//"page": 2,
openWidth: null,
openHeight: null,
icon: null,
};
if (p.pager.current_mode == CONST.SINGLE) {
console.log($this.make(e));
let ele = $this.make(e);
ele.each(function () {
this.innerHTML = user_id;
this.className = 'overlay show-user';
});
ele.on = null;
console.log(ele);
o = ele.appendTo(c);
} else if (p.pager.current_mode == CONST.DOUBLE) {
console.log($this.make(e));
let ele = $this.make(e);
ele.each(function () {
this.innerHTML = user_id;
this.className = 'overlay show-user';
});
ele.on = null;
console.log(ele);
o = ele.appendTo(left);
}
if (o) {
$this.objects.push(o);
//console.log($this.objects);
}
}
if (pgr.current_page == 0) {
$('#reader-container > div.content > div.pages.double').addClass(
'first'
);
} else {
$('#reader-container > div.content > div.pages.double').removeClass(
'first'
);
$('#reader-container .controls .left').addClass('firstbtn');
}
console.log(pgr.current_page, pgr.last_page_no);

if (pgr.current_mode == CONST.SINGLE) {
if (pgr.current_page == pgr.last_page_no) {
$('#reader-container .content .pages .overlayer .page').addClass(
'lastp'
);
$('#reader-container .content .pages .overlayer').css(
'display',
'none'
);
} else {
$(
'#reader-container .content .pages .overlayer .page'
).removeClass('lastp');
$('#reader-container .content .pages .overlayer').css(
'display',
'block'
);
}
} else {
let side = 'right';
let tmp_page_no = pgr.last_page_no - 1;

if (pgr.last_page_no % 2 == 0) {
side = 'left';
tmp_page_no = pgr.last_page_no;
}
if (pgr.current_page == tmp_page_no) {
$(
'#reader-container .content .pages.double .page.' + side
).addClass('lastp');
} else {
$(
'#reader-container .content .pages.double .page.' + side
).removeClass('lastp');
}
}
}
},

getAvailableSpace: function () {
var rect = p.math.rect(
p.pager.content_container[0].scrollTop,
p.pager.content_container[0].scrollLeft,
p.reader.container.getHeight() +
p.pager.content_container[0].scrollTop,
p.reader.container.getWidth() +
p.pager.content_container[0].scrollLeft
);

var topBlocked = false;
var leftBlocked = false;
var rightBlocked = false;
var bottomBlocked = false;

if (
p
.e(
'#reader-container .controls .top, #reader-container .controls .topleft .horizontal, #reader-container .controls .topright .horizontal'
)
.children().length > 0
)
topBlocked = true;

if (
p
.e(
'#reader-container .controls .left, #reader-container .controls .topleft .vertical, #reader-container .controls .bottomleft .vertical'
)
.children().length > 0
)
leftBlocked = true;

if (
p
.e(
'#reader-container .controls .bottom, #reader-container .controls .bottomleft .horizontal, #reader-container .controls .bottomright .horizontal'
)
.children().length > 0
)
bottomBlocked = true;

if (
p
.e(
'#reader-container .controls .right, #reader-container .controls .topright .vertical, #reader-container .controls .bottomright .vertical'
)
.children().length > 0
)
rightBlocked = true;

if (topBlocked)
rect.top += p.e('#reader-container .controls .top').getHeight();
if (leftBlocked)
rect.left += p.e('#reader-container .controls .left').getWidth();
if (bottomBlocked)
rect.bottom -= p.e('#reader-container .controls .bottom').getHeight();
if (rightBlocked)
rect.right -= p.e('#reader-container .controls .right').getWidth();

if (p.reader.overview.isOpen) {
if (p.reader.settings.overview_direction == 'top') {
rect.top += p.reader.settings.overview_size;
} else if (p.reader.settings.overview_direction == 'bottom') {
rect.bottom -= p.reader.settings.overview_size;
} else if (p.reader.settings.overview_direction == 'right') {
rect.right -= p.reader.settings.overview_size;
} else if (p.reader.settings.overview_direction == 'left') {
rect.left += p.reader.settings.overview_size;
}
}

return rect;
},

prepare: function () {
var $this = p.overlays,
CONST = p.pager.constant;
p.pager.touchBlocked = false;
$this.container.children().remove();
$this.container.setStyle('padding', p.pager.current_padding + 'px');
if (p.pager.current_mode == CONST.SINGLE) {
var size = p.pager.getPageSize(p.pager.current_page);
p.e('<div>', {
class: 'page',
width: size.width + 'px',
height: size.height + 'px',
}).appendTo($this.container);
} else if (p.pager.current_mode == CONST.DOUBLE) {
var sizeLeft = p.pager.getPageSize(p.pager.current_page_left);
var sizeRight = p.pager.getPageSize(p.pager.current_page_right);
p.e('<div>', {
class: 'page left',
width: sizeLeft.width + 'px',
height: sizeLeft.height + 'px',
}).appendTo($this.container);
p.e('<div>', {
class: 'page right',
width: sizeRight.width + 'px',
height: sizeRight.height + 'px',
}).appendTo($this.container);
}
},
make_audio_controls: function (e) {
var ele = e[0];
var container = p.e('<div>', {
class: 'controller flex horizontal',
});
var playing = false;
var play_pause = p
.e('<div>', {
class: 'icon',
html: 'play_arrow',
})
.appendTo(container);
var volume = p.reader
.make_slider({
dark: true,
discrete: true,
min: 0,
max: 100,
value: 50,
sigfigs: 0,
callback: function (vol) {
try {
ele.volume = vol / 100;
} catch (ex) {}
},
})
.appendTo(container);

play_pause.on('click tap', function () {
if (playing) {
play_pause.setHtml('play_arrow');

try {
ele.pause();
} catch (ex) {}
playing = false;
} else {
play_pause.setHtml('pause');
try {
ele.play();
} catch (ex) {
p.reader
.makeMessage(
p.locale.getString('ERROR_TITLE'),
p.locale.getString('UNSUPPORTED_AUDIO')
)
.appendTo(p.reader.container);
}
playing = true;
}
});
try {
ele.volume = 0.5;
} catch (ex) {}

container.extend({
close: function () {
play_pause.setHtml('play_arrow');

try {
ele.pause();
playing = false;
} catch (ex) {}
},
});

return container;
},
make_video_controls: function (e, onmeta) {
var uid = p.random.guid();
p.e(e.getParents()[0]).setAttr('id', uid);

var ele = e[0];
var container = p.e('<div>', {
class: 'controller flex horizontal',
});
var playing = false;
var play_pause = p
.e('<div>', {
class: 'icon',
html: 'play_arrow',
})
.appendTo(container);
var seekbar = p.reader
.make_slider(
{
dark: true,
discrete: false,
buffering: true,
buffer: 0,
min: 0,
max: 100,
value: 1,
callback: function (time, user) {
if (fncs) fncs.player.onSeek(time, user);
},
},
uid
)
.appendTo(container);
var audio = p
.e('<div>', {
class: 'icon',
html: 'volume_up',
})
.appendTo(container);
var audio_bar_container = p
.e('<div>', {
class: 'hidden_menu flex vertical',
})
.appendTo(container);
var fullscreen = p
.e('<div>', {
class: 'icon',
html: 'fullscreen',
})
.appendTo(container);

var volume = p.reader
.make_slider(
{
dark: true,
discrete: true,
vertical: true,
min: 0,
max: 100,
value: 50,
sigfigs: 0,
callback: function (vol) {
try {
ele.volume = vol / 100;
} catch (ex) {}
},
},
uid
)
.appendTo(audio_bar_container);

var fncs = {
player: {
playpause: function () {
if (playing) {
fncs.player.pause();
} else {
fncs.player.play();
}
},
pause: function () {
try {
ele.pause();
} catch (ex) {}
playing = false;
},
play: function () {
try {
ele.play();
} catch (ex) {
p.reader
.makeMessage(
p.locale.getString('ERROR_TITLE'),
p.locale.getString('UNSUPPORTED_VIDEO')
)
.appendTo(p.reader.container);
}
},
onTime: function () {
seekbar.slider.value = ele.currentTime;
seekbar.slider.max = ele.duration;
seekbar.slider.update(true);
},
onSeek: function (time, user) {
if (user) {
try {
ele.currentTime = time;
} catch (ex) {}
}
},
onProgress: function (e) {
if (ele.buffered.length > 0) {
//console.log(ele.buffered.start(0), ele.buffered.end(0), ele.duration);
seekbar.slider.setBuffer(
p.math.Percentage.XofY(ele.buffered.end(0), ele.duration)
);
}
},
onState: function () {
if (ele.paused) {
play_pause.setHtml('play_arrow');
playing = false;
} else {
play_pause.setHtml('pause');
playing = true;
}
},
onMeta: function () {
if (onmeta && p.is.function(onmeta)) onmeta();
},
onFullscreen: function (type, element) {
if (p.e(element).getAttr('id') == uid) {
if (type == 'exit') {
fullscreen.setHtml('fullscreen_enter');
} else {
fullscreen.setHtml('fullscreen_exit');
}
}
},
},
};

e.on('timeupdate', fncs.player.onTime);
e.on('progress', fncs.player.onProgress);
e.on('loadedmetadata', fncs.player.onMeta);
e.on('pause play ended abort', fncs.player.onState);

fullscreen.on('click tap', function fullscreenToggler() {
if (p.fullscreen.isFullscreen) {
p.fullscreen.exit();
} else {
p.fullscreen.enter(e.getParents()[0]);
}
});

p.subscribe('fullscreen', fncs.player.onFullscreen);

audio.on('mouseenter', function () {
audio_bar_container.toggleClass('open');
});
audio_bar_container.on('mouseleave', function () {
audio_bar_container.removeClass('open');
});

play_pause.on('click tap', fncs.player.playpause);

try {
ele.volume = 0.5;
} catch (ex) {}

container.extend(fncs);

return container;
},
make_iframe_controls: function (e) {
var ele = e[0];
var container = p.e('<div>', {
class: 'navigator flex horizontal',
});
var info = p.e('<div>').appendTo(container);
var back = p
.e('<div>', {
class: 'icon',
html: 'arrow_back',
})
.appendTo(container);
var forward = p
.e('<div>', {
class: 'icon',
html: 'arrow_forward',
})
.appendTo(container);
var reload = p
.e('<div>', {
class: 'icon',
html: 'refresh',
})
.appendTo(container);

ele.readystatechange = function (evt) {
//console.log(evt, ele.readyState);
};

return container;
},
make_gallery: function (sources) {
var uid = p.random.guid();
var container = p.e('<div>', {
class: 'container',
id: uid,
});
var arrow_left = p
.e('<div>', {
class: 'navigation icon left',
html: 'keyboard_arrow_left',
})
.appendTo(container);
var arrow_right = p
.e('<div>', {
class: 'navigation icon right',
html: 'keyboard_arrow_right',
})
.appendTo(container);
var fullscreen = p
.e('<div>', {
class: 'fullscreen icon',
html: 'fullscreen_enter',
})
.appendTo(container);
var dots_container = p
.e('<div>', {
class: 'dots',
})
.appendTo(container);

var loaders = [];
var dots = [];

for (var i = 0; i < sources.length; i++) {
//var src = sources[i];
loaders.push(p.reader.stageLoader().appendTo(container));
dots.push(
p
.e('<div>', {
class: 'dot',
})
.appendTo(dots_container)
);
}

var fncs = {
gallery: {
hasBeenStarted: false,
index: 0,
max: sources.length - 1,
start: function () {
if (!fncs.gallery.hasBeenStarted) {
fncs.gallery.hasBeenStarted = true;
for (var i = 0; i < sources.length; i++) {
var src = sources[i];
loaders[i].load([src]);
}

loaders[0].addClass('appear');
dots[0].addClass('active');
}
},
next: function () {
var $this = fncs.gallery,
next = $this.index + 1;
if (next > $this.max) next = 0;

p.e(loaders).removeClass('vanish appear left right');
loaders[$this.index].addClass('vanish');
loaders[next].addClass('appear right');
$this.index = next;
p.e(dots).removeClass('active');
dots[$this.index].addClass('active');
},
prev: function () {
var $this = fncs.gallery,
prev = $this.index - 1;
if (prev <= 0) prev = $this.max;

p.e(loaders).removeClass('vanish appear left right');
loaders[$this.index].addClass('vanish');
loaders[prev].addClass('appear left');
$this.index = prev;
p.e(dots).removeClass('active');
dots[$this.index].addClass('active');
},
onFullscreen: function (type, element) {
if (p.e(element).getAttr('id') == uid) {
if (type == 'exit') {
fullscreen.setHtml('fullscreen_enter');
} else {
fullscreen.setHtml('fullscreen_exit');
}
}
},
fullscreen: function () {
if (p.fullscreen.isFullscreen) {
p.fullscreen.exit();
//p.reader.container.removeClass("child-fullscreen");
} else {
p.fullscreen.enter(container[0]);
//p.reader.container.addClass("child-fullscreen");
}
},
},
};

p.TouchHandler(container, {
propagate: false,
priority: true,
onSwipeLeft: fncs.gallery.next,
onSwipeRight: fncs.gallery.prev,
});

p.subscribe('fullscreen', fncs.gallery.onFullscreen);
arrow_left.on('click tap', fncs.gallery.prev);
arrow_right.on('click tap', fncs.gallery.next);
fullscreen.on('click tap', fncs.gallery.fullscreen);

container.extend(fncs);
return container;
},
make: function (e) {
var ele = p.e('<div>', {
class: 'overlay visible ' + e.type,
});
var scale = p.pager.current_zoom;

var dimmer = p
.e('<div>', {
class: 'dimmer',
})
.appendTo(ele);

var controls = p
.e('<div>', {
class: 'controls flex horizontal reverse',
})
.appendTo(ele);
var content = p
.e('<div>', {
class: 'content',
})
.appendTo(ele);
var wrapper = p
.e('<div>', {
class: 'wrap',
})
.appendTo(content);
var requireTouch = false;
var overflowed = false;

var btn_close = p
.e('<div>', {
class: 'icon close',
html: 'close',
})
.appendTo(controls);

if (e.display == 'area') {
ele.addClass('area');
ele.setStyle('width', e.width * scale + 'px');
ele.setStyle('height', e.height * scale + 'px');
} else {
ele.addClass('pin');
}
// console.log(e)
ele.setStyle('width', e.width * scale + 'px');
ele.setStyle('height', e.height * scale + 'px');
ele.setStyle('left', e.x * scale + 'px');
ele.setStyle('bottom', e.y * scale + 'px');
if (showHighlight) {
setTimeout(function () {
ele.setStyle('opacity', 0.4);
}, 200);

setTimeout(function () {
showHighlight = false;
ele.setStyle('opacity', 0);
ele.setAttr('opacity', -1);
}, 5000);
}

// // ICON
// switch (e.type) {
// case "html":
// icon.setHtml("code");
// break;
// case "image":
// icon.setHtml("image");
// break;
// case "gallery":
// icon.setHtml("photo_library");
// break;
// case "video":
// icon.setHtml("video_library");
// break;
// case "audio":
// icon.setHtml("library_music");
// break;
// case "link":
// icon.setHtml("link");
// break;
// case "page":
// icon.setHtml("input");
// break;
// case "embed":
// icon.setHtml("web");
// break;
// }

// if (e.icon)
// icon.setHtml(e.icon);

// CONTENT
switch (e.type) {
case 'html':
wrapper.setHtml(e.html);
break;
case 'image':
var source = p.e(e.html);
p.e('<img>', {
src: source.getAttr('src'),
alt: p.locale.getString('IMG_ALT'),
}).appendTo(wrapper);
requireTouch = true;
break;
case 'gallery':
var sources = p.e(e.html);
var paths = [];
sources.each(function () {
paths.push(p.e(this).getAttr('src'));
});
var gallery = p.overlays.make_gallery(paths).appendTo(wrapper);

e.openWidth = !isNaN(e.openWidth) ? e.openWidth : 10000;
e.openHeight = !isNaN(e.openHeight) ? e.openHeight : 10000;
break;
case 'audio':
var audio = p.e('<audio>');
var sources = p.e(e.html).appendTo(audio);
var ctrls = p.overlays.make_audio_controls(audio);
audio.appendTo(wrapper);
ctrls.appendTo(wrapper);
break;
case 'video':
var videoWrap = p.e('<div>', {
class: 'player',
});
var videoShield = p
.e('<div>', {
class: 'shield',
})
.appendTo(videoWrap);
var video = p.e('<video>').appendTo(videoWrap);
var sources = p.e(e.html).appendTo(video);
var ctrls = p.overlays.make_video_controls(video, function () {
e.openWidth = !isNaN(e.openWidth)
? e.openWidth
: Math.max(320, video[0].videoWidth);
e.openHeight = !isNaN(e.openHeight)
? e.openHeight
: Math.max(240, video[0].videoHeight);
fncs.adjustSize(e.openWidth, e.openHeight);
});
videoWrap.appendTo(wrapper);
ctrls.appendTo(videoWrap);
e.openWidth = !isNaN(e.openWidth)
? e.openWidth
: Math.max(320, video[0].videoWidth);
e.openHeight = !isNaN(e.openHeight)
? e.openHeight
: Math.max(240, video[0].videoHeight);

p.reader.container.on('keyup', function (evt) {
if (
ele.hasClass('open') &&
(evt.keyCode == 32 || evt.keyCode == 75)
) {
// On space and K
if (evt && evt.preventDefault) evt.preventDefault();
if (evt && evt.stopPropagation) evt.stopPropagation();
ctrls.player.playpause();
}
});
break;
case 'link':
case 'page':
var source = p.e(e.html);
var target = source.getAttr('src');
break;
case 'embed':
var source = p.e(e.html);
var target = source.getAttr('src');
var iframe = p.e('<iframe>').appendTo(wrapper);
e.openWidth = !isNaN(e.openWidth) ? e.openWidth : 10000;
e.openHeight = !isNaN(e.openHeight) ? e.openHeight : 10000;
//var controls = p.overlays.make_iframe_controls(iframe).appendTo(controls);
break;
}

var pinchStartWidth, pinchStartHeight, pinchStartRect;
var pinchOffsetX, pinchOffsetY;
var pinchRelativeScale = 0;
var pinchStartFactor = 0;
var pinchStart = null;
var pinchCurrent = null;
var currentZoom = 1.0;
var maxZoom = 2.0;
var minZoom = 0.1;

var fncs = {
adjustSize: function (width, height) {
if (ele.hasClass('open')) {
var relPos = ele.getRelativeXY('.content');
var openWidth = Math.max(width + 8 * 2, 200);
var openHeight = Math.max(height + 8 + 32 + 8, 80);

var projectedRect = p.math.rect(
relPos.y,
relPos.x,
relPos.y + openHeight,
relPos.x + openWidth
);
var fittedRect = p.math.rect(
relPos.y,
relPos.x,
relPos.y + openHeight,
relPos.x + openWidth
);
var availableSpace = p.overlays.getAvailableSpace();

var newTop = e.y * scale;
var newLeft = e.x * scale;
var infiniteLoopSecurityCounterJustInCase = 0; // You never know with floating points

while (!availableSpace.contains(fittedRect)) {
if (fittedRect.height > availableSpace.height)
(overflowed = true),
(fittedRect.height = availableSpace.height);

if (fittedRect.width > availableSpace.width)
(overflowed = true),
(fittedRect.width = availableSpace.width);

if (fittedRect.top < availableSpace.top)
fittedRect.moveTopTo(availableSpace.top);

if (fittedRect.left < availableSpace.left)
fittedRect.moveLeftTo(availableSpace.left);

if (fittedRect.bottom > availableSpace.bottom)
fittedRect.moveTopBy(
availableSpace.bottom - fittedRect.bottom
);

if (fittedRect.right > availableSpace.right)
fittedRect.moveLeftBy(
availableSpace.right - fittedRect.right
);

if (infiniteLoopSecurityCounterJustInCase++ > 10) break;
}

newTop += fittedRect.top - projectedRect.top;
newLeft += fittedRect.left - projectedRect.left;
openWidth = fittedRect.width;
openHeight = fittedRect.height;

//ele.addClass("open" + (overflowed ? " overflow" : ""));
if (overflowed) ele.addClass('overflow');
else ele.removeClass('overflow');

ele.setStyle('width', openWidth + 'px');
ele.setStyle('height', openHeight + 'px');
ele.setStyle('bottom', newTop + 'px');
ele.setStyle('left', newLeft + 'px');
}
},
open: function (evt) {
if (evt && evt.preventDefault) evt.preventDefault();
if (evt && evt.stopPropagation) evt.stopPropagation();
//console.log("open");
if (!ele.hasClass('open')) {
p.overlays.closeAll();
switch (e.type) {
case 'link':
window.open(target);
p.pager.touchBlocked = true;
break;
case 'page':
p.pager.goToPage((p.pager.current_page = parseInt(target)));
break;
case 'embed':
if (!iframe.getAttr('src')) iframe.setAttr('src', target);
default:
p.pager.touchBlocked = true;
if (e.type == 'gallery') gallery.gallery.start();
var openWidth = !isNaN(e.openWidth)
? e.openWidth
: wrapper.getWidth();
var openHeight = !isNaN(e.openHeight)
? e.openHeight
: wrapper.getHeight();
ele.addClass('open');
fncs.adjustSize(openWidth, openHeight);
break;
}
}
},
close: function (evt) {
if (evt && evt.preventDefault) evt.preventDefault();
if (evt && evt.stopPropagation) evt.stopPropagation();
//console.log("close", ele);
if (ele.hasClass('open')) {
//console.log("closing", ele);
ele.removeClass('open');
p.pager.touchBlocked = false;

if (e.type == 'audio') {
ctrls.close();
}
if (e.type == 'video') {
ctrls.player.pause();
}

if (e.display == 'area') {
ele.setStyle('width', e.width * scale + 'px');
ele.setStyle('height', e.height * scale + 'px');
} else {
ele.setStyle('width', '');
ele.setStyle('height', '');
}

ele.setStyle('left', e.x * scale + 'px');
ele.setStyle('bottom', e.y * scale + 'px');
//console.log("closed", ele);
}
},

onDrag: function (difference) {
if (ele.hasClass('open') && overflowed) {
content[0].scrollLeft += difference.x;
content[0].scrollTop += difference.y;
}
},
/// WHEEL
//onWheelStart: function (start)
//{
// pinchStartWidth = wrapper.getWidth();
// pinchStartHeight = wrapper.getHeight();
// pinchStart = start;
// pinchStartFactor = pinchStartWidth / content.getWidth();
// pinchOffsetX = (pinchStart.x) + content[0].scrollLeft;
// pinchOffsetY = (pinchStart.y) + content[0].scrollTop;
// pinchStartRect = wrapper.getRelativeBoundingClientRect();

// wrapper.setStyle("transformOrigin", "{0}px {1}px".format(pinchOffsetX, pinchOffsetY));
//},
//onWheel: function (distDiff, distChange, now)
//{
// var zoomTest = currentZoom * distChange;

// if (zoomTest >= minZoom && zoomTest <= maxZoom)
// {
// pinchRelativeScale = distChange;
// pinchCurrent = now;

// wrapper.setStyle("height", "{0}px".format(pinchStartHeight));
// wrapper.setStyle("width", "{0}px".format(pinchStartWidth));
// wrapper.setStyle("transform", "scale({0})".format(pinchRelativeScale));
// }
//},
//onWheelEnd: function ()
//{
// try
// {
// var rect = wrapper.getRelativeBoundingClientRect();
// } catch (ex) { }

// currentZoom = currentZoom * pinchRelativeScale;
// var scrollTop = Math.round(-rect.top), scrollLeft = Math.round(-rect.left);

// content[0].scrollTop = scrollTop;
// content[0].scrollLeft = scrollLeft;
//}
};

if (requireTouch) {
//console.log("touch handler");
p.TouchHandler(content, {
propagate: false,
priority: true,
onDrag: fncs.onDrag,
onWheelStart: fncs.onWheelStart,
onWheel: fncs.onWheel,
onWheelEnd: fncs.onWheelEnd,
});
}
if (e.type != 'show_user') {
ele.on('click tap', fncs.open);
btn_close.on('click tap', fncs.close);
}
ele.extend(fncs);

return ele;
},
closeAll: function () {
var i = 0,
l = p.overlays.objects.length;
for (; i < l; i++) p.overlays.objects[i].close();
},
},

pager: {
pages: null,
get page_count() {
return Object.keys(this.pages).length;
},
current_script: null,
current_mode: 1, // 1 = single, 2 = double, (3 = single reverse?, 4 = double reverse?, 5 = continuous?)
current_mode_manual: false,
current_renderer: 1,
current_renderer_manual: false,
current_zoom: 1.0,
current_autozoom: true,
current_padding: 20,
current_controls: false,
current_controls_floating: false,
current_animation: 0,
current_animator: null,
holders: [],
loaders: [],
page_container: null,
content_container: null,
pages_uniform: true,
pdf_exists: false,
pdf_checked: false,
pdf_checking: false,
//pdf_enabled: false,
pdf_preparing: false,
pdf_loaded: false,
pdf_loaded_load: false,
pdf_loaded_progess: false,
pdf_rendering_slow: false,
pdf_last_rendertimes: [],
pdf_last_rendertime_index: 0,
pdf_last_rendertime_max: 10,
is_mobile: false,
touchBlocked: false,

get pdf_average_rendertimes() {
var i = 0,
o = 0,
c = this.pdf_last_rendertimes.length;
for (; i < c; i++) o += this.pdf_last_rendertimes[i];
return o / c;
},

//get paging_handled_by_animator()
//{
// return !(this.current_animation == this.constant.NONE);
//},
paging_handled_by_animator: false,

push_pdf_rendertime: function (time) {
this.pdf_last_rendertimes[this.pdf_last_rendertime_index++] = time;
if (this.pdf_last_rendertime_index >= this.pdf_last_rendertime_max)
this.pdf_last_rendertime_index = 0;
},

last_page: -1,
last_page_left: -1,
last_page_right: -1,
last_autozoom: 1,

current_page: 0,
current_page_temp: 0,
get current_page_firstvalid() {
if (this.current_page <= 0) return 1;
else if (this.current_page > this.page_count) return this.page_count;

return this.current_page;
},
get current_page_left() {
if (this.current_page <= 1) this.current_page = 0;
else {
if (
this.current_mode == this.constant.DOUBLE ||
this.current_mode == this.constant.DOUBLE_REVERSE
) {
if (this.current_page % 2) this.current_page--;
}
}

return this.current_page;
},
get current_page_right() {
return this.current_page_left + 1;
},
get show_page_left() {
return this.showPage(this.current_page_left);
//return this.current_page_left > 0;
},
get show_page_right() {
return this.showPage(this.current_page_right);
//return this.current_page_right <= this.page_count;
},

get can_go_back() {
if (
this.current_mode == this.constant.DOUBLE ||
this.current_mode == this.constant.DOUBLE_REVERSE
) {
if (Math.min(this.current_page_left, this.current_page_right) <= 1)
return false;
} else {
if (this.current_page <= 1) return false;
}

return true;
},

get can_go_forward() {
if (
this.current_mode == this.constant.DOUBLE ||
this.current_mode == this.constant.DOUBLE_REVERSE
) {
if (
Math.max(this.current_page_left, this.current_page_right) >=
this.page_count
)
return false;
} else {
if (this.current_page >= this.page_count) return false;
}

return true;
},

showPage: function (page) {
return page > 0 && page <= this.page_count;
},

_lastContentContained: null,
_contentContainedInvalidated: true,
get contentContained() {
if (this._contentContainedInvalidated) {
var contentSize = {
width: this.page_container.getWidth(),
height: this.page_container.getHeight(),
};
var containerSize = {
width: p.reader.container.getWidth(),
height: p.reader.container.getHeight(),
};
this._lastContentContained =
contentSize.width <= containerSize.width &&
contentSize.height <= containerSize.height;
this._contentContainedInvalidated = false;
}

return this._lastContentContained;
},

invalidateContentContained: function () {
this._contentContainedInvalidated = true;
},

constant: {
// Modes
SINGLE: 1,
DOUBLE: 2,
SINGLE_REVERSE: 3,
DOUBLE_REVERSE: 4,
SCROLL: 5,

// Canvases
PREV_LEFT: 0,
PREV_RIGHT: 1,
CUR_LEFT: 2,
CUR_RIGHT: 3,
NEXT_LEFT: 4,
NEXT_RIGHT: 5,
PREV: 0,
CUR: 1,
NEXT: 2,

// Renderers
IMG: 1,
PDF: 2,

// Animations
NONE: 0,
FADE: 1,
FLIP: 2,
SWIPE: 3,
},

ready_for_first_load: false,
first_load_done: false,
onFirstLoad: function () {
if (!this.first_load_done && this.ready_for_first_load) {
this.first_load_done = true;
p.e('.main-loader').addClass('hidden');

if (p.pager.is_mobile || p.reader.settings.no_pdf)
p.reader.setProgress(100);

p.pager.setAnimation(
p.pager.constant[p.reader.get('animation', 'flip').toUpperCase()]
);

if (p.reader.settings.slideshow_mode) {
p.reader.slideshow.play();
}
}
},

init: function () {
var $this = this;
this.page_container = p.e('#reader-container .content .pages');
this.content_container = p.e('#reader-container .content');
if (this.pages != null) {
this.prepareElements();

if (p.reader.settings.overview_start_open) p.reader.overview.open();

var pinchStartWidth, pinchStartHeight, pinchStartRect;
var pinchOffsetX, pinchOffsetY;
var pinchRelativeScale = 0;
var pinchStartFactor = 0;
var pinchStart = null;
var pinchCurrent = null;

//console.log(p.reader.container.find(".content"));
p.TouchHandler(this.content_container, {
propagate: true,
wheelTick: p.reader.settings.zoom_wheel_step * 10,
onSwipeRight: function () {
if (!p.pager.touchBlocked)
if (
p.reader.settings.enable_swiping &&
!p.pager.paging_handled_by_animator
) {
if (p.pager.current_animator == null) {
ga('send', 'event', {
eventCategory: 'Web-Reader',
eventAction: 'SwipeRight',
eventLabel: 'clicked',
});
if (p.ads.showAds()) {
return false;
}
p.pager.goBack();
} else p.pager.current_animator.doFullAnimationPrev();
}
},
onSwipeLeft: function () {
if (!p.pager.touchBlocked)
if (
p.reader.settings.enable_swiping &&
!p.pager.paging_handled_by_animator
) {
if (p.pager.current_animator == null) {
p.pager.goForward();
ga('send', 'event', {
eventCategory: 'Web-Reader',
eventAction: 'SwipeLeft',
eventLabel: 'clicked',
});
if (p.ads.showAds()) {
return false;
}
} else p.pager.current_animator.doFullAnimationNext();
}
},
onDrag: function (diff) {
if (!p.pager.touchBlocked)
if (p.reader.settings.enable_dragging) {
p.pager.content_container[0].scrollLeft += diff.x;
p.pager.content_container[0].scrollTop += diff.y;
}
},
onDoubleTap: function (e) {
if (!p.pager.touchBlocked)
if (p.reader.settings.enable_double_tapping) {
ga('send', 'event', {
eventCategory: 'Web-Reader',
eventAction: 'DoubleTap',
eventLabel: 'clicked',
});
if (!$this.current_autozoom) {
$this.current_autozoom = true;
$this.adjust({
reload: true,
});
} else {
//debugger;
pinchRelativeScale = 1 / $this.current_zoom;
var scrollTop =
e.y * pinchRelativeScale -
$this.content_container.getHeight() / 2,
scrollLeft =
e.x * pinchRelativeScale -
$this.content_container.getWidth() / 2;

$this.setZoom(p.reader.settings.zoom_doubleclick);
$this.adjust({
reload: true,
scroll: {
top: scrollTop,
left: scrollLeft,
},
callback: function () {
p.pager.content_container[0].scrollLeft = scrollLeft; // (((e.x * pinchRelativeScale)) - (($this.content_container.getWidth() / 2))); // - (p.pager.content_container[0].scrollLeft + $this.current_padding);
p.pager.content_container[0].scrollTop = scrollTop; //(((e.y * pinchRelativeScale)) - (($this.content_container.getHeight() / 2))); // - (p.pager.content_container[0].scrollTop + $this.current_padding);
},
});
}
}
},

/// WHEEL
onWheelStart: function (start) {
/* if (!p.pager.touchBlocked)
if (p.reader.settings.enable_mousewheel_zoom) {
pinchStartWidth = $this.page_container.getWidth();
pinchStartHeight = $this.page_container.getHeight();
pinchStart = start;
pinchStartFactor = pinchStartWidth / $this.content_container.getWidth();
pinchOffsetX = (pinchStart.x) + $this.content_container[0].scrollLeft;
pinchOffsetY = (pinchStart.y) + $this.content_container[0].scrollTop;
pinchStartRect = $this.page_container.getRelativeBoundingClientRect();

//console.log(pinchStart.x, pinchStart.y, $this.content_container[0].scrollLeft, $this.content_container[0].scrollTop);

// Very important to set this here!!!
// On mobile this is an insane performance drain, especially on android
$this.page_container.setStyle("transformOrigin", "{0}px {1}px".format(pinchOffsetX, pinchOffsetY));

//console.log("START", pinchStartRect);
}*/
},
onWheel: function (distDiff, distChange, now) {
/*if (!p.pager.touchBlocked)
if (p.reader.settings.enable_mousewheel_zoom) {
var zoomTest = p.pager.current_zoom * distChange;
//var zoomTest = Math.min(p.reader.settings.zoom_max, Math.max(p.reader.settings.zoom_min == "auto" ? p.pager.last_autozoom : p.reader.settings.zoom_min, p.pager.current_zoom * distChange));
if (zoomTest < (p.reader.settings.zoom_min == "auto" ? p.pager.last_autozoom : p.reader.settings.zoom_min)) {
distChange = (p.reader.settings.zoom_min == "auto" ? p.pager.last_autozoom : p.reader.settings.zoom_min) / p.pager.current_zoom;
} else if (zoomTest > p.reader.settings.zoom_max) {
distChange = p.reader.settings.zoom_max / p.pager.current_zoom;
}

pinchRelativeScale = distChange;
pinchCurrent = now;

$this.page_container.setStyle("padding", "{0}px".format($this.current_padding * (1 / pinchRelativeScale)));
$this.page_container.setStyle("height", "{0}px".format(pinchStartHeight));
$this.page_container.setStyle("width", "{0}px".format(pinchStartWidth));
$this.page_container.setStyle("transform", "scale({0})".format(pinchRelativeScale));
$this.page_container.setStyle("transition", "0.5s all".format(pinchRelativeScale));

}*/
},
onWheelEnd: function () {
/*if (!p.pager.touchBlocked)
if (p.reader.settings.enable_mousewheel_zoom) {
try {
var rect = $this.page_container.getRelativeBoundingClientRect();
//console.log("BEFORE", rect);
} catch (ex) {}

p.pager.setZoom(p.pager.current_zoom * pinchRelativeScale);
var scrollTop = Math.round(-rect.top),
scrollLeft = Math.round(-rect.left);
if ($this.current_mode == $this.constant.DOUBLE)
scrollLeft -= (rect.right - $this.page_container.getRelativeBoundingClientRect().right) / 2;

p.pager.adjust({
reload: true,
scroll: {
top: scrollTop,
left: scrollLeft
},
callback: function () {
if (rect) {
p.pager.content_container[0].scrollTop = scrollTop;
p.pager.content_container[0].scrollLeft = scrollLeft;

//console.log("AFTER", $this.page_container[0].getBoundingClientRect());

// I can't exactly figure out why we need to correct for the offset only in double sided mode
// the offset exists in single page mode too, but funnily enough it does not cause any problems there???
// I'm guessing it has something to do with "margin: 0 auto" and the way elements are centered?
//if ($this.current_mode == $this.constant.DOUBLE)
// p.pager.content_container[0].scrollLeft -= (rect.right - $this.page_container[0].getBoundingClientRect().right) / 2;
} else {
// Terrible fallback
p.pager.content_container[0].scrollLeft = (((pinchOffsetX * pinchRelativeScale)) - (($this.content_container.getWidth() / 2))) - $this.current_padding;
p.pager.content_container[0].scrollTop = (((pinchOffsetY * pinchRelativeScale)) - (($this.content_container.getHeight() / 2))) - $this.current_padding;
}
}
});
}*/
},

/// PINCH
onPinchStart: function (start) {
if (!p.pager.touchBlocked)
if (p.reader.settings.enable_pinching) {
pinchStartWidth = $this.page_container.getWidth();
pinchStartHeight = $this.page_container.getHeight();
pinchStart = start;
pinchStartFactor =
pinchStartWidth / $this.content_container.getWidth();
pinchOffsetX =
pinchStart.x + $this.content_container[0].scrollLeft;
pinchOffsetY =
pinchStart.y + $this.content_container[0].scrollTop;
pinchStartRect =
$this.page_container.getRelativeBoundingClientRect();

//console.log(pinchStart.x, pinchStart.y, $this.content_container[0].scrollLeft, $this.content_container[0].scrollTop);

// Very important to set this here!!!
// On mobile this is an insane performance drain, especially on android
$this.page_container.setStyle(
'transformOrigin',
'{0}px {1}px'.format(pinchOffsetX, pinchOffsetY)
);

//console.log("START", pinchStartRect);
}
},
onPinch: function (distDiff, distChange, now) {
if (!p.pager.touchBlocked)
if (p.reader.settings.enable_pinching) {
var zoomTest = p.pager.current_zoom * distChange;

if (
zoomTest >= p.pager.last_autozoom &&
zoomTest <= p.reader.settings.zoom_max
) {
pinchRelativeScale = distChange;
pinchCurrent = now;

/*$this.page_container.setStyle("padding", "{0}px".format($this.current_padding * (1 / pinchRelativeScale)));
$this.page_container.setStyle("height", "{0}px".format(pinchStartHeight));
$this.page_container.setStyle("width", "{0}px".format(pinchStartWidth));*/
$this.page_container.setStyle(
'transform',
'scale({0})'.format(pinchRelativeScale)
);
/*$this.page_container.setStyle("transition", "0.5s all".format(pinchRelativeScale));*/
}

//$this.page_container.setAttr("style",
// "padding: {0}px; width: {1}px; height: {2}px; transform: scale({3}); transform-origin: {4}px {5}px;"
// .format(
// $this.current_padding * (1 / pinchRelativeScale),
// pinchStartWidth,
// pinchStartHeight,
// pinchRelativeScale,
// pinchOffsetX,
// pinchOffsetY
// )
// );
//console.log("DURING", $this.page_container[0].getBoundingClientRect());
}
},
onPinchEnd: function () {
if (!p.pager.touchBlocked)
if (p.reader.settings.enable_pinching) {
try {
var rect =
$this.page_container.getRelativeBoundingClientRect();
//console.log("BEFORE", rect);
} catch (ex) {}

p.pager.setZoom(p.pager.current_zoom * pinchRelativeScale);
var scrollTop = Math.round(-rect.top),
scrollLeft = Math.round(-rect.left);
if ($this.current_mode == $this.constant.DOUBLE)
scrollLeft -=
(rect.right -
$this.page_container.getRelativeBoundingClientRect()
.right) /
2;

p.pager.adjust({
reload: true,
scroll: {
top: scrollTop,
left: scrollLeft,
},
callback: function () {
if (rect) {
p.pager.content_container[0].scrollTop = scrollTop;
p.pager.content_container[0].scrollLeft = scrollLeft;

//console.log("AFTER", $this.page_container[0].getBoundingClientRect());

// I can't exactly figure out why we need to correct for the offset only in double sided mode
// the offset exists in single page mode too, but funnily enough it does not cause any problems there???
// I'm guessing it has something to do with "margin: 0 auto" and the way elements are centered?
//if ($this.current_mode == $this.constant.DOUBLE)
// p.pager.content_container[0].scrollLeft -= (rect.right - $this.page_container[0].getBoundingClientRect().right) / 2;
} else {
// Terrible fallback
p.pager.content_container[0].scrollLeft =
pinchOffsetX * pinchRelativeScale -
$this.content_container.getWidth() / 2 -
$this.current_padding;
p.pager.content_container[0].scrollTop =
pinchOffsetY * pinchRelativeScale -
$this.content_container.getHeight() / 2 -
$this.current_padding;
}
},
});
}
},
});

this.is_mobile = p.browser.isMobile;

p.e(document).on('keyup', function (e) {
if (e.keyCode == 37) {
//left
if (p.reader.settings.enable_keyboard_navigation) {
if (p.pager.current_animator == null) {
ga('send', 'event', {
eventCategory: 'Web-Reader',
eventAction: 'Left Key',
eventLabel: 'clicked',
});
if (p.ads.showAds()) {
return false;
}
p.pager.goBack();
} else p.pager.current_animator.doFullAnimationPrev();
}
}

if (e.keyCode == 39) {
// right
if (p.reader.settings.enable_keyboard_navigation) {
if (p.pager.current_animator == null) {
ga('send', 'event', {
eventCategory: 'Web-Reader',
eventAction: 'Right Key',
eventLabel: 'clicked',
});
if (p.ads.showAds()) {
return false;
}
p.pager.goForward();
} else p.pager.current_animator.doFullAnimationNext();
}
}

if (e.keyCode == 107) {
// Plus +
//p.reader.zoomIn();
}

if (e.keyCode == 109) {
// Minus -
//p.reader.zoomOut();
}
});

var resizeTimeout = null;

p.pager.content_container.on('resize', function () {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(function () {
p.pager.invalidateContentContained();
p.pager.adjust();
}, 50);
});
this.adjust();

var lastPageSize = null;
for (var i in this.pages) {
if (lastPageSize != null)
if (
Math.abs(this.pages[i].ref_size.width - lastPageSize.width) >
20 ||
Math.abs(this.pages[i].ref_size.height - lastPageSize.height) >
20
) {
this.pages_uniform = false;
break;
}

lastPageSize = this.pages[i].ref_size;
}

//this.fixPageNumber(e);
this.ready_for_first_load = true;

this.current_page = p.reader.settings.start_page;
this.goToPage(this.current_page);
}
},

setAnimation: function (e, callback) {
var $this = p.pager,
CONST = $this.constant;

if (!$this.pages_uniform || $this.is_mobile) e = CONST.NONE;

p.pager.page_container.removeClass('flip fade swipe');

switch ($this.current_animation) {
case CONST.FLIP:
p.flip_animator.destruct();
break;

case CONST.FADE:
break;

case CONST.SWIPE:
p.swipe_animator.destruct();

break;
}

$this.current_animator = null;

switch (e) {
case CONST.FLIP:
$this.current_animation = CONST.FLIP;
p.reader.settings.preload = true;
p.flip_animator.init();
p.pager.page_container.addClass('flip');
$this.current_animator = p.flip_animator;
break;

case CONST.FADE:
$this.current_animation = CONST.FADE;
p.reader.settings.preload = true;
p.pager.page_container.addClass('fade');

break;

case CONST.SWIPE:
$this.current_animation = CONST.SWIPE;
p.reader.settings.preload = true;
p.swipe_animator.init();
p.pager.page_container.addClass('swipe');
$this.current_animator = p.swipe_animator;
break;

default:
$this.current_animation = CONST.NONE;
break;
}

$this.adjust({
reload: true,
callback: callback,
});
},

setZoom: function (e, dontFlipAutozoom) {
var clampedZoom = Math.min(
p.reader.settings.zoom_max,
Math.max(
p.reader.settings.zoom_min == 'auto'
? this.last_autozoom
: p.reader.settings.zoom_min,
e
)
);

this.current_zoom = clampedZoom;
p.PDFManager.scale = clampedZoom;

if (!dontFlipAutozoom) this.current_autozoom = false;

this.invalidateContentContained();
},
adjust: function (options) {
var $this = p.pager,
CONST = $this.constant,
callback = options ? options.callback : null,
reload = options ? options.reload : false;

//if ($this.current_animation == CONST.FLIP)
//{
// $this.page_container.addClass("effect3d");
//}
//else
//{
// $this.page_container.removeClass("effect3d");
//}

if (!$this.current_mode_manual) {
var calculatedMode = -1;

if (p.reader.container.getWidth() > p.reader.container.getHeight())
calculatedMode = CONST.DOUBLE;
else calculatedMode = CONST.SINGLE;

if (calculatedMode != -1 && calculatedMode != $this.current_mode) {
//console.log("Switching modes");
$this.current_mode = calculatedMode;

reload = true;
}
}

if ($this.current_mode == CONST.SINGLE && $this.current_page == 0)
$this.current_page = 1;

if (!$this.current_renderer_manual) {
var calculatedRenderer = -1;
if ($this.is_mobile || p.reader.settings.no_pdf) {
calculatedRenderer = CONST.IMG;
} else if (
!p.browser.isMobile /*&& $this.pdf_enabled */ &&
$this.pdf_loaded
) {
calculatedRenderer = CONST.PDF;
}
/*
else if (!p.browser.isMobile && !$this.pdf_enabled && !$this.pdf_checking && !$this.pdf_preparing)
{
$this.preparePdf();
}
*/
if (
calculatedRenderer != -1 &&
calculatedRenderer != $this.current_renderer
) {
//console.log("Switching Renderers");
$this.current_renderer = calculatedRenderer;
reload = true;
}
}

if ($this.current_autozoom) {
var calculatedZoom = $this.calculateAutozoom();
if (calculatedZoom != $this.current_zoom) {
//console.log("Switching Zoom");
$this.setZoom(calculatedZoom, true);
reload = true;
}
}

if (reload) {
$this.prepareElements();
if (options && options.scroll) {
p.pager.content_container[0].scrollLeft = options.scroll.left;
p.pager.content_container[0].scrollTop = options.scroll.top;
}
$this.goToPage($this.current_page, callback, options);
}
},

calculateAutozoom: function () {
var $this = p.pager,
CONST = $this.constant,
pageSize = $this.getPageSize($this.current_page_firstvalid, true),
available_space = {
width:
p.pager.content_container.getWidth() - $this.current_padding * 2,
height:
p.pager.content_container.getHeight() - $this.current_padding * 2,
},
required_space = {
width:
$this.current_mode == CONST.DOUBLE ||
$this.current_mode == CONST.DOUBLE_REVERSE
? pageSize.width * 2
: pageSize.width,
height: pageSize.height,
};

var scaleWidth = available_space.width / required_space.width,
scaleHeight = available_space.height / required_space.height;

//console.log("Scales", scaleWidth, scaleHeight, "Out scale:", scaleWidth > scaleHeight ? scaleHeight : scaleWidth);
$this.last_autozoom =
scaleWidth > scaleHeight ? scaleHeight : scaleWidth;
return $this.last_autozoom;
},

getFileName: function (page) {
let pageObj = this.pages[page];

//return p.md5("ECB042F43mynameismarypoppins" + page).toUpperCase();
return pageObj.page_content;
},
getFullPath: function (page) {
if (page == this.last_page_no) {
return 'last_page';
}
let svg = get_svg_name(this.getFileName(page)) || page + '.svg';
var full_path = file_path1 + this.getFileName(page) + '/' + svg;
return full_path;
},
getThumbPath: function (page) {
if (page == this.last_page_no) {
return 'https://d391aap0mzpb1y.cloudfront.net/web/assets/images/relArt_thumb.jpeg';
}
var tet_path = file_path1 + this.getFileName(page) + '/thumb.jpg';
return tet_path;
},
getPageSize: function (page, raw) {
if (this.pages[page]) {
let width = this.pages[page].ref_size.width;
let height = this.pages[page].ref_size.height;
let prop = width / height;
if (
page != 1 &&
(this.current_mode == this.constant.DOUBLE ||
this.current_mode == this.constant.DOUBLE_REVERSE)
) {
let p_no = page % 2 == 0 ? page : page - 1;
let left = this.pages[p_no];
let right = this.pages[p_no + 1];
if (
left &&
right &&
(Math.abs(left.ref_size.width - right.ref_size.width) > 20 ||
Math.abs(left.ref_size.height - right.ref_size.height) > 20)
) {
height = Math.max(left.ref_size.height, right.ref_size.height);
width = prop * height;
}
}
if (raw)
return {
width: width,
height: height,
};

return {
width: width * this.current_zoom,
height: height * this.current_zoom,
};
}

return {
width: 0,
height: 0,
};
},
prepareElements: function () {
var i,
CONST = this.constant;
//this.page_container.setAttr("style", "padding: {0}px;".format(this.current_padding));

if (this.holders.length == 0) {
var initialPageSize = this.getPageSize(1);
for (i = 0; i < 6; i++) {
this.holders[i] = p
.e('<div>', {
class: 'page',
})
.appendTo(this.page_container);
var wrapper = p
.e('<div>', {
class: 'wrapper',
})
.appendTo(this.holders[i]);

this.loaders[i] = p.reader.stageLoader().appendTo(wrapper);
p.e('<canvas>', {
class: 'loading',
}).appendTo(wrapper);

this.holders[i].setAttr(
'style',
'width: {0}px; height: {1}px;'.format(
initialPageSize.width,
initialPageSize.height
)
);
}
}

if (
this.current_mode == CONST.SINGLE ||
this.current_mode == CONST.SINGLE_REVERSE
) {
this.page_container.addClass('single').removeClass('double');
for (i = 0; i < 6; i++) {
this.holders[i].removeClass('previous next left right');
if (i == CONST.CUR)
this.holders[i].removeClass('hidden previous next');
else if (i == CONST.PREV)
this.holders[i].removeClass('next').addClass('hidden previous');
else if (i == CONST.NEXT)
this.holders[i].removeClass('previous').addClass('hidden next');
else
this.holders[i].addClass('hidden').removeClass('previous next');
}
} else if (
this.current_mode == CONST.DOUBLE ||
this.current_mode == CONST.DOUBLE_REVERSE
) {
this.page_container.addClass('double').removeClass('single');
for (i = 0; i < 6; i++) {
if (i == CONST.CUR_LEFT || i == CONST.CUR_RIGHT)
this.holders[i].removeClass('previous next');
else if (i == CONST.PREV_LEFT || i == CONST.PREV_RIGHT)
this.holders[i].removeClass('next').addClass('previous');
else if (i == CONST.NEXT_LEFT || i == CONST.NEXT_RIGHT)
this.holders[i].removeClass('previous').addClass('next');

if (
i ==
CONST.CUR_LEFT /*|| i == CONST.PREV_LEFT || i == CONST.NEXT_LEFT*/ &&
this.show_page_left
)
this.holders[i].removeClass('hidden');
else if (
i ==
CONST.CUR_RIGHT /*|| i == CONST.PREV_RIGHT || i == CONST.NEXT_RIGHT*/ &&
this.show_page_right
)
this.holders[i].removeClass('hidden');
else this.holders[i].addClass('hidden');

if (
i == CONST.CUR_LEFT ||
i == CONST.PREV_LEFT ||
i == CONST.NEXT_LEFT
)
this.holders[i].addClass('left').removeClass('right');
else if (
i == CONST.CUR_RIGHT ||
i == CONST.PREV_RIGHT ||
i == CONST.NEXT_RIGHT
)
this.holders[i].addClass('right').removeClass('left');
else this.holders[i].removeClass('left right');

/////////
//if (i == CONST.CUR_LEFT && this.show_page_left || i == CONST.CUR_RIGHT && this.show_page_right)
//{
// this.holders[i].removeClass("hidden");
// if (i == CONST.CUR_LEFT)
// this.holders[i].addClass("left");
// else
// this.holders[i].addClass("right");
//}
//else
// this.holders[i].addClass("hidden");
}
}
},
/*preparePdf: function ()
{
if (!this.pdf_checked && !this.pdf_checking)
{
this.pdf_checking = true;
p.net.request(this.getPDFPath(),
{
method: "HEAD",
finished: function (success, data)
{
p.pager.pdf_exists = success;
p.pager.pdf_checked = true;
p.pager.pdf_checking = false;

if (success)
{
p.pager.pdf_preparing = true;
p.pager.preparePdfJs();
}
else
{
p.pager.pdf_preparing = false;
p.reader.setProgress("error");
}
}
});
}
},*/
/*preparePdfJs: function ()
{
var scriptTags = p.e("script");
var currentScript = null;
scriptTags.each(function ()
{
if (this.src.contains("magalone."))
{
currentScript = this.src;
return false;
}
});

if (currentScript != null)
{
p.pager.current_script = currentScript;

p.pager.loadPdfJsCompat(function ()
{
p.pager.loadPdfJsMain(function ()
{
p.pager.pdf_preparing = false;
p.pager.pdf_enabled = true;
p.PDFManager.setOnDocumentLoadHandler(p.pager.pdfJsOnLoad);
p.PDFManager.setOnDocumentProgressHandler(p.pager.pdfJsOnProgress);
p.PDFManager.setOnPageLoadHandler(p.pager.pdfJsOnPage);
p.PDFManager.setOnPageRenderHandler(p.pager.pdfJsOnRender);
p.PDFManager.loadFile(p.pager.getPDFPath());
});
});
}
},

loadPdfJsCompat: function (callback)
{
var currentPath = p.pager.current_script.substr(0, p.pager.current_script.lastIndexOf("/"));
var pdfJsPath = currentPath + "/pdfjs/compatibility" + (p.pager.current_script.contains(".min") ? ".min" : "") + ".js";

var pdfJsScriptElement = document.createElement("script");
var pdfJsLoaded = false;
pdfJsScriptElement.onload = function ()
{
if (!pdfJsLoaded)
{
callback();
}

pdfJsLoaded = true;
};
pdfJsScriptElement.setAttribute("src", pdfJsPath);
document.getElementsByTagName('head')[0].appendChild(pdfJsScriptElement);
},
loadPdfJsMain: function (callback)
{
var currentPath = p.pager.current_script.substr(0, p.pager.current_script.lastIndexOf("/"));
var pdfJsPath = currentPath + "/pdfjs/pdf" + (p.pager.current_script.contains(".min") ? ".min" : "") + ".js";

var pdfJsScriptElement = document.createElement("script");
var pdfJsLoaded = false;
pdfJsScriptElement.onload = function ()
{
if (!pdfJsLoaded)
{
callback();
}

pdfJsLoaded = true;
};
pdfJsScriptElement.setAttribute("src", pdfJsPath);
document.getElementsByTagName('head')[0].appendChild(pdfJsScriptElement);
},*/

goBack: function (callback, onReady) {
var $this = p.pager,
CONST = $this.constant;

switch ($this.current_mode) {
case CONST.SINGLE:
if ($this.current_page <= 1) return;

$this.current_page--;
break;
case CONST.SINGLE_REVERSE:
break;

case CONST.DOUBLE:
if ($this.current_page == 0) return;

$this.current_page -= 2;
break;
case CONST.DOUBLE_REVERSE:
break;
}

$this.goToPage($this.current_page, callback, {
onReady: onReady,
});
},
goForward: function (callback, onReady) {
var $this = p.pager,
CONST = $this.constant;

switch ($this.current_mode) {
case CONST.SINGLE:
if ($this.current_page >= $this.page_count) return;

$this.current_page++;
break;
case CONST.SINGLE_REVERSE:
break;

case CONST.DOUBLE:
if (
$this.current_page_left >= $this.page_count ||
$this.current_page_right >= $this.page_count
)
return;

$this.current_page += 2;
break;
case CONST.DOUBLE_REVERSE:
break;
}

$this.goToPage($this.current_page, callback, {
onReady: onReady,
});
},

/// Rendering
goToPage: function (e, callback, options) {
var CONST = this.constant;

// Method to call page-stream
if (
this.current_page > 0 &&
this.current_page_temp != this.current_page
) {
this.current_page_temp = this.current_page;
let page = p.pager.pages[this.current_page];

clearTimeout(this.page_stream);
let pos = 1;
let page_no = page.page_content;
if (this.current_mode == CONST.DOUBLE) {
pos = 2;
page_no = [];
if (this.current_page_left > 0) {
let page = p.pager.pages[this.current_page_left];
page_no.push(page.page_content);
}

if (
this.current_page_right <= this.page_count &&
this.current_page_right != this.last_page_no
) {
let page = p.pager.pages[this.current_page_right];
page_no.push(page.page_content);
}
page_no = page_no.join(',');
}
// let pos = (this.current_mode == CONST.DOUBLE) ? 'l' : 'p';
this.page_stream = setTimeout(function () {
trackPage(page_no, pos);
}, 1000);
var lstPage = this.last_page;
if (this.current_page == lstPage - 1) {
$('#reader-container .content .pages').addClass('last');
} else {
$('#reader-container .content .pages').removeClass('last');
}
}

p.reader.overview.scrollToCurrentPage();
this.renderStop();
//console.trace("Render", callback, options);
//debugger;
if (
this.current_mode == CONST.SINGLE ||
this.current_mode == CONST.SINGLE_REVERSE
) {
this.renderSingle(callback, options);

if (p.reader.settings.enable_arrows) {
if (this.current_page <= 1)
p.e('.ctrl.btn.go-back').addClass('gone');
else p.e('.ctrl.btn.go-back').removeClass('gone');

if (this.current_page >= this.page_count)
p.e('.ctrl.btn.go-fwd').addClass('gone');
else p.e('.ctrl.btn.go-fwd').removeClass('gone');
if (this.current_page > 0) {
location.href = '#page/' + this.current_page;
}
}
} else if (this.current_mode == CONST.DOUBLE) {
this.renderDouble(callback, options);
if (p.reader.settings.enable_arrows) {
if (this.current_page_left == 0)
p.e('.ctrl.btn.go-back').addClass('gone');
else p.e('.ctrl.btn.go-back').removeClass('gone');

if (
this.current_page_left == this.page_count ||
this.current_page_right == this.page_count
)
p.e('.ctrl.btn.go-fwd').addClass('gone');
else p.e('.ctrl.btn.go-fwd').removeClass('gone');
if (this.current_page > 0) {
location.href = '#page/' + this.current_page;
}
}
}
p.overlays.render();
},

checkAndCallback: function checkAndCallback(cb) {
if (cb && p.is.function(cb)) {
//console.trace("Calling");
cb();
} else {
//console.trace("Not Calling");
}
},

renderStop: function () {
p.PDFQueue.reset();
clearTimeout(this.renderTimeout);
},
renderInstance: 0,
renderTimeout: null,
renderWaitingTime: 2000,
renderSingleSelf: function RENDERER_SinglePage_GenerateSelfVariables(
callback
) {
var self = {};
(self.callback = callback),
(self.this = p.pager),
(self.iid = ++self.this.renderInstance),
(self.CONST = self.this.constant),
(self.scrollPerformed = false),
(self.cur = self.this.current_page_firstvalid),
(self.next = self.this.current_page_firstvalid + 1),
(self.prev = self.this.current_page_firstvalid - 1),
(self.pageSize = self.this.getPageSize(self.cur)),
(self.pageSizeNext = self.this.getPageSize(self.next)),
(self.pageSizePrev = self.this.getPageSize(self.prev)),
(self.canvas = self.this.holders[self.CONST.CUR].find('canvas')),
(self.canvasNext = self.this.holders[self.CONST.NEXT].find('canvas')),
(self.canvasPrev = self.this.holders[self.CONST.PREV].find('canvas')),
(self.containerWidth =
self.pageSize.width + self.this.current_padding * 2),
(self.containerHeight =
self.pageSize.height + self.this.current_padding * 2),
(self.readjust =
Math.round(self.containerHeight) !=
Math.round(self.this.page_container.getHeight()) ||
Math.round(self.containerWidth) !=
Math.round(self.this.page_container.getWidth()));
return self;
},
renderSingle: function RENDERER_SinglePage_Main(callback, options) {
var self = p.pager.renderSingleSelf(callback);
if (self.readjust && options && options.adjusted) self.readjust = false;
if (self.readjust) {
self.this.page_container.setAttr(
'style',
'padding: {0}px; width: {1}px; height: {2}px;'.format(
self.this.current_padding,
self.containerWidth,
self.containerHeight
)
);

if (options && options.scroll && self.scrollPerformed == false) {
self.scrollPerformed = true;
p.pager.content_container[0].scrollLeft = options.scroll.left;
p.pager.content_container[0].scrollTop = options.scroll.top;
}

var fixedoptions = p.is.object(options) ? options : {};
p.extend(fixedoptions, {
reload: true,
callback: callback,
adjusted: true,
});
return setTimeout(function () {
p.pager.adjust(fixedoptions);
}, 1);
}

var onRenderedPerformed = false,
onReadyPerformed = false;

var onRendered =
function RENDERER_SinglePage_Main_onRenderedCallback() {
if (!onRenderedPerformed) {
onRenderedPerformed = true;

if (self.this.ready_for_first_load && !self.this.first_load_done)
self.this.onFirstLoad();

self.this.checkAndCallback(self.callback);
setTimeout(function () {
self.this.prerenderSingleClean(self);
}, 100);
}
};
var onReady = function RENDERER_SinglePage_Main_onReadyCallback() {
if (!onReadyPerformed && !onRenderedPerformed) {
onReadyPerformed = true;

if (options && options.scroll && self.scrollPerformed == false) {
self.scrollPerformed = true;
p.pager.content_container[0].scrollLeft = options.scroll.left;
p.pager.content_container[0].scrollTop = options.scroll.top;
}

//self.this.prepareElements();
setTimeout(function () {
if (options && options.onReady && p.is.function(options.onReady))
options.onReady();
self.this.prerenderSingleDirty(self);
}, 100);
}
};

if (self.this.current_renderer == self.CONST.IMG) {
self.this.renderSingleImg(self, onReady, onRendered, options);
} else if (self.this.current_renderer == self.CONST.PDF) {
self.canvas.addClass('loading');
self.this.renderSinglePdf(self, onReady, onRendered, options);
}
},
renderSingleImg: function RENDERER_SinglePage_Image(
self,
onReady,
onFinished,
options
) {
var readyPerformed = false,
finalPerformed = false;
self.this.holders[self.CONST.CUR].setAttr(
'style',
'width: {0}px; height: {1}px;'.format(
self.pageSize.width,
self.pageSize.height
)
);
self.this.loaders[self.CONST.CUR].setAttr('style', '');
self.this.loaders[self.CONST.CUR].load(
[self.this.getThumbPath(self.cur)],
function RENDERER_SinglePage_Image_ReadyRender() {
if (!readyPerformed) {
readyPerformed = true;
self.this.checkAndCallback(onReady);

setTimeout(function () {
self.this.loaders[self.CONST.CUR].load(
[
self.this.getThumbPath(self.cur),
self.this.getFullPath(self.cur),
],
function RENDERER_SinglePage_Image_FinalRender() {
if (!finalPerformed) {
finalPerformed = true;
self.this.checkAndCallback(onFinished);
}
}
);
}, 1);
}
},
true
);
},
renderSinglePdf: function RENDERER_SinglePage_PDF(
self,
onReady,
onFinished,
options
) {
var readyPerformed = false,
finalPerformed = false;
self.this.loaders[self.CONST.CUR].setAttr('style', '');
self.this.loaders[self.CONST.CUR].load(
[self.this.getFullPath(self.cur)],
function RENDERER_SinglePage_PDF_ReadyRender() {
self.this.holders[self.CONST.CUR].setAttr(
'style',
'width: {0}px; height: {1}px;'.format(
self.pageSize.width,
self.pageSize.height
)
);
if (!readyPerformed) {
readyPerformed = true;
self.this.checkAndCallback(onReady);
self.this.checkAndCallback(onFinished);

self.this.renderTimeout = setTimeout(function () {
p.PDFQueue.push(
self.canvas,
self.cur,
function RENDERER_SinglePage_PDF_FinalRender() {
if (!finalPerformed) {
finalPerformed = true;
self.canvas.removeClass('loading');
//self.this.checkAndCallback(onFinished);
}
}
);
p.PDFQueue.start();
}, self.this.renderWaitingTime);
}
},
true
);
},
prerenderSingleDirty: function RENDERER_SinglePage_Prerender_Dirty(
self,
callback
) {
self.this.holders[self.CONST.NEXT].setAttr(
'style',
'width: {0}px; height: {1}px;'.format(
self.pageSizeNext.width,
self.pageSizeNext.height
)
);
self.this.holders[self.CONST.PREV].setAttr(
'style',
'width: {0}px; height: {1}px;'.format(
self.pageSizePrev.width,
self.pageSizePrev.height
)
);
p.e([self.canvasNext, self.canvasPrev]).addClass('loading');

var counter = 0;
var target =
self.this.showPage(self.next) + self.this.showPage(self.prev);
var waitAndCallback =
function RENDERER_SinglePage_Prerender_Dirty_Waiter() {
if (++counter == target) self.this.checkAndCallback(callback);
};

if (self.this.showPage(self.next))
self.this.loaders[self.CONST.NEXT].load(
[self.this.getThumbPath(self.next)],
waitAndCallback
);
if (self.this.showPage(self.prev))
self.this.loaders[self.CONST.PREV].load(
[self.this.getThumbPath(self.prev)],
waitAndCallback
);
},
prerenderSingleClean: function RENDERER_SinglePage_Prerender_Clean(
self,
callback
) {
self.this.holders[self.CONST.NEXT].setAttr(
'style',
'width: {0}px; height: {1}px;'.format(
self.pageSizeNext.width,
self.pageSizeNext.height
)
);
self.this.holders[self.CONST.PREV].setAttr(
'style',
'width: {0}px; height: {1}px;'.format(
self.pageSizePrev.width,
self.pageSizePrev.height
)
);
p.e([self.canvasNext, self.canvasPrev]).addClass('loading');

var counter = 0;
var target =
self.this.showPage(self.next) + self.this.showPage(self.prev);
var waitAndCallback =
function RENDERER_SinglePage_Prerender_Clean_Waiter() {
if (++counter == target) self.this.checkAndCallback(callback);
};

//if (self.this.current_renderer == self.CONST.IMG)
//{
if (self.this.showPage(self.next))
self.this.loaders[self.CONST.NEXT].load(
[
self.this.getThumbPath(self.next),
self.this.getFullPath(self.next),
],
waitAndCallback
);
if (self.this.showPage(self.prev))
self.this.loaders[self.CONST.PREV].load(
[
self.this.getThumbPath(self.prev),
self.this.getFullPath(self.prev),
],
waitAndCallback
);
//}
//else if (self.this.current_renderer == self.CONST.PDF)
//{
// if (self.this.showPage(self.next))
// p.PDFQueue.push(self.canvasNext, self.next, function RENDERER_SinglePage_Prerender_Clean_PDFNext_Done() { self.canvasNext.removeClass("loading"), waitAndCallback(); }, true);
// if (self.this.showPage(self.prev))
// p.PDFQueue.push(self.canvasPrev, self.prev, function RENDERER_SinglePage_Prerender_Clean_PDFPrev_Done() { self.canvasPrev.removeClass("loading"), waitAndCallback(); }, true);
// p.PDFQueue.start();
//}
},

renderDoubleSelf: function RENDERER_DoublePage_GenerateSelfVariables(
callback
) {
var self = {};
(self.callback = callback),
(self.this = p.pager),
(self.iid = ++self.this.renderInstance),
(self.CONST = self.this.constant),
(self.scrollPerformed = false),
(self.pageSizeLeft = self.this.getPageSize(
self.this.current_page_left
)),
(self.pageSizeRight = self.this.getPageSize(
self.this.current_page_right
)),
(self.pageSizePrevLeft = self.this.getPageSize(
self.this.current_page_left - 2
)),
(self.pageSizePrevRight = self.this.getPageSize(
self.this.current_page_right - 2
)),
(self.pageSizeNextLeft = self.this.getPageSize(
self.this.current_page_left + 2
)),
(self.pageSizeNextRight = self.this.getPageSize(
self.this.current_page_right + 2
)),
(self.canvasLeft =
self.this.holders[self.CONST.CUR_LEFT].find('canvas')),
(self.canvasRight =
self.this.holders[self.CONST.CUR_RIGHT].find('canvas')),
(self.canvasNextLeft =
self.this.holders[self.CONST.NEXT_LEFT].find('canvas')),
(self.canvasNextRight =
self.this.holders[self.CONST.NEXT_RIGHT].find('canvas')),
(self.canvasPrevLeft =
self.this.holders[self.CONST.PREV_LEFT].find('canvas')),
(self.canvasPrevRight =
self.this.holders[self.CONST.PREV_RIGHT].find('canvas')),
(self.left = self.this.current_page_left),
(self.right = self.this.current_page_right),
(self.nextLeft = self.this.current_page_left + 2),
(self.nextRight = self.this.current_page_right + 2),
(self.prevLeft = self.this.current_page_left - 2),
(self.prevRight = self.this.current_page_right - 2),
(self.containerWidth =
(self.pageSizeLeft.width > self.pageSizeRight.width
? self.pageSizeLeft.width * 2
: self.pageSizeRight.width * 2) +
self.this.current_padding * 2),
(self.containerHeight =
(self.pageSizeLeft.height > self.pageSizeRight.height
? self.pageSizeLeft.height
: self.pageSizeRight.height) +
self.this.current_padding * 2),
(self.readjust =
Math.round(self.containerHeight) !=
Math.round(self.this.page_container.getHeight()) ||
Math.round(self.containerWidth) !=
Math.round(self.this.page_container.getWidth()));

return self;
},
renderDouble: function RENDERER_DoublePage_Main(callback, options) {
var self = p.pager.renderDoubleSelf(callback);

if (self.readjust && options && options.adjusted) self.readjust = false;

if (self.readjust) {
self.this.page_container.setAttr(
'style',
'padding: {0}px; width: {1}px; height: {2}px;'.format(
self.this.current_padding,
self.containerWidth,
self.containerHeight
)
);

if (options && options.scroll && self.scrollPerformed == false) {
self.scrollPerformed = true;
p.pager.content_container[0].scrollLeft = options.scroll.left;
p.pager.content_container[0].scrollTop = options.scroll.top;
}

var fixedoptions = p.is.object(options) ? options : {};
p.extend(fixedoptions, {
reload: true,
callback: callback,
adjusted: true,
});
return setTimeout(function () {
p.pager.adjust(fixedoptions);
}, 1);
}

var onRenderedPerformed = false,
onReadyPerformed = false;

var onRendered =
function RENDERER_DoublePage_Main_onRenderedCallback() {
if (!onRenderedPerformed) {
onRenderedPerformed = true;

if (self.this.ready_for_first_load && !self.this.first_load_done)
self.this.onFirstLoad();

self.this.checkAndCallback(self.callback);
setTimeout(function () {
self.this.prerenderDoubleClean(self);
}, 100);
}
};
var onReady = function RENDERER_DoublePage_Main_onReadyCallback() {
if (!onReadyPerformed && !onRenderedPerformed) {
onReadyPerformed = true;

if (options && options.scroll && self.scrollPerformed == false) {
self.scrollPerformed = true;
p.pager.content_container[0].scrollLeft = options.scroll.left;
p.pager.content_container[0].scrollTop = options.scroll.top;
}

//self.this.prepareElements();
setTimeout(function () {
if (options && options.onReady && p.is.function(options.onReady))
options.onReady();
self.this.prerenderDoubleDirty(self);
}, 100);
}
};

if (self.this.current_renderer == self.CONST.IMG) {
self.this.renderDoubleImg(self, onReady, onRendered, options);
} else if (self.this.current_renderer == self.CONST.PDF) {
p.e([
self.canvasLeft,
self.canvasRight,
self.canvasNextLeft,
self.canvasNextRight,
self.canvasPrevLeft,
self.canvasPrevRight,
]).addClass('loading');
self.this.renderDoublePdf(self, onReady, onRendered, options);
}
},
renderDoubleImg: function RENDERER_DoublePage_Image(
self,
onReady,
onFinished,
options
) {
var readyPerformed = false,
finalPerformed = false,
targetReady =
self.this.showPage(self.left) + self.this.showPage(self.right),
counterReady = 0,
targetFinish = targetReady,
counterFinish = 0;
var waitReady = function RENDERER_DoublePage_Image_Ready_Waiter() {
if (++counterReady == targetReady) {
readyPerformed = true;
self.this.checkAndCallback(onReady);
}
};
var waitFinish = function RENDERER_DoublePage_Image_Finish_Waiter() {
if (++counterFinish == targetFinish) {
finalPerformed = true;
self.this.checkAndCallback(onFinished);
}
};
var performFinalRender = function () {
setTimeout(function () {
if (self.this.show_page_left) {
self.this.loaders[self.CONST.CUR_LEFT].load(
[
self.this.getThumbPath(self.left),
self.this.getFullPath(self.left),
],
function RENDERER_DoublePage_Image_FinalRender_Left() {
if (!finalPerformed) {
waitFinish();
}
}
);
}
if (self.this.show_page_right) {
self.this.loaders[self.CONST.CUR_RIGHT].load(
[
self.this.getThumbPath(self.right),
self.this.getFullPath(self.right),
],
function RENDERER_DoublePage_Image_FinalRender_Right() {
if (!finalPerformed) {
waitFinish();
}
}
);
}
}, 1);
};

if (self.this.show_page_left) {
self.this.holders[self.CONST.CUR_LEFT].removeClass('hidden');
self.this.holders[self.CONST.CUR_LEFT].setAttr(
'style',
'width: {0}px; height: {1}px;'.format(
self.pageSizeLeft.width,
self.pageSizeLeft.height
)
);
self.this.loaders[self.CONST.CUR_LEFT].setAttr('style', '');
self.this.loaders[self.CONST.CUR_LEFT].load(
[self.this.getThumbPath(self.left)],
function RENDERER_DoublePage_Image_ReadyRender() {
if (!readyPerformed) {
waitReady();

if (readyPerformed) {
performFinalRender();
}
}
},
true
);
} else {
self.this.holders[self.CONST.CUR_LEFT].addClass('hidden');
}
if (self.this.show_page_right) {
self.this.holders[self.CONST.CUR_RIGHT].removeClass('hidden');
self.this.holders[self.CONST.CUR_RIGHT].setAttr(
'style',
'width: {0}px; height: {1}px;'.format(
self.pageSizeRight.width,
self.pageSizeRight.height
)
);
self.this.loaders[self.CONST.CUR_RIGHT].setAttr('style', '');
self.this.loaders[self.CONST.CUR_RIGHT].load(
[self.this.getThumbPath(self.right)],
function RENDERER_DoublePage_Image_ReadyRender() {
if (!readyPerformed) {
waitReady();

if (readyPerformed) {
performFinalRender();
}
}
},
true
);
} else {
self.this.holders[self.CONST.CUR_RIGHT].addClass('hidden');
}
},
renderDoublePdf: function RENDERER_DoublePage_PDF(
self,
onReady,
onFinished,
options
) {
var readyPerformed = false,
hiresPerformed = false,
finalPerformed = false,
targetReady =
self.this.showPage(self.left) + self.this.showPage(self.right),
targetFinish = targetReady,
counterReady = 0,
counterFinish = 0;
var waitReady = function RENDERER_DoublePage_PDF_Ready_Waiter() {
if (++counterReady == targetReady) {
readyPerformed = true;
self.this.checkAndCallback(onReady);
self.this.checkAndCallback(onFinished);
}
};
var waitFinish = function RENDERER_DoublePage_PDF_Finish_Waiter() {
if (++counterFinish == targetFinish) {
finalPerformed = true;
//self.this.checkAndCallback(onFinished);
}
};

var performFinalRender = function () {
self.this.renderTimeout = setTimeout(function () {
if (self.this.show_page_left) {
p.PDFQueue.push(
self.canvasLeft,
self.left,
function RENDERER_DoublePage_PDF_FinalRender_Left() {
self.canvasLeft.removeClass('loading');
if (!finalPerformed) {
waitFinish();
}
}
);
}
if (self.this.show_page_right) {
p.PDFQueue.push(
self.canvasRight,
self.right,
function RENDERER_DoublePage_PDF_FinalRender_Right() {
self.canvasRight.removeClass('loading');
if (!finalPerformed) {
waitFinish();
}
}
);
}
p.PDFQueue.start();
}, self.this.renderWaitingTime);
};

if (self.this.show_page_left) {
self.this.holders[self.CONST.CUR_LEFT].removeClass('hidden');
self.this.holders[self.CONST.CUR_LEFT].setAttr(
'style',
'width: {0}px; height: {1}px;'.format(
self.pageSizeLeft.width,
self.pageSizeLeft.height
)
);
self.this.loaders[self.CONST.CUR_LEFT].setAttr('style', '');
self.this.loaders[self.CONST.CUR_LEFT].load(
[self.this.getFullPath(self.left)],
function RENDERER_DoublePage_PDF_ReadyRender() {
if (!readyPerformed) {
waitReady();

if (readyPerformed) {
performFinalRender();
}
}
},
true
);
} else {
self.this.holders[self.CONST.CUR_LEFT].addClass('hidden');
}
if (self.this.show_page_right) {
self.this.holders[self.CONST.CUR_RIGHT].removeClass('hidden');
self.this.holders[self.CONST.CUR_RIGHT].setAttr(
'style',
'width: {0}px; height: {1}px;'.format(
self.pageSizeRight.width,
self.pageSizeRight.height
)
);
self.this.loaders[self.CONST.CUR_RIGHT].setAttr('style', '');
self.this.loaders[self.CONST.CUR_RIGHT].load(
[self.this.getFullPath(self.right)],
function RENDERER_DoublePage_PDF_ReadyRender() {
if (!readyPerformed) {
waitReady();

if (readyPerformed) {
performFinalRender();
}
}
},
true
);
} else {
self.this.holders[self.CONST.CUR_RIGHT].addClass('hidden');
}
},
prerenderDoubleDirty: function RENDERER_DoublePage_Prerender_Dirty(
self,
callback
) {
self.this.holders[self.CONST.NEXT_LEFT].setAttr(
'style',
'width: {0}px; height: {1}px;'.format(
self.pageSizeNextLeft.width,
self.pageSizeNextLeft.height
)
);
self.this.holders[self.CONST.NEXT_RIGHT].setAttr(
'style',
'width: {0}px; height: {1}px;'.format(
self.pageSizeNextRight.width,
self.pageSizeNextRight.height
)
);

self.this.holders[self.CONST.PREV_LEFT].setAttr(
'style',
'width: {0}px; height: {1}px;'.format(
self.pageSizePrevLeft.width,
self.pageSizePrevLeft.height
)
);
self.this.holders[self.CONST.PREV_RIGHT].setAttr(
'style',
'width: {0}px; height: {1}px;'.format(
self.pageSizePrevRight.width,
self.pageSizePrevRight.height
)
);

p.e([
self.canvasNextLeft,
self.canvasNextRight,
self.canvasPrevLeft,
self.canvasPrevRight,
]).addClass('loading');

var counter = 0;
var target =
self.this.showPage(self.nextLeft) +
self.this.showPage(self.nextRight) +
self.this.showPage(self.prevLeft) +
self.this.showPage(self.prevRight);
var waitAndCallback =
function RENDERER_DoublePage_Prerender_Dirty_Waiter() {
if (++counter == target) self.this.checkAndCallback(callback);
};

if (self.this.showPage(self.nextLeft)) {
self.this.loaders[self.CONST.NEXT_LEFT].load(
[self.this.getThumbPath(self.nextLeft)],
waitAndCallback
);
}

if (self.this.showPage(self.nextRight)) {
self.this.loaders[self.CONST.NEXT_RIGHT].load(
[self.this.getThumbPath(self.nextRight)],
waitAndCallback
);
}

if (self.this.showPage(self.prevLeft)) {
self.this.loaders[self.CONST.PREV_LEFT].load(
[self.this.getThumbPath(self.prevLeft)],
waitAndCallback
);
}

if (self.this.showPage(self.prevRight)) {
self.this.loaders[self.CONST.PREV_RIGHT].load(
[self.this.getThumbPath(self.prevRight)],
waitAndCallback
);
}
},
prerenderDoubleClean: function RENDERER_DoublePage_Prerender_Clean(
self,
callback
) {
self.this.holders[self.CONST.NEXT_LEFT].setAttr(
'style',
'width: {0}px; height: {1}px;'.format(
self.pageSizeNextLeft.width,
self.pageSizeNextLeft.height
)
);
self.this.holders[self.CONST.NEXT_RIGHT].setAttr(
'style',
'width: {0}px; height: {1}px;'.format(
self.pageSizeNextRight.width,
self.pageSizeNextRight.height
)
);

self.this.holders[self.CONST.PREV_LEFT].setAttr(
'style',
'width: {0}px; height: {1}px;'.format(
self.pageSizePrevLeft.width,
self.pageSizePrevLeft.height
)
);
self.this.holders[self.CONST.PREV_RIGHT].setAttr(
'style',
'width: {0}px; height: {1}px;'.format(
self.pageSizePrevRight.width,
self.pageSizePrevRight.height
)
);

p.e([
self.canvasNextLeft,
self.canvasNextRight,
self.canvasPrevLeft,
self.canvasPrevRight,
]).addClass('loading');

var counter = 0;
var target =
self.this.showPage(self.nextLeft) +
self.this.showPage(self.nextRight) +
self.this.showPage(self.prevLeft) +
self.this.showPage(self.prevRight);
var waitAndCallback =
function RENDERER_DoublePage_Prerender_Clean_Waiter() {
if (++counter == target) self.this.checkAndCallback(callback);
};

//if (self.this.current_renderer == self.CONST.IMG)
//{
if (self.this.showPage(self.nextLeft)) {
self.this.loaders[self.CONST.NEXT_LEFT].load(
[
self.this.getThumbPath(self.nextLeft),
self.this.getFullPath(self.nextLeft),
],
waitAndCallback
);
}

if (self.this.showPage(self.nextRight)) {
self.this.loaders[self.CONST.NEXT_RIGHT].load(
[
self.this.getThumbPath(self.nextRight),
self.this.getFullPath(self.nextRight),
],
waitAndCallback
);
}

if (self.this.showPage(self.prevLeft)) {
self.this.loaders[self.CONST.PREV_LEFT].load(
[
self.this.getThumbPath(self.prevLeft),
self.this.getFullPath(self.prevLeft),
],
waitAndCallback
);
}

if (self.this.showPage(self.prevRight)) {
self.this.loaders[self.CONST.PREV_RIGHT].load(
[
self.this.getThumbPath(self.prevRight),
self.this.getFullPath(self.prevRight),
],
waitAndCallback
);
}
//}
//else if (self.this.current_renderer == self.CONST.PDF)
//{
// if (self.this.showPage(self.nextLeft))
// p.PDFQueue.push(self.canvasNextLeft, self.nextLeft, function RENDERER_DoublePage_Prerender_Clean_PDFNextLeft_Done() { self.canvasNextLeft.removeClass("loading"), waitAndCallback(); }, true);
// if (self.this.showPage(self.nextRight))
// p.PDFQueue.push(self.canvasNextRight, self.nextRight, function RENDERER_DoublePage_Prerender_Clean_PDFNextRight_Done() { self.canvasNextRight.removeClass("loading"), waitAndCallback(); }, true);

// if (self.this.showPage(self.prevLeft))
// p.PDFQueue.push(self.canvasPrevLeft, self.prevLeft, function RENDERER_DoublePage_Prerender_Clean_PDFPrevLeft_Done() { self.canvasPrevLeft.removeClass("loading"), waitAndCallback(); }, true);
// if (self.this.showPage(self.prevRight))
// p.PDFQueue.push(self.canvasPrevRight, self.prevRight, function RENDERER_DoublePage_Prerender_Clean_PDFPrevRight_Done() { self.canvasPrevRight.removeClass("loading"), waitAndCallback(); }, true);

// p.PDFQueue.start();
//}
},

pdfJsOnLoad: function (e) {
p.pager.pdf_loaded_load = true;

p.pager.pdf_loaded =
p.pager.pdf_loaded_load && p.pager.pdf_loaded_progess;
if (p.pager.pdf_loaded) {
p.pager.adjust();
}
},
pdfJsOnProgress: function (e) {
var perc = p.math.Percentage.XofY(e.loaded, e.total);
p.reader.setProgress(perc);
if (perc >= 100) {
p.pager.pdf_loaded_progess = true;

p.pager.pdf_loaded =
p.pager.pdf_loaded_load && p.pager.pdf_loaded_progess;
if (p.pager.pdf_loaded) {
p.pager.adjust();
}
}
},
pdfJsOnPage: function (e) {
//console.log(e);
},
pdfJsOnRender: function (e) {
//console.log(e);
},
},

TouchHandler: function (on, options) {
var SWIPE_THRESHOLD = options.swipeThreshold || 125;
var MOVE_THRESHOLD = options.moveThreshold || 10;
var SWIPE_CANCEL = options.swipeCancel || 70;
var DOUBLETAP_CANCEL = options.doubleTapCancel || 200;
var WHEEL_CANCEL = options.wheelCancel || 500;
var WHEEL_TICK = options.wheelTick || 1;
var DIR_LEFT = 1;
var DIR_RIGHT = -1;
var PROPAGATE = true;

var mStartPoint,
mEndPoint,
mLastTouch,
mIsTouch,
mDirection,
mDeviation,
mDistance,
mDragging,
mSwiping,
mPinching,
mWaitingForDoubleTap,
mDoubleTapTimeout,
mOptimized,
mZoomTimeout,
mZooming,
mCumulZoom = WHEEL_TICK,
mLastSrc;

mOptimized = mPinching = mDragging = mSwiping = mZooming = false;

var target = p.e(on);
//console.log("Touch handler on", target);

var sign = function (e) {
return e < 0 ? -1 : 1;
};

var isContained = function () {
//var res = target[0].scrollHeight <= target.getHeight() || target[0].scrollWidth <= target.getWidth();
//if (!res)
// console.log(target[0].scrollHeight, target.getHeight(), target[0].scrollWidth, target.getWidth());

return (
target[0].scrollHeight <= target.getHeight() + 30 &&
target[0].scrollWidth <= target.getWidth()
);
};

var fncDoubleTapCheck = function (e) {
if (e.type == 'mouseleave') return;

var src = p.e(e.srcElement);
if (!src.getParents().hasClass('ctrl')) {
if (mWaitingForDoubleTap) {
mWaitingForDoubleTap = false;
clearTimeout(mDoubleTapTimeout);
if (
src.getAttr('id') == mLastSrc.getAttr('id') &&
src.getAttr('class') == mLastSrc.getAttr('class')
) {
//debugger;
if (options.onDoubleTap && p.is.function(options.onDoubleTap)) {
//debugger;
options.onDoubleTap(fncGetPos(e) || mLastTouch || mStartPoint);
}
}
} else {
mWaitingForDoubleTap = true;
mLastSrc = src;
mDoubleTapTimeout = setTimeout(function () {
mWaitingForDoubleTap = false;
}, DOUBLETAP_CANCEL);
}
}
};

//var debugbox = p.e("<div>", { "class": "debugbox" });
//debugbox.appendTo(p.reader.container);

var fncGetPos = function (event) {
var offset = target.getPageXY();
if (event.type.startsWith('touch')) {
if (event.touches.length == 1) {
return {
x: event.touches[0].pageX - offset.x,
y: event.touches[0].pageY - offset.y,
};
} else if (event.touches.length == 2) {
var a = {
x: event.touches[0].pageX - offset.x,
y: event.touches[0].pageY - offset.y,
},
b = {
x: event.touches[1].pageX - offset.x,
y: event.touches[1].pageY - offset.y,
},
midpoint = p.math.Midpoint2D(a, b);

return {
x: midpoint.x,
y: midpoint.y,
dist: p.math.Dist2D(a, b),
};
}
} else {
return {
x: event.pageX - offset.x,
y: event.pageY - offset.y,
};
}
};

var fncOnDown = function (e) {
if (!p.e(e.srcElement).getParents().hasClass('ctrl')) {
p.pager.content_container[0].focus();

if (e && e.preventDefault) e.preventDefault();
if (!PROPAGATE && e && e.stopPropagation) e.stopPropagation();

mIsTouch = e.type.startsWith('touch');

if (mIsTouch && e.touches.length >= 2) {
mPinching = true;
mSwiping = mDragging = false;
mStartPoint = mLastTouch = fncGetPos(e);

if (options.onPinchStart && p.is.function(options.onPinchStart)) {
options.onPinchStart(mStartPoint);
}
} else if (isContained()) {
mSwiping = true;
mStartPoint = fncGetPos(e);
} else {
mDragging = true;
mLastTouch = fncGetPos(e);
}
}
};

var fncOnMove = function (e) {
//console.info(e);
if (p.e(e.srcElement).getParents().hasClass('ctrl')) {
return;
}
if (e && e.preventDefault) e.preventDefault();
if (!PROPAGATE && e && e.stopPropagation) e.stopPropagation();

if (!mOptimized) {
target.addClass('speed');
mOptimized = true;
}

if (mPinching) {
var current = fncGetPos(e);
var difference = current.dist - mStartPoint.dist;
var differenceChange = current.dist / mStartPoint.dist;

if (options.onPinch && p.is.function(options.onPinch)) {
options.onPinch(difference, differenceChange, current);
}
} else if (!isContained() && mDragging) {
var current = fncGetPos(e);
var difference = {
x: mLastTouch.x - current.x,
y: mLastTouch.y - current.y,
};

//console.log("scroll");

if (options.onDrag && p.is.function(options.onDrag)) {
options.onDrag(difference);
}
//mContent.scrollLeft(mContent.scrollLeft() + difference.x);
//mContent.scrollTop(mContent.scrollTop() + difference.y);

//console.info(difference);
}

if (mIsTouch || !isContained()) mLastTouch = fncGetPos(e);
};

var fncOnUp = function (e) {
//return console.info(e);
if (p.e(e.srcElement).getParents().hasClass('ctrl')) {
return;
}
if (e && e.preventDefault) e.preventDefault();
if (!PROPAGATE && e && e.stopPropagation) e.stopPropagation();

if (mOptimized) {
target.removeClass('speed');
mOptimized = false;
}

if (!mPinching) {
fncDoubleTapCheck(e);
}

if (isContained() && mSwiping) {
if (
e.type.startsWith('touch') &&
mLastTouch != null &&
mLastTouch != undefined
)
mEndPoint = mLastTouch;
else mEndPoint = fncGetPos(e) || mStartPoint;

mDistance = p.math.Dist2D(mStartPoint, mEndPoint);
mDeviation = Math.abs(mStartPoint.y - mEndPoint.y);
mDirection = mStartPoint.x > mEndPoint.x ? DIR_LEFT : DIR_RIGHT;

if (mDistance > SWIPE_THRESHOLD && mDeviation < SWIPE_CANCEL) {
if (mDirection == DIR_LEFT) {
if (options.onSwipeLeft && p.is.function(options.onSwipeLeft)) {
options.onSwipeLeft();
}
} else {
if (options.onSwipeRight && p.is.function(options.onSwipeRight)) {
options.onSwipeRight();
}
}
}
mSwiping = false;
} else if (mPinching) {
if (options.onPinchEnd && p.is.function(options.onPinchEnd)) {
options.onPinchEnd(mLastTouch);
}
mPinching = false;
} else {
mDragging = false;
}
};

var fncWheel = function (e) {
if (e && e.preventDefault) e.preventDefault();
if (e && e.stopPropagation) e.stopPropagation();

if (!mPinching && !mDragging) {
if (!mZooming) {
mZooming = true;

mStartPoint = fncGetPos(e);
mCumulZoom = 10;

if (options.onWheelStart && p.is.function(options.onWheelStart)) {
options.onWheelStart(mStartPoint);
}
}

mCumulZoom += WHEEL_TICK * -sign(e.deltaY);
var current = fncGetPos(e);
var difference = WHEEL_TICK * sign(e.deltaY);
var differenceChange = mCumulZoom / 10;

if (options.onWheel && p.is.function(options.onWheel)) {
options.onWheel(difference, differenceChange, current);
}

clearTimeout(mZoomTimeout);
mZoomTimeout = setTimeout(fncWheelTimeout, WHEEL_CANCEL);
}
};

var fncWheelTimeout = function () {
if (mZooming) {
if (options.onWheelEnd && p.is.function(options.onWheelEnd)) {
options.onWheelEnd(mStartPoint);
}
mZooming = false;
}
};

target.on('wheel', fncWheel);
target.on('mousedown touchstart', fncOnDown);
target.on('mouseleave mouseup touchend', fncOnUp);
target.on('mousemove touchmove', fncOnMove);
},

PDFQueue: {
queue: [],
current_callback: null,
runnning: false,
qid: 0,

push: function (canvas, page, callback, prerender) {
this.queue.push({
canvas: canvas,
page: page,
callback: callback,
prerender: prerender || false,
qid: p.PDFQueue.qid,
});
},

reset: function () {
this.qid++;
this.queue = [];
},

start: function (callback) {
this.current_callback = callback;
if (!this.runnning) {
this.runnning = true;
this._render();
}
},

_render: function () {
var $this = p.PDFQueue,
item = $this.queue.pop(),
render = false,
CONST = p.pager.constant,
start = new Date().getTime();
if (item) {
//if (p.pager.current_mode == CONST.SINGLE || p.pager.current_mode == CONST.SINGLE_REVERSE)
// render = item.page == p.pager.current_page_firstvalid;
//else if (p.pager.current_mode == CONST.DOUBLE || p.pager.current_mode == CONST.DOUBLE_REVERSE)
// render = (item.page == p.pager.current_page) || (item.page == p.pager.current_page + 1);

//render = render || item.prerender;
//render =

render = item.qid == p.PDFQueue.qid;

if (render) {
try {
//console.info("Rendering page", item.page, "on", item.canvas);
p.PDFManager.renderPageOn(
item.page,
p.reader.render_canvas,
function () {
p.pager.push_pdf_rendertime(new Date().getTime() - start);

if (item.qid == p.PDFQueue.qid) {
var context = item.canvas[0].getContext('2d');
item.canvas[0].width = p.reader.render_canvas[0].width;
item.canvas[0].height = p.reader.render_canvas[0].height;
context.drawImage(p.reader.render_canvas[0], 0, 0);

if (item.callback && p.is.function(item.callback))
item.callback();
}

$this._render();
}
);

/*
p.PDFManager.renderPageOn(item.page, item.canvas, function ()
{
p.pager.push_pdf_rendertime((new Date()).getTime() - start);

if (item.callback && p.is.function(item.callback))
item.callback();

$this._render();
});
*/
} catch (ex) {
//console.error("Render failed");
$this._render();
}
} else {
//console.log("Skipping render");
$this._render();
}
} else {
$this.runnning = false;

if ($this.current_callback && p.is.function($this.current_callback))
$this.current_callback();
}
},
},

PDFManager: {
DEBUG_SYMBOL: 'PDFM',
document: null,
pages: {},
scale: 1.0,
ref_factor: -1,

_rendering: false,
_loading: 0,

get isRendering() {
return this._rendering;
},

get isLoading() {
return this._loading > 0;
},

loadFile: function PDFM_loadFile(e, callback) {
this._loading++;
PDFJS.getDocument(e, null, null, this.onDocumentProgress).then(
function PDFM_loadFile_chain(a) {
if (callback && p.is.function(callback)) callback(a);

p.PDFManager.onDocumentLoad(a);
}
);
},
getPage: function PDFM_getPage(i, callback) {
if (this.pages.hasOwnProperty(i)) {
if (callback && p.is.function(callback)) callback(this.pages[i]);
} else {
if (this.document != null) {
this.document
.getPage(parseInt(i))
.then(
function PDFM_getPage_chain(e) {
if (callback && p.is.function(callback)) callback(e);

p.PDFManager.onPageLoad(e);
},
function PDFM_getPage_chainException(ex) {
console.error(
'GetPageChainException',
ex,
ex.stack,
'for page',
i,
'Callback on:',
callback
);
}
)
.then(null, function PDFM_getPage_chainException(ex) {
console.error(
'GetPageUncaughtException',
ex,
ex.stack,
'for page',
i,
'Callback on:',
callback
);
});
}
}
},
renderPageOn: function PDFM_renderPageOn(
page,
canvas,
callback,
ignorePageSize
) {
if (p.isExElement(canvas) == false || canvas.length != 1) {
//Trace(["Invalid canvas"], this.DEBUG_SYMBOL, CONSOLE_ERROR);
return;
}

//console.log(page, 0, this.document.numPages);

if (page == 0 || page > this.document.numPages) {
if (callback && p.is.function(callback)) callback();

return;
}

this._rendering = true;

var RENDER_CONTEXT = {
canvasContext: canvas[0].getContext('2d'),
viewport: null,
};

if (this.pages.hasOwnProperty(page)) {
if (this.ref_factor == -1 && ignorePageSize !== true) {
RENDER_CONTEXT.viewport = this.pages[page].getViewport(1.0);
var refSize = p.pager.getPageSize(page, true);
this.ref_factor = refSize.width / RENDER_CONTEXT.viewport.width;
} else if (this.ref_factor == -1 && ignorePageSize == true) {
this.ref_factor = 1;
}

RENDER_CONTEXT.viewport = this.pages[page].getViewport(
this.scale * this.ref_factor
);
canvas[0].width = RENDER_CONTEXT.viewport.width;
canvas[0].height = RENDER_CONTEXT.viewport.height;

//p.Pager.refSize.width = RENDER_CONTEXT.viewport.width / this.scale;
//p.Pager.refSize.height = RENDER_CONTEXT.viewport.height / this.scale;

//$("#loader-left")[0].width = RENDER_CONTEXT.viewport.width;
//$("#loader-left")[0].height = RENDER_CONTEXT.viewport.height;
//$("#loader-right")[0].width = RENDER_CONTEXT.viewport.width;
//$("#loader-right")[0].height = RENDER_CONTEXT.viewport.height;
try {
this.pages[page]
.render(RENDER_CONTEXT)
.promise.then(
function PDFM_renderPageOn_chain(e) {
p.PDFManager._rendering = false;

if (callback && p.is.function(callback)) callback(e);

p.PDFManager.onPageRender(e);
},
function PDFM_renderPageOn_chainException(ex) {
console.error(
'RenderPageOn_ChainException',
ex,
ex.stack,
'for page',
page,
'on canvas',
canvas,
'callback on:',
callback
);

p.PDFManager._rendering = false;

if (callback && p.is.function(callback)) callback(false);

p.PDFManager.onPageRender(false);
}
)
.then(null, function (ex) {
console.error(
'RenderPageOn_UncaughtException',
ex,
ex.stack,
'for page',
page,
'on canvas',
canvas,
'callback on:',
callback
);

p.PDFManager._rendering = false;

if (callback && p.is.function(callback)) callback(false);

p.PDFManager.onPageRender(false);
});
} catch (ex) {
console.error(
'RenderPageOn_FatalException',
ex,
ex.stack,
'for page',
page,
'on canvas',
canvas,
'callback on:',
callback
);

p.PDFManager._rendering = false;

if (callback && p.is.function(callback)) callback(false);

p.PDFManager.onPageRender(false);
}
} else {
try {
this.getPage(page, function PDFM_renderPageOn_loader() {
p.PDFManager.renderPageOn(page, canvas, callback, ignorePageSize);
});
} catch (ex) {
console.error(
'GetPageChainException',
ex,
ex.stack,
'for page',
page,
'Callback on:',
callback
);
}
}
},

//#region Events

// #region Handlers

_handlerOnDocumentLoad: null,
_handlerOnDocumentProgress: null,
_handlerOnPageLoad: null,
_handlerOnPageRender: null,

setOnDocumentLoadHandler: function PDFM_handlerSet_onDocumentLoad(e) {
if (e && p.is.function(e)) this._handlerOnDocumentLoad = e;
},
setOnDocumentProgressHandler: function PDFM_handlerSet_onDocumentProgress(
e
) {
if (e && p.is.function(e)) this._handlerOnDocumentProgress = e;
},
setOnPageLoadHandler: function PDFM_handlerSet_onPageLoad(e) {
if (e && p.is.function(e)) this._handlerOnPageLoad = e;
},
setOnPageRenderHandler: function PDFM_handlerSet_onPageRender(e) {
if (e && p.is.function(e)) this._handlerOnPageRender = e;
},

// #endregion

onDocumentLoad: function PDFM_handlerTrigger_onDocumentLoad(e) {
var $this = p.PDFManager;
$this.document = e;

if (
$this._handlerOnDocumentLoad != null &&
p.is.function($this._handlerOnDocumentLoad)
) {
$this._handlerOnDocumentLoad(e);
}
},
onDocumentProgress: function PDFM_handlerTrigger_onDocumentProgress(e) {
var $this = p.PDFManager;

if (e && e['loaded'] && e['total']) {
if (e.loaded >= e.total) {
$this._loading--;

if ($this._loading < 0) $this._loading = 0;
}
}

if (
$this._handlerOnDocumentProgress != null &&
p.is.function($this._handlerOnDocumentProgress)
) {
$this._handlerOnDocumentProgress(e);
}
},
onPageLoad: function PDFM_handlerTrigger_onPageLoad(e) {
var $this = p.PDFManager;
$this.pages[e.pageNumber] = e;

if (
$this._handlerOnPageLoad != null &&
p.is.function($this._handlerOnPageLoad)
) {
$this._handlerOnPageLoad(e);
}
},
onPageRender: function PDFM_handlerTrigger_onPageRender(e) {
var $this = p.PDFManager;

if (
$this._handlerOnPageRender != null &&
p.is.function($this._handlerOnPageRender)
) {
$this._handlerOnPageRender(e);
}
},

//#endregion
},

utf8_encode: function (string) {
string = string.replace(/\r\n/g, '\n');
var utftext = '';

for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);

if (c < 128) {
utftext += String.fromCharCode(c);
} else if (c > 127 && c < 2048) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}

return utftext;
},

// private method for UTF-8 decoding
utf8_decode: function (utftext) {
var string = '';
var i = 0;
var c = (c1 = c2 = 0);

while (i < utftext.length) {
c = utftext.charCodeAt(i);

if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if (c > 191 && c < 224) {
c2 = utftext.charCodeAt(i + 1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = utftext.charCodeAt(i + 1);
c3 = utftext.charCodeAt(i + 2);
string += String.fromCharCode(
((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)
);
i += 3;
}
}

return string;
},

sha1: function (str) {
// http://kevin.vanzonneveld.net
// + original by: Webtoolkit.info (http://www.webtoolkit.info/)
// + namespaced by: Michael White (http://getsprink.com)
// + input by: Brett Zamir (http://brett-zamir.me)
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// - depends on: utf8_encode
// * example 1: sha1('Kevin van Zonneveld');
// * returns 1: '54916d2e62f65b3afa6e192e6a601cdbe5cb5897'
var rotate_left = function (n, s) {
var t4 = (n << s) | (n >>> (32 - s));
return t4;
};

/*var lsb_hex = function (val) { // Not in use; needed?
var str="";
var i;
var vh;
var vl;

for ( i=0; i<=6; i+=2 ) {
vh = (val>>>(i*4+4))&0x0f;
vl = (val>>>(i*4))&0x0f;
str += vh.toString(16) + vl.toString(16);
}
return str;
};*/

var cvt_hex = function (val) {
var str = '';
var i;
var v;

for (i = 7; i >= 0; i--) {
v = (val >>> (i * 4)) & 0x0f;
str += v.toString(16);
}
return str;
};

var blockstart;
var i, j;
var W = new Array(80);
var H0 = 0x67452301;
var H1 = 0xefcdab89;
var H2 = 0x98badcfe;
var H3 = 0x10325476;
var H4 = 0xc3d2e1f0;
var A, B, C, D, E;
var temp;

str = this.utf8_encode(str);
var str_len = str.length;

var word_array = [];
for (i = 0; i < str_len - 3; i += 4) {
j =
(str.charCodeAt(i) << 24) |
(str.charCodeAt(i + 1) << 16) |
(str.charCodeAt(i + 2) << 8) |
str.charCodeAt(i + 3);
word_array.push(j);
}

switch (str_len % 4) {
case 0:
i = 0x080000000;
break;
case 1:
i = (str.charCodeAt(str_len - 1) << 24) | 0x0800000;
break;
case 2:
i =
(str.charCodeAt(str_len - 2) << 24) |
(str.charCodeAt(str_len - 1) << 16) |
0x08000;
break;
case 3:
i =
(str.charCodeAt(str_len - 3) << 24) |
(str.charCodeAt(str_len - 2) << 16) |
(str.charCodeAt(str_len - 1) << 8) |
0x80;
break;
}

word_array.push(i);

while (word_array.length % 16 != 14) {
word_array.push(0);
}

word_array.push(str_len >>> 29);
word_array.push((str_len << 3) & 0x0ffffffff);

for (blockstart = 0; blockstart < word_array.length; blockstart += 16) {
for (i = 0; i < 16; i++) {
W[i] = word_array[blockstart + i];
}
for (i = 16; i <= 79; i++) {
W[i] = rotate_left(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
}

A = H0;
B = H1;
C = H2;
D = H3;
E = H4;

for (i = 0; i <= 19; i++) {
temp =
(rotate_left(A, 5) + ((B & C) | (~B & D)) + E + W[i] + 0x5a827999) &
0x0ffffffff;
E = D;
D = C;
C = rotate_left(B, 30);
B = A;
A = temp;
}

for (i = 20; i <= 39; i++) {
temp =
(rotate_left(A, 5) + (B ^ C ^ D) + E + W[i] + 0x6ed9eba1) &
0x0ffffffff;
E = D;
D = C;
C = rotate_left(B, 30);
B = A;
A = temp;
}

for (i = 40; i <= 59; i++) {
temp =
(rotate_left(A, 5) +
((B & C) | (B & D) | (C & D)) +
E +
W[i] +
0x8f1bbcdc) &
0x0ffffffff;
E = D;
D = C;
C = rotate_left(B, 30);
B = A;
A = temp;
}

for (i = 60; i <= 79; i++) {
temp =
(rotate_left(A, 5) + (B ^ C ^ D) + E + W[i] + 0xca62c1d6) &
0x0ffffffff;
E = D;
D = C;
C = rotate_left(B, 30);
B = A;
A = temp;
}

H0 = (H0 + A) & 0x0ffffffff;
H1 = (H1 + B) & 0x0ffffffff;
H2 = (H2 + C) & 0x0ffffffff;
H3 = (H3 + D) & 0x0ffffffff;
H4 = (H4 + E) & 0x0ffffffff;
}

temp =
cvt_hex(H0) + cvt_hex(H1) + cvt_hex(H2) + cvt_hex(H3) + cvt_hex(H4);
return temp.toLowerCase();
},

md5: function (string) {
function RotateLeft(lValue, iShiftBits) {
return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
}

function AddUnsigned(lX, lY) {
var lX4, lY4, lX8, lY8, lResult;
lX8 = lX & 0x80000000;
lY8 = lY & 0x80000000;
lX4 = lX & 0x40000000;
lY4 = lY & 0x40000000;
lResult = (lX & 0x3fffffff) + (lY & 0x3fffffff);
if (lX4 & lY4) {
return lResult ^ 0x80000000 ^ lX8 ^ lY8;
}
if (lX4 | lY4) {
if (lResult & 0x40000000) {
return lResult ^ 0xc0000000 ^ lX8 ^ lY8;
} else {
return lResult ^ 0x40000000 ^ lX8 ^ lY8;
}
} else {
return lResult ^ lX8 ^ lY8;
}
}

function F(x, y, z) {
return (x & y) | (~x & z);
}

function G(x, y, z) {
return (x & z) | (y & ~z);
}

function H(x, y, z) {
return x ^ y ^ z;
}

function I(x, y, z) {
return y ^ (x | ~z);
}

function FF(a, b, c, d, x, s, ac) {
a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
return AddUnsigned(RotateLeft(a, s), b);
}

function GG(a, b, c, d, x, s, ac) {
a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
return AddUnsigned(RotateLeft(a, s), b);
}

function HH(a, b, c, d, x, s, ac) {
a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
return AddUnsigned(RotateLeft(a, s), b);
}

function II(a, b, c, d, x, s, ac) {
a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
return AddUnsigned(RotateLeft(a, s), b);
}

function ConvertToWordArray(string) {
var lWordCount;
var lMessageLength = string.length;
var lNumberOfWords_temp1 = lMessageLength + 8;
var lNumberOfWords_temp2 =
(lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64;
var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16;
var lWordArray = Array(lNumberOfWords - 1);
var lBytePosition = 0;
var lByteCount = 0;
while (lByteCount < lMessageLength) {
lWordCount = (lByteCount - (lByteCount % 4)) / 4;
lBytePosition = (lByteCount % 4) * 8;
lWordArray[lWordCount] =
lWordArray[lWordCount] |
(string.charCodeAt(lByteCount) << lBytePosition);
lByteCount++;
}
lWordCount = (lByteCount - (lByteCount % 4)) / 4;
lBytePosition = (lByteCount % 4) * 8;
lWordArray[lWordCount] =
lWordArray[lWordCount] | (0x80 << lBytePosition);
lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
return lWordArray;
}

function WordToHex(lValue) {
var WordToHexValue = '',
WordToHexValue_temp = '',
lByte,
lCount;
for (lCount = 0; lCount <= 3; lCount++) {
lByte = (lValue >>> (lCount * 8)) & 255;
WordToHexValue_temp = '0' + lByte.toString(16);
WordToHexValue =
WordToHexValue +
WordToHexValue_temp.substr(WordToHexValue_temp.length - 2, 2);
}
return WordToHexValue;
}

function Utf8Encode(string) {
string = string.replace(/\r\n/g, '\n');
var utftext = '';

for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);

if (c < 128) {
utftext += String.fromCharCode(c);
} else if (c > 127 && c < 2048) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}

return utftext;
}

var x = Array();
var k, AA, BB, CC, DD, a, b, c, d;
var S11 = 7,
S12 = 12,
S13 = 17,
S14 = 22;
var S21 = 5,
S22 = 9,
S23 = 14,
S24 = 20;
var S31 = 4,
S32 = 11,
S33 = 16,
S34 = 23;
var S41 = 6,
S42 = 10,
S43 = 15,
S44 = 21;

string = Utf8Encode(string);

x = ConvertToWordArray(string);

a = 0x67452301;
b = 0xefcdab89;
c = 0x98badcfe;
d = 0x10325476;

for (k = 0; k < x.length; k += 16) {
AA = a;
BB = b;
CC = c;
DD = d;
a = FF(a, b, c, d, x[k + 0], S11, 0xd76aa478);
d = FF(d, a, b, c, x[k + 1], S12, 0xe8c7b756);
c = FF(c, d, a, b, x[k + 2], S13, 0x242070db);
b = FF(b, c, d, a, x[k + 3], S14, 0xc1bdceee);
a = FF(a, b, c, d, x[k + 4], S11, 0xf57c0faf);
d = FF(d, a, b, c, x[k + 5], S12, 0x4787c62a);
c = FF(c, d, a, b, x[k + 6], S13, 0xa8304613);
b = FF(b, c, d, a, x[k + 7], S14, 0xfd469501);
a = FF(a, b, c, d, x[k + 8], S11, 0x698098d8);
d = FF(d, a, b, c, x[k + 9], S12, 0x8b44f7af);
c = FF(c, d, a, b, x[k + 10], S13, 0xffff5bb1);
b = FF(b, c, d, a, x[k + 11], S14, 0x895cd7be);
a = FF(a, b, c, d, x[k + 12], S11, 0x6b901122);
d = FF(d, a, b, c, x[k + 13], S12, 0xfd987193);
c = FF(c, d, a, b, x[k + 14], S13, 0xa679438e);
b = FF(b, c, d, a, x[k + 15], S14, 0x49b40821);
a = GG(a, b, c, d, x[k + 1], S21, 0xf61e2562);
d = GG(d, a, b, c, x[k + 6], S22, 0xc040b340);
c = GG(c, d, a, b, x[k + 11], S23, 0x265e5a51);
b = GG(b, c, d, a, x[k + 0], S24, 0xe9b6c7aa);
a = GG(a, b, c, d, x[k + 5], S21, 0xd62f105d);
d = GG(d, a, b, c, x[k + 10], S22, 0x2441453);
c = GG(c, d, a, b, x[k + 15], S23, 0xd8a1e681);
b = GG(b, c, d, a, x[k + 4], S24, 0xe7d3fbc8);
a = GG(a, b, c, d, x[k + 9], S21, 0x21e1cde6);
d = GG(d, a, b, c, x[k + 14], S22, 0xc33707d6);
c = GG(c, d, a, b, x[k + 3], S23, 0xf4d50d87);
b = GG(b, c, d, a, x[k + 8], S24, 0x455a14ed);
a = GG(a, b, c, d, x[k + 13], S21, 0xa9e3e905);
d = GG(d, a, b, c, x[k + 2], S22, 0xfcefa3f8);
c = GG(c, d, a, b, x[k + 7], S23, 0x676f02d9);
b = GG(b, c, d, a, x[k + 12], S24, 0x8d2a4c8a);
a = HH(a, b, c, d, x[k + 5], S31, 0xfffa3942);
d = HH(d, a, b, c, x[k + 8], S32, 0x8771f681);
c = HH(c, d, a, b, x[k + 11], S33, 0x6d9d6122);
b = HH(b, c, d, a, x[k + 14], S34, 0xfde5380c);
a = HH(a, b, c, d, x[k + 1], S31, 0xa4beea44);
d = HH(d, a, b, c, x[k + 4], S32, 0x4bdecfa9);
c = HH(c, d, a, b, x[k + 7], S33, 0xf6bb4b60);
b = HH(b, c, d, a, x[k + 10], S34, 0xbebfbc70);
a = HH(a, b, c, d, x[k + 13], S31, 0x289b7ec6);
d = HH(d, a, b, c, x[k + 0], S32, 0xeaa127fa);
c = HH(c, d, a, b, x[k + 3], S33, 0xd4ef3085);
b = HH(b, c, d, a, x[k + 6], S34, 0x4881d05);
a = HH(a, b, c, d, x[k + 9], S31, 0xd9d4d039);
d = HH(d, a, b, c, x[k + 12], S32, 0xe6db99e5);
c = HH(c, d, a, b, x[k + 15], S33, 0x1fa27cf8);
b = HH(b, c, d, a, x[k + 2], S34, 0xc4ac5665);
a = II(a, b, c, d, x[k + 0], S41, 0xf4292244);
d = II(d, a, b, c, x[k + 7], S42, 0x432aff97);
c = II(c, d, a, b, x[k + 14], S43, 0xab9423a7);
b = II(b, c, d, a, x[k + 5], S44, 0xfc93a039);
a = II(a, b, c, d, x[k + 12], S41, 0x655b59c3);
d = II(d, a, b, c, x[k + 3], S42, 0x8f0ccc92);
c = II(c, d, a, b, x[k + 10], S43, 0xffeff47d);
b = II(b, c, d, a, x[k + 1], S44, 0x85845dd1);
a = II(a, b, c, d, x[k + 8], S41, 0x6fa87e4f);
d = II(d, a, b, c, x[k + 15], S42, 0xfe2ce6e0);
c = II(c, d, a, b, x[k + 6], S43, 0xa3014314);
b = II(b, c, d, a, x[k + 13], S44, 0x4e0811a1);
a = II(a, b, c, d, x[k + 4], S41, 0xf7537e82);
d = II(d, a, b, c, x[k + 11], S42, 0xbd3af235);
c = II(c, d, a, b, x[k + 2], S43, 0x2ad7d2bb);
b = II(b, c, d, a, x[k + 9], S44, 0xeb86d391);
a = AddUnsigned(a, AA);
b = AddUnsigned(b, BB);
c = AddUnsigned(c, CC);
d = AddUnsigned(d, DD);
}

var temp = WordToHex(a) + WordToHex(b) + WordToHex(c) + WordToHex(d);

return temp.toLowerCase();
},
};

var ads = {
ads: {
interactives: interactives,

isShowing: false,
count: 0,
options: {
frq: 2,
},

showAds: function showAds() {
console.log(ads);
var curpag = p.pager.current_page;
if (window.matchMedia('(min-width: 479px)').matches) {
if (
curpag != p.pager.page_count &&
curpag != 0 &&
(curpag + 2) % p.ads.options.frq == 0 &&
!p.ads.isShowing
) {
/*var dnyAds = p.ads.getRepeatAd(curpag);*/
var dnyAds = p.ads.getAds(curpag);
if (!('unzippath' in dnyAds)) {
return false;
}
//console.log(dnyAds);
p.ads.isShowing = true;
$('#reader-container .content .pages .overlayer').after(
"<div class='ad1' style='width: 100%;top:0;box-shadow:1px 1px 15px rgba(255,255,255,0.5);height: 100%;z-index:16;left:0;position: absolute; visibility: hidden;'><iframe src='" +
dnyAds.unzippath +
"/index.html' id='p2Ad' border='0' width='100%' height='100%'></iframe></div>"
);
$('.ad1').css('visibility', 'visible');
$('.ad1 iframe').css('border', '0');
dnyAds.shown = true;
dnyAds.page_no = curpag;
return true;
} else {
p.ads.isShowing = false;
//console.log('got to next page');
$('.ad1').remove();
return false;
}
}
},

hideAds: function hideAds() {
p.ads.isShowing = false;
$('.ad1').remove();
return false;
},

getAds: function getAds(page) {
var dynAds = p.ads.interactives.find(function (v) {
return typeof v.shown == 'undefined' || v.page_no == page;
});
return dynAds || {};
},

getRepeatAd: function getAds(page) {
var len = p.ads.interactives.length;

var dynAds = p.ads.interactives[p.ads.count % len];
p.ads.count++;
return dynAds || {};
},
},
};
exHelp.extend(reader);
exHelp.extend(ads);
})(window);

/*exHelp.e(document).on("ready", function ()
{
exHelp.reader.init();
});*/

let showHighlight = true;
$(document).ready(function () {
//exHelp.reader.init();
var createOverlay = function (e) {
var o = $('<div></div>');
o.addClass('overlay');
o.attr('data-display', e.display);
o.attr('data-type', e.type);
o.attr('data-x', e.x);
o.attr('data-y', e.y);
o.attr('data-width', e.Width);
o.attr('data-height', e.Height);
o.attr('data-page', e.page);

switch (e.type) {
case 'link':
var $source = $('<source></source>');
$source.attr('src', e.link);

$source.appendTo(o);
break;

case 'page':
var $source = $('<source></source>');
$source.attr('src', e.link);

$source.appendTo(o);
break;
}

o.appendTo('#reader-container');
};

!(function () {
var data1 = raw_data;
// console.log(data);
// $.get(path, function (data) {
if (data1) {
let preview_page = $('#preview_page').val();
if (!preview_page) {
for (var i in data1) {
if (data1[i].overlays) {
var overlay = data1[i].overlays;
overlay.forEach(function (v) {
createOverlay(v);
});
}
}
}
raw_data = data1;
exHelp.reader.init();
}
// })
})();
});

Back to list