ginipick commited on
Commit
90337b7
·
verified ·
1 Parent(s): ba82085

Upload 12 files

Browse files
Files changed (6) hide show
  1. iscroll.js +2607 -0
  2. mark.js +1464 -0
  3. mod3d.js +2520 -0
  4. pdf.js +0 -0
  5. pdf.worker.js +0 -0
  6. three.js +0 -0
iscroll.js ADDED
@@ -0,0 +1,2607 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Real3D FlipBook [https://real3dflipbook.com]
3
+ * @author creativeinteractivemedia [https://codecanyon.net/user/creativeinteractivemedia/portfolio]
4
+ * @version 4.10
5
+ * @date 2025-05-15
6
+ */
7
+ /*! iScroll v5.2.0-snapshot ~ (c) 2008-2017 Matteo Spinelli ~ http://cubiq.org/license */
8
+ (function (window, document, Math) {
9
+ var rAF =
10
+ window.requestAnimationFrame ||
11
+ window.webkitRequestAnimationFrame ||
12
+ window.mozRequestAnimationFrame ||
13
+ window.oRequestAnimationFrame ||
14
+ window.msRequestAnimationFrame ||
15
+ function (callback) {
16
+ window.setTimeout(callback, 1000 / 60);
17
+ };
18
+
19
+ var utils = (function () {
20
+ var me = {};
21
+
22
+ var _elementStyle = document.createElement('div').style;
23
+ var _vendor = (function () {
24
+ var vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT'];
25
+ var transform;
26
+ var i = 0;
27
+ var l = vendors.length;
28
+
29
+ for (; i < l; i++) {
30
+ transform = vendors[i] + 'ransform';
31
+ if (transform in _elementStyle) {
32
+ return vendors[i].substr(0, vendors[i].length - 1);
33
+ }
34
+ }
35
+
36
+ return false;
37
+ })();
38
+
39
+ function _prefixStyle(style) {
40
+ if (_vendor === false) {
41
+ return false;
42
+ }
43
+ if (_vendor === '') {
44
+ return style;
45
+ }
46
+ return _vendor + style.charAt(0).toUpperCase() + style.substr(1);
47
+ }
48
+
49
+ me.getTime =
50
+ Date.now ||
51
+ function getTime() {
52
+ return new Date().getTime();
53
+ };
54
+
55
+ me.extend = function (target, obj) {
56
+ for (var i in obj) {
57
+ target[i] = obj[i];
58
+ }
59
+ };
60
+
61
+ me.addEvent = function (el, type, fn, capture) {
62
+ el.addEventListener(type, fn, !!capture);
63
+ };
64
+
65
+ me.removeEvent = function (el, type, fn, capture) {
66
+ el.removeEventListener(type, fn, !!capture);
67
+ };
68
+
69
+ me.prefixPointerEvent = function (pointerEvent) {
70
+ return window.MSPointerEvent
71
+ ? 'MSPointer' + pointerEvent.charAt(7).toUpperCase() + pointerEvent.substr(8)
72
+ : pointerEvent;
73
+ };
74
+
75
+ me.momentum = function (current, start, time, lowerMargin, wrapperSize, deceleration) {
76
+ var distance = current - start;
77
+ var speed = Math.abs(distance) / time;
78
+ var destination;
79
+ var duration;
80
+
81
+ deceleration = deceleration === undefined ? 0.0006 : deceleration;
82
+
83
+ destination = current + ((speed * speed) / (2 * deceleration)) * (distance < 0 ? -1 : 1);
84
+ duration = speed / deceleration;
85
+
86
+ if (destination < lowerMargin) {
87
+ destination = wrapperSize ? lowerMargin - (wrapperSize / 2.5) * (speed / 8) : lowerMargin;
88
+ distance = Math.abs(destination - current);
89
+ duration = distance / speed;
90
+ } else if (destination > 0) {
91
+ destination = wrapperSize ? (wrapperSize / 2.5) * (speed / 8) : 0;
92
+ distance = Math.abs(current) + destination;
93
+ duration = distance / speed;
94
+ }
95
+
96
+ return {
97
+ destination: Math.round(destination),
98
+ duration: duration,
99
+ };
100
+ };
101
+
102
+ var _transform = _prefixStyle('transform');
103
+
104
+ me.extend(me, {
105
+ hasTransform: _transform !== false,
106
+ hasPerspective: _prefixStyle('perspective') in _elementStyle,
107
+ hasTouch: 'ontouchstart' in window,
108
+ hasPointer: !!(window.PointerEvent || window.MSPointerEvent), // IE10 is prefixed
109
+ hasTransition: _prefixStyle('transition') in _elementStyle,
110
+ });
111
+
112
+ /*
113
+ This should find all Android browsers lower than build 535.19 (both stock browser and webview)
114
+ - galaxy S2 is ok
115
+ - 2.3.6 : `AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1`
116
+ - 4.0.4 : `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
117
+ - galaxy S3 is badAndroid (stock brower, webview)
118
+ `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
119
+ - galaxy S4 is badAndroid (stock brower, webview)
120
+ `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
121
+ - galaxy S5 is OK
122
+ `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)`
123
+ - galaxy S6 is OK
124
+ `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)`
125
+ */
126
+ me.isBadAndroid = (function () {
127
+ var appVersion = window.navigator.appVersion;
128
+ // Android browser is not a chrome browser.
129
+ if (/Android/.test(appVersion) && !/Chrome\/\d/.test(appVersion)) {
130
+ var safariVersion = appVersion.match(/Safari\/(\d+.\d)/);
131
+ if (safariVersion && typeof safariVersion === 'object' && safariVersion.length >= 2) {
132
+ return parseFloat(safariVersion[1]) < 535.19;
133
+ } else {
134
+ return true;
135
+ }
136
+ } else {
137
+ return false;
138
+ }
139
+ })();
140
+
141
+ me.extend((me.style = {}), {
142
+ transform: _transform,
143
+ transitionTimingFunction: _prefixStyle('transitionTimingFunction'),
144
+ transitionDuration: _prefixStyle('transitionDuration'),
145
+ transitionDelay: _prefixStyle('transitionDelay'),
146
+ transformOrigin: _prefixStyle('transformOrigin'),
147
+ touchAction: _prefixStyle('touchAction'),
148
+ });
149
+
150
+ me.hasClass = function (e, c) {
151
+ var re = new RegExp('(^|\\s)' + c + '(\\s|$)');
152
+ return re.test(e.className);
153
+ };
154
+
155
+ me.addClass = function (e, c) {
156
+ if (me.hasClass(e, c)) {
157
+ return;
158
+ }
159
+
160
+ var newclass = e.className.split(' ');
161
+ newclass.push(c);
162
+ e.className = newclass.join(' ');
163
+ };
164
+
165
+ me.removeClass = function (e, c) {
166
+ if (!me.hasClass(e, c)) {
167
+ return;
168
+ }
169
+
170
+ var re = new RegExp('(^|\\s)' + c + '(\\s|$)', 'g');
171
+ e.className = e.className.replace(re, ' ');
172
+ };
173
+
174
+ me.offset = function (el) {
175
+ var left = -el.offsetLeft;
176
+ var top = -el.offsetTop;
177
+
178
+ // jshint -W084
179
+ while ((el = el.offsetParent)) {
180
+ left -= el.offsetLeft;
181
+ top -= el.offsetTop;
182
+ }
183
+ // jshint +W084
184
+
185
+ /*custom*/
186
+ return { left: 0, top: 0 };
187
+ /*end*/
188
+
189
+ return {
190
+ left: left,
191
+ top: top,
192
+ };
193
+ };
194
+
195
+ me.preventDefaultException = function (el, exceptions) {
196
+ for (var i in exceptions) {
197
+ if (exceptions[i].test(el[i])) {
198
+ return true;
199
+ }
200
+ }
201
+
202
+ return false;
203
+ };
204
+
205
+ me.extend((me.eventType = {}), {
206
+ touchstart: 1,
207
+ touchmove: 1,
208
+ touchend: 1,
209
+
210
+ mousedown: 2,
211
+ mousemove: 2,
212
+ mouseup: 2,
213
+
214
+ pointerdown: 3,
215
+ pointermove: 3,
216
+ pointerup: 3,
217
+
218
+ MSPointerDown: 3,
219
+ MSPointerMove: 3,
220
+ MSPointerUp: 3,
221
+ });
222
+
223
+ me.extend((me.ease = {}), {
224
+ quadratic: {
225
+ style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
226
+ fn: function (k) {
227
+ return k * (2 - k);
228
+ },
229
+ },
230
+ circular: {
231
+ style: 'cubic-bezier(0.1, 0.57, 0.1, 1)', // Not properly "circular" but this looks better, it should be (0.075, 0.82, 0.165, 1)
232
+ fn: function (k) {
233
+ return Math.sqrt(1 - --k * k);
234
+ },
235
+ },
236
+ back: {
237
+ style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)',
238
+ fn: function (k) {
239
+ var b = 4;
240
+ return (k = k - 1) * k * ((b + 1) * k + b) + 1;
241
+ },
242
+ },
243
+ bounce: {
244
+ style: '',
245
+ fn: function (k) {
246
+ if ((k /= 1) < 1 / 2.75) {
247
+ return 7.5625 * k * k;
248
+ } else if (k < 2 / 2.75) {
249
+ return 7.5625 * (k -= 1.5 / 2.75) * k + 0.75;
250
+ } else if (k < 2.5 / 2.75) {
251
+ return 7.5625 * (k -= 2.25 / 2.75) * k + 0.9375;
252
+ } else {
253
+ return 7.5625 * (k -= 2.625 / 2.75) * k + 0.984375;
254
+ }
255
+ },
256
+ },
257
+ elastic: {
258
+ style: '',
259
+ fn: function (k) {
260
+ var f = 0.22;
261
+ var e = 0.4;
262
+
263
+ if (k === 0) {
264
+ return 0;
265
+ }
266
+ if (k == 1) {
267
+ return 1;
268
+ }
269
+
270
+ return e * Math.pow(2, -10 * k) * Math.sin(((k - f / 4) * (2 * Math.PI)) / f) + 1;
271
+ },
272
+ },
273
+ });
274
+
275
+ me.tap = function (e, eventName) {
276
+ var ev = document.createEvent('Event');
277
+ ev.initEvent(eventName, true, true);
278
+ ev.pageX = e.pageX;
279
+ ev.pageY = e.pageY;
280
+ e.target.dispatchEvent(ev);
281
+ };
282
+
283
+ me.click = function (e) {
284
+ var target = e.target;
285
+ var ev;
286
+
287
+ if (!/(SELECT|INPUT|TEXTAREA)/i.test(target.tagName)) {
288
+ // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent
289
+ // initMouseEvent is deprecated.
290
+ ev = document.createEvent(window.MouseEvent ? 'MouseEvents' : 'Event');
291
+ ev.initEvent('click', true, true);
292
+ ev.view = e.view || window;
293
+ ev.detail = 1;
294
+ ev.screenX = target.screenX || 0;
295
+ ev.screenY = target.screenY || 0;
296
+ ev.clientX = target.clientX || 0;
297
+ ev.clientY = target.clientY || 0;
298
+ ev.ctrlKey = !!e.ctrlKey;
299
+ ev.altKey = !!e.altKey;
300
+ ev.shiftKey = !!e.shiftKey;
301
+ ev.metaKey = !!e.metaKey;
302
+ ev.button = 0;
303
+ ev.relatedTarget = null;
304
+ ev._constructed = true;
305
+ target.dispatchEvent(ev);
306
+ }
307
+ };
308
+
309
+ me.getTouchAction = function (eventPassthrough, addPinch) {
310
+ var touchAction = 'none';
311
+ if (eventPassthrough === 'vertical') {
312
+ touchAction = 'pan-y';
313
+ } else if (eventPassthrough === 'horizontal') {
314
+ touchAction = 'pan-x';
315
+ }
316
+ if (addPinch && touchAction != 'none') {
317
+ // add pinch-zoom support if the browser supports it, but if not (eg. Chrome <55) do nothing
318
+ touchAction += ' pinch-zoom';
319
+ }
320
+ return touchAction;
321
+ };
322
+
323
+ me.getRect = function (el) {
324
+ if (el instanceof SVGElement) {
325
+ var rect = el.getBoundingClientRect();
326
+ return {
327
+ top: rect.top,
328
+ left: rect.left,
329
+ width: rect.width,
330
+ height: rect.height,
331
+ };
332
+ } else {
333
+ return {
334
+ top: el.offsetTop,
335
+ left: el.offsetLeft,
336
+ width: el.offsetWidth,
337
+ height: el.offsetHeight,
338
+ };
339
+ }
340
+ };
341
+
342
+ return me;
343
+ })();
344
+ function IScroll(el, options) {
345
+ this.wrapper = typeof el == 'string' ? document.querySelector(el) : el;
346
+ this.scroller = this.wrapper.children[0];
347
+ this.scrollerStyle = this.scroller.style; // cache style for better performance
348
+
349
+ this.options = {
350
+ zoomMin: 1,
351
+ zoomMax: 4,
352
+ startZoom: 1,
353
+
354
+ resizeScrollbars: true,
355
+
356
+ mouseWheelSpeed: 20,
357
+ mouseWheelTimeout: 400,
358
+
359
+ snapThreshold: 0.334,
360
+
361
+ // INSERT POINT: OPTIONS
362
+ disablePointer: !utils.hasPointer,
363
+ disableTouch: utils.hasPointer || !utils.hasTouch,
364
+ disableMouse: utils.hasPointer || utils.hasTouch,
365
+ startX: 0,
366
+ startY: 0,
367
+ scrollY: true,
368
+ directionLockThreshold: 5,
369
+ momentum: true,
370
+
371
+ bounce: true,
372
+ bounceTime: 600,
373
+ bounceEasing: '',
374
+
375
+ preventDefault: true,
376
+ preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT)$/ },
377
+
378
+ HWCompositing: true,
379
+ useTransition: true,
380
+ useTransform: true,
381
+ bindToWrapper: typeof window.onmousedown === 'undefined',
382
+ };
383
+
384
+ for (var i in options) {
385
+ this.options[i] = options[i];
386
+ }
387
+
388
+ // Normalize options
389
+ this.translateZ = this.options.HWCompositing && utils.hasPerspective ? ' translateZ(0)' : '';
390
+
391
+ this.options.useTransition = utils.hasTransition && this.options.useTransition;
392
+ this.options.useTransform = utils.hasTransform && this.options.useTransform;
393
+
394
+ this.options.eventPassthrough =
395
+ this.options.eventPassthrough === true ? 'vertical' : this.options.eventPassthrough;
396
+ this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault;
397
+
398
+ // If you want eventPassthrough I have to lock one of the axes
399
+ this.options.scrollY = this.options.eventPassthrough == 'vertical' ? false : this.options.scrollY;
400
+ this.options.scrollX = this.options.eventPassthrough == 'horizontal' ? false : this.options.scrollX;
401
+
402
+ // With eventPassthrough we also need lockDirection mechanism
403
+ this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough;
404
+ this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold;
405
+
406
+ this.options.bounceEasing =
407
+ typeof this.options.bounceEasing == 'string'
408
+ ? utils.ease[this.options.bounceEasing] || utils.ease.circular
409
+ : this.options.bounceEasing;
410
+
411
+ this.options.resizePolling = this.options.resizePolling === undefined ? 60 : this.options.resizePolling;
412
+
413
+ if (this.options.tap === true) {
414
+ this.options.tap = 'tap';
415
+ }
416
+
417
+ // https://github.com/cubiq/iscroll/issues/1029
418
+ if (!this.options.useTransition && !this.options.useTransform) {
419
+ if (!/relative|absolute/i.test(this.scrollerStyle.position)) {
420
+ this.scrollerStyle.position = 'relative';
421
+ }
422
+ }
423
+
424
+ if (this.options.shrinkScrollbars == 'scale') {
425
+ this.options.useTransition = false;
426
+ }
427
+
428
+ this.options.invertWheelDirection = this.options.invertWheelDirection ? -1 : 1;
429
+
430
+ // INSERT POINT: NORMALIZATION
431
+
432
+ // Some defaults
433
+ this.x = 0;
434
+ this.y = 0;
435
+ this.directionX = 0;
436
+ this.directionY = 0;
437
+ this._events = {};
438
+
439
+ this.scale = Math.min(Math.max(this.options.startZoom, this.options.zoomMin), this.options.zoomMax);
440
+
441
+ // INSERT POINT: DEFAULTS
442
+
443
+ this._init();
444
+ this.refresh();
445
+
446
+ this.scrollTo(this.options.startX, this.options.startY);
447
+ this.enable();
448
+ }
449
+
450
+ IScroll.prototype = {
451
+ version: '5.2.0-snapshot',
452
+
453
+ _init: function () {
454
+ this._initEvents();
455
+
456
+ if (this.options.zoom) {
457
+ this._initZoom();
458
+ }
459
+
460
+ if (this.options.scrollbars || this.options.indicators) {
461
+ this._initIndicators();
462
+ }
463
+
464
+ if (this.options.mouseWheel) {
465
+ this._initWheel();
466
+ }
467
+
468
+ if (this.options.snap) {
469
+ this._initSnap();
470
+ }
471
+
472
+ if (this.options.keyBindings) {
473
+ this._initKeys();
474
+ }
475
+
476
+ // INSERT POINT: _init
477
+ },
478
+
479
+ destroy: function () {
480
+ this._initEvents(true);
481
+ clearTimeout(this.resizeTimeout);
482
+ this.resizeTimeout = null;
483
+ this._execEvent('destroy');
484
+ },
485
+
486
+ _transitionEnd: function (e) {
487
+ if (e.target != this.scroller || !this.isInTransition) {
488
+ return;
489
+ }
490
+
491
+ this._transitionTime();
492
+ if (!this.resetPosition(this.options.bounceTime)) {
493
+ this.isInTransition = false;
494
+ this._execEvent('scrollEnd');
495
+ }
496
+ },
497
+
498
+ _start: function (e) {
499
+ //ignore secondary touch
500
+ if (e.type == 'pointerdown' && !e.isPrimary) {
501
+ return;
502
+ }
503
+ // React to left mouse button only
504
+ if (utils.eventType[e.type] != 1) {
505
+ // for button property
506
+ // http://unixpapa.com/js/mouse.html
507
+ var button;
508
+ if (!e.which) {
509
+ /* IE case */
510
+ button = e.button < 2 ? 0 : e.button == 4 ? 1 : 2;
511
+ } else {
512
+ /* All others */
513
+ button = e.button;
514
+ }
515
+ if (button !== 0) {
516
+ return;
517
+ }
518
+ }
519
+
520
+ if (!this.enabled || (this.initiated && utils.eventType[e.type] !== this.initiated)) {
521
+ return;
522
+ }
523
+
524
+ if (
525
+ this.options.preventDefault &&
526
+ !utils.isBadAndroid &&
527
+ !utils.preventDefaultException(e.target, this.options.preventDefaultException)
528
+ ) {
529
+ e.preventDefault();
530
+ }
531
+
532
+ var point = e.touches ? e.touches[0] : e;
533
+ var pos;
534
+
535
+ this.initiated = utils.eventType[e.type];
536
+ this.moved = false;
537
+ this.distX = 0;
538
+ this.distY = 0;
539
+ this.directionX = 0;
540
+ this.directionY = 0;
541
+ this.directionLocked = 0;
542
+
543
+ this.startTime = utils.getTime();
544
+
545
+ if (this.options.useTransition && this.isInTransition) {
546
+ this._transitionTime();
547
+ this.isInTransition = false;
548
+ pos = this.getComputedPosition();
549
+ this._translate(Math.round(pos.x), Math.round(pos.y));
550
+ this._execEvent('scrollEnd');
551
+ } else if (!this.options.useTransition && this.isAnimating) {
552
+ this.isAnimating = false;
553
+ this._execEvent('scrollEnd');
554
+ }
555
+
556
+ this.startX = this.x;
557
+ this.startY = this.y;
558
+ this.absStartX = this.x;
559
+ this.absStartY = this.y;
560
+ this.pointX = point.pageX;
561
+ this.pointY = point.pageY;
562
+
563
+ this._execEvent('beforeScrollStart');
564
+ },
565
+
566
+ _move: function (e) {
567
+ if (!this.enabled || utils.eventType[e.type] !== this.initiated) {
568
+ return;
569
+ }
570
+
571
+ //ignore secondary touch
572
+ if (e.type == 'pointermove' && !e.isPrimary) {
573
+ return;
574
+ }
575
+
576
+ if (this.options.preventDefault) {
577
+ // increases performance on Android? TODO: check!
578
+ e.preventDefault();
579
+ }
580
+
581
+ var point = e.touches ? e.touches[0] : e;
582
+ var deltaX = point.pageX - this.pointX;
583
+ var deltaY = point.pageY - this.pointY;
584
+ var timestamp = utils.getTime();
585
+ var newX;
586
+ var newY;
587
+ var absDistX;
588
+ var absDistY;
589
+
590
+ this.pointX = point.pageX;
591
+ this.pointY = point.pageY;
592
+
593
+ this.distX += deltaX;
594
+ this.distY += deltaY;
595
+ absDistX = Math.abs(this.distX);
596
+ absDistY = Math.abs(this.distY);
597
+
598
+ // We need to move at least 10 pixels for the scrolling to initiate
599
+ if (timestamp - this.endTime > 300 && absDistX < 10 && absDistY < 10) {
600
+ return;
601
+ }
602
+
603
+ // If you are scrolling in one direction lock the other
604
+ if (!this.directionLocked && !this.options.freeScroll) {
605
+ if (absDistX > absDistY + this.options.directionLockThreshold) {
606
+ this.directionLocked = 'h'; // lock horizontally
607
+ } else if (absDistY >= absDistX + this.options.directionLockThreshold) {
608
+ this.directionLocked = 'v'; // lock vertically
609
+ } else {
610
+ this.directionLocked = 'n'; // no lock
611
+ }
612
+ }
613
+
614
+ if (this.directionLocked == 'h') {
615
+ if (this.options.eventPassthrough == 'vertical') {
616
+ e.preventDefault();
617
+ } else if (this.options.eventPassthrough == 'horizontal') {
618
+ this.initiated = false;
619
+ return;
620
+ }
621
+
622
+ deltaY = 0;
623
+ } else if (this.directionLocked == 'v') {
624
+ if (this.options.eventPassthrough == 'horizontal') {
625
+ e.preventDefault();
626
+ } else if (this.options.eventPassthrough == 'vertical') {
627
+ this.initiated = false;
628
+ return;
629
+ }
630
+
631
+ deltaX = 0;
632
+ }
633
+
634
+ deltaX = this.hasHorizontalScroll ? deltaX : 0;
635
+ deltaY = this.hasVerticalScroll ? deltaY : 0;
636
+
637
+ newX = this.x + deltaX;
638
+ newY = this.y + deltaY;
639
+
640
+ // Slow down if outside of the boundaries
641
+ if (newX > 0 || newX < this.maxScrollX) {
642
+ newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX;
643
+ }
644
+ if (newY > 0 || newY < this.maxScrollY) {
645
+ newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY;
646
+ }
647
+
648
+ this.directionX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0;
649
+ this.directionY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0;
650
+
651
+ if (!this.moved) {
652
+ this._execEvent('scrollStart');
653
+ }
654
+
655
+ this.moved = true;
656
+
657
+ this._translate(newX, newY);
658
+
659
+ /* REPLACE START: _move */
660
+
661
+ if (timestamp - this.startTime > 300) {
662
+ this.startTime = timestamp;
663
+ this.startX = this.x;
664
+ this.startY = this.y;
665
+ }
666
+
667
+ /* REPLACE END: _move */
668
+ },
669
+
670
+ _end: function (e) {
671
+ if (!this.enabled || utils.eventType[e.type] !== this.initiated) {
672
+ return;
673
+ }
674
+
675
+ //ignore secondary touch
676
+ if (e.type == 'pointerup' && !e.isPrimary) {
677
+ return;
678
+ }
679
+
680
+ if (
681
+ this.options.preventDefault &&
682
+ !utils.preventDefaultException(e.target, this.options.preventDefaultException)
683
+ ) {
684
+ e.preventDefault();
685
+ }
686
+
687
+ var point = e.changedTouches ? e.changedTouches[0] : e;
688
+ var momentumX;
689
+ var momentumY;
690
+ var duration = utils.getTime() - this.startTime;
691
+ var newX = Math.round(this.x);
692
+ var newY = Math.round(this.y);
693
+ var distanceX = Math.abs(newX - this.startX);
694
+ var distanceY = Math.abs(newY - this.startY);
695
+ var time = 0;
696
+ var easing = '';
697
+
698
+ this.isInTransition = 0;
699
+ this.initiated = 0;
700
+ this.endTime = utils.getTime();
701
+
702
+ // reset if we are outside of the boundaries
703
+ if (this.resetPosition(this.options.bounceTime)) {
704
+ return;
705
+ }
706
+
707
+ this.scrollTo(newX, newY); // ensures that the last position is rounded
708
+
709
+ // we scrolled less than 10 pixels
710
+ if (!this.moved) {
711
+ if (this.options.tap) {
712
+ utils.tap(e, this.options.tap);
713
+ }
714
+
715
+ if (this.options.click) {
716
+ utils.click(e);
717
+ }
718
+
719
+ this._execEvent('scrollCancel');
720
+ return;
721
+ }
722
+
723
+ if (this._events.flick && duration < 200 && distanceX < 100 && distanceY < 100) {
724
+ this._execEvent('flick');
725
+ return;
726
+ }
727
+
728
+ // start momentum animation if needed
729
+ if (this.options.momentum && duration < 300) {
730
+ momentumX = this.hasHorizontalScroll
731
+ ? utils.momentum(
732
+ this.x,
733
+ this.startX,
734
+ duration,
735
+ this.maxScrollX,
736
+ this.options.bounce ? this.wrapperWidth : 0,
737
+ this.options.deceleration
738
+ )
739
+ : { destination: newX, duration: 0 };
740
+ momentumY = this.hasVerticalScroll
741
+ ? utils.momentum(
742
+ this.y,
743
+ this.startY,
744
+ duration,
745
+ this.maxScrollY,
746
+ this.options.bounce ? this.wrapperHeight : 0,
747
+ this.options.deceleration
748
+ )
749
+ : { destination: newY, duration: 0 };
750
+ newX = momentumX.destination;
751
+ newY = momentumY.destination;
752
+ time = Math.max(momentumX.duration, momentumY.duration);
753
+ this.isInTransition = 1;
754
+ }
755
+
756
+ if (this.options.snap) {
757
+ var snap = this._nearestSnap(newX, newY);
758
+ this.currentPage = snap;
759
+ time =
760
+ this.options.snapSpeed ||
761
+ Math.max(
762
+ Math.max(Math.min(Math.abs(newX - snap.x), 1000), Math.min(Math.abs(newY - snap.y), 1000)),
763
+ 300
764
+ );
765
+ newX = snap.x;
766
+ newY = snap.y;
767
+
768
+ this.directionX = 0;
769
+ this.directionY = 0;
770
+ easing = this.options.bounceEasing;
771
+ }
772
+
773
+ // INSERT POINT: _end
774
+
775
+ if (newX != this.x || newY != this.y) {
776
+ // change easing function when scroller goes out of the boundaries
777
+ if (newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY) {
778
+ easing = utils.ease.quadratic;
779
+ }
780
+
781
+ this.scrollTo(newX, newY, time, easing);
782
+
783
+ //custom
784
+ this._execEvent('scrollToPage');
785
+ return;
786
+ }
787
+
788
+ this._execEvent('scrollEnd');
789
+ },
790
+
791
+ _resize: function () {
792
+ var that = this;
793
+
794
+ clearTimeout(this.resizeTimeout);
795
+
796
+ this.resizeTimeout = setTimeout(function () {
797
+ that.refresh();
798
+ }, this.options.resizePolling);
799
+ },
800
+
801
+ resetPosition: function (time) {
802
+ var x = this.x;
803
+ var y = this.y;
804
+
805
+ time = time || 0;
806
+
807
+ if (!this.hasHorizontalScroll || this.x > 0) {
808
+ x = 0;
809
+ // custom start
810
+ if (this.options.keepInCenterH && this.getScrollerWidth() * this.scale < this.wrapperWidth) {
811
+ x = this.wrapperWidth / 2 - (this.getScrollerWidth() * this.scale) / 2;
812
+ }
813
+ // custom end
814
+ } else if (this.x < this.maxScrollX) {
815
+ x = this.maxScrollX;
816
+ }
817
+
818
+ if (!this.hasVerticalScroll || this.y > 0) {
819
+ y = 0;
820
+ // custom start
821
+ if (this.options.keepInCenterV && this.getScrollerHeight() * this.scale < this.wrapperHeight) {
822
+ y = this.wrapperHeight / 2 - (this.getScrollerHeight() * this.scale) / 2;
823
+ }
824
+ // custom end
825
+ } else if (this.y < this.maxScrollY) {
826
+ y = this.maxScrollY;
827
+ }
828
+
829
+ if (x == this.x && y == this.y) {
830
+ return false;
831
+ }
832
+
833
+ this.scrollTo(x, y, time, this.options.bounceEasing);
834
+
835
+ return true;
836
+ },
837
+
838
+ disable: function () {
839
+ this.enabled = false;
840
+ },
841
+
842
+ enable: function () {
843
+ this.enabled = true;
844
+ },
845
+
846
+ //custom
847
+
848
+ setScrollerSize: function (w, h) {
849
+ this.scrollerW = w;
850
+ this.scrollerH = h;
851
+ },
852
+
853
+ setWrapperOffset: function (left, top) {
854
+ this.wrapperOffsetLeft = left;
855
+ this.wrapperOffsetTop = top;
856
+ },
857
+
858
+ //custom end
859
+
860
+ refresh: function () {
861
+ utils.getRect(this.wrapper); // Force reflow
862
+
863
+ this.wrapperWidth = this.wrapper.clientWidth;
864
+ this.wrapperHeight = this.wrapper.clientHeight;
865
+
866
+ var rect = utils.getRect(this.scroller);
867
+ if (this.scrollerW) {
868
+ rect.width = this.scrollerW;
869
+ }
870
+ if (this.scrollerH) {
871
+ rect.height = this.scrollerH;
872
+ }
873
+ /* REPLACE START: refresh */
874
+ this.scrollerWidth = Math.round(rect.width * this.scale);
875
+ this.scrollerHeight = Math.round(rect.height * this.scale);
876
+
877
+ this.maxScrollX = this.wrapperWidth - this.scrollerWidth;
878
+ this.maxScrollY = this.wrapperHeight - this.scrollerHeight;
879
+ /* REPLACE END: refresh */
880
+
881
+ this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < 0;
882
+ this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0;
883
+
884
+ if (!this.hasHorizontalScroll) {
885
+ this.maxScrollX = 0;
886
+ this.scrollerWidth = this.wrapperWidth;
887
+ }
888
+
889
+ if (!this.hasVerticalScroll) {
890
+ this.maxScrollY = 0;
891
+ this.scrollerHeight = this.wrapperHeight;
892
+ }
893
+
894
+ this.endTime = 0;
895
+ this.directionX = 0;
896
+ this.directionY = 0;
897
+
898
+ if (utils.hasPointer && !this.options.disablePointer) {
899
+ // The wrapper should have `touchAction` property for using pointerEvent.
900
+ this.wrapper.style[utils.style.touchAction] = utils.getTouchAction(this.options.eventPassthrough, true);
901
+
902
+ // case. not support 'pinch-zoom'
903
+ // https://github.com/cubiq/iscroll/issues/1118#issuecomment-270057583
904
+ if (!this.wrapper.style[utils.style.touchAction]) {
905
+ this.wrapper.style[utils.style.touchAction] = utils.getTouchAction(
906
+ this.options.eventPassthrough,
907
+ false
908
+ );
909
+ }
910
+ }
911
+ this.wrapperOffset = utils.offset(this.wrapper);
912
+ if (this.wrapperOffsetLeft) {
913
+ this.wrapperOffset.left = this.wrapperOffsetLeft;
914
+ }
915
+ if (this.wrapperOffsetTop) {
916
+ this.wrapperOffset.top = this.wrapperOffsetTop;
917
+ }
918
+
919
+ this._execEvent('refresh');
920
+
921
+ this.resetPosition();
922
+
923
+ // INSERT POINT: _refresh
924
+ },
925
+
926
+ on: function (type, fn) {
927
+ if (!this._events[type]) {
928
+ this._events[type] = [];
929
+ }
930
+
931
+ this._events[type].push(fn);
932
+ },
933
+
934
+ off: function (type, fn) {
935
+ if (!this._events[type]) {
936
+ return;
937
+ }
938
+
939
+ var index = this._events[type].indexOf(fn);
940
+
941
+ if (index > -1) {
942
+ this._events[type].splice(index, 1);
943
+ }
944
+ },
945
+
946
+ _execEvent: function (type) {
947
+ if (!this._events[type]) {
948
+ return;
949
+ }
950
+
951
+ var i = 0;
952
+ var l = this._events[type].length;
953
+
954
+ if (!l) {
955
+ return;
956
+ }
957
+
958
+ for (; i < l; i++) {
959
+ this._events[type][i].apply(this, [].slice.call(arguments, 1));
960
+ }
961
+ },
962
+
963
+ scrollBy: function (x, y, time, easing) {
964
+ x = this.x + x;
965
+ y = this.y + y;
966
+ time = time || 0;
967
+
968
+ this.scrollTo(x, y, time, easing);
969
+ },
970
+
971
+ //custom
972
+
973
+ getScrollerWidth: function () {
974
+ return this.scrollerW !== undefined ? this.scrollerW : this.scroller.offsetWidth;
975
+ },
976
+
977
+ getScrollerHeight: function () {
978
+ return this.scrollerH !== undefined ? this.scrollerH : this.scroller.offsetHeight;
979
+ },
980
+
981
+ //end custom
982
+
983
+ scrollTo: function (x, y, time, easing) {
984
+ /*custom*/
985
+
986
+ if (this.wrapperWidth == 0 || this.wrapperHeight == 0) {
987
+ return;
988
+ }
989
+
990
+ if (time) {
991
+ if (this.prevDisabled && x == 0) {
992
+ this.goToPage(1, 0, 0);
993
+ return;
994
+ }
995
+
996
+ if (this.nextDisabled && x == -(this.scrollerWidth - this.wrapperWidth)) {
997
+ this.goToPage(1, 0, 0);
998
+ return;
999
+ }
1000
+ }
1001
+
1002
+ if (this.options.keepInCenterH && this.getScrollerWidth() * this.scale < this.wrapperWidth) {
1003
+ x = this.wrapperWidth / 2 - (this.getScrollerWidth() * this.scale) / 2;
1004
+ }
1005
+
1006
+ if (this.options.keepInCenterV && this.getScrollerHeight() * this.scale < this.wrapperHeight) {
1007
+ y = this.wrapperHeight / 2 - (this.getScrollerHeight() * this.scale) / 2;
1008
+ }
1009
+ /*end custom*/
1010
+
1011
+ easing = easing || utils.ease.circular;
1012
+
1013
+ this.isInTransition = this.options.useTransition && time > 0;
1014
+ var transitionType = this.options.useTransition && easing.style;
1015
+ if (!time || transitionType) {
1016
+ if (transitionType) {
1017
+ this._transitionTimingFunction(easing.style);
1018
+ this._transitionTime(time);
1019
+ }
1020
+ this._translate(x, y);
1021
+ } else {
1022
+ this._animate(x, y, time, easing.fn);
1023
+ }
1024
+ },
1025
+
1026
+ scrollToElement: function (el, time, offsetX, offsetY, easing) {
1027
+ el = el.nodeType ? el : this.scroller.querySelector(el);
1028
+
1029
+ if (!el) {
1030
+ return;
1031
+ }
1032
+
1033
+ var pos = utils.offset(el);
1034
+
1035
+ pos.left -= this.wrapperOffset.left;
1036
+ pos.top -= this.wrapperOffset.top;
1037
+
1038
+ // if offsetX/Y are true we center the element to the screen
1039
+ var elRect = utils.getRect(el);
1040
+ var wrapperRect = utils.getRect(this.wrapper);
1041
+ if (offsetX === true) {
1042
+ offsetX = Math.round(elRect.width / 2 - wrapperRect.width / 2);
1043
+ }
1044
+ if (offsetY === true) {
1045
+ offsetY = Math.round(elRect.height / 2 - wrapperRect.height / 2);
1046
+ }
1047
+
1048
+ pos.left -= offsetX || 0;
1049
+ pos.top -= offsetY || 0;
1050
+
1051
+ pos.left = pos.left > 0 ? 0 : pos.left < this.maxScrollX ? this.maxScrollX : pos.left;
1052
+ pos.top = pos.top > 0 ? 0 : pos.top < this.maxScrollY ? this.maxScrollY : pos.top;
1053
+
1054
+ time =
1055
+ time === undefined || time === null || time === 'auto'
1056
+ ? Math.max(Math.abs(this.x - pos.left), Math.abs(this.y - pos.top))
1057
+ : time;
1058
+
1059
+ this.scrollTo(pos.left, pos.top, time, easing);
1060
+ },
1061
+
1062
+ _transitionTime: function (time) {
1063
+ if (!this.options.useTransition) {
1064
+ return;
1065
+ }
1066
+ time = time || 0;
1067
+ var durationProp = utils.style.transitionDuration;
1068
+ if (!durationProp) {
1069
+ return;
1070
+ }
1071
+
1072
+ this.scrollerStyle[durationProp] = time + 'ms';
1073
+
1074
+ if (!time && utils.isBadAndroid) {
1075
+ this.scrollerStyle[durationProp] = '0.0001ms';
1076
+ // remove 0.0001ms
1077
+ var self = this;
1078
+ rAF(function () {
1079
+ if (self.scrollerStyle[durationProp] === '0.0001ms') {
1080
+ self.scrollerStyle[durationProp] = '0s';
1081
+ }
1082
+ });
1083
+ }
1084
+
1085
+ if (this.indicators) {
1086
+ for (var i = this.indicators.length; i--; ) {
1087
+ this.indicators[i].transitionTime(time);
1088
+ }
1089
+ }
1090
+
1091
+ // INSERT POINT: _transitionTime
1092
+ },
1093
+
1094
+ _transitionTimingFunction: function (easing) {
1095
+ this.scrollerStyle[utils.style.transitionTimingFunction] = easing;
1096
+
1097
+ if (this.indicators) {
1098
+ for (var i = this.indicators.length; i--; ) {
1099
+ this.indicators[i].transitionTimingFunction(easing);
1100
+ }
1101
+ }
1102
+
1103
+ // INSERT POINT: _transitionTimingFunction
1104
+ },
1105
+
1106
+ _translate: function (x, y) {
1107
+ if (this.options.useTransform) {
1108
+ /* REPLACE START: _translate */ this.scrollerStyle[utils.style.transform] =
1109
+ 'translate(' +
1110
+ x +
1111
+ 'px,' +
1112
+ y +
1113
+ 'px) scale(' +
1114
+ this.scale +
1115
+ ') ' +
1116
+ this.translateZ; /* REPLACE END: _translate */
1117
+ } else {
1118
+ x = Math.round(x);
1119
+ y = Math.round(y);
1120
+ this.scrollerStyle.left = x + 'px';
1121
+ this.scrollerStyle.top = y + 'px';
1122
+ }
1123
+
1124
+ this.x = x;
1125
+ this.y = y;
1126
+
1127
+ if (this.indicators) {
1128
+ for (var i = this.indicators.length; i--; ) {
1129
+ this.indicators[i].updatePosition();
1130
+ }
1131
+ }
1132
+
1133
+ // INSERT POINT: _translate
1134
+ },
1135
+
1136
+ _initEvents: function (remove) {
1137
+ var eventType = remove ? utils.removeEvent : utils.addEvent;
1138
+ var target = this.options.bindToWrapper ? this.wrapper : window;
1139
+
1140
+ eventType(window, 'orientationchange', this);
1141
+ eventType(window, 'resize', this);
1142
+
1143
+ if (this.options.click) {
1144
+ eventType(this.wrapper, 'click', this, true);
1145
+ }
1146
+
1147
+ if (!this.options.disableMouse) {
1148
+ eventType(this.wrapper, 'mousedown', this);
1149
+ eventType(target, 'mousemove', this);
1150
+ eventType(target, 'mousecancel', this);
1151
+ eventType(target, 'mouseup', this);
1152
+ }
1153
+
1154
+ if (utils.hasPointer && !this.options.disablePointer) {
1155
+ eventType(this.wrapper, utils.prefixPointerEvent('pointerdown'), this);
1156
+ eventType(target, utils.prefixPointerEvent('pointermove'), this);
1157
+ eventType(target, utils.prefixPointerEvent('pointercancel'), this);
1158
+ eventType(target, utils.prefixPointerEvent('pointerup'), this);
1159
+ }
1160
+
1161
+ if (utils.hasTouch && !this.options.disableTouch) {
1162
+ eventType(this.wrapper, 'touchstart', this);
1163
+ eventType(target, 'touchmove', this);
1164
+ eventType(target, 'touchcancel', this);
1165
+ eventType(target, 'touchend', this);
1166
+ }
1167
+
1168
+ eventType(this.scroller, 'transitionend', this);
1169
+ eventType(this.scroller, 'webkitTransitionEnd', this);
1170
+ eventType(this.scroller, 'oTransitionEnd', this);
1171
+ eventType(this.scroller, 'MSTransitionEnd', this);
1172
+ },
1173
+
1174
+ getComputedPosition: function () {
1175
+ var matrix = window.getComputedStyle(this.scroller, null);
1176
+ var x;
1177
+ var y;
1178
+
1179
+ if (this.options.useTransform) {
1180
+ matrix = matrix[utils.style.transform].split(')')[0].split(', ');
1181
+ x = +(matrix[12] || matrix[4]);
1182
+ y = +(matrix[13] || matrix[5]);
1183
+ } else {
1184
+ x = +matrix.left.replace(/[^-\d.]/g, '');
1185
+ y = +matrix.top.replace(/[^-\d.]/g, '');
1186
+ }
1187
+
1188
+ return { x: x, y: y };
1189
+ },
1190
+ _initIndicators: function () {
1191
+ var interactive = this.options.interactiveScrollbars;
1192
+ var customStyle = typeof this.options.scrollbars != 'string';
1193
+ var indicators = [];
1194
+ var indicator;
1195
+
1196
+ var that = this;
1197
+
1198
+ this.indicators = [];
1199
+
1200
+ if (this.options.scrollbars) {
1201
+ // Vertical scrollbar
1202
+ if (this.options.scrollY) {
1203
+ indicator = {
1204
+ el: createDefaultScrollbar('v', interactive, this.options.scrollbars),
1205
+ interactive: interactive,
1206
+ defaultScrollbars: true,
1207
+ customStyle: customStyle,
1208
+ resize: this.options.resizeScrollbars,
1209
+ shrink: this.options.shrinkScrollbars,
1210
+ fade: this.options.fadeScrollbars,
1211
+ listenX: false,
1212
+ };
1213
+
1214
+ this.wrapper.appendChild(indicator.el);
1215
+ indicators.push(indicator);
1216
+ }
1217
+
1218
+ // Horizontal scrollbar
1219
+ if (this.options.scrollX) {
1220
+ indicator = {
1221
+ el: createDefaultScrollbar('h', interactive, this.options.scrollbars),
1222
+ interactive: interactive,
1223
+ defaultScrollbars: true,
1224
+ customStyle: customStyle,
1225
+ resize: this.options.resizeScrollbars,
1226
+ shrink: this.options.shrinkScrollbars,
1227
+ fade: this.options.fadeScrollbars,
1228
+ listenY: false,
1229
+ };
1230
+
1231
+ this.wrapper.appendChild(indicator.el);
1232
+ indicators.push(indicator);
1233
+ }
1234
+ }
1235
+
1236
+ if (this.options.indicators) {
1237
+ // TODO: check concat compatibility
1238
+ indicators = indicators.concat(this.options.indicators);
1239
+ }
1240
+
1241
+ for (var i = indicators.length; i--; ) {
1242
+ this.indicators.push(new Indicator(this, indicators[i]));
1243
+ }
1244
+
1245
+ // TODO: check if we can use array.map (wide compatibility and performance issues)
1246
+ function _indicatorsMap(fn) {
1247
+ if (that.indicators) {
1248
+ for (var i = that.indicators.length; i--; ) {
1249
+ fn.call(that.indicators[i]);
1250
+ }
1251
+ }
1252
+ }
1253
+
1254
+ if (this.options.fadeScrollbars) {
1255
+ this.on('scrollEnd', function () {
1256
+ _indicatorsMap(function () {
1257
+ this.fade();
1258
+ });
1259
+ });
1260
+
1261
+ this.on('scrollCancel', function () {
1262
+ _indicatorsMap(function () {
1263
+ this.fade();
1264
+ });
1265
+ });
1266
+
1267
+ this.on('scrollStart', function () {
1268
+ _indicatorsMap(function () {
1269
+ this.fade(1);
1270
+ });
1271
+ });
1272
+
1273
+ this.on('beforeScrollStart', function () {
1274
+ _indicatorsMap(function () {
1275
+ this.fade(1, true);
1276
+ });
1277
+ });
1278
+ }
1279
+
1280
+ this.on('refresh', function () {
1281
+ _indicatorsMap(function () {
1282
+ this.refresh();
1283
+ });
1284
+ });
1285
+
1286
+ this.on('destroy', function () {
1287
+ _indicatorsMap(function () {
1288
+ this.destroy();
1289
+ });
1290
+
1291
+ delete this.indicators;
1292
+ });
1293
+ },
1294
+
1295
+ _initZoom: function () {
1296
+ this.scrollerStyle[utils.style.transformOrigin] = '0 0';
1297
+ },
1298
+
1299
+ _zoomStart: function (e) {
1300
+ var c1 = Math.abs(e.touches[0].pageX - e.touches[1].pageX);
1301
+ var c2 = Math.abs(e.touches[0].pageY - e.touches[1].pageY);
1302
+
1303
+ this.touchesDistanceStart = Math.sqrt(c1 * c1 + c2 * c2);
1304
+ this.startScale = this.scale;
1305
+
1306
+ this.originX = Math.abs(e.touches[0].pageX + e.touches[1].pageX) / 2 + this.wrapperOffset.left - this.x;
1307
+ this.originY = Math.abs(e.touches[0].pageY + e.touches[1].pageY) / 2 + this.wrapperOffset.top - this.y;
1308
+
1309
+ this._execEvent('zoomStart');
1310
+ },
1311
+
1312
+ _zoom: function (e) {
1313
+ if (!this.enabled || utils.eventType[e.type] !== this.initiated) {
1314
+ return;
1315
+ }
1316
+
1317
+ if (this.options.preventDefault) {
1318
+ e.preventDefault();
1319
+ }
1320
+
1321
+ var c1 = Math.abs(e.touches[0].pageX - e.touches[1].pageX);
1322
+ var c2 = Math.abs(e.touches[0].pageY - e.touches[1].pageY);
1323
+ var distance = Math.sqrt(c1 * c1 + c2 * c2);
1324
+ var scale = (1 / this.touchesDistanceStart) * distance * this.startScale;
1325
+ var lastScale;
1326
+ var x;
1327
+ var y;
1328
+
1329
+ this.scaled = true;
1330
+
1331
+ if (scale < this.options.zoomMin) {
1332
+ scale = 0.5 * this.options.zoomMin * Math.pow(2.0, scale / this.options.zoomMin);
1333
+ } else if (scale > this.options.zoomMax) {
1334
+ scale = 2.0 * this.options.zoomMax * Math.pow(0.5, this.options.zoomMax / scale);
1335
+ }
1336
+
1337
+ lastScale = scale / this.startScale;
1338
+ x = this.originX - this.originX * lastScale + this.startX;
1339
+ y = this.originY - this.originY * lastScale + this.startY;
1340
+
1341
+ this.scale = scale;
1342
+
1343
+ this.scrollTo(x, y, 0);
1344
+ },
1345
+
1346
+ _zoomEnd: function (e) {
1347
+ if (!this.enabled || utils.eventType[e.type] !== this.initiated) {
1348
+ return;
1349
+ }
1350
+
1351
+ if (this.options.preventDefault) {
1352
+ e.preventDefault();
1353
+ }
1354
+
1355
+ var newX;
1356
+ var newY;
1357
+ var lastScale;
1358
+
1359
+ this.isInTransition = 0;
1360
+ this.initiated = 0;
1361
+
1362
+ if (this.scale > this.options.zoomMax) {
1363
+ this.scale = this.options.zoomMax;
1364
+ } else if (this.scale < this.options.zoomMin) {
1365
+ this.scale = this.options.zoomMin;
1366
+ }
1367
+
1368
+ // Update boundaries
1369
+ this.refresh();
1370
+
1371
+ lastScale = this.scale / this.startScale;
1372
+
1373
+ newX = this.originX - this.originX * lastScale + this.startX;
1374
+ newY = this.originY - this.originY * lastScale + this.startY;
1375
+
1376
+ if (newX > 0) {
1377
+ newX = 0;
1378
+ } else if (newX < this.maxScrollX) {
1379
+ newX = this.maxScrollX;
1380
+ }
1381
+
1382
+ if (newY > 0) {
1383
+ newY = 0;
1384
+ } else if (newY < this.maxScrollY) {
1385
+ newY = this.maxScrollY;
1386
+ }
1387
+
1388
+ if (this.x != newX || this.y != newY) {
1389
+ this.scrollTo(newX, newY, this.options.bounceTime);
1390
+ }
1391
+
1392
+ this.scaled = false;
1393
+
1394
+ this._execEvent('zoomEnd');
1395
+ },
1396
+
1397
+ zoom: function (scale, x, y, time) {
1398
+ /*custom*/
1399
+ if (this.wrapperWidth == 0 || this.wrapperHeight == 0) {
1400
+ return;
1401
+ }
1402
+ /* end custom*/
1403
+
1404
+ if (scale < this.options.zoomMin) {
1405
+ scale = this.options.zoomMin;
1406
+ } else if (scale > this.options.zoomMax) {
1407
+ scale = this.options.zoomMax;
1408
+ }
1409
+
1410
+ if (scale == this.scale) {
1411
+ return;
1412
+ }
1413
+
1414
+ var relScale = scale / this.scale;
1415
+
1416
+ /*custom*/
1417
+ var that = this;
1418
+ if (relScale != 1) {
1419
+ clearTimeout(this.zoomStartTimeout);
1420
+ this.zoomStartTimeout = setTimeout(function () {
1421
+ that._execEvent('zoomStart');
1422
+ }, 0);
1423
+
1424
+ // Execute the zoomEnd event after 400ms the wheel stopped scrolling
1425
+ clearTimeout(this.wheelTimeout);
1426
+ this.wheelTimeout = setTimeout(function () {
1427
+ that._execEvent('zoomEnd');
1428
+ }, Number(time + 100));
1429
+ }
1430
+
1431
+ /*custom end*/
1432
+
1433
+ x = x === undefined ? this.wrapperWidth / 2 : x;
1434
+ y = y === undefined ? this.wrapperHeight / 2 : y;
1435
+ time = time === undefined ? 300 : time;
1436
+
1437
+ x = x + this.wrapperOffset.left - this.x;
1438
+ y = y + this.wrapperOffset.top - this.y;
1439
+
1440
+ x = x - x * relScale + this.x;
1441
+ y = y - y * relScale + this.y;
1442
+
1443
+ this.scale = scale;
1444
+
1445
+ this.refresh(); // update boundaries
1446
+
1447
+ if (x > 0) {
1448
+ x = 0;
1449
+ } else if (x < this.maxScrollX) {
1450
+ x = this.maxScrollX;
1451
+ }
1452
+
1453
+ if (y > 0) {
1454
+ y = 0;
1455
+ } else if (y < this.maxScrollY) {
1456
+ y = this.maxScrollY;
1457
+ }
1458
+
1459
+ this.scrollTo(x, y, time);
1460
+ },
1461
+
1462
+ _wheelZoom: function (e) {
1463
+ var wheelDeltaY;
1464
+ var deltaScale;
1465
+ var that = this;
1466
+
1467
+ /*custom - moved to function zoom()
1468
+
1469
+ // Execute the zoomEnd event after 400ms the wheel stopped scrolling
1470
+ clearTimeout(this.wheelTimeout);
1471
+ this.wheelTimeout = setTimeout(function () {
1472
+ that._execEvent('zoomEnd');
1473
+ }, 400);
1474
+
1475
+ custom end*/
1476
+
1477
+ if ('deltaX' in e) {
1478
+ wheelDeltaY = -e.deltaY / Math.abs(e.deltaY);
1479
+ } else if ('wheelDeltaX' in e) {
1480
+ wheelDeltaY = e.wheelDeltaY / Math.abs(e.wheelDeltaY);
1481
+ } else if ('wheelDelta' in e) {
1482
+ wheelDeltaY = e.wheelDelta / Math.abs(e.wheelDelta);
1483
+ } else if ('detail' in e) {
1484
+ wheelDeltaY = -e.detail / Math.abs(e.wheelDelta);
1485
+ } else {
1486
+ return;
1487
+ }
1488
+
1489
+ deltaScale = this.scale + wheelDeltaY / 5;
1490
+
1491
+ this.zoom(deltaScale, e.pageX, e.pageY, 0);
1492
+ },
1493
+
1494
+ _initWheel: function () {
1495
+ utils.addEvent(this.wrapper, 'wheel', this);
1496
+ utils.addEvent(this.wrapper, 'mousewheel', this);
1497
+ utils.addEvent(this.wrapper, 'DOMMouseScroll', this);
1498
+
1499
+ this.on('destroy', function () {
1500
+ clearTimeout(this.wheelTimeout);
1501
+ this.wheelTimeout = null;
1502
+ utils.removeEvent(this.wrapper, 'wheel', this);
1503
+ utils.removeEvent(this.wrapper, 'mousewheel', this);
1504
+ utils.removeEvent(this.wrapper, 'DOMMouseScroll', this);
1505
+ });
1506
+ },
1507
+
1508
+ _wheel: function (e) {
1509
+ if (!this.enabled) {
1510
+ return;
1511
+ }
1512
+ //custom - prevent default wheel behavior only if options.preventDefault
1513
+ if (this.options.preventDefault) {
1514
+ //custom end
1515
+ e.preventDefault();
1516
+ //custom
1517
+ }
1518
+ //custom end
1519
+ var wheelDeltaX;
1520
+ var wheelDeltaY;
1521
+ var newX;
1522
+ var newY;
1523
+ var that = this;
1524
+
1525
+ if (this.wheelTimeout === undefined) {
1526
+ that._execEvent('scrollStart');
1527
+ }
1528
+
1529
+ // Execute the scrollEnd event after 400ms the wheel stopped scrolling
1530
+ clearTimeout(this.wheelTimeout);
1531
+
1532
+ /* custom - fixed timet 400ms changed to this.options.mouseWheelTimeout, default is 400
1533
+ this.wheelTimeout = setTimeout(function () {
1534
+ if (!that.options.snap) {
1535
+ that._execEvent('scrollEnd');
1536
+ }
1537
+ that.wheelTimeout = undefined;
1538
+ }, 400);
1539
+
1540
+ */
1541
+
1542
+ this.wheelTimeout = setTimeout(function () {
1543
+ if (!that.options.snap) {
1544
+ that._execEvent('scrollEnd');
1545
+ }
1546
+ that.wheelTimeout = undefined;
1547
+ }, this.options.mouseWheelTimeout);
1548
+
1549
+ if ('deltaX' in e) {
1550
+ if (e.deltaMode === 1) {
1551
+ wheelDeltaX = -e.deltaX * this.options.mouseWheelSpeed;
1552
+ wheelDeltaY = -e.deltaY * this.options.mouseWheelSpeed;
1553
+ } else {
1554
+ wheelDeltaX = -e.deltaX;
1555
+ wheelDeltaY = -e.deltaY;
1556
+ }
1557
+ } else if ('wheelDeltaX' in e) {
1558
+ wheelDeltaX = (e.wheelDeltaX / 120) * this.options.mouseWheelSpeed;
1559
+ wheelDeltaY = (e.wheelDeltaY / 120) * this.options.mouseWheelSpeed;
1560
+ } else if ('wheelDelta' in e) {
1561
+ wheelDeltaX = wheelDeltaY = (e.wheelDelta / 120) * this.options.mouseWheelSpeed;
1562
+ } else if ('detail' in e) {
1563
+ wheelDeltaX = wheelDeltaY = (-e.detail / 3) * this.options.mouseWheelSpeed;
1564
+ } else {
1565
+ return;
1566
+ }
1567
+
1568
+ wheelDeltaX *= this.options.invertWheelDirection;
1569
+ wheelDeltaY *= this.options.invertWheelDirection;
1570
+
1571
+ if (!this.hasVerticalScroll) {
1572
+ wheelDeltaX = wheelDeltaY;
1573
+ wheelDeltaY = 0;
1574
+ }
1575
+
1576
+ if (this.options.snap) {
1577
+ newX = this.currentPage.pageX;
1578
+ newY = this.currentPage.pageY;
1579
+
1580
+ if (wheelDeltaX > 0) {
1581
+ newX--;
1582
+ } else if (wheelDeltaX < 0) {
1583
+ newX++;
1584
+ }
1585
+
1586
+ if (wheelDeltaY > 0) {
1587
+ newY--;
1588
+ } else if (wheelDeltaY < 0) {
1589
+ newY++;
1590
+ }
1591
+
1592
+ this.goToPage(newX, newY);
1593
+
1594
+ return;
1595
+ }
1596
+
1597
+ newX = this.x + Math.round(this.hasHorizontalScroll ? wheelDeltaX : 0);
1598
+ newY = this.y + Math.round(this.hasVerticalScroll ? wheelDeltaY : 0);
1599
+
1600
+ this.directionX = wheelDeltaX > 0 ? -1 : wheelDeltaX < 0 ? 1 : 0;
1601
+ this.directionY = wheelDeltaY > 0 ? -1 : wheelDeltaY < 0 ? 1 : 0;
1602
+
1603
+ if (newX > 0) {
1604
+ newX = 0;
1605
+ } else if (newX < this.maxScrollX) {
1606
+ newX = this.maxScrollX;
1607
+ }
1608
+
1609
+ if (newY > 0) {
1610
+ newY = 0;
1611
+ } else if (newY < this.maxScrollY) {
1612
+ newY = this.maxScrollY;
1613
+ }
1614
+ //custom - prevent page scrolling if iscroll is scrolling
1615
+ else {
1616
+ e.preventDefault();
1617
+ }
1618
+ //end custom
1619
+
1620
+ this.scrollTo(newX, newY, 0);
1621
+
1622
+ // INSERT POINT: _wheel
1623
+ },
1624
+
1625
+ _initSnap: function () {
1626
+ this.currentPage = {};
1627
+
1628
+ if (typeof this.options.snap == 'string') {
1629
+ this.options.snap = this.scroller.querySelectorAll(this.options.snap);
1630
+ }
1631
+
1632
+ this.on('refresh', function () {
1633
+ var i = 0;
1634
+ var l;
1635
+ var m = 0;
1636
+ var n;
1637
+ var cx;
1638
+ var cy;
1639
+ var x = 0;
1640
+ var y;
1641
+ var stepX = this.options.snapStepX || this.wrapperWidth;
1642
+ var stepY = this.options.snapStepY || this.wrapperHeight;
1643
+ var el;
1644
+ var rect;
1645
+
1646
+ this.pages = [];
1647
+
1648
+ if (!this.wrapperWidth || !this.wrapperHeight || !this.scrollerWidth || !this.scrollerHeight) {
1649
+ return;
1650
+ }
1651
+
1652
+ if (this.options.snap === true) {
1653
+ cx = Math.round(stepX / 2);
1654
+ cy = Math.round(stepY / 2);
1655
+
1656
+ while (x > -this.scrollerWidth) {
1657
+ this.pages[i] = [];
1658
+ l = 0;
1659
+ y = 0;
1660
+
1661
+ while (y > -this.scrollerHeight) {
1662
+ this.pages[i][l] = {
1663
+ x: Math.max(x, this.maxScrollX),
1664
+ y: Math.max(y, this.maxScrollY),
1665
+ width: stepX,
1666
+ height: stepY,
1667
+ cx: x - cx,
1668
+ cy: y - cy,
1669
+ };
1670
+
1671
+ y -= stepY;
1672
+ l++;
1673
+ }
1674
+
1675
+ x -= stepX;
1676
+ i++;
1677
+ }
1678
+ } else {
1679
+ el = this.options.snap;
1680
+ l = el.length;
1681
+ n = -1;
1682
+
1683
+ for (; i < l; i++) {
1684
+ rect = utils.getRect(el[i]);
1685
+ if (i === 0 || rect.left <= utils.getRect(el[i - 1]).left) {
1686
+ m = 0;
1687
+ n++;
1688
+ }
1689
+
1690
+ if (!this.pages[m]) {
1691
+ this.pages[m] = [];
1692
+ }
1693
+
1694
+ x = Math.max(-rect.left, this.maxScrollX);
1695
+ y = Math.max(-rect.top, this.maxScrollY);
1696
+ cx = x - Math.round(rect.width / 2);
1697
+ cy = y - Math.round(rect.height / 2);
1698
+
1699
+ this.pages[m][n] = {
1700
+ x: x,
1701
+ y: y,
1702
+ width: rect.width,
1703
+ height: rect.height,
1704
+ cx: cx,
1705
+ cy: cy,
1706
+ };
1707
+
1708
+ if (x > this.maxScrollX) {
1709
+ m++;
1710
+ }
1711
+ }
1712
+ }
1713
+
1714
+ this.goToPage(this.currentPage.pageX || 0, this.currentPage.pageY || 0, 0);
1715
+
1716
+ // Update snap threshold if needed
1717
+ if (this.options.snapThreshold % 1 === 0) {
1718
+ this.snapThresholdX = this.options.snapThreshold;
1719
+ this.snapThresholdY = this.options.snapThreshold;
1720
+ } else {
1721
+ this.snapThresholdX = Math.round(
1722
+ this.pages[this.currentPage.pageX][this.currentPage.pageY].width * this.options.snapThreshold
1723
+ );
1724
+ this.snapThresholdY = Math.round(
1725
+ this.pages[this.currentPage.pageX][this.currentPage.pageY].height * this.options.snapThreshold
1726
+ );
1727
+ }
1728
+ });
1729
+
1730
+ this.on('flick', function () {
1731
+ var time =
1732
+ this.options.snapSpeed ||
1733
+ Math.max(
1734
+ Math.max(
1735
+ Math.min(Math.abs(this.x - this.startX), 1000),
1736
+ Math.min(Math.abs(this.y - this.startY), 1000)
1737
+ ),
1738
+ 300
1739
+ );
1740
+
1741
+ this.goToPage(this.currentPage.pageX + this.directionX, this.currentPage.pageY + this.directionY, time);
1742
+ });
1743
+ },
1744
+
1745
+ _nearestSnap: function (x, y) {
1746
+ if (!this.pages.length) {
1747
+ return { x: 0, y: 0, pageX: 0, pageY: 0 };
1748
+ }
1749
+
1750
+ var i = 0;
1751
+ var l = this.pages.length;
1752
+ var m = 0;
1753
+
1754
+ // Check if we exceeded the snap threshold
1755
+ if (
1756
+ Math.abs(x - this.absStartX) < this.snapThresholdX &&
1757
+ Math.abs(y - this.absStartY) < this.snapThresholdY
1758
+ ) {
1759
+ return this.currentPage;
1760
+ }
1761
+
1762
+ if (x > 0) {
1763
+ x = 0;
1764
+ } else if (x < this.maxScrollX) {
1765
+ x = this.maxScrollX;
1766
+ }
1767
+
1768
+ if (y > 0) {
1769
+ y = 0;
1770
+ } else if (y < this.maxScrollY) {
1771
+ y = this.maxScrollY;
1772
+ }
1773
+
1774
+ for (; i < l; i++) {
1775
+ if (x >= this.pages[i][0].cx) {
1776
+ x = this.pages[i][0].x;
1777
+ break;
1778
+ }
1779
+ }
1780
+
1781
+ l = this.pages[i].length;
1782
+
1783
+ for (; m < l; m++) {
1784
+ if (y >= this.pages[0][m].cy) {
1785
+ y = this.pages[0][m].y;
1786
+ break;
1787
+ }
1788
+ }
1789
+
1790
+ if (i == this.currentPage.pageX) {
1791
+ i += this.directionX;
1792
+
1793
+ if (i < 0) {
1794
+ i = 0;
1795
+ } else if (i >= this.pages.length) {
1796
+ i = this.pages.length - 1;
1797
+ }
1798
+
1799
+ x = this.pages[i][0].x;
1800
+ }
1801
+
1802
+ if (m == this.currentPage.pageY) {
1803
+ m += this.directionY;
1804
+
1805
+ if (m < 0) {
1806
+ m = 0;
1807
+ } else if (m >= this.pages[0].length) {
1808
+ m = this.pages[0].length - 1;
1809
+ }
1810
+
1811
+ y = this.pages[0][m].y;
1812
+ }
1813
+
1814
+ return {
1815
+ x: x,
1816
+ y: y,
1817
+ pageX: i,
1818
+ pageY: m,
1819
+ };
1820
+ },
1821
+
1822
+ goToPage: function (x, y, time, easing) {
1823
+ easing = easing || this.options.bounceEasing;
1824
+
1825
+ if (x >= this.pages.length) {
1826
+ x = this.pages.length - 1;
1827
+ } else if (x < 0) {
1828
+ x = 0;
1829
+ }
1830
+
1831
+ if (y >= this.pages[x].length) {
1832
+ y = this.pages[x].length - 1;
1833
+ } else if (y < 0) {
1834
+ y = 0;
1835
+ }
1836
+
1837
+ var posX = this.pages[x][y].x;
1838
+ var posY = this.pages[x][y].y;
1839
+
1840
+ time =
1841
+ time === undefined
1842
+ ? this.options.snapSpeed ||
1843
+ Math.max(
1844
+ Math.max(Math.min(Math.abs(posX - this.x), 1000), Math.min(Math.abs(posY - this.y), 1000)),
1845
+ 300
1846
+ )
1847
+ : time;
1848
+
1849
+ this.currentPage = {
1850
+ x: posX,
1851
+ y: posY,
1852
+ pageX: x,
1853
+ pageY: y,
1854
+ };
1855
+
1856
+ this.scrollTo(posX, posY, time, easing);
1857
+ },
1858
+
1859
+ next: function (time, easing) {
1860
+ var x = this.currentPage.pageX;
1861
+ var y = this.currentPage.pageY;
1862
+
1863
+ x++;
1864
+
1865
+ if (x >= this.pages.length && this.hasVerticalScroll) {
1866
+ x = 0;
1867
+ y++;
1868
+ }
1869
+
1870
+ this.goToPage(x, y, time, easing);
1871
+ },
1872
+
1873
+ prev: function (time, easing) {
1874
+ var x = this.currentPage.pageX;
1875
+ var y = this.currentPage.pageY;
1876
+
1877
+ x--;
1878
+
1879
+ if (x < 0 && this.hasVerticalScroll) {
1880
+ x = 0;
1881
+ y--;
1882
+ }
1883
+
1884
+ this.goToPage(x, y, time, easing);
1885
+ },
1886
+
1887
+ _initKeys: function (e) {
1888
+ // default key bindings
1889
+ var keys = {
1890
+ pageUp: 33,
1891
+ pageDown: 34,
1892
+ end: 35,
1893
+ home: 36,
1894
+ left: 37,
1895
+ up: 38,
1896
+ right: 39,
1897
+ down: 40,
1898
+ };
1899
+ var i;
1900
+
1901
+ // if you give me characters I give you keycode
1902
+ if (typeof this.options.keyBindings == 'object') {
1903
+ for (i in this.options.keyBindings) {
1904
+ if (typeof this.options.keyBindings[i] == 'string') {
1905
+ this.options.keyBindings[i] = this.options.keyBindings[i].toUpperCase().charCodeAt(0);
1906
+ }
1907
+ }
1908
+ } else {
1909
+ this.options.keyBindings = {};
1910
+ }
1911
+
1912
+ for (i in keys) {
1913
+ this.options.keyBindings[i] = this.options.keyBindings[i] || keys[i];
1914
+ }
1915
+
1916
+ utils.addEvent(window, 'keydown', this);
1917
+
1918
+ this.on('destroy', function () {
1919
+ utils.removeEvent(window, 'keydown', this);
1920
+ });
1921
+ },
1922
+
1923
+ _key: function (e) {
1924
+ if (!this.enabled) {
1925
+ return;
1926
+ }
1927
+
1928
+ var snap = this.options.snap; // we are using this alot, better to cache it
1929
+ var newX = snap ? this.currentPage.pageX : this.x;
1930
+ var newY = snap ? this.currentPage.pageY : this.y;
1931
+ var now = utils.getTime();
1932
+ var prevTime = this.keyTime || 0;
1933
+ var acceleration = 0.25;
1934
+ var pos;
1935
+
1936
+ if (this.options.useTransition && this.isInTransition) {
1937
+ pos = this.getComputedPosition();
1938
+
1939
+ this._translate(Math.round(pos.x), Math.round(pos.y));
1940
+ this.isInTransition = false;
1941
+ }
1942
+
1943
+ this.keyAcceleration = now - prevTime < 200 ? Math.min(this.keyAcceleration + acceleration, 50) : 0;
1944
+
1945
+ switch (e.keyCode) {
1946
+ case this.options.keyBindings.pageUp:
1947
+ if (this.hasHorizontalScroll && !this.hasVerticalScroll) {
1948
+ newX += snap ? 1 : this.wrapperWidth;
1949
+ } else {
1950
+ newY += snap ? 1 : this.wrapperHeight;
1951
+ }
1952
+ break;
1953
+ case this.options.keyBindings.pageDown:
1954
+ if (this.hasHorizontalScroll && !this.hasVerticalScroll) {
1955
+ newX -= snap ? 1 : this.wrapperWidth;
1956
+ } else {
1957
+ newY -= snap ? 1 : this.wrapperHeight;
1958
+ }
1959
+ break;
1960
+ case this.options.keyBindings.end:
1961
+ newX = snap ? this.pages.length - 1 : this.maxScrollX;
1962
+ newY = snap ? this.pages[0].length - 1 : this.maxScrollY;
1963
+ break;
1964
+ case this.options.keyBindings.home:
1965
+ newX = 0;
1966
+ newY = 0;
1967
+ break;
1968
+ case this.options.keyBindings.left:
1969
+ newX += snap ? -1 : (5 + this.keyAcceleration) >> 0;
1970
+ break;
1971
+ case this.options.keyBindings.up:
1972
+ newY += snap ? 1 : (5 + this.keyAcceleration) >> 0;
1973
+ break;
1974
+ case this.options.keyBindings.right:
1975
+ newX -= snap ? -1 : (5 + this.keyAcceleration) >> 0;
1976
+ break;
1977
+ case this.options.keyBindings.down:
1978
+ newY -= snap ? 1 : (5 + this.keyAcceleration) >> 0;
1979
+ break;
1980
+ default:
1981
+ return;
1982
+ }
1983
+
1984
+ if (snap) {
1985
+ this.goToPage(newX, newY);
1986
+ return;
1987
+ }
1988
+
1989
+ if (newX > 0) {
1990
+ newX = 0;
1991
+ this.keyAcceleration = 0;
1992
+ } else if (newX < this.maxScrollX) {
1993
+ newX = this.maxScrollX;
1994
+ this.keyAcceleration = 0;
1995
+ }
1996
+
1997
+ if (newY > 0) {
1998
+ newY = 0;
1999
+ this.keyAcceleration = 0;
2000
+ } else if (newY < this.maxScrollY) {
2001
+ newY = this.maxScrollY;
2002
+ this.keyAcceleration = 0;
2003
+ }
2004
+
2005
+ this.scrollTo(newX, newY, 0);
2006
+
2007
+ this.keyTime = now;
2008
+ },
2009
+
2010
+ _animate: function (destX, destY, duration, easingFn) {
2011
+ var that = this;
2012
+ var startX = this.x;
2013
+ var startY = this.y;
2014
+ var startTime = utils.getTime();
2015
+ var destTime = startTime + duration;
2016
+
2017
+ function step() {
2018
+ var now = utils.getTime();
2019
+ var newX;
2020
+ var newY;
2021
+ var easing;
2022
+
2023
+ if (now >= destTime) {
2024
+ that.isAnimating = false;
2025
+ that._translate(destX, destY);
2026
+
2027
+ if (!that.resetPosition(that.options.bounceTime)) {
2028
+ that._execEvent('scrollEnd');
2029
+ }
2030
+
2031
+ return;
2032
+ }
2033
+
2034
+ now = (now - startTime) / duration;
2035
+ easing = easingFn(now);
2036
+ newX = (destX - startX) * easing + startX;
2037
+ newY = (destY - startY) * easing + startY;
2038
+ that._translate(newX, newY);
2039
+
2040
+ if (that.isAnimating) {
2041
+ rAF(step);
2042
+ }
2043
+ }
2044
+
2045
+ this.isAnimating = true;
2046
+ step();
2047
+ },
2048
+ handleEvent: function (e) {
2049
+ switch (e.type) {
2050
+ case 'touchstart':
2051
+ case 'pointerdown':
2052
+ case 'MSPointerDown':
2053
+ case 'mousedown':
2054
+ this._start(e);
2055
+
2056
+ if (this.options.zoom && e.touches && e.touches.length > 1) {
2057
+ this._zoomStart(e);
2058
+ }
2059
+ break;
2060
+ case 'touchmove':
2061
+ case 'pointermove':
2062
+ case 'MSPointerMove':
2063
+ case 'mousemove':
2064
+ if (this.options.zoom && e.touches && e.touches[1]) {
2065
+ this._zoom(e);
2066
+ return;
2067
+ }
2068
+ this._move(e);
2069
+ break;
2070
+ case 'touchend':
2071
+ case 'pointerup':
2072
+ case 'MSPointerUp':
2073
+ case 'mouseup':
2074
+ case 'touchcancel':
2075
+ case 'pointercancel':
2076
+ case 'MSPointerCancel':
2077
+ case 'mousecancel':
2078
+ if (this.scaled) {
2079
+ this._zoomEnd(e);
2080
+ return;
2081
+ }
2082
+ this._end(e);
2083
+ break;
2084
+ case 'orientationchange':
2085
+ case 'resize':
2086
+ this._resize();
2087
+ break;
2088
+ case 'transitionend':
2089
+ case 'webkitTransitionEnd':
2090
+ case 'oTransitionEnd':
2091
+ case 'MSTransitionEnd':
2092
+ this._transitionEnd(e);
2093
+ break;
2094
+ case 'wheel':
2095
+ case 'DOMMouseScroll':
2096
+ case 'mousewheel':
2097
+ if (this.options.wheelAction == 'zoom') {
2098
+ this._wheelZoom(e);
2099
+ return;
2100
+ }
2101
+ this._wheel(e);
2102
+ break;
2103
+ case 'keydown':
2104
+ this._key(e);
2105
+ break;
2106
+ }
2107
+ },
2108
+ };
2109
+ function createDefaultScrollbar(direction, interactive, type) {
2110
+ var scrollbar = document.createElement('div');
2111
+ var indicator = document.createElement('div');
2112
+
2113
+ if (type === true) {
2114
+ scrollbar.style.cssText = 'position:absolute;z-index:9999';
2115
+ indicator.style.cssText =
2116
+ '-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;background:rgba(0,0,0,0.5);border:1px solid rgba(255,255,255,0.9);border-radius:3px';
2117
+ }
2118
+
2119
+ indicator.className = 'iScrollIndicator';
2120
+
2121
+ if (direction == 'h') {
2122
+ if (type === true) {
2123
+ scrollbar.style.cssText += ';height:7px;left:2px;right:2px;bottom:0';
2124
+ indicator.style.height = '100%';
2125
+ }
2126
+ scrollbar.className = 'iScrollHorizontalScrollbar';
2127
+ } else {
2128
+ if (type === true) {
2129
+ scrollbar.style.cssText += ';width:7px;bottom:2px;top:2px;right:1px';
2130
+ indicator.style.width = '100%';
2131
+ }
2132
+ scrollbar.className = 'iScrollVerticalScrollbar';
2133
+ }
2134
+
2135
+ scrollbar.style.cssText += ';overflow:hidden';
2136
+
2137
+ if (!interactive) {
2138
+ scrollbar.style.pointerEvents = 'none';
2139
+ }
2140
+
2141
+ scrollbar.appendChild(indicator);
2142
+
2143
+ return scrollbar;
2144
+ }
2145
+
2146
+ function Indicator(scroller, options) {
2147
+ this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el;
2148
+ this.wrapperStyle = this.wrapper.style;
2149
+ this.indicator = this.wrapper.children[0];
2150
+ this.indicatorStyle = this.indicator.style;
2151
+ this.scroller = scroller;
2152
+
2153
+ this.options = {
2154
+ listenX: true,
2155
+ listenY: true,
2156
+ interactive: false,
2157
+ resize: true,
2158
+ defaultScrollbars: false,
2159
+ shrink: false,
2160
+ fade: false,
2161
+ speedRatioX: 0,
2162
+ speedRatioY: 0,
2163
+ };
2164
+
2165
+ for (var i in options) {
2166
+ this.options[i] = options[i];
2167
+ }
2168
+
2169
+ this.sizeRatioX = 1;
2170
+ this.sizeRatioY = 1;
2171
+ this.maxPosX = 0;
2172
+ this.maxPosY = 0;
2173
+
2174
+ if (this.options.interactive) {
2175
+ if (!this.options.disableTouch) {
2176
+ utils.addEvent(this.indicator, 'touchstart', this);
2177
+ utils.addEvent(window, 'touchend', this);
2178
+ }
2179
+ if (!this.options.disablePointer) {
2180
+ utils.addEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this);
2181
+ utils.addEvent(window, utils.prefixPointerEvent('pointerup'), this);
2182
+ }
2183
+ if (!this.options.disableMouse) {
2184
+ utils.addEvent(this.indicator, 'mousedown', this);
2185
+ utils.addEvent(window, 'mouseup', this);
2186
+ }
2187
+ }
2188
+
2189
+ if (this.options.fade) {
2190
+ this.wrapperStyle[utils.style.transform] = this.scroller.translateZ;
2191
+ var durationProp = utils.style.transitionDuration;
2192
+ if (!durationProp) {
2193
+ return;
2194
+ }
2195
+ this.wrapperStyle[durationProp] = utils.isBadAndroid ? '0.0001ms' : '0ms';
2196
+ // remove 0.0001ms
2197
+ var self = this;
2198
+ if (utils.isBadAndroid) {
2199
+ rAF(function () {
2200
+ if (self.wrapperStyle[durationProp] === '0.0001ms') {
2201
+ self.wrapperStyle[durationProp] = '0s';
2202
+ }
2203
+ });
2204
+ }
2205
+ this.wrapperStyle.opacity = '0';
2206
+ }
2207
+ }
2208
+
2209
+ Indicator.prototype = {
2210
+ handleEvent: function (e) {
2211
+ switch (e.type) {
2212
+ case 'touchstart':
2213
+ case 'pointerdown':
2214
+ case 'MSPointerDown':
2215
+ case 'mousedown':
2216
+ this._start(e);
2217
+ break;
2218
+ case 'touchmove':
2219
+ case 'pointermove':
2220
+ case 'MSPointerMove':
2221
+ case 'mousemove':
2222
+ this._move(e);
2223
+ break;
2224
+ case 'touchend':
2225
+ case 'pointerup':
2226
+ case 'MSPointerUp':
2227
+ case 'mouseup':
2228
+ case 'touchcancel':
2229
+ case 'pointercancel':
2230
+ case 'MSPointerCancel':
2231
+ case 'mousecancel':
2232
+ this._end(e);
2233
+ break;
2234
+ }
2235
+ },
2236
+
2237
+ destroy: function () {
2238
+ if (this.options.fadeScrollbars) {
2239
+ clearTimeout(this.fadeTimeout);
2240
+ this.fadeTimeout = null;
2241
+ }
2242
+ if (this.options.interactive) {
2243
+ utils.removeEvent(this.indicator, 'touchstart', this);
2244
+ utils.removeEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this);
2245
+ utils.removeEvent(this.indicator, 'mousedown', this);
2246
+
2247
+ utils.removeEvent(window, 'touchmove', this);
2248
+ utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this);
2249
+ utils.removeEvent(window, 'mousemove', this);
2250
+
2251
+ utils.removeEvent(window, 'touchend', this);
2252
+ utils.removeEvent(window, utils.prefixPointerEvent('pointerup'), this);
2253
+ utils.removeEvent(window, 'mouseup', this);
2254
+ }
2255
+
2256
+ if (this.options.defaultScrollbars && this.wrapper.parentNode) {
2257
+ this.wrapper.parentNode.removeChild(this.wrapper);
2258
+ }
2259
+ },
2260
+
2261
+ _start: function (e) {
2262
+ var point = e.touches ? e.touches[0] : e;
2263
+
2264
+ e.preventDefault();
2265
+ e.stopPropagation();
2266
+
2267
+ this.transitionTime();
2268
+
2269
+ this.initiated = true;
2270
+ this.moved = false;
2271
+ this.lastPointX = point.pageX;
2272
+ this.lastPointY = point.pageY;
2273
+
2274
+ this.startTime = utils.getTime();
2275
+
2276
+ if (!this.options.disableTouch) {
2277
+ utils.addEvent(window, 'touchmove', this);
2278
+ }
2279
+ if (!this.options.disablePointer) {
2280
+ utils.addEvent(window, utils.prefixPointerEvent('pointermove'), this);
2281
+ }
2282
+ if (!this.options.disableMouse) {
2283
+ utils.addEvent(window, 'mousemove', this);
2284
+ }
2285
+
2286
+ this.scroller._execEvent('beforeScrollStart');
2287
+ },
2288
+
2289
+ _move: function (e) {
2290
+ var point = e.touches ? e.touches[0] : e;
2291
+ var deltaX;
2292
+ var deltaY;
2293
+ var newX;
2294
+ var newY;
2295
+ var timestamp = utils.getTime();
2296
+
2297
+ if (!this.moved) {
2298
+ this.scroller._execEvent('scrollStart');
2299
+ }
2300
+
2301
+ this.moved = true;
2302
+
2303
+ deltaX = point.pageX - this.lastPointX;
2304
+ this.lastPointX = point.pageX;
2305
+
2306
+ deltaY = point.pageY - this.lastPointY;
2307
+ this.lastPointY = point.pageY;
2308
+
2309
+ newX = this.x + deltaX;
2310
+ newY = this.y + deltaY;
2311
+
2312
+ this._pos(newX, newY);
2313
+
2314
+ // INSERT POINT: indicator._move
2315
+
2316
+ e.preventDefault();
2317
+ e.stopPropagation();
2318
+ },
2319
+
2320
+ _end: function (e) {
2321
+ if (!this.initiated) {
2322
+ return;
2323
+ }
2324
+
2325
+ this.initiated = false;
2326
+
2327
+ e.preventDefault();
2328
+ e.stopPropagation();
2329
+
2330
+ utils.removeEvent(window, 'touchmove', this);
2331
+ utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this);
2332
+ utils.removeEvent(window, 'mousemove', this);
2333
+
2334
+ if (this.scroller.options.snap) {
2335
+ var snap = this.scroller._nearestSnap(this.scroller.x, this.scroller.y);
2336
+
2337
+ var time =
2338
+ this.options.snapSpeed ||
2339
+ Math.max(
2340
+ Math.max(
2341
+ Math.min(Math.abs(this.scroller.x - snap.x), 1000),
2342
+ Math.min(Math.abs(this.scroller.y - snap.y), 1000)
2343
+ ),
2344
+ 300
2345
+ );
2346
+
2347
+ if (this.scroller.x != snap.x || this.scroller.y != snap.y) {
2348
+ this.scroller.directionX = 0;
2349
+ this.scroller.directionY = 0;
2350
+ this.scroller.currentPage = snap;
2351
+ this.scroller.scrollTo(snap.x, snap.y, time, this.scroller.options.bounceEasing);
2352
+ }
2353
+ }
2354
+
2355
+ if (this.moved) {
2356
+ this.scroller._execEvent('scrollEnd');
2357
+ }
2358
+ },
2359
+
2360
+ transitionTime: function (time) {
2361
+ time = time || 0;
2362
+ var durationProp = utils.style.transitionDuration;
2363
+ if (!durationProp) {
2364
+ return;
2365
+ }
2366
+
2367
+ this.indicatorStyle[durationProp] = time + 'ms';
2368
+
2369
+ if (!time && utils.isBadAndroid) {
2370
+ this.indicatorStyle[durationProp] = '0.0001ms';
2371
+ // remove 0.0001ms
2372
+ var self = this;
2373
+ rAF(function () {
2374
+ if (self.indicatorStyle[durationProp] === '0.0001ms') {
2375
+ self.indicatorStyle[durationProp] = '0s';
2376
+ }
2377
+ });
2378
+ }
2379
+ },
2380
+
2381
+ transitionTimingFunction: function (easing) {
2382
+ this.indicatorStyle[utils.style.transitionTimingFunction] = easing;
2383
+ },
2384
+
2385
+ refresh: function () {
2386
+ this.transitionTime();
2387
+
2388
+ if (this.options.listenX && !this.options.listenY) {
2389
+ this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none';
2390
+ } else if (this.options.listenY && !this.options.listenX) {
2391
+ this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none';
2392
+ } else {
2393
+ this.indicatorStyle.display =
2394
+ this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none';
2395
+ }
2396
+
2397
+ if (this.scroller.hasHorizontalScroll && this.scroller.hasVerticalScroll) {
2398
+ utils.addClass(this.wrapper, 'iScrollBothScrollbars');
2399
+ utils.removeClass(this.wrapper, 'iScrollLoneScrollbar');
2400
+
2401
+ if (this.options.defaultScrollbars && this.options.customStyle) {
2402
+ if (this.options.listenX) {
2403
+ this.wrapper.style.right = '8px';
2404
+ } else {
2405
+ this.wrapper.style.bottom = '8px';
2406
+ }
2407
+ }
2408
+ } else {
2409
+ utils.removeClass(this.wrapper, 'iScrollBothScrollbars');
2410
+ utils.addClass(this.wrapper, 'iScrollLoneScrollbar');
2411
+
2412
+ if (this.options.defaultScrollbars && this.options.customStyle) {
2413
+ if (this.options.listenX) {
2414
+ this.wrapper.style.right = '2px';
2415
+ } else {
2416
+ this.wrapper.style.bottom = '2px';
2417
+ }
2418
+ }
2419
+ }
2420
+
2421
+ utils.getRect(this.wrapper); // force refresh
2422
+
2423
+ if (this.options.listenX) {
2424
+ this.wrapperWidth = this.wrapper.clientWidth;
2425
+ if (this.options.resize) {
2426
+ this.indicatorWidth = Math.max(
2427
+ Math.round(
2428
+ (this.wrapperWidth * this.wrapperWidth) /
2429
+ (this.scroller.scrollerWidth || this.wrapperWidth || 1)
2430
+ ),
2431
+ 8
2432
+ );
2433
+ this.indicatorStyle.width = this.indicatorWidth + 'px';
2434
+ } else {
2435
+ this.indicatorWidth = this.indicator.clientWidth;
2436
+ }
2437
+
2438
+ this.maxPosX = this.wrapperWidth - this.indicatorWidth;
2439
+
2440
+ if (this.options.shrink == 'clip') {
2441
+ this.minBoundaryX = -this.indicatorWidth + 8;
2442
+ this.maxBoundaryX = this.wrapperWidth - 8;
2443
+ } else {
2444
+ this.minBoundaryX = 0;
2445
+ this.maxBoundaryX = this.maxPosX;
2446
+ }
2447
+
2448
+ this.sizeRatioX =
2449
+ this.options.speedRatioX || (this.scroller.maxScrollX && this.maxPosX / this.scroller.maxScrollX);
2450
+ }
2451
+
2452
+ if (this.options.listenY) {
2453
+ this.wrapperHeight = this.wrapper.clientHeight;
2454
+ if (this.options.resize) {
2455
+ this.indicatorHeight = Math.max(
2456
+ Math.round(
2457
+ (this.wrapperHeight * this.wrapperHeight) /
2458
+ (this.scroller.scrollerHeight || this.wrapperHeight || 1)
2459
+ ),
2460
+ 8
2461
+ );
2462
+ this.indicatorStyle.height = this.indicatorHeight + 'px';
2463
+ } else {
2464
+ this.indicatorHeight = this.indicator.clientHeight;
2465
+ }
2466
+
2467
+ this.maxPosY = this.wrapperHeight - this.indicatorHeight;
2468
+
2469
+ if (this.options.shrink == 'clip') {
2470
+ this.minBoundaryY = -this.indicatorHeight + 8;
2471
+ this.maxBoundaryY = this.wrapperHeight - 8;
2472
+ } else {
2473
+ this.minBoundaryY = 0;
2474
+ this.maxBoundaryY = this.maxPosY;
2475
+ }
2476
+
2477
+ this.maxPosY = this.wrapperHeight - this.indicatorHeight;
2478
+ this.sizeRatioY =
2479
+ this.options.speedRatioY || (this.scroller.maxScrollY && this.maxPosY / this.scroller.maxScrollY);
2480
+ }
2481
+
2482
+ this.updatePosition();
2483
+ },
2484
+
2485
+ updatePosition: function () {
2486
+ var x = (this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x)) || 0;
2487
+ var y = (this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y)) || 0;
2488
+
2489
+ if (!this.options.ignoreBoundaries) {
2490
+ if (x < this.minBoundaryX) {
2491
+ if (this.options.shrink == 'scale') {
2492
+ this.width = Math.max(this.indicatorWidth + x, 8);
2493
+ this.indicatorStyle.width = this.width + 'px';
2494
+ }
2495
+ x = this.minBoundaryX;
2496
+ } else if (x > this.maxBoundaryX) {
2497
+ if (this.options.shrink == 'scale') {
2498
+ this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8);
2499
+ this.indicatorStyle.width = this.width + 'px';
2500
+ x = this.maxPosX + this.indicatorWidth - this.width;
2501
+ } else {
2502
+ x = this.maxBoundaryX;
2503
+ }
2504
+ } else if (this.options.shrink == 'scale' && this.width != this.indicatorWidth) {
2505
+ this.width = this.indicatorWidth;
2506
+ this.indicatorStyle.width = this.width + 'px';
2507
+ }
2508
+
2509
+ if (y < this.minBoundaryY) {
2510
+ if (this.options.shrink == 'scale') {
2511
+ this.height = Math.max(this.indicatorHeight + y * 3, 8);
2512
+ this.indicatorStyle.height = this.height + 'px';
2513
+ }
2514
+ y = this.minBoundaryY;
2515
+ } else if (y > this.maxBoundaryY) {
2516
+ if (this.options.shrink == 'scale') {
2517
+ this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8);
2518
+ this.indicatorStyle.height = this.height + 'px';
2519
+ y = this.maxPosY + this.indicatorHeight - this.height;
2520
+ } else {
2521
+ y = this.maxBoundaryY;
2522
+ }
2523
+ } else if (this.options.shrink == 'scale' && this.height != this.indicatorHeight) {
2524
+ this.height = this.indicatorHeight;
2525
+ this.indicatorStyle.height = this.height + 'px';
2526
+ }
2527
+ }
2528
+
2529
+ this.x = x;
2530
+ this.y = y;
2531
+
2532
+ if (this.scroller.options.useTransform) {
2533
+ this.indicatorStyle[utils.style.transform] =
2534
+ 'translate(' + x + 'px,' + y + 'px)' + this.scroller.translateZ;
2535
+ } else {
2536
+ this.indicatorStyle.left = x + 'px';
2537
+ this.indicatorStyle.top = y + 'px';
2538
+ }
2539
+ },
2540
+
2541
+ _pos: function (x, y) {
2542
+ if (x < 0) {
2543
+ x = 0;
2544
+ } else if (x > this.maxPosX) {
2545
+ x = this.maxPosX;
2546
+ }
2547
+
2548
+ if (y < 0) {
2549
+ y = 0;
2550
+ } else if (y > this.maxPosY) {
2551
+ y = this.maxPosY;
2552
+ }
2553
+
2554
+ x = this.options.listenX ? Math.round(x / this.sizeRatioX) : this.scroller.x;
2555
+ y = this.options.listenY ? Math.round(y / this.sizeRatioY) : this.scroller.y;
2556
+
2557
+ this.scroller.scrollTo(x, y);
2558
+ },
2559
+
2560
+ fade: function (val, hold) {
2561
+ if (hold && !this.visible) {
2562
+ return;
2563
+ }
2564
+
2565
+ clearTimeout(this.fadeTimeout);
2566
+ this.fadeTimeout = null;
2567
+
2568
+ var time = val ? 250 : 500;
2569
+ var delay = val ? 0 : 300;
2570
+
2571
+ val = val ? '1' : '0';
2572
+
2573
+ this.wrapperStyle[utils.style.transitionDuration] = time + 'ms';
2574
+
2575
+ this.fadeTimeout = setTimeout(
2576
+ function (val) {
2577
+ this.wrapperStyle.opacity = val;
2578
+ this.visible = +val;
2579
+ }.bind(this, val),
2580
+ delay
2581
+ );
2582
+ },
2583
+ };
2584
+
2585
+ IScroll.utils = utils;
2586
+
2587
+ if (typeof module != 'undefined' && module.exports) {
2588
+ module.exports = IScroll;
2589
+ } else if (typeof define == 'function' && define.amd) {
2590
+ define(function () {
2591
+ return IScroll;
2592
+ });
2593
+ } else {
2594
+ window.IScroll = IScroll;
2595
+ }
2596
+
2597
+ window.FLIPBOOK = window.FLIPBOOK || {};
2598
+ window.FLIPBOOK.IScroll = IScroll;
2599
+
2600
+ window.PointerEvent = undefined;
2601
+
2602
+ // var oldEPD = Event.prototype.preventDefault;
2603
+ // Event.prototype.preventDefault = function() {
2604
+ // debugger;
2605
+ // oldEPD.call(this);
2606
+ // };
2607
+ })(window, document, Math);
mark.js ADDED
@@ -0,0 +1,1464 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Real3D FlipBook [https://real3dflipbook.com]
3
+ * @author creativeinteractivemedia [https://codecanyon.net/user/creativeinteractivemedia/portfolio]
4
+ * @version 4.10
5
+ * @date 2025-05-15
6
+ */
7
+ /*!***************************************************
8
+ * mark.js v9.0.0
9
+ * https://markjs.io/
10
+ * Copyright (c) 2014–2018, Julian Kühnel
11
+ * Released under the MIT license https://git.io/vwTVl
12
+ *****************************************************/
13
+
14
+ (function (global, factory) {
15
+ typeof exports === 'object' && typeof module !== 'undefined'
16
+ ? (module.exports = factory())
17
+ : typeof define === 'function' && define.amd
18
+ ? define(factory)
19
+ : (global.Mark = factory());
20
+ })(this, function () {
21
+ 'use strict';
22
+
23
+ function _typeof(obj) {
24
+ if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
25
+ _typeof = function (obj) {
26
+ return typeof obj;
27
+ };
28
+ } else {
29
+ _typeof = function (obj) {
30
+ return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype
31
+ ? 'symbol'
32
+ : typeof obj;
33
+ };
34
+ }
35
+
36
+ return _typeof(obj);
37
+ }
38
+
39
+ function _classCallCheck(instance, Constructor) {
40
+ if (!(instance instanceof Constructor)) {
41
+ throw new TypeError('Cannot call a class as a function');
42
+ }
43
+ }
44
+
45
+ function _defineProperties(target, props) {
46
+ for (var i = 0; i < props.length; i++) {
47
+ var descriptor = props[i];
48
+ descriptor.enumerable = descriptor.enumerable || false;
49
+ descriptor.configurable = true;
50
+ if ('value' in descriptor) descriptor.writable = true;
51
+ Object.defineProperty(target, descriptor.key, descriptor);
52
+ }
53
+ }
54
+
55
+ function _createClass(Constructor, protoProps, staticProps) {
56
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
57
+ if (staticProps) _defineProperties(Constructor, staticProps);
58
+ return Constructor;
59
+ }
60
+
61
+ function _extends() {
62
+ _extends =
63
+ Object.assign ||
64
+ function (target) {
65
+ for (var i = 1; i < arguments.length; i++) {
66
+ var source = arguments[i];
67
+
68
+ for (var key in source) {
69
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
70
+ target[key] = source[key];
71
+ }
72
+ }
73
+ }
74
+
75
+ return target;
76
+ };
77
+
78
+ return _extends.apply(this, arguments);
79
+ }
80
+
81
+ var DOMIterator =
82
+ /*#__PURE__*/
83
+ (function () {
84
+ function DOMIterator(ctx) {
85
+ var iframes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
86
+ var exclude = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
87
+ var iframesTimeout = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 5000;
88
+
89
+ _classCallCheck(this, DOMIterator);
90
+
91
+ this.ctx = ctx;
92
+ this.iframes = iframes;
93
+ this.exclude = exclude;
94
+ this.iframesTimeout = iframesTimeout;
95
+ }
96
+
97
+ _createClass(
98
+ DOMIterator,
99
+ [
100
+ {
101
+ key: 'getContexts',
102
+ value: function getContexts() {
103
+ var ctx,
104
+ filteredCtx = [];
105
+
106
+ if (typeof this.ctx === 'undefined' || !this.ctx) {
107
+ ctx = [];
108
+ } else if (NodeList.prototype.isPrototypeOf(this.ctx)) {
109
+ ctx = Array.prototype.slice.call(this.ctx);
110
+ } else if (Array.isArray(this.ctx)) {
111
+ ctx = this.ctx;
112
+ } else if (typeof this.ctx === 'string') {
113
+ ctx = Array.prototype.slice.call(document.querySelectorAll(this.ctx));
114
+ } else {
115
+ ctx = [this.ctx];
116
+ }
117
+
118
+ ctx.forEach(function (ctx) {
119
+ var isDescendant =
120
+ filteredCtx.filter(function (contexts) {
121
+ return contexts.contains(ctx);
122
+ }).length > 0;
123
+
124
+ if (filteredCtx.indexOf(ctx) === -1 && !isDescendant) {
125
+ filteredCtx.push(ctx);
126
+ }
127
+ });
128
+ return filteredCtx;
129
+ },
130
+ },
131
+ {
132
+ key: 'getIframeContents',
133
+ value: function getIframeContents(ifr, successFn) {
134
+ var errorFn =
135
+ arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function () {};
136
+ var doc;
137
+
138
+ try {
139
+ var ifrWin = ifr.contentWindow;
140
+ doc = ifrWin.document;
141
+
142
+ if (!ifrWin || !doc) {
143
+ throw new Error('iframe inaccessible');
144
+ }
145
+ } catch (e) {
146
+ errorFn();
147
+ }
148
+
149
+ if (doc) {
150
+ successFn(doc);
151
+ }
152
+ },
153
+ },
154
+ {
155
+ key: 'isIframeBlank',
156
+ value: function isIframeBlank(ifr) {
157
+ var bl = 'about:blank',
158
+ src = ifr.getAttribute('src').trim(),
159
+ href = ifr.contentWindow.location.href;
160
+ return href === bl && src !== bl && src;
161
+ },
162
+ },
163
+ {
164
+ key: 'observeIframeLoad',
165
+ value: function observeIframeLoad(ifr, successFn, errorFn) {
166
+ var _this = this;
167
+
168
+ var called = false,
169
+ tout = null;
170
+
171
+ var listener = function listener() {
172
+ if (called) {
173
+ return;
174
+ }
175
+
176
+ called = true;
177
+ clearTimeout(tout);
178
+
179
+ try {
180
+ if (!_this.isIframeBlank(ifr)) {
181
+ ifr.removeEventListener('load', listener);
182
+
183
+ _this.getIframeContents(ifr, successFn, errorFn);
184
+ }
185
+ } catch (e) {
186
+ errorFn();
187
+ }
188
+ };
189
+
190
+ ifr.addEventListener('load', listener);
191
+ tout = setTimeout(listener, this.iframesTimeout);
192
+ },
193
+ },
194
+ {
195
+ key: 'onIframeReady',
196
+ value: function onIframeReady(ifr, successFn, errorFn) {
197
+ try {
198
+ if (ifr.contentWindow.document.readyState === 'complete') {
199
+ if (this.isIframeBlank(ifr)) {
200
+ this.observeIframeLoad(ifr, successFn, errorFn);
201
+ } else {
202
+ this.getIframeContents(ifr, successFn, errorFn);
203
+ }
204
+ } else {
205
+ this.observeIframeLoad(ifr, successFn, errorFn);
206
+ }
207
+ } catch (e) {
208
+ errorFn();
209
+ }
210
+ },
211
+ },
212
+ {
213
+ key: 'waitForIframes',
214
+ value: function waitForIframes(ctx, done) {
215
+ var _this2 = this;
216
+
217
+ var eachCalled = 0;
218
+ this.forEachIframe(
219
+ ctx,
220
+ function () {
221
+ return true;
222
+ },
223
+ function (ifr) {
224
+ eachCalled++;
225
+
226
+ _this2.waitForIframes(ifr.querySelector('html'), function () {
227
+ if (!--eachCalled) {
228
+ done();
229
+ }
230
+ });
231
+ },
232
+ function (handled) {
233
+ if (!handled) {
234
+ done();
235
+ }
236
+ }
237
+ );
238
+ },
239
+ },
240
+ {
241
+ key: 'forEachIframe',
242
+ value: function forEachIframe(ctx, filter, each) {
243
+ var _this3 = this;
244
+
245
+ var end =
246
+ arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : function () {};
247
+ var ifr = ctx.querySelectorAll('iframe'),
248
+ open = ifr.length,
249
+ handled = 0;
250
+ ifr = Array.prototype.slice.call(ifr);
251
+
252
+ var checkEnd = function checkEnd() {
253
+ if (--open <= 0) {
254
+ end(handled);
255
+ }
256
+ };
257
+
258
+ if (!open) {
259
+ checkEnd();
260
+ }
261
+
262
+ ifr.forEach(function (ifr) {
263
+ if (DOMIterator.matches(ifr, _this3.exclude)) {
264
+ checkEnd();
265
+ } else {
266
+ _this3.onIframeReady(
267
+ ifr,
268
+ function (con) {
269
+ if (filter(ifr)) {
270
+ handled++;
271
+ each(con);
272
+ }
273
+
274
+ checkEnd();
275
+ },
276
+ checkEnd
277
+ );
278
+ }
279
+ });
280
+ },
281
+ },
282
+ {
283
+ key: 'createIterator',
284
+ value: function createIterator(ctx, whatToShow, filter) {
285
+ return document.createNodeIterator(ctx, whatToShow, filter, false);
286
+ },
287
+ },
288
+ {
289
+ key: 'createInstanceOnIframe',
290
+ value: function createInstanceOnIframe(contents) {
291
+ return new DOMIterator(contents.querySelector('html'), this.iframes);
292
+ },
293
+ },
294
+ {
295
+ key: 'compareNodeIframe',
296
+ value: function compareNodeIframe(node, prevNode, ifr) {
297
+ var compCurr = node.compareDocumentPosition(ifr),
298
+ prev = Node.DOCUMENT_POSITION_PRECEDING;
299
+
300
+ if (compCurr & prev) {
301
+ if (prevNode !== null) {
302
+ var compPrev = prevNode.compareDocumentPosition(ifr),
303
+ after = Node.DOCUMENT_POSITION_FOLLOWING;
304
+
305
+ if (compPrev & after) {
306
+ return true;
307
+ }
308
+ } else {
309
+ return true;
310
+ }
311
+ }
312
+
313
+ return false;
314
+ },
315
+ },
316
+ {
317
+ key: 'getIteratorNode',
318
+ value: function getIteratorNode(itr) {
319
+ var prevNode = itr.previousNode();
320
+ var node;
321
+
322
+ if (prevNode === null) {
323
+ node = itr.nextNode();
324
+ } else {
325
+ node = itr.nextNode() && itr.nextNode();
326
+ }
327
+
328
+ return {
329
+ prevNode: prevNode,
330
+ node: node,
331
+ };
332
+ },
333
+ },
334
+ {
335
+ key: 'checkIframeFilter',
336
+ value: function checkIframeFilter(node, prevNode, currIfr, ifr) {
337
+ var key = false,
338
+ handled = false;
339
+ ifr.forEach(function (ifrDict, i) {
340
+ if (ifrDict.val === currIfr) {
341
+ key = i;
342
+ handled = ifrDict.handled;
343
+ }
344
+ });
345
+
346
+ if (this.compareNodeIframe(node, prevNode, currIfr)) {
347
+ if (key === false && !handled) {
348
+ ifr.push({
349
+ val: currIfr,
350
+ handled: true,
351
+ });
352
+ } else if (key !== false && !handled) {
353
+ ifr[key].handled = true;
354
+ }
355
+
356
+ return true;
357
+ }
358
+
359
+ if (key === false) {
360
+ ifr.push({
361
+ val: currIfr,
362
+ handled: false,
363
+ });
364
+ }
365
+
366
+ return false;
367
+ },
368
+ },
369
+ {
370
+ key: 'handleOpenIframes',
371
+ value: function handleOpenIframes(ifr, whatToShow, eCb, fCb) {
372
+ var _this4 = this;
373
+
374
+ ifr.forEach(function (ifrDict) {
375
+ if (!ifrDict.handled) {
376
+ _this4.getIframeContents(ifrDict.val, function (con) {
377
+ _this4.createInstanceOnIframe(con).forEachNode(whatToShow, eCb, fCb);
378
+ });
379
+ }
380
+ });
381
+ },
382
+ },
383
+ {
384
+ key: 'iterateThroughNodes',
385
+ value: function iterateThroughNodes(whatToShow, ctx, eachCb, filterCb, doneCb) {
386
+ var _this5 = this;
387
+
388
+ var itr = this.createIterator(ctx, whatToShow, filterCb);
389
+
390
+ var ifr = [],
391
+ elements = [],
392
+ node,
393
+ prevNode,
394
+ retrieveNodes = function retrieveNodes() {
395
+ var _this5$getIteratorNod = _this5.getIteratorNode(itr);
396
+
397
+ prevNode = _this5$getIteratorNod.prevNode;
398
+ node = _this5$getIteratorNod.node;
399
+ return node;
400
+ };
401
+
402
+ while (retrieveNodes()) {
403
+ if (this.iframes) {
404
+ this.forEachIframe(
405
+ ctx,
406
+ function (currIfr) {
407
+ return _this5.checkIframeFilter(node, prevNode, currIfr, ifr);
408
+ },
409
+ function (con) {
410
+ _this5.createInstanceOnIframe(con).forEachNode(
411
+ whatToShow,
412
+ function (ifrNode) {
413
+ return elements.push(ifrNode);
414
+ },
415
+ filterCb
416
+ );
417
+ }
418
+ );
419
+ }
420
+
421
+ elements.push(node);
422
+ }
423
+
424
+ elements.forEach(function (node) {
425
+ eachCb(node);
426
+ });
427
+
428
+ if (this.iframes) {
429
+ this.handleOpenIframes(ifr, whatToShow, eachCb, filterCb);
430
+ }
431
+
432
+ doneCb();
433
+ },
434
+ },
435
+ {
436
+ key: 'forEachNode',
437
+ value: function forEachNode(whatToShow, each, filter) {
438
+ var _this6 = this;
439
+
440
+ var done =
441
+ arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : function () {};
442
+ var contexts = this.getContexts();
443
+ var open = contexts.length;
444
+
445
+ if (!open) {
446
+ done();
447
+ }
448
+
449
+ contexts.forEach(function (ctx) {
450
+ var ready = function ready() {
451
+ _this6.iterateThroughNodes(whatToShow, ctx, each, filter, function () {
452
+ if (--open <= 0) {
453
+ done();
454
+ }
455
+ });
456
+ };
457
+
458
+ if (_this6.iframes) {
459
+ _this6.waitForIframes(ctx, ready);
460
+ } else {
461
+ ready();
462
+ }
463
+ });
464
+ },
465
+ },
466
+ ],
467
+ [
468
+ {
469
+ key: 'matches',
470
+ value: function matches(element, selector) {
471
+ var selectors = typeof selector === 'string' ? [selector] : selector,
472
+ fn =
473
+ element.matches ||
474
+ element.matchesSelector ||
475
+ element.msMatchesSelector ||
476
+ element.mozMatchesSelector ||
477
+ element.oMatchesSelector ||
478
+ element.webkitMatchesSelector;
479
+
480
+ if (fn) {
481
+ var match = false;
482
+ selectors.every(function (sel) {
483
+ if (fn.call(element, sel)) {
484
+ match = true;
485
+ return false;
486
+ }
487
+
488
+ return true;
489
+ });
490
+ return match;
491
+ } else {
492
+ return false;
493
+ }
494
+ },
495
+ },
496
+ ]
497
+ );
498
+
499
+ return DOMIterator;
500
+ })();
501
+
502
+ var RegExpCreator =
503
+ /*#__PURE__*/
504
+ (function () {
505
+ function RegExpCreator(options) {
506
+ _classCallCheck(this, RegExpCreator);
507
+
508
+ this.opt = _extends(
509
+ {},
510
+ {
511
+ diacritics: true,
512
+ synonyms: {},
513
+ accuracy: 'partially',
514
+ caseSensitive: false,
515
+ ignoreJoiners: false,
516
+ ignorePunctuation: [],
517
+ wildcards: 'disabled',
518
+ },
519
+ options
520
+ );
521
+ }
522
+
523
+ _createClass(RegExpCreator, [
524
+ {
525
+ key: 'create',
526
+ value: function create(str) {
527
+ if (this.opt.wildcards !== 'disabled') {
528
+ str = this.setupWildcardsRegExp(str);
529
+ }
530
+
531
+ str = this.escapeStr(str);
532
+
533
+ if (Object.keys(this.opt.synonyms).length) {
534
+ str = this.createSynonymsRegExp(str);
535
+ }
536
+
537
+ if (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) {
538
+ str = this.setupIgnoreJoinersRegExp(str);
539
+ }
540
+
541
+ if (this.opt.diacritics) {
542
+ str = this.createDiacriticsRegExp(str);
543
+ }
544
+
545
+ str = this.createMergedBlanksRegExp(str);
546
+
547
+ if (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) {
548
+ str = this.createJoinersRegExp(str);
549
+ }
550
+
551
+ if (this.opt.wildcards !== 'disabled') {
552
+ str = this.createWildcardsRegExp(str);
553
+ }
554
+
555
+ str = this.createAccuracyRegExp(str);
556
+ return new RegExp(str, 'gm'.concat(this.opt.caseSensitive ? '' : 'i'));
557
+ },
558
+ },
559
+ {
560
+ key: 'sortByLength',
561
+ value: function sortByLength(arry) {
562
+ return arry.sort(function (a, b) {
563
+ return a.length === b.length ? (a > b ? 1 : -1) : b.length - a.length;
564
+ });
565
+ },
566
+ },
567
+ {
568
+ key: 'escapeStr',
569
+ value: function escapeStr(str) {
570
+ return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
571
+ },
572
+ },
573
+ {
574
+ key: 'createSynonymsRegExp',
575
+ value: function createSynonymsRegExp(str) {
576
+ var _this = this;
577
+
578
+ var syn = this.opt.synonyms,
579
+ sens = this.opt.caseSensitive ? '' : 'i',
580
+ joinerPlaceholder = this.opt.ignoreJoiners || this.opt.ignorePunctuation.length ? '\0' : '';
581
+
582
+ for (var index in syn) {
583
+ if (syn.hasOwnProperty(index)) {
584
+ var keys = Array.isArray(syn[index]) ? syn[index] : [syn[index]];
585
+ keys.unshift(index);
586
+ keys = this.sortByLength(keys)
587
+ .map(function (key) {
588
+ if (_this.opt.wildcards !== 'disabled') {
589
+ key = _this.setupWildcardsRegExp(key);
590
+ }
591
+
592
+ key = _this.escapeStr(key);
593
+ return key;
594
+ })
595
+ .filter(function (k) {
596
+ return k !== '';
597
+ });
598
+
599
+ if (keys.length > 1) {
600
+ str = str.replace(
601
+ new RegExp(
602
+ '('.concat(
603
+ keys
604
+ .map(function (k) {
605
+ return _this.escapeStr(k);
606
+ })
607
+ .join('|'),
608
+ ')'
609
+ ),
610
+ 'gm'.concat(sens)
611
+ ),
612
+ joinerPlaceholder +
613
+ '('.concat(
614
+ keys
615
+ .map(function (k) {
616
+ return _this.processSynonyms(k);
617
+ })
618
+ .join('|'),
619
+ ')'
620
+ ) +
621
+ joinerPlaceholder
622
+ );
623
+ }
624
+ }
625
+ }
626
+
627
+ return str;
628
+ },
629
+ },
630
+ {
631
+ key: 'processSynonyms',
632
+ value: function processSynonyms(str) {
633
+ if (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) {
634
+ str = this.setupIgnoreJoinersRegExp(str);
635
+ }
636
+
637
+ return str;
638
+ },
639
+ },
640
+ {
641
+ key: 'setupWildcardsRegExp',
642
+ value: function setupWildcardsRegExp(str) {
643
+ str = str.replace(/(?:\\)*\?/g, function (val) {
644
+ return val.charAt(0) === '\\' ? '?' : '\x01';
645
+ });
646
+ return str.replace(/(?:\\)*\*/g, function (val) {
647
+ return val.charAt(0) === '\\' ? '*' : '\x02';
648
+ });
649
+ },
650
+ },
651
+ {
652
+ key: 'createWildcardsRegExp',
653
+ value: function createWildcardsRegExp(str) {
654
+ var spaces = this.opt.wildcards === 'withSpaces';
655
+ return str
656
+ .replace(/\u0001/g, spaces ? '[\\S\\s]?' : '\\S?')
657
+ .replace(/\u0002/g, spaces ? '[\\S\\s]*?' : '\\S*');
658
+ },
659
+ },
660
+ {
661
+ key: 'setupIgnoreJoinersRegExp',
662
+ value: function setupIgnoreJoinersRegExp(str) {
663
+ return str.replace(/[^(|)\\]/g, function (val, indx, original) {
664
+ var nextChar = original.charAt(indx + 1);
665
+
666
+ if (/[(|)\\]/.test(nextChar) || nextChar === '') {
667
+ return val;
668
+ } else {
669
+ return val + '\0';
670
+ }
671
+ });
672
+ },
673
+ },
674
+ {
675
+ key: 'createJoinersRegExp',
676
+ value: function createJoinersRegExp(str) {
677
+ var joiner = [];
678
+ var ignorePunctuation = this.opt.ignorePunctuation;
679
+
680
+ if (Array.isArray(ignorePunctuation) && ignorePunctuation.length) {
681
+ joiner.push(this.escapeStr(ignorePunctuation.join('')));
682
+ }
683
+
684
+ if (this.opt.ignoreJoiners) {
685
+ joiner.push('\\u00ad\\u200b\\u200c\\u200d');
686
+ }
687
+
688
+ return joiner.length ? str.split(/\u0000+/).join('['.concat(joiner.join(''), ']*')) : str;
689
+ },
690
+ },
691
+ {
692
+ key: 'createDiacriticsRegExp',
693
+ value: function createDiacriticsRegExp(str) {
694
+ var sens = this.opt.caseSensitive ? '' : 'i',
695
+ dct = this.opt.caseSensitive
696
+ ? [
697
+ 'aàáảãạăằắẳẵặâầấẩẫậäåāą',
698
+ 'AÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ',
699
+ 'cçćč',
700
+ 'CÇĆČ',
701
+ 'dđď',
702
+ 'DĐĎ',
703
+ 'eèéẻẽẹêềếểễệëěēę',
704
+ 'EÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ',
705
+ 'iìíỉĩịîïī',
706
+ 'IÌÍỈĨỊÎÏĪ',
707
+ 'lł',
708
+ 'LŁ',
709
+ 'nñňń',
710
+ 'NÑŇŃ',
711
+ 'oòóỏõọôồốổỗộơởỡớờợöøō',
712
+ 'OÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ',
713
+ 'rř',
714
+ 'RŘ',
715
+ 'sšśșş',
716
+ 'SŠŚȘŞ',
717
+ 'tťțţ',
718
+ 'TŤȚŢ',
719
+ 'uùúủũụưừứửữựûüůū',
720
+ 'UÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ',
721
+ 'yýỳỷỹỵÿ',
722
+ 'YÝỲỶỸỴŸ',
723
+ 'zžżź',
724
+ 'ZŽŻŹ',
725
+ ]
726
+ : [
727
+ 'aàáảãạăằắẳẵặâầấẩẫậäåāąAÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ',
728
+ 'cçćčCÇĆČ',
729
+ 'dđďDĐĎ',
730
+ 'eèéẻẽẹêềếểễệëěēęEÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ',
731
+ 'iìíỉĩịîïīIÌÍỈĨỊÎÏĪ',
732
+ 'lłLŁ',
733
+ 'nñňńNÑŇŃ',
734
+ 'oòóỏõọôồốổỗộơởỡớờợöøōOÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ',
735
+ 'rřRŘ',
736
+ 'sšśșşSŠŚȘŞ',
737
+ 'tťțţTŤȚŢ',
738
+ 'uùúủũụưừứửữựûüůūUÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ',
739
+ 'yýỳỷỹỵÿYÝỲỶỸỴŸ',
740
+ 'zžżźZŽŻŹ',
741
+ ];
742
+ var handled = [];
743
+ str.split('').forEach(function (ch) {
744
+ dct.every(function (dct) {
745
+ if (dct.indexOf(ch) !== -1) {
746
+ if (handled.indexOf(dct) > -1) {
747
+ return false;
748
+ }
749
+
750
+ str = str.replace(
751
+ new RegExp('['.concat(dct, ']'), 'gm'.concat(sens)),
752
+ '['.concat(dct, ']')
753
+ );
754
+ handled.push(dct);
755
+ }
756
+
757
+ return true;
758
+ });
759
+ });
760
+ return str;
761
+ },
762
+ },
763
+ {
764
+ key: 'createMergedBlanksRegExp',
765
+ value: function createMergedBlanksRegExp(str) {
766
+ return str.replace(/[\s]+/gim, '[\\s]+');
767
+ },
768
+ },
769
+ {
770
+ key: 'createAccuracyRegExp',
771
+ value: function createAccuracyRegExp(str) {
772
+ var _this2 = this;
773
+
774
+ var chars = '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~¡¿';
775
+ var acc = this.opt.accuracy,
776
+ val = typeof acc === 'string' ? acc : acc.value,
777
+ ls = typeof acc === 'string' ? [] : acc.limiters,
778
+ lsJoin = '';
779
+ ls.forEach(function (limiter) {
780
+ lsJoin += '|'.concat(_this2.escapeStr(limiter));
781
+ });
782
+
783
+ switch (val) {
784
+ case 'partially':
785
+ default:
786
+ return '()('.concat(str, ')');
787
+
788
+ case 'complementary':
789
+ lsJoin = '\\s' + (lsJoin ? lsJoin : this.escapeStr(chars));
790
+ return '()([^'.concat(lsJoin, ']*').concat(str, '[^').concat(lsJoin, ']*)');
791
+
792
+ case 'exactly':
793
+ return '(^|\\s'.concat(lsJoin, ')(').concat(str, ')(?=$|\\s').concat(lsJoin, ')');
794
+ }
795
+ },
796
+ },
797
+ ]);
798
+
799
+ return RegExpCreator;
800
+ })();
801
+
802
+ var Mark =
803
+ /*#__PURE__*/
804
+ (function () {
805
+ function Mark(ctx) {
806
+ _classCallCheck(this, Mark);
807
+
808
+ this.ctx = ctx;
809
+ this.ie = false;
810
+ var ua = window.navigator.userAgent;
811
+
812
+ if (ua.indexOf('MSIE') > -1 || ua.indexOf('Trident') > -1) {
813
+ this.ie = true;
814
+ }
815
+ }
816
+
817
+ _createClass(Mark, [
818
+ {
819
+ key: 'log',
820
+ value: function log(msg) {
821
+ var level = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'debug';
822
+ var log = this.opt.log;
823
+
824
+ if (!this.opt.debug) {
825
+ return;
826
+ }
827
+
828
+ if (_typeof(log) === 'object' && typeof log[level] === 'function') {
829
+ log[level]('mark.js: '.concat(msg));
830
+ }
831
+ },
832
+ },
833
+ {
834
+ key: 'getSeparatedKeywords',
835
+ value: function getSeparatedKeywords(sv) {
836
+ var _this = this;
837
+
838
+ var stack = [];
839
+ sv.forEach(function (kw) {
840
+ if (!_this.opt.separateWordSearch) {
841
+ if (kw.trim() && stack.indexOf(kw) === -1) {
842
+ stack.push(kw);
843
+ }
844
+ } else {
845
+ kw.split(' ').forEach(function (kwSplitted) {
846
+ if (kwSplitted.trim() && stack.indexOf(kwSplitted) === -1) {
847
+ stack.push(kwSplitted);
848
+ }
849
+ });
850
+ }
851
+ });
852
+ return {
853
+ keywords: stack.sort(function (a, b) {
854
+ return b.length - a.length;
855
+ }),
856
+ length: stack.length,
857
+ };
858
+ },
859
+ },
860
+ {
861
+ key: 'isNumeric',
862
+ value: function isNumeric(value) {
863
+ return Number(parseFloat(value)) == value;
864
+ },
865
+ },
866
+ {
867
+ key: 'checkRanges',
868
+ value: function checkRanges(array) {
869
+ var _this2 = this;
870
+
871
+ if (!Array.isArray(array) || Object.prototype.toString.call(array[0]) !== '[object Object]') {
872
+ this.log('markRanges() will only accept an array of objects');
873
+ this.opt.noMatch(array);
874
+ return [];
875
+ }
876
+
877
+ var stack = [];
878
+ var last = 0;
879
+ array
880
+ .sort(function (a, b) {
881
+ return a.start - b.start;
882
+ })
883
+ .forEach(function (item) {
884
+ var _this2$callNoMatchOnI = _this2.callNoMatchOnInvalidRanges(item, last),
885
+ start = _this2$callNoMatchOnI.start,
886
+ end = _this2$callNoMatchOnI.end,
887
+ valid = _this2$callNoMatchOnI.valid;
888
+
889
+ if (valid) {
890
+ item.start = start;
891
+ item.length = end - start;
892
+ stack.push(item);
893
+ last = end;
894
+ }
895
+ });
896
+ return stack;
897
+ },
898
+ },
899
+ {
900
+ key: 'callNoMatchOnInvalidRanges',
901
+ value: function callNoMatchOnInvalidRanges(range, last) {
902
+ var start,
903
+ end,
904
+ valid = false;
905
+
906
+ if (range && typeof range.start !== 'undefined') {
907
+ start = parseInt(range.start, 10);
908
+ end = start + parseInt(range.length, 10);
909
+
910
+ if (
911
+ this.isNumeric(range.start) &&
912
+ this.isNumeric(range.length) &&
913
+ end - last > 0 &&
914
+ end - start > 0
915
+ ) {
916
+ valid = true;
917
+ } else {
918
+ this.log('Ignoring invalid or overlapping range: ' + ''.concat(JSON.stringify(range)));
919
+ this.opt.noMatch(range);
920
+ }
921
+ } else {
922
+ this.log('Ignoring invalid range: '.concat(JSON.stringify(range)));
923
+ this.opt.noMatch(range);
924
+ }
925
+
926
+ return {
927
+ start: start,
928
+ end: end,
929
+ valid: valid,
930
+ };
931
+ },
932
+ },
933
+ {
934
+ key: 'checkWhitespaceRanges',
935
+ value: function checkWhitespaceRanges(range, originalLength, string) {
936
+ var end,
937
+ valid = true,
938
+ max = string.length,
939
+ offset = originalLength - max,
940
+ start = parseInt(range.start, 10) - offset;
941
+ start = start > max ? max : start;
942
+ end = start + parseInt(range.length, 10);
943
+
944
+ if (end > max) {
945
+ end = max;
946
+ this.log('End range automatically set to the max value of '.concat(max));
947
+ }
948
+
949
+ if (start < 0 || end - start < 0 || start > max || end > max) {
950
+ valid = false;
951
+ this.log('Invalid range: '.concat(JSON.stringify(range)));
952
+ this.opt.noMatch(range);
953
+ } else if (string.substring(start, end).replace(/\s+/g, '') === '') {
954
+ valid = false;
955
+ this.log('Skipping whitespace only range: ' + JSON.stringify(range));
956
+ this.opt.noMatch(range);
957
+ }
958
+
959
+ return {
960
+ start: start,
961
+ end: end,
962
+ valid: valid,
963
+ };
964
+ },
965
+ },
966
+ {
967
+ key: 'getTextNodes',
968
+ value: function getTextNodes(cb) {
969
+ var _this3 = this;
970
+
971
+ var val = '',
972
+ nodes = [];
973
+ this.iterator.forEachNode(
974
+ NodeFilter.SHOW_TEXT,
975
+ function (node) {
976
+ nodes.push({
977
+ start: val.length,
978
+ end: (val += node.textContent).length,
979
+ node: node,
980
+ });
981
+ },
982
+ function (node) {
983
+ if (_this3.matchesExclude(node.parentNode)) {
984
+ return NodeFilter.FILTER_REJECT;
985
+ } else {
986
+ return NodeFilter.FILTER_ACCEPT;
987
+ }
988
+ },
989
+ function () {
990
+ cb({
991
+ value: val,
992
+ nodes: nodes,
993
+ });
994
+ }
995
+ );
996
+ },
997
+ },
998
+ {
999
+ key: 'matchesExclude',
1000
+ value: function matchesExclude(el) {
1001
+ return DOMIterator.matches(
1002
+ el,
1003
+ this.opt.exclude.concat(['script', 'style', 'title', 'head', 'html'])
1004
+ );
1005
+ },
1006
+ },
1007
+ {
1008
+ key: 'wrapRangeInTextNode',
1009
+ value: function wrapRangeInTextNode(node, start, end) {
1010
+ var hEl = !this.opt.element ? 'mark' : this.opt.element,
1011
+ startNode = node.splitText(start),
1012
+ ret = startNode.splitText(end - start);
1013
+ var repl = document.createElement(hEl);
1014
+ repl.setAttribute('data-markjs', 'true');
1015
+
1016
+ if (this.opt.className) {
1017
+ repl.setAttribute('class', this.opt.className);
1018
+ }
1019
+
1020
+ repl.textContent = startNode.textContent;
1021
+ startNode.parentNode.replaceChild(repl, startNode);
1022
+ return ret;
1023
+ },
1024
+ },
1025
+ {
1026
+ key: 'wrapRangeInMappedTextNode',
1027
+ value: function wrapRangeInMappedTextNode(dict, start, end, filterCb, eachCb) {
1028
+ var _this4 = this;
1029
+
1030
+ dict.nodes.every(function (n, i) {
1031
+ var sibl = dict.nodes[i + 1];
1032
+
1033
+ if (typeof sibl === 'undefined' || sibl.start > start) {
1034
+ if (!filterCb(n.node)) {
1035
+ return false;
1036
+ }
1037
+
1038
+ var s = start - n.start,
1039
+ e = (end > n.end ? n.end : end) - n.start,
1040
+ startStr = dict.value.substr(0, n.start),
1041
+ endStr = dict.value.substr(e + n.start);
1042
+ n.node = _this4.wrapRangeInTextNode(n.node, s, e);
1043
+ dict.value = startStr + endStr;
1044
+ dict.nodes.forEach(function (k, j) {
1045
+ if (j >= i) {
1046
+ if (dict.nodes[j].start > 0 && j !== i) {
1047
+ dict.nodes[j].start -= e;
1048
+ }
1049
+
1050
+ dict.nodes[j].end -= e;
1051
+ }
1052
+ });
1053
+ end -= e;
1054
+ eachCb(n.node.previousSibling, n.start);
1055
+
1056
+ if (end > n.end) {
1057
+ start = n.end;
1058
+ } else {
1059
+ return false;
1060
+ }
1061
+ }
1062
+
1063
+ return true;
1064
+ });
1065
+ },
1066
+ },
1067
+ {
1068
+ key: 'wrapGroups',
1069
+ value: function wrapGroups(node, pos, len, eachCb) {
1070
+ node = this.wrapRangeInTextNode(node, pos, pos + len);
1071
+ eachCb(node.previousSibling);
1072
+ return node;
1073
+ },
1074
+ },
1075
+ {
1076
+ key: 'separateGroups',
1077
+ value: function separateGroups(node, match, matchIdx, filterCb, eachCb) {
1078
+ var matchLen = match.length;
1079
+
1080
+ for (var i = 1; i < matchLen; i++) {
1081
+ var pos = node.textContent.indexOf(match[i]);
1082
+
1083
+ if (match[i] && pos > -1 && filterCb(match[i], node)) {
1084
+ node = this.wrapGroups(node, pos, match[i].length, eachCb);
1085
+ }
1086
+ }
1087
+
1088
+ return node;
1089
+ },
1090
+ },
1091
+ {
1092
+ key: 'wrapMatches',
1093
+ value: function wrapMatches(regex, ignoreGroups, filterCb, eachCb, endCb) {
1094
+ var _this5 = this;
1095
+
1096
+ var matchIdx = ignoreGroups === 0 ? 0 : ignoreGroups + 1;
1097
+ this.getTextNodes(function (dict) {
1098
+ dict.nodes.forEach(function (node) {
1099
+ node = node.node;
1100
+ var match;
1101
+
1102
+ while ((match = regex.exec(node.textContent)) !== null && match[matchIdx] !== '') {
1103
+ if (_this5.opt.separateGroups) {
1104
+ node = _this5.separateGroups(node, match, matchIdx, filterCb, eachCb);
1105
+ } else {
1106
+ if (!filterCb(match[matchIdx], node)) {
1107
+ continue;
1108
+ }
1109
+
1110
+ var pos = match.index;
1111
+
1112
+ if (matchIdx !== 0) {
1113
+ for (var i = 1; i < matchIdx; i++) {
1114
+ pos += match[i].length;
1115
+ }
1116
+ }
1117
+
1118
+ node = _this5.wrapGroups(node, pos, match[matchIdx].length, eachCb);
1119
+ }
1120
+
1121
+ regex.lastIndex = 0;
1122
+ }
1123
+ });
1124
+ endCb();
1125
+ });
1126
+ },
1127
+ },
1128
+ {
1129
+ key: 'wrapMatchesAcrossElements',
1130
+ value: function wrapMatchesAcrossElements(regex, ignoreGroups, filterCb, eachCb, endCb) {
1131
+ var _this6 = this;
1132
+
1133
+ var matchIdx = ignoreGroups === 0 ? 0 : ignoreGroups + 1;
1134
+ this.getTextNodes(function (dict) {
1135
+ var match;
1136
+
1137
+ while ((match = regex.exec(dict.value)) !== null && match[matchIdx] !== '') {
1138
+ var start = match.index;
1139
+
1140
+ if (matchIdx !== 0) {
1141
+ for (var i = 1; i < matchIdx; i++) {
1142
+ start += match[i].length;
1143
+ }
1144
+ }
1145
+
1146
+ var end = start + match[matchIdx].length;
1147
+
1148
+ _this6.wrapRangeInMappedTextNode(
1149
+ dict,
1150
+ start,
1151
+ end,
1152
+ function (node) {
1153
+ return filterCb(match[matchIdx], node);
1154
+ },
1155
+ function (node, lastIndex) {
1156
+ regex.lastIndex = lastIndex;
1157
+ eachCb(node);
1158
+ }
1159
+ );
1160
+ }
1161
+
1162
+ endCb();
1163
+ });
1164
+ },
1165
+ },
1166
+ {
1167
+ key: 'wrapRangeFromIndex',
1168
+ value: function wrapRangeFromIndex(ranges, filterCb, eachCb, endCb) {
1169
+ var _this7 = this;
1170
+
1171
+ this.getTextNodes(function (dict) {
1172
+ var originalLength = dict.value.length;
1173
+ ranges.forEach(function (range, counter) {
1174
+ var _this7$checkWhitespac = _this7.checkWhitespaceRanges(
1175
+ range,
1176
+ originalLength,
1177
+ dict.value
1178
+ ),
1179
+ start = _this7$checkWhitespac.start,
1180
+ end = _this7$checkWhitespac.end,
1181
+ valid = _this7$checkWhitespac.valid;
1182
+
1183
+ if (valid) {
1184
+ _this7.wrapRangeInMappedTextNode(
1185
+ dict,
1186
+ start,
1187
+ end,
1188
+ function (node) {
1189
+ return filterCb(node, range, dict.value.substring(start, end), counter);
1190
+ },
1191
+ function (node) {
1192
+ eachCb(node, range);
1193
+ }
1194
+ );
1195
+ }
1196
+ });
1197
+ endCb();
1198
+ });
1199
+ },
1200
+ },
1201
+ {
1202
+ key: 'unwrapMatches',
1203
+ value: function unwrapMatches(node) {
1204
+ var parent = node.parentNode;
1205
+ var docFrag = document.createDocumentFragment();
1206
+
1207
+ while (node.firstChild) {
1208
+ docFrag.appendChild(node.removeChild(node.firstChild));
1209
+ }
1210
+
1211
+ parent.replaceChild(docFrag, node);
1212
+
1213
+ if (!this.ie) {
1214
+ parent.normalize();
1215
+ } else {
1216
+ this.normalizeTextNode(parent);
1217
+ }
1218
+ },
1219
+ },
1220
+ {
1221
+ key: 'normalizeTextNode',
1222
+ value: function normalizeTextNode(node) {
1223
+ if (!node) {
1224
+ return;
1225
+ }
1226
+
1227
+ if (node.nodeType === 3) {
1228
+ while (node.nextSibling && node.nextSibling.nodeType === 3) {
1229
+ node.nodeValue += node.nextSibling.nodeValue;
1230
+ node.parentNode.removeChild(node.nextSibling);
1231
+ }
1232
+ } else {
1233
+ this.normalizeTextNode(node.firstChild);
1234
+ }
1235
+
1236
+ this.normalizeTextNode(node.nextSibling);
1237
+ },
1238
+ },
1239
+ {
1240
+ key: 'markRegExp',
1241
+ value: function markRegExp(regexp, opt) {
1242
+ var _this8 = this;
1243
+
1244
+ this.opt = opt;
1245
+ this.log('Searching with expression "'.concat(regexp, '"'));
1246
+ var totalMatches = 0,
1247
+ fn = 'wrapMatches';
1248
+
1249
+ var eachCb = function eachCb(element) {
1250
+ totalMatches++;
1251
+
1252
+ _this8.opt.each(element);
1253
+ };
1254
+
1255
+ if (this.opt.acrossElements) {
1256
+ fn = 'wrapMatchesAcrossElements';
1257
+ }
1258
+
1259
+ this[fn](
1260
+ regexp,
1261
+ this.opt.ignoreGroups,
1262
+ function (match, node) {
1263
+ return _this8.opt.filter(node, match, totalMatches);
1264
+ },
1265
+ eachCb,
1266
+ function () {
1267
+ if (totalMatches === 0) {
1268
+ _this8.opt.noMatch(regexp);
1269
+ }
1270
+
1271
+ _this8.opt.done(totalMatches);
1272
+ }
1273
+ );
1274
+ },
1275
+ },
1276
+ {
1277
+ key: 'mark',
1278
+ value: function mark(sv, opt) {
1279
+ var _this9 = this;
1280
+
1281
+ this.opt = opt;
1282
+ var totalMatches = 0,
1283
+ fn = 'wrapMatches';
1284
+
1285
+ var _this$getSeparatedKey = this.getSeparatedKeywords(typeof sv === 'string' ? [sv] : sv),
1286
+ kwArr = _this$getSeparatedKey.keywords,
1287
+ kwArrLen = _this$getSeparatedKey.length,
1288
+ handler = function handler(kw) {
1289
+ var regex = new RegExpCreator(_this9.opt).create(kw);
1290
+ var matches = 0;
1291
+
1292
+ _this9.log('Searching with expression "'.concat(regex, '"'));
1293
+
1294
+ _this9[fn](
1295
+ regex,
1296
+ 1,
1297
+ function (term, node) {
1298
+ return _this9.opt.filter(node, kw, totalMatches, matches);
1299
+ },
1300
+ function (element) {
1301
+ matches++;
1302
+ totalMatches++;
1303
+
1304
+ _this9.opt.each(element);
1305
+ },
1306
+ function () {
1307
+ if (matches === 0) {
1308
+ _this9.opt.noMatch(kw);
1309
+ }
1310
+
1311
+ if (kwArr[kwArrLen - 1] === kw) {
1312
+ _this9.opt.done(totalMatches);
1313
+ } else {
1314
+ handler(kwArr[kwArr.indexOf(kw) + 1]);
1315
+ }
1316
+ }
1317
+ );
1318
+ };
1319
+
1320
+ if (this.opt.acrossElements) {
1321
+ fn = 'wrapMatchesAcrossElements';
1322
+ }
1323
+
1324
+ if (kwArrLen === 0) {
1325
+ this.opt.done(totalMatches);
1326
+ } else {
1327
+ handler(kwArr[0]);
1328
+ }
1329
+ },
1330
+ },
1331
+ {
1332
+ key: 'markRanges',
1333
+ value: function markRanges(rawRanges, opt) {
1334
+ var _this10 = this;
1335
+
1336
+ this.opt = opt;
1337
+ var totalMatches = 0,
1338
+ ranges = this.checkRanges(rawRanges);
1339
+
1340
+ if (ranges && ranges.length) {
1341
+ this.log('Starting to mark with the following ranges: ' + JSON.stringify(ranges));
1342
+ this.wrapRangeFromIndex(
1343
+ ranges,
1344
+ function (node, range, match, counter) {
1345
+ return _this10.opt.filter(node, range, match, counter);
1346
+ },
1347
+ function (element, range) {
1348
+ totalMatches++;
1349
+
1350
+ _this10.opt.each(element, range);
1351
+ },
1352
+ function () {
1353
+ _this10.opt.done(totalMatches);
1354
+ }
1355
+ );
1356
+ } else {
1357
+ this.opt.done(totalMatches);
1358
+ }
1359
+ },
1360
+ },
1361
+ {
1362
+ key: 'unmark',
1363
+ value: function unmark(opt) {
1364
+ var _this11 = this;
1365
+
1366
+ this.opt = opt;
1367
+ var sel = this.opt.element ? this.opt.element : '*';
1368
+ sel += '[data-markjs]';
1369
+
1370
+ if (this.opt.className) {
1371
+ sel += '.'.concat(this.opt.className);
1372
+ }
1373
+
1374
+ this.log('Removal selector "'.concat(sel, '"'));
1375
+ this.iterator.forEachNode(
1376
+ NodeFilter.SHOW_ELEMENT,
1377
+ function (node) {
1378
+ _this11.unwrapMatches(node);
1379
+ },
1380
+ function (node) {
1381
+ var matchesSel = DOMIterator.matches(node, sel),
1382
+ matchesExclude = _this11.matchesExclude(node);
1383
+
1384
+ if (!matchesSel || matchesExclude) {
1385
+ return NodeFilter.FILTER_REJECT;
1386
+ } else {
1387
+ return NodeFilter.FILTER_ACCEPT;
1388
+ }
1389
+ },
1390
+ this.opt.done
1391
+ );
1392
+ },
1393
+ },
1394
+ {
1395
+ key: 'opt',
1396
+ set: function set(val) {
1397
+ this._opt = _extends(
1398
+ {},
1399
+ {
1400
+ element: '',
1401
+ className: '',
1402
+ exclude: [],
1403
+ iframes: false,
1404
+ iframesTimeout: 5000,
1405
+ separateWordSearch: true,
1406
+ acrossElements: false,
1407
+ ignoreGroups: 0,
1408
+ each: function each() {},
1409
+ noMatch: function noMatch() {},
1410
+ filter: function filter() {
1411
+ return true;
1412
+ },
1413
+ done: function done() {},
1414
+ debug: false,
1415
+ log: window.console,
1416
+ },
1417
+ val
1418
+ );
1419
+ },
1420
+ get: function get() {
1421
+ return this._opt;
1422
+ },
1423
+ },
1424
+ {
1425
+ key: 'iterator',
1426
+ get: function get() {
1427
+ return new DOMIterator(this.ctx, this.opt.iframes, this.opt.exclude, this.opt.iframesTimeout);
1428
+ },
1429
+ },
1430
+ ]);
1431
+
1432
+ return Mark;
1433
+ })();
1434
+
1435
+ function Mark$1(ctx) {
1436
+ var _this = this;
1437
+
1438
+ var instance = new Mark(ctx);
1439
+
1440
+ this.mark = function (sv, opt) {
1441
+ instance.mark(sv, opt);
1442
+ return _this;
1443
+ };
1444
+
1445
+ this.markRegExp = function (sv, opt) {
1446
+ instance.markRegExp(sv, opt);
1447
+ return _this;
1448
+ };
1449
+
1450
+ this.markRanges = function (sv, opt) {
1451
+ instance.markRanges(sv, opt);
1452
+ return _this;
1453
+ };
1454
+
1455
+ this.unmark = function (opt) {
1456
+ instance.unmark(opt);
1457
+ return _this;
1458
+ };
1459
+
1460
+ return this;
1461
+ }
1462
+
1463
+ return Mark$1;
1464
+ });
mod3d.js ADDED
@@ -0,0 +1,2520 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Real3D FlipBook [https://real3dflipbook.com]
3
+ * @author creativeinteractivemedia [https://codecanyon.net/user/creativeinteractivemedia/portfolio]
4
+ * @version 4.10
5
+ * @date 2025-05-15
6
+ */
7
+ /**
8
+ * MOD3 3D Modifier Library for JavaScript
9
+ * port of AS3DMod ActionScript3 library (http://code.google.com/p/as3dmod/)
10
+ *
11
+ * @version 1.0.0 (2023-01-03 16:08:34)
12
+ * https://github.com/foo123/MOD3
13
+ *
14
+ **//**
15
+ * MOD3 3D Modifier Library for JavaScript
16
+ * port of AS3DMod ActionScript3 library (http://code.google.com/p/as3dmod/)
17
+ *
18
+ * @version 1.0.0 (2023-01-03 16:08:34)
19
+ * https://github.com/foo123/MOD3
20
+ *
21
+ **/
22
+ !function(root, name, factory) {
23
+ "use strict";
24
+ if (('object' === typeof module) && module.exports) /* CommonJS */
25
+ (module.$deps = module.$deps||{}) && (module.exports = module.$deps[name] = factory.call(root));
26
+ else if (('function' === typeof define) && define.amd && ('function' === typeof require) && ('function' === typeof require.specified) && require.specified(name) /*&& !require.defined(name)*/) /* AMD */
27
+ define(name, ['module'], function(module) {factory.moduleUri = module.uri; return factory.call(root);});
28
+ else if (!(name in root)) /* Browser/WebWorker/.. */
29
+ (root[name] = factory.call(root)||1) && ('function' === typeof(define)) && define.amd && define(function() {return root[name];});
30
+ }( /* current root */ 'undefined' !== typeof self ? self : this,
31
+ /* module name */ "MOD3",
32
+ /* module factory */ function ModuleFactory__MOD3(undef) {
33
+ "use strict";
34
+
35
+ var HAS = Object.prototype.hasOwnProperty,
36
+ toString = Object.prototype.toString,
37
+ def = Object.defineProperty,
38
+ stdMath = Math, PI = stdMath.PI,
39
+ TWO_PI = 2*PI, HALF_PI = PI/2, INV_PI = 1/PI,
40
+ EMPTY_ARR = [], EMPTY_OBJ = {}, NOP = function() {},
41
+ isNode = ("undefined" !== typeof global) && ("[object global]" === toString.call(global)),
42
+ isBrowser = ("undefined" !== typeof window) && ("[object Window]" === toString.call(window))
43
+ ;
44
+
45
+ // basic backwards-compatible "class" construction
46
+ function makeSuper(superklass)
47
+ {
48
+ var called = {};
49
+ return function $super(method, args) {
50
+ var self = this, m = ':'+method, ret;
51
+ if (1 === called[m]) return (superklass.prototype.$super || NOP).call(self, method, args);
52
+ called[m] = 1;
53
+ ret = ('constructor' === method ? superklass : (superklass.prototype[method] || NOP)).apply(self, args || []);
54
+ called[m] = 0;
55
+ return ret;
56
+ };
57
+ }
58
+ function makeClass(superklass, klass, statik)
59
+ {
60
+ if (arguments.length < 2)
61
+ {
62
+ klass = superklass;
63
+ superklass = null;
64
+ }
65
+ var C = HAS.call(klass, 'constructor') ? klass.constructor : function() {}, p;
66
+ if (superklass)
67
+ {
68
+ C.prototype = Object.create(superklass.prototype);
69
+ C.prototype.$super = makeSuper(superklass);
70
+ }
71
+ else
72
+ {
73
+ C.prototype.$super = NOP;
74
+ }
75
+ C.prototype.constructor = C;
76
+ for (p in klass)
77
+ {
78
+ if (HAS.call(klass, p) && ('constructor' !== p))
79
+ {
80
+ C.prototype[p] = klass[p];
81
+ }
82
+ }
83
+ if (statik)
84
+ {
85
+ for (p in statik)
86
+ {
87
+ if (HAS.call(statik, p))
88
+ {
89
+ C[p] = statik[p];
90
+ }
91
+ }
92
+ }
93
+ return C;
94
+ }
95
+ var MOD3 = {
96
+ VERSION: "1.0.0",
97
+ Class: makeClass
98
+ };
99
+ /**
100
+ * MOD3 Constants and Auxilliary methods
101
+ **/
102
+ MOD3.Constants = {
103
+ // cache math constants for reference and optimization
104
+ PI: PI,
105
+ invPI: INV_PI,
106
+ halfPI: HALF_PI,
107
+ doublePI: TWO_PI,
108
+ toRad: PI/180,
109
+ toDeg: 180/PI
110
+ };
111
+ MOD3.ModConstant = {
112
+ NONE: 0,
113
+ LEFT: -1,
114
+ RIGHT: 1,
115
+
116
+ X: 1,
117
+ Y: 2,
118
+ Z: 4,
119
+
120
+ Xi: 0,
121
+ Yi: 1,
122
+ Zi: 2
123
+ };
124
+ MOD3.XYZi = [
125
+ null,
126
+ 0,
127
+ 1,
128
+ null,
129
+ 2
130
+ ];
131
+ MOD3.iXYZ = [
132
+ 1,
133
+ 2,
134
+ 4
135
+ ];
136
+ MOD3.xyz = [
137
+ "x",
138
+ "y",
139
+ "z"
140
+ ];
141
+ MOD3.XYZ = [
142
+ "X",
143
+ "Y",
144
+ "Z"
145
+ ];
146
+
147
+ // Typed Arrays Substitutes
148
+ MOD3.Array32F = typeof Float32Array !== "undefined" ? Float32Array : Array;
149
+ MOD3.Array64F = typeof Float64Array !== "undefined" ? Float64Array : Array;
150
+ MOD3.Array8I = typeof Int8Array !== "undefined" ? Int8Array : Array;
151
+ MOD3.Array16I = typeof Int16Array !== "undefined" ? Int16Array : Array;
152
+ MOD3.Array32I = typeof Int32Array !== "undefined" ? Int32Array : Array;
153
+ MOD3.Array8U = typeof Uint8Array !== "undefined" ? Uint8Array : Array;
154
+ MOD3.Array16U = typeof Uint16Array !== "undefined" ? Uint16Array : Array;
155
+ MOD3.Array32U = typeof Uint32Array !== "undefined" ? Uint32Array : Array;
156
+ // vector typed-array
157
+ MOD3.VecArray = MOD3.Array32F;
158
+ /**
159
+ * MOD3 Math Utilities Class
160
+ **/
161
+ MOD3.XMath = {
162
+ normalize: function(start, end, val) {
163
+ var range = end - start;
164
+ return 0 === range ? 1 : MOD3.XMath.trim(0, 1, (val - start)/end);
165
+ },
166
+
167
+ toRange: function(start, end, normalized) {
168
+ var range = end - start;
169
+ return 0 === range ? 0 : (start + range*normalized);
170
+ },
171
+
172
+ inRange: function(start, end, value, excluding) {
173
+ return false !== excluding ? (value >= start && value <= end) : (value > start && value < end);
174
+ },
175
+
176
+ sign: function(val, ifZero) {
177
+ return 0 === val ? (ifZero || 0) : (val > 0 ? 1 : -1);
178
+ },
179
+
180
+ trim: function(start, end, value) {
181
+ return value < start ? start : (value > end ? end : value);
182
+ },
183
+
184
+ wrap: function(start, end, value) {
185
+ var r = end - start;
186
+ return value < start ? (value + r) : (value >= end ? value - r : value);
187
+ },
188
+
189
+ degToRad: function(deg) {
190
+ return deg/180*PI;
191
+ },
192
+
193
+ radToDeg: function(rad) {
194
+ return rad/PI*180;
195
+ },
196
+
197
+ presicion: function(number, precision) {
198
+ var r = stdMath.pow(10, precision);
199
+ return stdMath.round(number*r)/r;
200
+ },
201
+
202
+ uceil: function(val) {
203
+ return val < 0 ? stdMath.floor(val) : stdMath.ceil(val);
204
+ }
205
+ };
206
+ // alias
207
+ MOD3.XMath.clamp = MOD3.XMath.trim;
208
+ /**
209
+ * MOD3 Range Auxilliary Class
210
+ **/
211
+ MOD3.Range = MOD3.Class({
212
+ constructor: function Range(s, e) {
213
+ var self = this;
214
+ if (!(self instanceof Range)) return new Range(s, e);
215
+ self.start = null != s ? s : 0;
216
+ self.end = null != e ? e : 1;
217
+ },
218
+
219
+ name: "Range",
220
+ start: 0,
221
+ end: 1,
222
+
223
+ dispose: function() {
224
+ var self = this;
225
+ self.start = null;
226
+ self.end = null;
227
+ return self;
228
+ },
229
+
230
+ getSize: function() {
231
+ return this.end - this.start;
232
+ },
233
+
234
+ move: function(amount) {
235
+ this.start += amount;
236
+ this.end += amount;
237
+ },
238
+
239
+ isIn: function(n) {
240
+ return (n >= this.start && n <= this.end);
241
+ },
242
+
243
+ normalize: function(n) {
244
+ return MOD3.XMath.normalize(this.start, this.end, n);
245
+ },
246
+
247
+ toRange: function(n) {
248
+ return MOD3.XMath.toRange(this.start, this.end, n);
249
+ },
250
+
251
+ trim: function(n) {
252
+ return MOD3.XMath.trim(this.start, this.end, n);
253
+ },
254
+
255
+ interpolate: function(n, r) {
256
+ return MOD3.XMath.toRange(this.start, this.end, r.normalize(n));
257
+ },
258
+
259
+ toString: function() {
260
+ return "[" + this.start + " - " + this.end + "]";
261
+ }
262
+ });
263
+ /**
264
+ * MOD3 Phase Auxilliary Class
265
+ **/
266
+ MOD3.Phase = MOD3.Class({
267
+ constructor: function Phase(v) {
268
+ var self = this;
269
+ if (!(self instanceof Phase)) return new Phase(v);
270
+ self.value = v || 0;
271
+ },
272
+
273
+ name: "Phase",
274
+ value: 0,
275
+
276
+ dispose: function() {
277
+ this.value = null;
278
+ return this;
279
+ },
280
+
281
+ getPhasedValue: function() {
282
+ return stdMath.sin(this.value);
283
+ },
284
+
285
+ getAbsPhasedValue: function() {
286
+ return stdMath.abs(stdMath.sin(this.value));
287
+ },
288
+
289
+ getNormValue: function() {
290
+ return (stdMath.sin(this.value) + 1)*0.5;
291
+ }
292
+ });
293
+ /**
294
+ * MOD3 2D Point Class
295
+ **/
296
+ MOD3.Point = MOD3.Class({
297
+ constructor: function Point(x, y) {
298
+ var self = this;
299
+ if (!(self instanceof Point)) return new Point(x, y);
300
+ self.x = x || 0;
301
+ self.y = y || 0;
302
+ },
303
+
304
+ name: "Point",
305
+ x: 0,
306
+ y: 0,
307
+
308
+ dispose: function() {
309
+ var self = this;
310
+ self.x = null;
311
+ self.y = null;
312
+ return self;
313
+ },
314
+
315
+ clone: function() {
316
+ return new MOD3.Point(this.x, this.y);
317
+ }
318
+ });
319
+ /**
320
+ * MOD3 2D Transform Matrix Class
321
+ **/
322
+ MOD3.Matrix = MOD3.Class(null, {
323
+ constructor: function Matrix(m11, m12,
324
+ m21, m22)
325
+ {
326
+ var self = this;
327
+ if (!(self instanceof Matrix)) return new Matrix(m11, m12,
328
+ m21, m22);
329
+ self.m = new MOD3.VecArray([
330
+ m11 == null ? 1 : m11,
331
+ m12 == null ? 0 : m12,
332
+ m21 == null ? 0 : m21,
333
+ m22 == null ? 1 : m22
334
+ ]);
335
+ },
336
+
337
+ name: "Matrix",
338
+ m: null,
339
+
340
+ dispose: function() {
341
+ this.m = null;
342
+ return this;
343
+ },
344
+
345
+ reset: function() {
346
+ var m = this.m;
347
+ m[0] = 1; m[1] = 0;
348
+ m[2] = 0; m[3] = 1;
349
+ return this;
350
+ },
351
+
352
+ rotate: function(angle) {
353
+ var m = this.m, c = stdMath.cos(angle), s = stdMath.sin(angle);
354
+ m[0] = c; m[1] = -s;
355
+ m[2] = s; m[3] = c;
356
+ return this;
357
+ },
358
+
359
+ scale: function(sx, sy) {
360
+ var m = this.m;
361
+ m[0] = 1; m[1] = 0;
362
+ m[2] = 0; m[3] = 1;
363
+ if (sx != null)
364
+ {
365
+ m[0] = sx;
366
+ m[3] = sx;
367
+ }
368
+ if (sy != null)
369
+ {
370
+ m[3] = sy;
371
+ }
372
+ return this;
373
+ },
374
+
375
+ multiply: function(b) {
376
+ return MOD3.Matrix.mult(this, b);
377
+ },
378
+
379
+ transformPoint: function(p) {
380
+ var xy = MOD3.Matrix.transform(this, [p.x, p.y]);
381
+ return new MOD3.Point(xy[0], xy[1]);
382
+ },
383
+
384
+ transformPointSelf: function(p) {
385
+ var xy = MOD3.Matrix.transform(this, [p.x, p.y]);
386
+ p.x = xy[0]; p.y = xy[1];
387
+ return p;
388
+ },
389
+
390
+ clone: function() {
391
+ var m = this.m;
392
+ return new MOD3.Matrix(m[0], m[1],
393
+ m[2], m[3]);
394
+ }
395
+ }, {
396
+ transform: function(m2, xy) {
397
+ var m = m2.m, x = xy[0], y = xy[1];
398
+ xy[0] = m[0]*x + m[1]*y;
399
+ xy[1] = m[2]*x + m[3]*y;
400
+ return xy;
401
+ },
402
+
403
+ mult: function(m1, m2) {
404
+ var a = m1.m, b = m2.m, a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3];
405
+ a[0] = a0*b[0] + a1*b[2];
406
+ a[1] = a0*b[1] + a1*b[3];
407
+ a[2] = a2*b[0] + a3*b[2];
408
+ a[3] = a2*b[1] + a3*b[3];
409
+ return m1;
410
+ }
411
+ });
412
+ /**
413
+ * MOD3 Vector3 Class
414
+ **/
415
+ MOD3.Vector3 = MOD3.Class(null, {
416
+ constructor: function Vector3(x, y, z) {
417
+ var self = this;
418
+ if (!(self instanceof Vector3)) return new Vector3(x, y, z);
419
+
420
+ // use an internal typed-array for speed
421
+ var v = new MOD3.VecArray(3);
422
+ if (x && (3 === x.length))
423
+ {
424
+ // array passed
425
+ v[0] = x[0] || 0;
426
+ v[1] = x[1] || 0;
427
+ v[2] = x[2] || 0;
428
+ }
429
+ else
430
+ {
431
+ // numbers passed
432
+ v[0] = x || 0;
433
+ v[1] = y || 0;
434
+ v[2] = z || 0;
435
+ }
436
+ self.xyz = v;
437
+ },
438
+
439
+ name: "Vector3",
440
+ xyz: null,
441
+
442
+ dispose: function() {
443
+ this.xyz = null;
444
+ return this;
445
+ },
446
+
447
+ getXYZ: function() {
448
+ // copy it
449
+ return new MOD3.VecArray(this.xyz);
450
+ },
451
+
452
+ getXYZRef: function() {
453
+ return this.xyz;
454
+ },
455
+
456
+ setXYZ: function(w) {
457
+ var v = this.xyz;
458
+ v[0] = w[0];
459
+ v[1] = w[1];
460
+ v[2] = w[2];
461
+ return this;
462
+ },
463
+
464
+ setXYZRef: function(xyz) {
465
+ this.xyz = xyz;
466
+ return this;
467
+ },
468
+
469
+ clone: function() {
470
+ return new MOD3.Vector3(this.xyz);
471
+ },
472
+
473
+ equalsSelf: function(b) {
474
+ var v = this.xyz, w = b.xyz;
475
+ return (v[0] === w[0]) && (v[1] === w[1]) && (v[2] === w[2]);
476
+ },
477
+
478
+ zeroSelf: function() {
479
+ var v = this.xyz;
480
+ v[0] = 0; v[1] = 0; v[2] = 0;
481
+ return this;
482
+ },
483
+
484
+ negate: function() {
485
+ var v = this.xyz;
486
+ return new MOD3.Vector3(-v[0], -v[1], -v[2]);
487
+ },
488
+
489
+ negateSelf: function() {
490
+ var v = this.xyz;
491
+ v[0] = -v[0]; v[1] = -v[1]; v[2] = -v[2];
492
+ return this;
493
+ },
494
+
495
+ add: function(b) {
496
+ var v = this.xyz, w = b.xyz;
497
+ return new MOD3.Vector3(v[0] + w[0], v[1] + w[1], v[2] + w[2]);
498
+ },
499
+
500
+ addSelf: function(b) {
501
+ var v = this.xyz, w = b.xyz;
502
+ v[0] += w[0]; v[1] += w[1]; v[2] += w[2];
503
+ return this;
504
+ },
505
+
506
+ subtract: function(b) {
507
+ var v = this.xyz, w = b.xyz;
508
+ return new MOD3.Vector3(v[0] - w[0], v[1] - w[1], v[2] - w[2]);
509
+ },
510
+
511
+ subtractSelf: function(b) {
512
+ var v = this.xyz, w = b.xyz;
513
+ v[0] -= w[0]; v[1] -= w[1]; v[2] -= w[2];
514
+ return this;
515
+ },
516
+
517
+ multiplyScalar: function(s) {
518
+ var v = this.xyz;
519
+ return new MOD3.Vector3(v[0]*s, v[1]*s, v[2]*s);
520
+ },
521
+
522
+ multiplyScalarSelf: function(s) {
523
+ var v = this.xyz;
524
+ v[0] *= s; v[1] *= s; v[2] *= s;
525
+ return this;
526
+ },
527
+
528
+ multiply: function(b) {
529
+ var v = this.xyz, w = b.xyz;
530
+ return new MOD3.Vector3(v[0] * w[0], v[1] * w[1], v[2] * w[2]);
531
+ },
532
+
533
+ multiplySelf: function(b) {
534
+ var v = this.xyz, w = b.xyz;
535
+ v[0] *= w[0]; v[1] *= w[1]; v[2] *= w[2];
536
+ return this;
537
+ },
538
+
539
+ divide: function(s) {
540
+ var v = this.xyz;
541
+ return new MOD3.Vector3(v[0] / s, v[1] / s, v[2] / s);
542
+ },
543
+
544
+ divideSelf: function(s) {
545
+ var v = this.xyz;
546
+ v[0] /= s; v[1] /= s; v[2] /= s;
547
+ return this;
548
+ },
549
+
550
+ normalize: function() {
551
+ var v = this.xyz,
552
+ x = v[0], y = v[1], z = v[2],
553
+ m = x * x + y * y + z * z, n;
554
+ if (0 < m)
555
+ {
556
+ n = stdMath.sqrt(m);
557
+ x /= n;
558
+ y /= n;
559
+ z /= n;
560
+ }
561
+ return new MOD3.Vector3(x, y, z);
562
+ },
563
+
564
+ normalizeSelf: function() {
565
+ var v = this.xyz,
566
+ x = v[0], y = v[1], z = v[2],
567
+ m = x * x + y * y + z * z, n;
568
+ if (0 < m)
569
+ {
570
+ n = stdMath.sqrt(m);
571
+ x /= n;
572
+ y /= n;
573
+ z /= n;
574
+ }
575
+ v[0] = x; v[1] = y; v[2] = z;
576
+ return this;
577
+ },
578
+
579
+ getMagnitude: function() {
580
+ var v = this.xyz, x = v[0], y = v[1], z = v[2];
581
+ return stdMath.sqrt(x*x + y*y + z*z);
582
+ },
583
+
584
+ setMagnitude: function(m) {
585
+ this.normalizeSelf();
586
+ var v = this.xyz;
587
+ v[0] *= m; v[1] *= m; v[2] *= m;
588
+ return this;
589
+ },
590
+
591
+ dot: function(b) {
592
+ var v = this.xyz, w = b.xyz;
593
+ return v[0]*w[0] + v[1]*w[1] + v[2]*w[2];
594
+ },
595
+
596
+ cross: function(b) {
597
+ var v = this.xyz, w = b.xyz,
598
+ x1 = v[0], y1 = v[1], z1 = v[2],
599
+ x2 = w[0], y2 = w[1], z2 = w[2];
600
+ return new MOD3.Vector3(y1 * z2 - z1 * y2, z1 * x2 - x1 * z2, x1 * y2 - y1 * x2);
601
+ },
602
+
603
+ crossSelf: function(v) {
604
+ var v = this.xyz, w = b.xyz,
605
+ x1 = v[0], y1 = v[1], z1 = v[2],
606
+ x2 = w[0], y2 = w[1], z2 = w[2];
607
+ v[0] = y1 * z2 - z1 * y2;
608
+ v[1] = z1 * x2 - x1 * z2;
609
+ v[2] = x1 * y2 - y1 * x2;
610
+ return this;
611
+ },
612
+
613
+ distance: function(b) {
614
+ var v = this.xyz, w = b.xyz,
615
+ dx = v[0] - w[0],
616
+ dy = v[1] - w[1],
617
+ dz = v[2] - w[2];
618
+ return stdMath.sqrt(dx*dx + dy*dy + dz*dz);
619
+ },
620
+
621
+ toString: function() {
622
+ var v = this.xyz;
623
+ return "[" + v[0] + " , " + v[1] + " , " + v[2] + "]";
624
+ }
625
+ }, {
626
+ ZERO: function() {
627
+ return new MOD3.Vector3(0, 0, 0);
628
+ },
629
+
630
+ X: function(direct_or_complement) {
631
+ return false === direct_or_complement ? new MOD3.Vector3(0, 1, 1) : new MOD3.Vector3(1, 0, 0);
632
+ },
633
+
634
+ Y: function(direct_or_complement) {
635
+ return false === direct_or_complement ? new MOD3.Vector3(1, 0, 1) : new MOD3.Vector3(0, 1, 0);
636
+ },
637
+
638
+ Z: function(direct_or_complement) {
639
+ return false === direct_or_complement ? new MOD3.Vector3(1, 1, 0) : new MOD3.Vector3(0, 0, 1);
640
+ },
641
+
642
+ dot: function(v, w) {
643
+ return v[0]*w[0] + v[1]*w[1] + v[2]*w[2];
644
+ },
645
+
646
+ equals: function(v, w) {
647
+ return (v[0] === w[0]) && (v[1] === w[1]) && (v[2] === w[2]);
648
+ },
649
+
650
+ cross: function(v, w) {
651
+ var vw = new MOD3.VecArray(3);
652
+ vw[0] = v[1] * w[2] - v[2] * w[1];
653
+ vw[1] = v[2] * w[0] - v[0] * w[2];
654
+ vw[2] = v[0] * w[1] - v[1] * w[0];
655
+ return vw;
656
+ },
657
+
658
+ mod: function(v) {
659
+ var x = v[0], y = v[1], z = v[2];
660
+ return stdMath.sqrt(x*x + y*y + z*z);
661
+ },
662
+
663
+ dist: function(v, w) {
664
+ var dx = v[0] - w[0],
665
+ dy = v[1] - w[1],
666
+ dz = v[2] - w[2];
667
+ return stdMath.sqrt(dx*dx + dy*dy + dz*dz);
668
+ },
669
+
670
+ add: function(v, w) {
671
+ v[0] += w[0];
672
+ v[1] += w[1];
673
+ v[2] += w[2];
674
+ return v;
675
+ },
676
+
677
+ sub: function(v, w) {
678
+ v[0] -= w[0];
679
+ v[1] -= w[1];
680
+ v[2] -= w[2];
681
+ return v;
682
+ },
683
+
684
+ mul: function(v, w) {
685
+ v[0] *= w[0];
686
+ v[1] *= w[1];
687
+ v[2] *= w[2];
688
+ return v;
689
+ },
690
+
691
+ muls: function(v, m) {
692
+ v[0] *= m;
693
+ v[1] *= m;
694
+ v[2] *= m;
695
+ return v;
696
+ },
697
+
698
+ norm: function(v) {
699
+ var x = v[0], y = v[1], z = v[2],
700
+ m = x*x + y*y + z*z, n;
701
+ if (0 < m)
702
+ {
703
+ n = stdMath.sqrt(m);
704
+ x /= n;
705
+ y /= n;
706
+ z /= n;
707
+ }
708
+ v[0] = x; v[1] = y; v[2] = z;
709
+ return v;
710
+ }
711
+ });
712
+ // alaises
713
+ MOD3.Vector3.modulo = MOD3.Vector3.mod;
714
+ MOD3.Vector3.distance = MOD3.Vector3.dist;
715
+ MOD3.Vector3.prototype.dotSelf = MOD3.Vector3.prototype.dot;
716
+ MOD3.Vector3.prototype.distanceSelf = MOD3.Vector3.prototype.distance;
717
+ /**
718
+ * MOD3 3D Transform Matrix Class
719
+ **/
720
+ MOD3.Matrix4 = MOD3.Class(null, {
721
+ constructor: function Matrix4(n11, n12, n13, n14,
722
+ n21, n22, n23, n24,
723
+ n31, n32, n33, n34,
724
+ n41, n42, n43, n44)
725
+ {
726
+ var self = this;
727
+ if (!(self instanceof Matrix4)) return new Matrix4(n11, n12, n13, n14,
728
+ n21, n22, n23, n24,
729
+ n31, n32, n33, n34,
730
+ n41, n42, n43, n44);
731
+ self.m = new MOD3.VecArray([
732
+ n11 == null ? 1 : n11,
733
+ n12 == null ? 0 : n12,
734
+ n13 == null ? 0 : n13,
735
+ n14 == null ? 0 : n14,
736
+
737
+ n21 == null ? 0 : n21,
738
+ n22 == null ? 1 : n22,
739
+ n23 == null ? 0 : n23,
740
+ n24 == null ? 0 : n24,
741
+
742
+ n31 == null ? 0 : n31,
743
+ n32 == null ? 0 : n32,
744
+ n33 == null ? 1 : n33,
745
+ n34 == null ? 0 : n34,
746
+
747
+ n41 == null ? 0 : n41,
748
+ n42 == null ? 0 : n42,
749
+ n43 == null ? 0 : n43,
750
+ n44 == null ? 1 : n44
751
+ ]);
752
+ },
753
+
754
+ name: "Matrix4",
755
+ m: null,
756
+
757
+ dispose: function() {
758
+ this.m = null;
759
+ return this;
760
+ },
761
+
762
+ reset: function() {
763
+ var m = this.m;
764
+ m[0 ] = 1; m[1 ] = 0; m[2 ] = 0; m[3 ] = 0;
765
+ m[4 ] = 0; m[5 ] = 1; m[6 ] = 0; m[7 ] = 0;
766
+ m[8 ] = 0; m[9 ] = 0; m[10] = 1; m[11] = 0;
767
+ m[12] = 0; m[13] = 0; m[14] = 0; m[15] = 1;
768
+ return this;
769
+ },
770
+
771
+ translate: function(tx, ty, tz, reset) {
772
+ var m = this.m;
773
+ if (true === reset) this.reset();
774
+ m[3 ] = tx;
775
+ m[7 ] = ty;
776
+ m[11] = tz;
777
+ return this;
778
+ },
779
+
780
+ scale: function(sx, sy, sz, reset) {
781
+ var m = this.m;
782
+ if (true === reset) this.reset();
783
+ m[0 ] = sx;
784
+ m[5 ] = sy;
785
+ m[10] = sz;
786
+ return this;
787
+ },
788
+
789
+ rotate: function(rx, ry, rz, theta, reset) {
790
+ var m = this.m,
791
+ nCos = stdMath.cos(theta), nSin = stdMath.sin(theta), scos = 1 - nCos,
792
+ sxy = rx*ry*scos, syz = ry*rz*scos, sxz = rx*rz*scos,
793
+ sz = nSin*rz, sy = nSin*ry, sx = nSin*rx
794
+ ;
795
+ if (true === reset) this.reset();
796
+ m[0 ] = nCos + rx*rx*scos;
797
+ m[1 ] = -sz + sxy;
798
+ m[2 ] = sy + sxz;
799
+ m[3 ] = 0;
800
+
801
+ m[4 ] = sz + sxy;
802
+ m[5 ] = nCos + ry*ry*scos;
803
+ m[6 ] = -sx + syz;
804
+ m[7 ] = 0;
805
+
806
+ m[8 ] = -sy + sxz;
807
+ m[9 ] = sx + syz;
808
+ m[10] = nCos + rz*rz*scos;
809
+ m[11] = 0;
810
+ return this;
811
+ },
812
+
813
+ translateFromVector: function(v, reset) {
814
+ return this.translate(v.xyz[0], v.xyz[1], v.xyz[2], reset);
815
+ },
816
+
817
+ scaleFromVector: function(v, reset) {
818
+ return this.scale(v.xyz[0], v.xyz[1], v.xyz[2], reset);
819
+ },
820
+
821
+ rotateFromVector: function(v, theta, reset) {
822
+ return this.rotate(v.xyz[0], v.xyz[1], v.xyz[2], theta, reset);
823
+ },
824
+
825
+ multiply: function(b) {
826
+ return MOD3.Matrix4.mult(this, b);
827
+ },
828
+
829
+ multiplyVector: function(v) {
830
+ MOD3.Matrix4.multXYZ(this, v.xyz);
831
+ return v;
832
+ }
833
+ }, {
834
+ multXYZ: function(m4, v) {
835
+ var m = m4.m, x = v[0], y = v[1], z = v[2];
836
+ v[0] = x*m[0 ] + y*m[1 ] + z*m[2 ] + m[3 ];
837
+ v[1] = x*m[4 ] + y*m[5 ] + z*m[6 ] + m[7 ];
838
+ v[2] = x*m[8 ] + y*m[9 ] + z*m[10] + m[11];
839
+ return v;
840
+ },
841
+
842
+ mult: function(m1, m2) {
843
+ var a = m1.m, b = m2.m,
844
+ a11 = a[0 ], b11 = b[0 ],
845
+ a21 = a[4 ], b21 = b[4 ],
846
+ a31 = a[8 ], b31 = b[8 ],
847
+ a12 = a[1 ], b12 = b[1 ],
848
+ a22 = a[5 ], b22 = b[5 ],
849
+ a32 = a[9 ], b32 = b[9 ],
850
+ a13 = a[2 ], b13 = b[2 ],
851
+ a23 = a[6 ], b23 = b[6 ],
852
+ a33 = a[10], b33 = b[10],
853
+ a14 = a[3 ], b14 = b[3 ],
854
+ a24 = a[7 ], b24 = b[7 ],
855
+ a34 = a[11], b34 = b[11];
856
+
857
+ a[0 ] = a11*b11 + a12*b21 + a13*b31;
858
+ a[1 ] = a11*b12 + a12*b22 + a13*b32;
859
+ a[2 ] = a11*b13 + a12*b23 + a13*b33;
860
+ a[3 ] = a11*b14 + a12*b24 + a13*b34 + a14;
861
+
862
+ a[4 ] = a21*b11 + a22*b21 + a23*b31;
863
+ a[5 ] = a21*b12 + a22*b22 + a23*b32;
864
+ a[6 ] = a21*b13 + a22*b23 + a23*b33;
865
+ a[7 ] = a21*b14 + a22*b24 + a23*b34 + a24;
866
+
867
+ a[8 ] = a31*b11 + a32*b21 + a33*b31;
868
+ a[9 ] = a31*b12 + a32*b22 + a33*b32;
869
+ a[10] = a31*b13 + a32*b23 + a33*b33;
870
+ a[11] = a31*b14 + a32*b24 + a33*b34 + a34;
871
+ return m1;
872
+ }
873
+ });
874
+ // aliases
875
+ MOD3.Matrix4.prototype.translationMatrix = MOD3.Matrix4.prototype.translate;
876
+ MOD3.Matrix4.prototype.scaleMatrix = MOD3.Matrix4.prototype.scale;
877
+ MOD3.Matrix4.prototype.rotationMatrix = MOD3.Matrix4.prototype.rotate;
878
+ MOD3.Matrix4.prototype.translationMatrixFromVector = MOD3.Matrix4.prototype.translateFromVector;
879
+ MOD3.Matrix4.prototype.scaleMatrixFromVector = MOD3.Matrix4.prototype.scaleFromVector;
880
+ MOD3.Matrix4.prototype.rotationMatrixFromVector = MOD3.Matrix4.prototype.rotateFromVector;
881
+ // fast list utilities
882
+ MOD3.List = {
883
+ operate: function operate(x, F, F0, i0, i1, reverse) {
884
+ var len = x.length;
885
+ if (arguments.length < 5) i1 = len-1;
886
+ if (0 > i1) i1 += len;
887
+ if (arguments.length < 4) i0 = 0;
888
+ if (i0 > i1) return F0;
889
+ if (true === reverse)
890
+ {
891
+ var i, k, l=i1-i0+1, l1=l-1, r=l&15, q=r&1, lr=l1-r, Fv=q?F(F0,x[i1],i1):F0;
892
+ for (i=l1-q; i>lr; i-=2) { k = i0+i; Fv = F(F(Fv,x[k],k),x[k-1],k-1); }
893
+ for (i=lr; i>=0; i-=16) { k = i0+i; Fv = F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(Fv,x[k],k),x[k-1],k-1),x[k-2],k-2),x[k-3],k-3),x[k-4],k-4),x[k-5],k-5),x[k-6],k-6),x[k-7],k-7),x[k-8],k-8),x[k-9],k-9),x[k-10],k-10),x[k-11],k-11),x[k-12],k-12),x[k-13],k-13),x[k-14],k-14),x[k-15],k-15); }
894
+ }
895
+ else
896
+ {
897
+ var i, k, l=i1-i0+1, r=l&15, q=r&1, Fv=q?F(F0,x[i0],i0):F0;
898
+ for (i=q; i<r; i+=2) { k = i0+i; Fv = F(F(Fv,x[k],k),x[k+1],k+1); }
899
+ for (i=r; i<l; i+=16) { k = i0+i; Fv = F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(Fv,x[k],k),x[k+1],k+1),x[k+2],k+2),x[k+3],k+3),x[k+4],k+4),x[k+5],k+5),x[k+6],k+6),x[k+7],k+7),x[k+8],k+8),x[k+9],k+9),x[k+10],k+10),x[k+11],k+11),x[k+12],k+12),x[k+13],k+13),x[k+14],k+14),x[k+15],k+15); }
900
+ }
901
+ return Fv;
902
+ }
903
+
904
+ ,each: function each(x, F, i0, i1, reverse) {
905
+ if (null == x || !x.length) return x;
906
+ var len = x.length;
907
+ if (arguments.length < 4) i1 = len-1;
908
+ if (0 > i1) i1 += len;
909
+ if (arguments.length < 3) i0 = 0;
910
+ if (i0 > i1) return x;
911
+ var i, k, l=i1-i0+1, l1, lr, r, q;
912
+ if (true === reverse)
913
+ {
914
+ l1=l-1; r=l&15; q=r&1; lr=l1-r;
915
+ if (q) F(x[i1]);
916
+ for (i=l1-q; i>lr; i-=2)
917
+ {
918
+ k = i0+i;
919
+ F(x[k ]);
920
+ F(x[k-1]);
921
+ }
922
+ for (i=lr; i>=0; i-=16)
923
+ {
924
+ k = i0+i;
925
+ F(x[k ] );
926
+ F(x[k-1] );
927
+ F(x[k-2] );
928
+ F(x[k-3] );
929
+ F(x[k-4] );
930
+ F(x[k-5] );
931
+ F(x[k-6] );
932
+ F(x[k-7] );
933
+ F(x[k-8] );
934
+ F(x[k-9] );
935
+ F(x[k-10]);
936
+ F(x[k-11]);
937
+ F(x[k-12]);
938
+ F(x[k-13]);
939
+ F(x[k-14]);
940
+ F(x[k-15]);
941
+ }
942
+ }
943
+ else
944
+ {
945
+ r=l&15; q=r&1;
946
+ if (q) F(x[i0]);
947
+ for (i=q; i<r; i+=2)
948
+ {
949
+ k = i0+i;
950
+ F(x[k ]);
951
+ F(x[k+1]);
952
+ }
953
+ for (i=r; i<l; i+=16)
954
+ {
955
+ k = i0+i;
956
+ F(x[k ] );
957
+ F(x[k+1] );
958
+ F(x[k+2] );
959
+ F(x[k+3] );
960
+ F(x[k+4] );
961
+ F(x[k+5] );
962
+ F(x[k+6] );
963
+ F(x[k+7] );
964
+ F(x[k+8] );
965
+ F(x[k+9] );
966
+ F(x[k+10]);
967
+ F(x[k+11]);
968
+ F(x[k+12]);
969
+ F(x[k+13]);
970
+ F(x[k+14]);
971
+ F(x[k+15]);
972
+ }
973
+ }
974
+ return x;
975
+ }
976
+ };
977
+ /**
978
+ * MOD3 MeshProxy Super Class
979
+ **/
980
+ function dispose(o)
981
+ {
982
+ o.dispose();
983
+ }
984
+ function reset(o)
985
+ {
986
+ o.reset();
987
+ }
988
+ function collapse(o)
989
+ {
990
+ o.collapse();
991
+ }
992
+
993
+ MOD3.FaceProxy = MOD3.Class(null, {
994
+ constructor: function FaceProxy() {
995
+ this.vertices = [];
996
+ },
997
+
998
+ name: "FaceProxy",
999
+ vertices: null,
1000
+
1001
+ dispose: function() {
1002
+ var self = this;
1003
+ self.vertices = null;
1004
+ return self;
1005
+ },
1006
+
1007
+ addVertex: function(v) {
1008
+ this.vertices.push(v);
1009
+ },
1010
+
1011
+ getVertices: function() {
1012
+ return this.vertices;
1013
+ }
1014
+ });
1015
+
1016
+ MOD3.VertexProxy = MOD3.Class(null, {
1017
+ constructor: function VertexProxy(vertex, mesh) {
1018
+ var self = this;
1019
+ self.mesh = mesh || null;
1020
+ // use internal typed-arrays for speed
1021
+ self.original = new MOD3.VecArray([0,0,0]);
1022
+ self.ratio = new MOD3.VecArray([0,0,0]);
1023
+ // vertex can be zero
1024
+ if (null != vertex) self.setVertex(vertex);
1025
+ },
1026
+
1027
+ name: "VertexProxy",
1028
+ mesh: null,
1029
+ vertex: null,
1030
+ original: null,
1031
+ ratio: null,
1032
+
1033
+ dispose: function() {
1034
+ var self = this;
1035
+ self.mesh = null;
1036
+ self.vertex = null;
1037
+ self.original = null;
1038
+ self.ratio = null;
1039
+ return self;
1040
+ },
1041
+
1042
+ setVertex: function(vt) {
1043
+ // override
1044
+ var self = this;
1045
+ self.vertex = vt;
1046
+ return self;
1047
+ },
1048
+
1049
+ getRatioVector: function() {
1050
+ var r = this.ratio, rv = new MOD3.VecArray(3);
1051
+ rv[0] = r[0]; rv[1] = r[1]; rv[2] = r[2];
1052
+ return rv;
1053
+ },
1054
+
1055
+ getRatio: function(axis) {
1056
+ return this.ratio[MOD3.XYZi[axis]] || 0;
1057
+ },
1058
+
1059
+ setRatios: function(rx, ry, rz) {
1060
+ var r = this.ratio;
1061
+ r[0] = rx || 0;
1062
+ r[1] = ry || 0;
1063
+ r[2] = rz || 0;
1064
+ return this;
1065
+ },
1066
+
1067
+ getOriginalValue: function(axis) {
1068
+ return this.original[MOD3.XYZi[axis]] || 0;
1069
+ },
1070
+
1071
+ setOriginalPosition: function(ox, oy, oz) {
1072
+ var o = this.original;
1073
+ o[0] = ox || 0;
1074
+ o[1] = oy || 0;
1075
+ o[2] = oz || 0;
1076
+ return this;
1077
+ },
1078
+
1079
+ getXYZ: function() {
1080
+ // override
1081
+ return new MOD3.VecArray([0,0,0]);
1082
+ },
1083
+
1084
+ getX: function() {
1085
+ // override
1086
+ return 0;
1087
+ },
1088
+
1089
+ getY: function() {
1090
+ // override
1091
+ return 0;
1092
+ },
1093
+
1094
+ getZ: function() {
1095
+ // override
1096
+ return 0;
1097
+ },
1098
+
1099
+ getValue: function(axis) {
1100
+ var self = this;
1101
+ // override
1102
+ return MOD3.ModConstant.X === axis
1103
+ ? self.getX()
1104
+ : (MOD3.ModConstant.Y === axis
1105
+ ? self.getY()
1106
+ : (MOD3.ModConstant.Z === axis
1107
+ ? self.getZ()
1108
+ : 0))
1109
+ ;
1110
+ },
1111
+
1112
+ setXYZ: function(xyz) {
1113
+ // override
1114
+ return this;
1115
+ },
1116
+
1117
+ setX: function(vo) {
1118
+ // override
1119
+ return this;
1120
+ },
1121
+
1122
+ setY: function(vo) {
1123
+ // override
1124
+ return this;
1125
+ },
1126
+
1127
+ setZ: function(vo) {
1128
+ // override
1129
+ return this;
1130
+ },
1131
+
1132
+ setValue: function(axis, vo) {
1133
+ var self = this;
1134
+ // override
1135
+ if (MOD3.ModConstant.X === axis) self.setX(vo);
1136
+ else if (MOD3.ModConstant.Y === axis) self.setY(vo);
1137
+ else if (MOD3.ModConstant.Z === axis) self.setZ(vo);
1138
+ return self;
1139
+ },
1140
+
1141
+ reset: function() {
1142
+ // override
1143
+ var self = this;
1144
+ self.setXYZ(self.original);
1145
+ return self;
1146
+ },
1147
+
1148
+ collapse: function() {
1149
+ // override
1150
+ var self = this, xyz = self.getXYZ(), o = self.original;
1151
+ o[0] = xyz[0]; o[1] = xyz[1]; o[2] = xyz[2];
1152
+ return self;
1153
+ }
1154
+ });
1155
+
1156
+ MOD3.MeshProxy = MOD3.Class(null, {
1157
+ constructor: function MeshProxy(mesh) {
1158
+ var self = this;
1159
+ self.maxX = 0;
1160
+ self.maxY = 0;
1161
+ self.maxZ = 0;
1162
+
1163
+ self.minX = 0;
1164
+ self.minY = 0;
1165
+ self.minZ = 0;
1166
+
1167
+ self.maxAxis = 0;
1168
+ self.midAxis = 0;
1169
+ self.minAxis = 0;
1170
+
1171
+ self.width = 0;
1172
+ self.height = 0;
1173
+ self.depth = 0;
1174
+
1175
+ self.vertices = null;
1176
+ self.faces = null;
1177
+ self.mesh = null;
1178
+
1179
+ if (null != mesh) self.setMesh(mesh);
1180
+ },
1181
+
1182
+ name: "MeshProxy",
1183
+
1184
+ maxX: 0,
1185
+ maxY: 0,
1186
+ maxZ: 0,
1187
+ minX: 0,
1188
+ minY: 0,
1189
+ minZ: 0,
1190
+
1191
+ maxAxis: 0,
1192
+ midAxis: 0,
1193
+ minAxis: 0,
1194
+
1195
+ width: 0,
1196
+ height: 0,
1197
+ depth: 0,
1198
+
1199
+ vertices : null,
1200
+ faces : null,
1201
+ mesh : null,
1202
+ v: null,
1203
+
1204
+ dispose: function() {
1205
+ var self = this;
1206
+ self.maxX = null;
1207
+ self.maxY = null;
1208
+ self.maxZ = null;
1209
+ self.minX = null;
1210
+ self.minY = null;
1211
+ self.minZ = null;
1212
+
1213
+ self.maxAxis = null;
1214
+ self.midAxis = null;
1215
+ self.minAxis = null;
1216
+
1217
+ self.width = null;
1218
+ self.height = null;
1219
+ self.depth = null;
1220
+
1221
+ self.disposeFaces();
1222
+ self.disposeVertices();
1223
+ self.mesh = null;
1224
+ self.v = null;
1225
+ return self;
1226
+ },
1227
+
1228
+ disposeVertices: function() {
1229
+ var self = this;
1230
+ if (self.vertices) MOD3.List.each(self.vertices, dispose);
1231
+ self.vertices = null;
1232
+ return self;
1233
+ },
1234
+
1235
+ disposeFaces: function() {
1236
+ var self = this;
1237
+ if (self.faces) MOD3.List.each(self.faces, dispose);
1238
+ self.faces = null;
1239
+ return self;
1240
+ },
1241
+
1242
+ init: function(mesh) {
1243
+ var self = this;
1244
+ self.mesh = mesh;
1245
+ //self.vertices = [];
1246
+ // not used
1247
+ //self.faces = [];
1248
+ return self;
1249
+ },
1250
+
1251
+ setMesh: function(mesh) {
1252
+ var self = this;
1253
+ self.init(mesh);
1254
+ self.preApply();
1255
+ self.analyzeGeometry()
1256
+ self.postApply();
1257
+ return self;
1258
+ },
1259
+
1260
+ getVertices: function() {
1261
+ return this.vertices;
1262
+ },
1263
+
1264
+ getFaces: function() {
1265
+ return this.faces;
1266
+ },
1267
+
1268
+ applyModifiers: function(modStack) {
1269
+ var self = this, sl, i;
1270
+ for (i=0,sl=modStack.length; i<sl; ++i)
1271
+ {
1272
+ modStack[i].enabled && modStack[i].apply(self);
1273
+ }
1274
+ return self;
1275
+ },
1276
+
1277
+ analyzeGeometry: function() {
1278
+ var self = this,
1279
+ vertices = self.vertices,
1280
+ minX = 0, minY = 0, minZ = 0,
1281
+ maxX = 0, maxY = 0, maxZ = 0,
1282
+ width = 0, height = 0, depth = 0,
1283
+ maxe, mine, w
1284
+ ;
1285
+ if (!vertices || !vertices.length) return self;
1286
+
1287
+ w = vertices[0].getXYZ();
1288
+ minX = w[0];
1289
+ minY = w[1];
1290
+ minZ = w[2];
1291
+
1292
+ maxX = w[0];
1293
+ maxY = w[1];
1294
+ maxZ = w[2];
1295
+
1296
+ MOD3.List.each(vertices, function(v) {
1297
+ var xyz = v.getXYZ(), x = xyz[0], y = xyz[1], z = xyz[2];
1298
+ minX = stdMath.min(minX, x);
1299
+ minY = stdMath.min(minY, y);
1300
+ minZ = stdMath.min(minZ, z);
1301
+
1302
+ maxX = stdMath.max(maxX, x);
1303
+ maxY = stdMath.max(maxY, y);
1304
+ maxZ = stdMath.max(maxZ, z);
1305
+ v.setOriginalPosition(x, y, z);
1306
+ });
1307
+
1308
+ width = maxX - minX;
1309
+ height = maxY - minY;
1310
+ depth = maxZ - minZ;
1311
+
1312
+ self.width = width;
1313
+ self.height = height;
1314
+ self.depth = depth;
1315
+ self.minX = minX;
1316
+ self.maxX = maxX;
1317
+ self.minY = minY;
1318
+ self.maxY = maxY;
1319
+ self.minZ = minZ;
1320
+ self.maxZ = maxZ;
1321
+
1322
+ maxe = stdMath.max(width, height, depth);
1323
+ mine = stdMath.min(width, height, depth);
1324
+
1325
+ if ((maxe === width) && (mine === height))
1326
+ {
1327
+ self.minAxis = MOD3.ModConstant.Y;
1328
+ self.midAxis = MOD3.ModConstant.Z;
1329
+ self.maxAxis = MOD3.ModConstant.X;
1330
+ }
1331
+ else if ((maxe === width) && (mine === depth))
1332
+ {
1333
+ self.minAxis = MOD3.ModConstant.Z;
1334
+ self.midAxis = MOD3.ModConstant.Y;
1335
+ self.maxAxis = MOD3.ModConstant.X;
1336
+ }
1337
+ else if ((maxe === height) && (mine === width))
1338
+ {
1339
+ self.minAxis = MOD3.ModConstant.X;
1340
+ self.midAxis = MOD3.ModConstant.Z;
1341
+ self.maxAxis = MOD3.ModConstant.Y;
1342
+ }
1343
+ else if ((maxe === height) && (mine === depth))
1344
+ {
1345
+ self.minAxis = MOD3.ModConstant.Z;
1346
+ self.midAxis = MOD3.ModConstant.X;
1347
+ self.maxAxis = MOD3.ModConstant.Y;
1348
+ }
1349
+ else if ((maxe === depth) && (mine === width))
1350
+ {
1351
+ self.minAxis = MOD3.ModConstant.X;
1352
+ self.midAxis = MOD3.ModConstant.Y;
1353
+ self.maxAxis = MOD3.ModConstant.Z;
1354
+ }
1355
+ else if ((maxe === depth) && (mine === height))
1356
+ {
1357
+ self.minAxis = MOD3.ModConstant.Y;
1358
+ self.midAxis = MOD3.ModConstant.X;
1359
+ self.maxAxis = MOD3.ModConstant.Z;
1360
+ }
1361
+
1362
+ MOD3.List.each(vertices, function(v) {
1363
+ var xyz = v.getXYZ();
1364
+ v.setRatios(width > 0 ? (xyz[0] - minX) / width : 0, height > 0 ? (xyz[1] - minY) / height : 0, depth > 0 ? (xyz[2] - minZ) / depth : 0);
1365
+ });
1366
+ return self;
1367
+ },
1368
+
1369
+ resetGeometry: function() {
1370
+ var self = this;
1371
+ MOD3.List.each(self.vertices, reset);
1372
+ return self;
1373
+ },
1374
+
1375
+ collapseGeometry: function() {
1376
+ var self = this;
1377
+ MOD3.List.each(self.vertices, collapse);
1378
+ self.analyzeGeometry();
1379
+ return self;
1380
+ },
1381
+
1382
+ getMin: function(axis) {
1383
+ var self = this;
1384
+ return MOD3.ModConstant.X === axis
1385
+ ? self.minX
1386
+ : (MOD3.ModConstant.Y === axis
1387
+ ? self.minY
1388
+ : (MOD3.ModConstant.Z === axis
1389
+ ? self.minZ
1390
+ : -1))
1391
+ ;
1392
+ },
1393
+
1394
+ getMax: function(axis) {
1395
+ var self = this;
1396
+ return MOD3.ModConstant.X === axis
1397
+ ? self.maxX
1398
+ : (MOD3.ModConstant.Y === axis
1399
+ ? self.maxY
1400
+ : (MOD3.ModConstant.Z === axis
1401
+ ? self.maxZ
1402
+ : -1))
1403
+ ;
1404
+ },
1405
+
1406
+ getSize: function(axis) {
1407
+ var self = this;
1408
+ return MOD3.ModConstant.X === axis
1409
+ ? self.width
1410
+ : (MOD3.ModConstant.Y === axis
1411
+ ? self.height
1412
+ : (MOD3.ModConstant.Z === axis
1413
+ ? self.depth
1414
+ : -1))
1415
+ ;
1416
+ },
1417
+
1418
+ update: function() {
1419
+ // do nothing
1420
+ return this;
1421
+ },
1422
+
1423
+ preApply: function() {
1424
+ // do nothing
1425
+ return this;
1426
+ },
1427
+
1428
+ postApply: function() {
1429
+ // do nothing
1430
+ return this;
1431
+ },
1432
+
1433
+ updateMeshPosition: function(p) {
1434
+ // do nothing
1435
+ return this;
1436
+ }
1437
+ });
1438
+
1439
+ MOD3.Library3d = {
1440
+ id : "Library3d",
1441
+ Mesh : MOD3.MeshProxy,
1442
+ Vertex : MOD3.VertexProxy
1443
+ };
1444
+
1445
+ MOD3.Factory = {
1446
+ getLibrary: function(json) {
1447
+ if (json && json.library && MOD3[json.library]) return MOD3[json.library];
1448
+ // dummy, default
1449
+ return MOD3.Library3d;
1450
+ }
1451
+
1452
+ ,getMeshProxy: function(lib3D) {
1453
+ if (arguments.length) return lib3D.Mesh ? new lib3D.Mesh() : null;
1454
+ return null;
1455
+ }
1456
+
1457
+ ,getModifier: function(json) {
1458
+ if (json && json.modifier && MOD3[json.modifier]) return new MOD3[json.modifier]();
1459
+ return null;
1460
+ }
1461
+
1462
+ /*
1463
+ ,getMesh: function(json) {
1464
+ if (json && json.mesh && MOD3[json.mesh] ) return new MOD3.MeshProxy().unserialize(json);
1465
+ // dummy, default
1466
+ return new MOD3.MeshProxy();
1467
+ }
1468
+
1469
+ ,getVertex: function(json) {
1470
+ if (json && json.vertex && MOD3[json.vertex]) return new MOD3.VertexProxy().unserialize(json);
1471
+ // dummy, default
1472
+ return new MOD3.VertexProxy();
1473
+ }*/
1474
+ };
1475
+ /**
1476
+ * MOD3 Modifier & ModifierStack Classes
1477
+ **/
1478
+ var _modCount = 0;
1479
+
1480
+ MOD3.Modifier = MOD3.Class({
1481
+ constructor: function Modifier() {
1482
+ var self = this;
1483
+ self.id = ++_modCount;
1484
+ self.name = 'Modifier';
1485
+ self.axes = MOD3.ModConstant.NONE;
1486
+ self.constraint = MOD3.ModConstant.NONE;
1487
+ self.enabled = true;
1488
+ },
1489
+
1490
+ id: null,
1491
+ name: 'Modifier',
1492
+ axes: null,
1493
+ constraint: null,
1494
+ enabled: true,
1495
+
1496
+ dispose: function() {
1497
+ var self = this;
1498
+ self.name = null;
1499
+ self.axes = null;
1500
+ self.constraint = null;
1501
+ return self;
1502
+ },
1503
+
1504
+ enable: function(enabled) {
1505
+ if (arguments.length)
1506
+ {
1507
+ this.enabled = !!enabled;
1508
+ return this;
1509
+ }
1510
+ return this.enabled;
1511
+ },
1512
+
1513
+ constraintAxes: function(axes) {
1514
+ this.axes = axes || MOD3.ModConstant.NONE;
1515
+ return this;
1516
+ },
1517
+
1518
+ setConstraint: function(c) {
1519
+ this.constraint = c || MOD3.ModConstant.NONE;
1520
+ return this;
1521
+ },
1522
+
1523
+ // override
1524
+ apply: function(modifiable) {
1525
+ return this;
1526
+ },
1527
+
1528
+ toString: function() {
1529
+ return '[Modifier '+this.name+']';
1530
+ }
1531
+ });
1532
+
1533
+ MOD3.ModifierStack = MOD3.Class({
1534
+ constructor: function ModifierStack(lib3d, mesh) {
1535
+ var self = this;
1536
+ if (!(self instanceof ModifierStack)) return new ModifierStack(lib3d, mesh);
1537
+ self.stack = [];
1538
+ self.setModifiable(MOD3.Factory.getMeshProxy(lib3d), mesh);
1539
+ },
1540
+
1541
+ name: "ModifierStack",
1542
+ modifiable: null,
1543
+ stack: null,
1544
+
1545
+ dispose: function(withModifiers) {
1546
+ var self = this;
1547
+ if (withModifiers && self.stack) while (self.stack.length) self.stack.pop().dispose();
1548
+ if (self.modifiable) self.modifiable.dispose();
1549
+ self.stack = null;
1550
+ self.modifiable = null;
1551
+ return self;
1552
+ },
1553
+
1554
+ getModifiable: function() {
1555
+ return this.modifiable;
1556
+ },
1557
+
1558
+ setModifiable: function(modifiable, mesh) {
1559
+ var self = this;
1560
+ self.modifiable = modifiable;
1561
+ if (mesh) self.modifiable.setMesh(mesh);
1562
+ return self;
1563
+ },
1564
+
1565
+ add: function(modifier) {
1566
+ var self = this;
1567
+ if (modifier) self.stack.push(modifier);
1568
+ return self;
1569
+ },
1570
+
1571
+ apply: function() {
1572
+ var self = this, modifiable = self.modifiable, stack = self.stack;
1573
+ if (modifiable && stack && stack.length)
1574
+ modifiable
1575
+ .preApply()
1576
+ .resetGeometry()
1577
+ .applyModifiers(stack)
1578
+ .postApply()
1579
+ .update()
1580
+ ;
1581
+ return self;
1582
+ },
1583
+
1584
+ collapse: function() {
1585
+ var self = this, modifiable = self.modifiable, stack = self.stack;
1586
+ if (modifiable && stack && stack.length)
1587
+ {
1588
+ modifiable
1589
+ .preApply()
1590
+ .resetGeometry()
1591
+ .applyModifiers(stack)
1592
+ .collapseGeometry()
1593
+ .postApply()
1594
+ .update()
1595
+ ;
1596
+ stack.length = 0;
1597
+ }
1598
+ return self;
1599
+ },
1600
+
1601
+ clear: function() {
1602
+ var self = this;
1603
+ if (self.stack) self.stack.length = 0;
1604
+ return self;
1605
+ }
1606
+ });
1607
+ // aliases
1608
+ MOD3.ModifierStack.prototype.getMeshInfo = MOD3.ModifierStack.prototype.getModifiable;
1609
+ MOD3.ModifierStack.prototype.addModifier = MOD3.ModifierStack.prototype.add;
1610
+ !function(MOD3) {
1611
+ "use strict";
1612
+ /**
1613
+ * MOD3 Pivot Modifier
1614
+ **/
1615
+
1616
+ /**[DOC_MD]
1617
+ * ### Pivot modifier
1618
+ *
1619
+ * Allows to move the pivot point of a 3D mesh.
1620
+ *
1621
+ * @author Bartek Drozdz
1622
+ *
1623
+ [/DOC_MD]**/
1624
+ MOD3.Pivot = MOD3.Class(MOD3.Modifier, {
1625
+ constructor: function Pivot(x, y, z) {
1626
+ var self = this;
1627
+ if (!(self instanceof Pivot)) return new Pivot(x, y, z);
1628
+ self.$super('constructor');
1629
+ self.name = 'Pivot';
1630
+ self.vector = new MOD3.Vector3(x||0, y||0, z||0);
1631
+ },
1632
+
1633
+ vector: null,
1634
+
1635
+ dispose: function() {
1636
+ var self = this;
1637
+ self.vector.dispose();
1638
+ self.vector = null;
1639
+ self.$super('dispose');
1640
+ return self;
1641
+ },
1642
+
1643
+ setMeshCenter: function(modifiable) {
1644
+ var self = this;
1645
+ self.vector = new MOD3.Vector3(
1646
+ -(modifiable.minX + 0.5*modifiable.width),
1647
+ -(modifiable.minY + 0.5*modifiable.height),
1648
+ -(modifiable.minZ + 0.5*modifiable.depth)
1649
+ );
1650
+ return self;
1651
+ },
1652
+
1653
+ apply: function(modifiable) {
1654
+ var self = this, pivot = self.vector, pv = pivot.xyz;
1655
+
1656
+ MOD3.List.each(modifiable.vertices, function(v) {
1657
+ v.setXYZ(MOD3.Vector3.add(v.getXYZ(), pv));
1658
+ });
1659
+ modifiable.updateMeshPosition(pivot.negate());
1660
+ return self;
1661
+ }
1662
+ });
1663
+ }(MOD3);!function(MOD3) {
1664
+ "use strict";
1665
+ /**
1666
+ * MOD3 Bend Modifier
1667
+ **/
1668
+
1669
+ /**[DOC_MD]
1670
+ * ### Bend modifier
1671
+ *
1672
+ * Bends an object along an axis.
1673
+ *
1674
+ * @author Bartek Drozdz
1675
+ *
1676
+ [/DOC_MD]**/
1677
+ var stdMath = Math, PI = stdMath.PI,
1678
+ TWO_PI = 2*PI, HALF_PI = PI/2;
1679
+
1680
+ MOD3.Bend = MOD3.Class(MOD3.Modifier, {
1681
+ constructor: function Bend(force, offset, angle) {
1682
+ var self = this;
1683
+ if (!(self instanceof Bend)) return new Bend(force, offset, angle);
1684
+ self.$super('constructor');
1685
+ self.name = 'Bend';
1686
+ self.constraint = MOD3.ModConstant.NONE;
1687
+ self.switchAxes = false;
1688
+ self.force = force || 0;
1689
+ self.offset = offset || 0;
1690
+ self.angle = angle || 0;
1691
+ },
1692
+
1693
+ force: 0,
1694
+ offset: 0,
1695
+ angle: 0,
1696
+ switchAxes: false,
1697
+
1698
+ dispose: function() {
1699
+ var self = this;
1700
+ self.force = null;
1701
+ self.offset = null;
1702
+ self.angle = null;
1703
+ self.switchAxes = null;
1704
+ self.$super('dispose');
1705
+ return self;
1706
+ },
1707
+
1708
+ apply: function(modifiable) {
1709
+ var self = this;
1710
+
1711
+ if (0 === self.force) return self;
1712
+
1713
+ var constraint = self.constraint, switchAxes = self.switchAxes,
1714
+ force = self.force, offset = stdMath.min(1, stdMath.max(0, self.offset)), a = self.angle,
1715
+ max = switchAxes ? modifiable.midAxis : modifiable.maxAxis,
1716
+ min = modifiable.minAxis,
1717
+ mid = switchAxes ? modifiable.maxAxis : modifiable.midAxis,
1718
+ width = modifiable.getSize(max),
1719
+ height = modifiable.getSize(mid),
1720
+ origin = modifiable.getMin(max),
1721
+ //diagAngle = stdMath.atan2(height, width),
1722
+ m1 = new MOD3.Matrix().rotate(a),
1723
+ m2 = new MOD3.Matrix().rotate(-a),
1724
+ distance = origin + width * offset,
1725
+ radius = width / PI / force,
1726
+ bendAngle = TWO_PI * (width / (radius * TWO_PI))
1727
+ ;
1728
+
1729
+ MOD3.List.each(modifiable.vertices, function(v) {
1730
+ var xyz = v.getXYZ(),
1731
+ vmax = xyz[MOD3.XYZi[max]],
1732
+ vmid = xyz[MOD3.XYZi[mid]],
1733
+ vmin = xyz[MOD3.XYZi[min]],
1734
+ np = MOD3.Matrix.transform(m1, [vmax, vmid]),
1735
+ p, fa, op, ow, np2
1736
+ ;
1737
+ vmax = np[0]; vmid = np[1];
1738
+
1739
+ p = (vmax - origin) / width;
1740
+
1741
+ if (
1742
+ ((MOD3.ModConstant.LEFT === constraint) && (p <= offset)) ||
1743
+ ((MOD3.ModConstant.RIGHT === constraint) && (p >= offset))
1744
+ )
1745
+ {
1746
+ /* do nothing */
1747
+ }
1748
+ else
1749
+ {
1750
+ fa = (HALF_PI - bendAngle * offset) + (bendAngle * p);
1751
+ op = stdMath.sin(fa) * (radius + vmin);
1752
+ ow = stdMath.cos(fa) * (radius + vmin);
1753
+ vmin = op - radius;
1754
+ vmax = distance - ow;
1755
+ }
1756
+
1757
+ np2 = MOD3.Matrix.transform(m2, [vmax, vmid]);
1758
+ vmax = np2[0]; vmid = np2[1];
1759
+ xyz[MOD3.XYZi[max]] = vmax;
1760
+ xyz[MOD3.XYZi[mid]] = vmid;
1761
+ xyz[MOD3.XYZi[min]] = vmin;
1762
+ v.setXYZ(xyz);
1763
+ });
1764
+ return self;
1765
+ }
1766
+ });
1767
+ }(MOD3);!function(MOD3) {
1768
+ "use strict";
1769
+ /**
1770
+ * MOD3 Bloat Modifier
1771
+ **/
1772
+
1773
+ /**[DOC_MD]
1774
+ * ### Bloat modifier
1775
+ *
1776
+ * Bloats a mesh by forcing vertices out of specified sphere
1777
+ *
1778
+ * @author makc
1779
+ *
1780
+ [/DOC_MD]**/
1781
+ var stdMath = Math;
1782
+
1783
+ MOD3.Bloat = MOD3.Class(MOD3.Modifier, {
1784
+ constructor: function Bloat(radius, a, center) {
1785
+ var self = this;
1786
+ if (!(self instanceof Bloat)) return new Bloat(radius, a, center);
1787
+ self.$super('constructor');
1788
+ self.name = 'Bloat';
1789
+ self.radius = radius || 0;
1790
+ self.a = null == a ? 0.01 : a;
1791
+ self.center = center || MOD3.Vector3.ZERO();
1792
+ //self.u = MOD3.Vector3.ZERO();
1793
+ },
1794
+
1795
+ radius: 0,
1796
+ a: 0.01,
1797
+ center: null,
1798
+ //u: null,
1799
+
1800
+ dispose: function() {
1801
+ var self = this;
1802
+ self.center.dispose();
1803
+ self.center = null;
1804
+ self.radius = null;
1805
+ self.a = null;
1806
+ self.$super('dispose');
1807
+ return self;
1808
+ },
1809
+
1810
+ apply: function(modifiable) {
1811
+ var self = this, center = self.center.xyz,
1812
+ radius = stdMath.max(0, self.radius), a = stdMath.max(0, self.a);
1813
+
1814
+ MOD3.List.each(modifiable.vertices, function(v) {
1815
+ // get a vector towards vertex
1816
+ // change norm to norm + r * exp (-a * norm)
1817
+ var uu = MOD3.Vector3.sub(v.getXYZ(), center), magn = MOD3.Vector3.mod(uu);
1818
+ MOD3.Vector3.muls(MOD3.Vector3.norm(uu), magn + radius * stdMath.exp(- magn * a));
1819
+ // move vertex accordingly
1820
+ v.setXYZ(MOD3.Vector3.add(uu, center));
1821
+ // ?? needed??
1822
+ //self.u=uu;
1823
+ });
1824
+ return self;
1825
+ }
1826
+ });
1827
+ }(MOD3);!function(MOD3) {
1828
+ "use strict";
1829
+ /**
1830
+ * MOD3 Twist Modifier
1831
+ **/
1832
+
1833
+ /**[DOC_MD]
1834
+ * ### Twist modifier
1835
+ *
1836
+ * Twist mesh along an axis
1837
+ * Adapted from the Twist modifier for PV3D
1838
+ *
1839
+ [/DOC_MD]**/
1840
+ MOD3.Twist = MOD3.Class(MOD3.Modifier, {
1841
+ constructor: function Twist(angle, vector, center) {
1842
+ var self = this;
1843
+ if (!(self instanceof Twist)) return new Twist(angle, vector, center);
1844
+ self.$super('constructor');
1845
+ self.name = 'Twist';
1846
+ self.angle = angle || 0;
1847
+ self.vector = vector || MOD3.Vector3.Y();
1848
+ self.center = center || MOD3.Vector3.ZERO();
1849
+ },
1850
+
1851
+ angle: 0,
1852
+ vector: null,
1853
+ center: null,
1854
+
1855
+ dispose: function() {
1856
+ var self = this;
1857
+ self.vector.dispose();
1858
+ self.vector = null;
1859
+ self.angle = null;
1860
+ self.center.dispose();
1861
+ self.center = null;
1862
+ self.$super('dispose');
1863
+ return self;
1864
+ },
1865
+
1866
+ apply: function(modifiable) {
1867
+ var self = this,
1868
+ tvec = self.vector.normalizeSelf().xyz, angle = self.angle, center = self.center.xyz,
1869
+ modulo = MOD3.Vector3.mod([0.5*modifiable.maxX, 0.5*modifiable.maxY, 0.5*modifiable.maxZ]),
1870
+ d = -MOD3.Vector3.dot(tvec, center),
1871
+ m1 = new MOD3.Matrix4(), m2 = new MOD3.Matrix4()
1872
+ ;
1873
+
1874
+ MOD3.List.each(modifiable.vertices, function(v) {
1875
+ var xyz = v.getXYZ(),
1876
+ a = (MOD3.Vector3.dot(xyz, tvec) + d) * angle / modulo,
1877
+ m = MOD3.Matrix4.mult(
1878
+ m2.rotate(tvec[0], tvec[1], tvec[2], a, true),
1879
+ m1.translate(xyz[0], xyz[1], xyz[2], true)
1880
+ )
1881
+ ;
1882
+ v.setXYZ([m.m[3], m.m[7], m.m[11]]);
1883
+ });
1884
+ return self;
1885
+ }
1886
+ });
1887
+ }(MOD3);!function(MOD3) {
1888
+ "use strict";
1889
+ /**
1890
+ * MOD3 Skew Modifier
1891
+ **/
1892
+
1893
+ /**[DOC_MD]
1894
+ * ### Skew modifier
1895
+ *
1896
+ * Skew mesh along an axis
1897
+ *
1898
+ * @author Bartek Drozdz
1899
+ *
1900
+ [/DOC_MD]**/
1901
+ var stdMath = Math;
1902
+
1903
+ MOD3.Skew = MOD3.Class(MOD3.Modifier, {
1904
+ constructor: function Skew(force, offset, power, falloff) {
1905
+ var self = this;
1906
+ if (!(self instanceof Skew)) return new Skew(force, offset, power, falloff);
1907
+ self.$super('constructor');
1908
+ self.name = 'Skew';
1909
+ self.constraint = MOD3.ModConstant.NONE;
1910
+ self.force = force != null ? force : 0;
1911
+ self.offset = offset != null ? offset : 0.5;
1912
+ self.power = power != null ? power : 1;
1913
+ self.falloff = falloff != null ? falloff : 1;
1914
+ self.inverseFalloff = false;
1915
+ self.oneSide = false;
1916
+ self.swapAxes = false;
1917
+ self.skewAxis = 0;
1918
+ },
1919
+
1920
+ force: 0,
1921
+ skewAxis: 0,
1922
+ offset: 0.5,
1923
+ power: 1,
1924
+ falloff: 1,
1925
+ inverseFalloff: false,
1926
+ oneSide: false,
1927
+ swapAxes: false,
1928
+
1929
+ dispose: function() {
1930
+ var self = this;
1931
+ self.force = null;
1932
+ self.skewAxis = null;
1933
+ self.offset = null;
1934
+ self.power = null;
1935
+ self.falloff = null;
1936
+ self.inverseFalloff = null;
1937
+ self.oneSide = null;
1938
+ self.swapAxes = null;
1939
+ self.$super('dispose');
1940
+ return self;
1941
+ },
1942
+
1943
+ apply: function(modifiable) {
1944
+ var self = this,
1945
+ constraint = self.constraint,
1946
+ skewAxis = self.skewAxis || modifiable.maxAxis,
1947
+ swapAxes = self.swapAxes,
1948
+ offset = stdMath.min(1, stdMath.max(0, self.offset)),
1949
+ oneSide = self.oneSide,
1950
+ inverseFalloff = !!self.inverseFalloff,
1951
+ falloff = stdMath.min(1, stdMath.max(0, self.falloff)),
1952
+ mirrorfalloff = 1-falloff,
1953
+ power = self.power,
1954
+ force = self.force,
1955
+ displaceAxis = MOD3.ModConstant.X === skewAxis
1956
+ ? (swapAxes ? MOD3.ModConstant.Z : MOD3.ModConstant.Y)
1957
+ : (MOD3.ModConstant.Y === skewAxis
1958
+ ? (swapAxes ? MOD3.ModConstant.Z : MOD3.ModConstant.X)
1959
+ : (MOD3.ModConstant.Z === skewAxis
1960
+ ? (swapAxes ? MOD3.ModConstant.Y : MOD3.ModConstant.X)
1961
+ : 0))
1962
+ ;
1963
+
1964
+ MOD3.List.each(modifiable.vertices, function(v) {
1965
+ var r, dr, f, p, vRatio;
1966
+ vRatio = v.getRatio(skewAxis);
1967
+ if ((MOD3.ModConstant.LEFT === constraint) && (vRatio <= offset)) return;
1968
+ if ((MOD3.ModConstant.RIGHT === constraint) && (vRatio > offset)) return;
1969
+
1970
+ r = vRatio - offset;
1971
+ if (oneSide && (0 > r)) r = -r;
1972
+
1973
+ dr = v.getRatio(displaceAxis);
1974
+ if (inverseFalloff) dr = 1 - dr;
1975
+
1976
+ f = falloff + dr * mirrorfalloff;
1977
+ p = (0 > r ? -1 : 1) * stdMath.pow(stdMath.abs(r), power);
1978
+ v.setValue(displaceAxis, v.getValue(displaceAxis) + force * p * f);
1979
+ });
1980
+ return self;
1981
+ },
1982
+ });
1983
+ }(MOD3);!function(MOD3) {
1984
+ "use strict";
1985
+ /**
1986
+ * MOD3 Taper Modifier
1987
+ **/
1988
+
1989
+ /**[DOC_MD]
1990
+ * ### Taper modifier
1991
+ *
1992
+ * The taper modifier displaces the vertices on two axes proportionally to their position on the third axis.
1993
+ *
1994
+ * @author Bartek Drozdz
1995
+ *
1996
+ [/DOC_MD]**/
1997
+ var stdMath = Math;
1998
+
1999
+ MOD3.Taper = MOD3.Class(MOD3.Modifier, {
2000
+ constructor: function Taper(force, power, v1, v2) {
2001
+ var self = this;
2002
+ if (!(self instanceof Taper)) return new Taper(force, power, v1, v2);
2003
+ self.$super('constructor');
2004
+ self.name = 'Taper';
2005
+ /*self.start = 0;
2006
+ self.end = 1;*/
2007
+ self.force = force != null ? force : 0;
2008
+ self.power = power != null ? power : 1;
2009
+ self.vector = v1 || MOD3.Vector3.Y(false);
2010
+ self.vector2 = v2 || MOD3.Vector3.Y();
2011
+ },
2012
+
2013
+ force: 0,
2014
+ power: 1,
2015
+ /*start: 0,
2016
+ end: 1,*/
2017
+ vector: null,
2018
+ vector2: null,
2019
+
2020
+ /*setFalloff : function(start, end) {
2021
+ this.start = (start!==undef) ? start : 0;
2022
+ this.end = (end!==undef) ? end : 1;
2023
+
2024
+ return this;
2025
+ },*/
2026
+
2027
+ dispose: function() {
2028
+ var self = this;
2029
+ self.vector.dispose();
2030
+ self.vector2.dispose();
2031
+ self.vector = null;
2032
+ self.vector2 = null;
2033
+ self.force = null;
2034
+ self.power = null;
2035
+ self.$super('dispose');
2036
+ return self;
2037
+ },
2038
+
2039
+ apply: function(modifiable) {
2040
+ var self = this,
2041
+ vec = self.vector.xyz, vec2 = self.vector2.xyz,
2042
+ force = self.force, power = self.power, m = new MOD3.Matrix4();
2043
+
2044
+ MOD3.List.each(modifiable.vertices, 1 !== power
2045
+ ? function(v) {
2046
+ var ar = MOD3.Vector3.mod(MOD3.Vector3.mul(v.getRatioVector(), vec2)), sc = force * stdMath.pow(ar, power);
2047
+ v.setXYZ(MOD3.Matrix4.multXYZ(m.scale(1 + sc * vec[0], 1 + sc * vec[1], 1 + sc * vec[2]), v.getXYZ()));
2048
+ }
2049
+ : function(v) {
2050
+ var ar = MOD3.Vector3.mod(MOD3.Vector3.mul(v.getRatioVector(), vec2)), sc = force * ar;
2051
+ v.setXYZ(MOD3.Matrix4.multXYZ(m.scale(1 + sc * vec[0], 1 + sc * vec[1], 1 + sc * vec[2]), v.getXYZ()));
2052
+ }
2053
+ );
2054
+ return self;
2055
+ }
2056
+ });
2057
+ }(MOD3);!function(MOD3) {
2058
+ "use strict";
2059
+ /**
2060
+ * MOD3 Wheel Modifier
2061
+ **/
2062
+
2063
+ /**[DOC_MD]
2064
+ * ### Wheel modifier
2065
+ *
2066
+ * Use it with vehicle models for wheels.
2067
+ *
2068
+ * The usual problem with a 3d wheel in a vahicle is that it is
2069
+ * supposed to turn (steer) and roll in the same time.
2070
+ * So, this code:
2071
+ *
2072
+ * ```javascript
2073
+ * wheel.rotationY = 10; // Steer 10deg to the left
2074
+ * wheel.rotationZ += 5; // Roll with a speed of 5
2075
+ * ```
2076
+ * This will make the wheel roll incorectly.
2077
+ *
2078
+ * A usual way to solve this problem is to put the wheel in another DisplayObject3D/Mesh,
2079
+ * turn the parent and roll the child, like that:
2080
+ * ```javascript
2081
+ * steer.rotationY = 10; // Steer 10deg to the left
2082
+ * steer.wheel.rotationZ += 5; // Roll with a speed of 5
2083
+ * ```
2084
+ * That will make the wheel behave correctly. But it can be uncomfortanble to apply, especially
2085
+ * to imported complex Collada models.
2086
+ *
2087
+ * The Wheel modifier elegantly solves this problem by doind the proper math in order to steer and roll
2088
+ * a single mesh at the same time. The only thing you need to do is to specify a steer vector and
2089
+ * roll vector - usually it will be 2 of the cardinal axes. The default value is:
2090
+ *
2091
+ * * steer - along the Y axis / new Vector3(0, 1, 0)
2092
+ * * roll - along the Z axis / new Vector3(0, 0, 1)
2093
+ *
2094
+ *
2095
+ * It should work with most car models imported from 3D editors as this is the natural position of a wheel.
2096
+ *
2097
+ * *Please note, that Papervision primitive cylinder, which may also be used as wheel, will require different axes
2098
+ * (Y for roll and Z or X for steer).*
2099
+ *
2100
+ * @author Bartek Drozdz
2101
+ *
2102
+ [/DOC_MD]**/
2103
+ MOD3.Wheel = MOD3.Class(MOD3.Modifier, {
2104
+ constructor: function Wheel(speed, turn, roll, steerVector, rollVector) {
2105
+ var self = this;
2106
+ if (!(self instanceof Wheel)) return new Wheel(speed, turn, roll, steerVector, rollVector);
2107
+ self.$super('constructor');
2108
+ self.name = 'Wheel';
2109
+ self.speed = speed || 0;
2110
+ self.turn = turn || 0;
2111
+ self.roll = roll || 0;
2112
+ self.steerVector = steerVector || MOD3.Vector3.Y();
2113
+ self.rollVector = rollVector || MOD3.Vector3.Z();
2114
+ },
2115
+
2116
+ speed: 0,
2117
+ turn: 0,
2118
+ roll: 0,
2119
+ steerVector: null,
2120
+ rollVector: null,
2121
+
2122
+ dispose: function() {
2123
+ var self = this;
2124
+ self.speed = null;
2125
+ self.turn = null;
2126
+ self.roll = null;
2127
+ self.steerVector.dispose();
2128
+ self.rollVector.dispose();
2129
+ self.steerVector = null;
2130
+ self.rollVector = null;
2131
+ self.$super('dispose');
2132
+
2133
+ return self;
2134
+ },
2135
+
2136
+ apply: function(modifiable) {
2137
+ var self = this,
2138
+ steerVector = self.steerVector.normalizeSelf(),
2139
+ rollVector = self.rollVector.normalizeSelf(),
2140
+ turn = self.turn, roll = self.roll,
2141
+ //radius = 0.5*modifiable.width,
2142
+ //step = radius * self.speed / PI,
2143
+ //perimeter = radius * TWO_PI,
2144
+ ms = null, mt = null
2145
+ ;
2146
+
2147
+ self.roll += self.speed;
2148
+
2149
+ if (turn)
2150
+ {
2151
+ mt = new MOD3.Matrix4().rotateFromVector(steerVector, turn);
2152
+ ms = new MOD3.Matrix4().rotateFromVector(mt.multiplyVector(rollVector.clone()), roll);
2153
+ }
2154
+ else
2155
+ {
2156
+ ms = new MOD3.Matrix4().rotateFromVector(rollVector, roll);
2157
+ }
2158
+
2159
+ MOD3.List.each(modifiable.vertices, mt
2160
+ ? function(v) {
2161
+ v.setXYZ(MOD3.Matrix4.multXYZ(ms, MOD3.Matrix4.multXYZ(mt, v.getXYZ())));
2162
+ }
2163
+ : function(v) {
2164
+ v.setXYZ(MOD3.Matrix4.multXYZ(ms, v.getXYZ()));
2165
+ }
2166
+ );
2167
+ return self;
2168
+ }
2169
+ });
2170
+ }(MOD3);!function(MOD3) {
2171
+ "use strict";
2172
+ /**
2173
+ * MOD3 Break Modifier
2174
+ **/
2175
+
2176
+ /**[DOC_MD]
2177
+ * ### Break modifier
2178
+ *
2179
+ * Allow to break a mesh
2180
+ *
2181
+ * @author Bartek Drozdz
2182
+ *
2183
+ [/DOC_MD]**/
2184
+ var stdMath = Math;
2185
+
2186
+ MOD3.Break = MOD3.Class(MOD3.Modifier, {
2187
+ constructor: function Break(offset, angle, vector) {
2188
+ var self = this;
2189
+ if (!(self instanceof Break)) return new Break(offset, angle, vector);
2190
+ self.$super('constructor');
2191
+ self.name = 'Break';
2192
+ self.offset = offset || 0;
2193
+ self.angle = angle || 0;
2194
+ self.vector = vector || MOD3.Vector3.Y();
2195
+ self.range = new MOD3.Range(0, 1);
2196
+ },
2197
+
2198
+ offset: 0,
2199
+ angle: 0,
2200
+ vector: null,
2201
+ range: null,
2202
+
2203
+ dispose: function() {
2204
+ var self = this;
2205
+ self.vector.dispose();
2206
+ self.range.dispose();
2207
+ self.vector = null;
2208
+ self.range = null;
2209
+ self.offset = null;
2210
+ self.angle = null;
2211
+ self.$super('dispose');
2212
+ return self;
2213
+ },
2214
+
2215
+ apply: function(modifiable) {
2216
+ var self = this,
2217
+ offset = stdMath.min(1, stdMath.max(0, self.offset)), range = self.range, angle = self.angle,
2218
+ bv = self.vector.normalizeSelf().xyz, pv, rm;
2219
+
2220
+ pv = modifiable.minZ + modifiable.depth*offset;
2221
+ rm = new MOD3.Matrix4().rotate(bv[0], bv[1], bv[2], angle);
2222
+
2223
+ MOD3.List.each(modifiable.vertices, function(v) {
2224
+ var c = v.getXYZ();
2225
+ c[2] -= pv;
2226
+ if ((0 <= c[2]) && range.isIn(v.ratio[1])) MOD3.Matrix4.multXYZ(rm, c);
2227
+ c[2] += pv;
2228
+ v.setXYZ(c);
2229
+ });
2230
+ return self;
2231
+ }
2232
+ });
2233
+ }(MOD3);!function(MOD3) {
2234
+ "use strict";
2235
+ /**
2236
+ * MOD3 Noise Modifier
2237
+ **/
2238
+
2239
+ /**[DOC_MD]
2240
+ * ### Noise modifier
2241
+ *
2242
+ * Randomly displaces each vertex in all 3 axes
2243
+ *
2244
+ *
2245
+ [/DOC_MD]**/
2246
+ var stdMath = Math;
2247
+
2248
+ MOD3.Noise = MOD3.Class(MOD3.Modifier, {
2249
+ constructor: function Noise(force) {
2250
+ var self = this;
2251
+ if (!(self instanceof Noise)) return new Noise(force);
2252
+ self.$super('constructor');
2253
+ self.name = 'Noise';
2254
+ self.force = force || 0;
2255
+ self.start = 0;
2256
+ self.end = 1;
2257
+ self.axes = MOD3.ModConstant.X | MOD3.ModConstant.Y | MOD3.ModConstant.Z;
2258
+ },
2259
+
2260
+ force: 0,
2261
+ start: 0,
2262
+ end: 1,
2263
+
2264
+ dispose: function() {
2265
+ var self = this;
2266
+ self.force = null;
2267
+ self.start = null;
2268
+ self.end = null;
2269
+ self.$super('dispose');
2270
+ return self;
2271
+ },
2272
+
2273
+ setFalloff: function(start, end) {
2274
+ var self = this;
2275
+ self.start = start != null ? start : 0;
2276
+ self.end = end != null ? end : 1;
2277
+ return self;
2278
+ },
2279
+
2280
+ apply: function(modifiable) {
2281
+ var self = this,
2282
+ axes = self.axes, start = self.start, end = self.end,
2283
+ force = self.force, halfforce = 0.5*force,
2284
+ maxAxis = modifiable.maxAxis;
2285
+
2286
+ if ((0 == axes) || (0 == force)) return self;
2287
+
2288
+ MOD3.List.each(modifiable.vertices, function(v) {
2289
+ var r = stdMath.random() * force - halfforce,
2290
+ p = v.getRatio(maxAxis), rp, xyz;
2291
+ if (start < end)
2292
+ {
2293
+ if (p < start) p = 0;
2294
+ else if (p > end) p = 1;
2295
+ }
2296
+ else if (start > end)
2297
+ {
2298
+ p = 1 - p;
2299
+ if (p > start) p = 0;
2300
+ else if (p < end) p = 1;
2301
+ }
2302
+ else
2303
+ {
2304
+ p = 1;
2305
+ }
2306
+
2307
+ rp = r * p;
2308
+ xyz = v.getXYZ();
2309
+ v.setXYZ([
2310
+ xyz[0] + (axes & MOD3.ModConstant.X ? rp : 0),
2311
+ xyz[1] + (axes & MOD3.ModConstant.Y ? rp : 0),
2312
+ xyz[2] + (axes & MOD3.ModConstant.Z ? rp : 0)
2313
+ ]);
2314
+ });
2315
+ return self;
2316
+ }
2317
+ });
2318
+ }(MOD3);!function(MOD3) {
2319
+ "use strict";
2320
+ /**
2321
+ * MOD3 DisplaceMap (BitmapDisplacement) Modifier
2322
+ **/
2323
+
2324
+ /**[DOC_MD]
2325
+ * ### DisplaceMap (BitmapDisplacement) Modifier
2326
+ *
2327
+ * Displaces vertices based on RGB values of bitmapData pixels.
2328
+ *
2329
+ * BitmapDisplacement is inspired by both the AS3 built-in DisplacementMapFilter. It allows
2330
+ * to use color values for each channels of a bitmap to modify the position of vertices in a mesh.
2331
+ *
2332
+ * The displacement takes place along the cardinal axes, and each axis is mapped to a
2333
+ * channel in the bitmap: X for Red, Y for Green and Z for Blue.
2334
+ *
2335
+ * @author Bartek Drozdz
2336
+ *
2337
+ [/DOC_MD]**/
2338
+ MOD3.DisplaceMap = MOD3.Class(MOD3.Modifier, {
2339
+ constructor: function DisplaceMap(bmp, force, offset) {
2340
+ var self = this;
2341
+ if (!(self instanceof DisplaceMap)) return new DisplaceMap(bmp, force, offset);
2342
+ self.$super('constructor');
2343
+ self.name = 'DisplaceMap';
2344
+ if (+bmp === bmp) // number
2345
+ {
2346
+ self.force = bmp || 1;
2347
+ self.offset = null == force ? 127 : force;// 0x7F;
2348
+ }
2349
+ else
2350
+ {
2351
+ self.setBitmap(bmp);
2352
+ self.force = force || 1;
2353
+ self.offset = null == offset ? 127 : offset;// 0x7F;
2354
+ }
2355
+ self.axes = MOD3.ModConstant.X | MOD3.ModConstant.Y | MOD3.ModConstant.Z;
2356
+ },
2357
+
2358
+ width: null,
2359
+ height: null,
2360
+ bmpData: null,
2361
+ force: 1,
2362
+ offset: 127,
2363
+
2364
+ dispose: function() {
2365
+ var self = this;
2366
+ self.bmpData = null;
2367
+ self.width = null;
2368
+ self.height = null;
2369
+ self.force = null;
2370
+ self.offset = null;
2371
+ self.$super('dispose');
2372
+ return self;
2373
+ },
2374
+
2375
+ setBitmap: function(bmpData) {
2376
+ var self = this;
2377
+ self.bmpData = bmpData ? bmpData.data : null;
2378
+ self.width = bmpData ? bmpData.width : 0;
2379
+ self.height = bmpData ? bmpData.height : 0;
2380
+ return self;
2381
+ },
2382
+
2383
+ apply: function(modifiable) {
2384
+ var self = this,
2385
+ axes = self.axes,
2386
+ w = self.width, h = self.height, bmp = self.bmpData,
2387
+ force = self.force, offset = self.offset;
2388
+
2389
+ if (!axes || !bmp) return self;
2390
+
2391
+ MOD3.List.each(modifiable.vertices, function(v) {
2392
+ var uv, uu, vv, xyz = v.getXYZ();
2393
+
2394
+ uu = ~~((w - 1) * v.ratio[0]/* X */);
2395
+ vv = ~~((h - 1) * v.ratio[2]/* Z */);
2396
+ uv = (vv * w + uu) << 2;
2397
+
2398
+ v.setXYZ([
2399
+ xyz[0] + (axes & MOD3.ModConstant.X ? ((bmp[uv] & 0xff) - offset) * force : 0),
2400
+ xyz[1] + (axes & MOD3.ModConstant.Y ? ((bmp[uv+1] & 0xff) - offset) * force : 0),
2401
+ xyz[2] + (axes & MOD3.ModConstant.Z ? ((bmp[uv+2] & 0xff) - offset) * force : 0)
2402
+ ]);
2403
+ });
2404
+ return self;
2405
+ }
2406
+ });
2407
+ }(MOD3);!function(MOD3) {
2408
+ "use strict";
2409
+ /**
2410
+ * MOD3 Perlin/Simplex Noise Modifier
2411
+ **/
2412
+
2413
+ /**[DOC_MD]
2414
+ * ### Perlin modifier
2415
+ *
2416
+ * Displaces vertices based on a perlin/simplex noise source.
2417
+ *
2418
+ * Accepts a perlin/simplex noise data (with width and height information) and displaces vertices
2419
+ * based on the value of each point of the noise map.
2420
+ *
2421
+ * @author Bartek Drozdz
2422
+ *
2423
+ * @uses: https://github.com/josephg/noisejs for JavaScript
2424
+ *
2425
+ [/DOC_MD]**/
2426
+ function cyclic_shift(a, w, h, dX, dY)
2427
+ {
2428
+ var size = w*h, b = new MOD3.VecArray(size), i, j, i2, j2, index;
2429
+ if (dX < 0) dX += w;
2430
+ if (dY < 0) dY += h;
2431
+ dX = ~~dX; dY = ~~dY;
2432
+ for (i=0,j=0,index=0; index<size; ++index,++i)
2433
+ {
2434
+ if (i >= w) {i = 0; ++j;}
2435
+ i2 = (i + dX) % w; j2 = (j + dY) % h;
2436
+ b[index] = a[i2 + j2 * w];
2437
+ }
2438
+ return b;
2439
+ }
2440
+ /*function generate2d(perlinNoise2d, w, h)
2441
+ {
2442
+ var size = w*h, a = new MOD3.VecArray(size), i, j, index;
2443
+ for (i=0,j=0,index=0; index<size; ++index,++i)
2444
+ {
2445
+ if (i >= w) {i = 0; ++j;}
2446
+ a[index] = perlinNoise2d(i/w, j/h);
2447
+ }
2448
+ return a;
2449
+ }*/
2450
+ MOD3.Perlin = MOD3.Class(MOD3.Modifier, {
2451
+ constructor: function Perlin(force, noise, autoRun) {
2452
+ var self = this;
2453
+ if (!(self instanceof Perlin)) return new Perlin(force, noise, autoRun);
2454
+ self.$super('constructor');
2455
+ self.name = 'Perlin';
2456
+ self.force = null != force ? force : 1;
2457
+ self.perlin = noise;
2458
+ self.autoRun = null != autoRun ? !!autoRun : true;
2459
+ self.axes = MOD3.ModConstant.X | MOD3.ModConstant.Y | MOD3.ModConstant.Z;
2460
+ },
2461
+
2462
+ speedX: 1,
2463
+ speedY: 1,
2464
+ perlin: null,
2465
+ force: 1,
2466
+ offset: 0,
2467
+ autoRun: true,
2468
+
2469
+ dispose: function() {
2470
+ var self = this;
2471
+ self.perlin = null;
2472
+ self.speedX = null;
2473
+ self.speedY = null;
2474
+ self.force = null;
2475
+ self.offset = null;
2476
+ self.autoRun = null;
2477
+ self.$super('dispose');
2478
+
2479
+ return self;
2480
+ },
2481
+
2482
+ setSpeed: function(dX, dY) {
2483
+ var self = this;
2484
+ self.speedX = dX;
2485
+ self.speedY = dY;
2486
+ return self;
2487
+ },
2488
+
2489
+ apply: function(modifiable) {
2490
+ var self = this,
2491
+ axes = self.axes, force = self.force,
2492
+ offset = self.offset, pn = self.perlin,
2493
+ w, h;
2494
+
2495
+ if (!axes || !pn) return self;
2496
+ w = pn.width; h = pn.height;
2497
+ if (self.autoRun)
2498
+ {
2499
+ pn = self.perlin = cyclic_shift(pn, w, h, self.speedX, self.speedY);
2500
+ pn.width = w; pn.height = h;
2501
+ }
2502
+
2503
+ MOD3.List.each(modifiable.vertices, function(v) {
2504
+ var xyz = v.getXYZ(),
2505
+ uu = ~~((w - 1) * v.ratio[0]/* u */),
2506
+ vv = ~~((h - 1) * v.ratio[2]/* v */),
2507
+ uv = uu + vv * w;
2508
+
2509
+ v.setXYZ([
2510
+ xyz[0] + (axes & MOD3.ModConstant.X ? (pn[uv] - offset) * force : 0),
2511
+ xyz[1] + (axes & MOD3.ModConstant.Y ? (pn[uv/*+1*/] - offset) * force : 0),
2512
+ xyz[2] + (axes & MOD3.ModConstant.Z ? (pn[uv/*+2*/] - offset) * force : 0)
2513
+ ]);
2514
+ });
2515
+ return self;
2516
+ }
2517
+ });
2518
+ }(MOD3);// export it
2519
+ return MOD3;
2520
+ });
pdf.js ADDED
The diff for this file is too large to render. See raw diff
 
pdf.worker.js ADDED
The diff for this file is too large to render. See raw diff
 
three.js ADDED
The diff for this file is too large to render. See raw diff