spotlight-frontend 3.5.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/LICENSE +13 -0
  2. package/README.md +114 -0
  3. package/app/assets/images/blacklight/arrow-alt-circle-left.svg +1 -0
  4. package/app/assets/images/blacklight/arrow-alt-circle-right.svg +1 -0
  5. package/app/assets/images/blacklight/arrow_back_ios.svg +1 -0
  6. package/app/assets/images/blacklight/arrow_forward_ios.svg +1 -0
  7. package/app/assets/images/blacklight/check.svg +1 -0
  8. package/app/assets/images/blacklight/check_circle.svg +1 -0
  9. package/app/assets/images/blacklight/chevron_right.svg +1 -0
  10. package/app/assets/images/blacklight/close.svg +1 -0
  11. package/app/assets/images/blacklight/edit.svg +1 -0
  12. package/app/assets/images/blacklight/error.svg +1 -0
  13. package/app/assets/images/blacklight/highlight_off.svg +1 -0
  14. package/app/assets/images/blacklight/info.svg +1 -0
  15. package/app/assets/images/blacklight/warning.svg +1 -0
  16. package/app/assets/images/blacklight/zoom_in.svg +1 -0
  17. package/app/assets/images/blacklight/zoom_out.svg +1 -0
  18. package/app/assets/images/spotlight/.keep +0 -0
  19. package/app/assets/images/spotlight/blocks/sir-trevor-icons.svg +320 -0
  20. package/app/assets/images/spotlight/default_browse_thumbnail.jpg +0 -0
  21. package/app/assets/images/spotlight/default_thumbnail.jpg +0 -0
  22. package/app/assets/images/spotlight/fallback/default.png +0 -0
  23. package/app/assets/javascripts/spotlight/admin/add_another.js +22 -0
  24. package/app/assets/javascripts/spotlight/admin/add_new_button.js +81 -0
  25. package/app/assets/javascripts/spotlight/admin/appearance.js +24 -0
  26. package/app/assets/javascripts/spotlight/admin/attachments.js +2 -0
  27. package/app/assets/javascripts/spotlight/admin/blacklight_configuration.js +63 -0
  28. package/app/assets/javascripts/spotlight/admin/block_mixins/autocompleteable.js +72 -0
  29. package/app/assets/javascripts/spotlight/admin/block_mixins/formable.js +78 -0
  30. package/app/assets/javascripts/spotlight/admin/block_mixins/plustextable.js +57 -0
  31. package/app/assets/javascripts/spotlight/admin/blocks/block.js +23 -0
  32. package/app/assets/javascripts/spotlight/admin/blocks/browse_block.js +87 -0
  33. package/app/assets/javascripts/spotlight/admin/blocks/browse_group_categories_block.js +88 -0
  34. package/app/assets/javascripts/spotlight/admin/blocks/iframe_block.js +34 -0
  35. package/app/assets/javascripts/spotlight/admin/blocks/link_to_search_block.js +16 -0
  36. package/app/assets/javascripts/spotlight/admin/blocks/oembed_block.js +40 -0
  37. package/app/assets/javascripts/spotlight/admin/blocks/pages_block.js +22 -0
  38. package/app/assets/javascripts/spotlight/admin/blocks/resources_block.js +145 -0
  39. package/app/assets/javascripts/spotlight/admin/blocks/rule_block.js +25 -0
  40. package/app/assets/javascripts/spotlight/admin/blocks/search_result_block.js +44 -0
  41. package/app/assets/javascripts/spotlight/admin/blocks/solr_documents_base_block.js +108 -0
  42. package/app/assets/javascripts/spotlight/admin/blocks/solr_documents_block.js +25 -0
  43. package/app/assets/javascripts/spotlight/admin/blocks/solr_documents_carousel_block.js +103 -0
  44. package/app/assets/javascripts/spotlight/admin/blocks/solr_documents_embed_block.js +17 -0
  45. package/app/assets/javascripts/spotlight/admin/blocks/solr_documents_features_block.js +41 -0
  46. package/app/assets/javascripts/spotlight/admin/blocks/solr_documents_grid_block.js +14 -0
  47. package/app/assets/javascripts/spotlight/admin/blocks/uploaded_items_block.js +145 -0
  48. package/app/assets/javascripts/spotlight/admin/catalog_edit.js +16 -0
  49. package/app/assets/javascripts/spotlight/admin/copy_email_addresses.js +9 -0
  50. package/app/assets/javascripts/spotlight/admin/crop.es6 +310 -0
  51. package/app/assets/javascripts/spotlight/admin/croppable.js +25 -0
  52. package/app/assets/javascripts/spotlight/admin/edit_in_place.js +54 -0
  53. package/app/assets/javascripts/spotlight/admin/exhibit_tag_autocomplete.js +37 -0
  54. package/app/assets/javascripts/spotlight/admin/exhibits.js +58 -0
  55. package/app/assets/javascripts/spotlight/admin/form_observer.js +86 -0
  56. package/app/assets/javascripts/spotlight/admin/iiif.es6 +54 -0
  57. package/app/assets/javascripts/spotlight/admin/index.js +16 -0
  58. package/app/assets/javascripts/spotlight/admin/locks.js +12 -0
  59. package/app/assets/javascripts/spotlight/admin/multi_image_selector.js +158 -0
  60. package/app/assets/javascripts/spotlight/admin/pages.js.erb +40 -0
  61. package/app/assets/javascripts/spotlight/admin/progress_monitor.js +148 -0
  62. package/app/assets/javascripts/spotlight/admin/readonly_checkbox.js +6 -0
  63. package/app/assets/javascripts/spotlight/admin/search_typeahead.js +108 -0
  64. package/app/assets/javascripts/spotlight/admin/select_related_input.js +34 -0
  65. package/app/assets/javascripts/spotlight/admin/sir-trevor/block_controls.js +120 -0
  66. package/app/assets/javascripts/spotlight/admin/sir-trevor/block_limits.js +37 -0
  67. package/app/assets/javascripts/spotlight/admin/sir-trevor/locales.js +120 -0
  68. package/app/assets/javascripts/spotlight/admin/spotlight_nestable.js +72 -0
  69. package/app/assets/javascripts/spotlight/admin/tabs.js +6 -0
  70. package/app/assets/javascripts/spotlight/admin/translation_progress.js +23 -0
  71. package/app/assets/javascripts/spotlight/admin/users.js +79 -0
  72. package/app/assets/javascripts/spotlight/application.js +14 -0
  73. package/app/assets/javascripts/spotlight/spotlight.js +23 -0
  74. package/app/assets/javascripts/spotlight/user/analytics.js +9 -0
  75. package/app/assets/javascripts/spotlight/user/browse_group_categories.js +59 -0
  76. package/app/assets/javascripts/spotlight/user/carousel.js +3 -0
  77. package/app/assets/javascripts/spotlight/user/clear_form_button.js +27 -0
  78. package/app/assets/javascripts/spotlight/user/index.js +8 -0
  79. package/app/assets/javascripts/spotlight/user/report_a_problem.js +39 -0
  80. package/app/assets/javascripts/spotlight/user/zpr_links.js.erb +45 -0
  81. package/app/assets/stylesheets/spotlight/_accessibility.scss +8 -0
  82. package/app/assets/stylesheets/spotlight/_attachments.css +4 -0
  83. package/app/assets/stylesheets/spotlight/_blacklight_configuration.scss +82 -0
  84. package/app/assets/stylesheets/spotlight/_blacklight_overrides.scss +21 -0
  85. package/app/assets/stylesheets/spotlight/_bootstrap_overrides.scss +105 -0
  86. package/app/assets/stylesheets/spotlight/_breadcrumbs.scss +6 -0
  87. package/app/assets/stylesheets/spotlight/_browse.scss +158 -0
  88. package/app/assets/stylesheets/spotlight/_catalog.scss +161 -0
  89. package/app/assets/stylesheets/spotlight/_collapse_toggle.scss +14 -0
  90. package/app/assets/stylesheets/spotlight/_croppable.scss +4 -0
  91. package/app/assets/stylesheets/spotlight/_curation.scss +224 -0
  92. package/app/assets/stylesheets/spotlight/_edit_in_place.scss +9 -0
  93. package/app/assets/stylesheets/spotlight/_exhibit_admin.scss +81 -0
  94. package/app/assets/stylesheets/spotlight/_exhibit_navbar.scss +10 -0
  95. package/app/assets/stylesheets/spotlight/_exhibits_index.scss +147 -0
  96. package/app/assets/stylesheets/spotlight/_featured_browse_categories_block.scss +269 -0
  97. package/app/assets/stylesheets/spotlight/_footer.scss +12 -0
  98. package/app/assets/stylesheets/spotlight/_header.scss +155 -0
  99. package/app/assets/stylesheets/spotlight/_item_text_block.scss +50 -0
  100. package/app/assets/stylesheets/spotlight/_mixins.scss +17 -0
  101. package/app/assets/stylesheets/spotlight/_modals.scss +3 -0
  102. package/app/assets/stylesheets/spotlight/_multi_image_selector.scss +22 -0
  103. package/app/assets/stylesheets/spotlight/_multi_up_item_grid.scss +63 -0
  104. package/app/assets/stylesheets/spotlight/_nestable.scss +124 -0
  105. package/app/assets/stylesheets/spotlight/_pages.scss +282 -0
  106. package/app/assets/stylesheets/spotlight/_report_a_problem.scss +14 -0
  107. package/app/assets/stylesheets/spotlight/_sir-trevor_overrides.scss +87 -0
  108. package/app/assets/stylesheets/spotlight/_slideshow_block.scss +87 -0
  109. package/app/assets/stylesheets/spotlight/_spotlight.scss +49 -0
  110. package/app/assets/stylesheets/spotlight/_translations.scss +86 -0
  111. package/app/assets/stylesheets/spotlight/_upload.scss +0 -0
  112. package/app/assets/stylesheets/spotlight/_uploaded_items_block.scss +7 -0
  113. package/app/assets/stylesheets/spotlight/_utilities.scss +7 -0
  114. package/app/assets/stylesheets/spotlight/_variables.scss +42 -0
  115. package/app/assets/stylesheets/spotlight/_variables_bootstrap.scss +7 -0
  116. package/app/assets/stylesheets/spotlight/_view_larger.scss +22 -0
  117. package/app/assets/stylesheets/spotlight/browse_group_categories_block.scss +92 -0
  118. package/app/assets/stylesheets/spotlight/typeahead.css +77 -0
  119. package/package.json +29 -0
  120. package/vendor/assets/images/sir-trevor-icons.svg +263 -0
  121. package/vendor/assets/javascripts/Leaflet.Editable.js +1917 -0
  122. package/vendor/assets/javascripts/MutationObserver.js +625 -0
  123. package/vendor/assets/javascripts/Path.Drag.js +137 -0
  124. package/vendor/assets/javascripts/bootstrap-tagsinput.js +530 -0
  125. package/vendor/assets/javascripts/eventable.js +205 -0
  126. package/vendor/assets/javascripts/jquery.serializejson.js +234 -0
  127. package/vendor/assets/javascripts/jquery.waitforimages.min.js +2 -0
  128. package/vendor/assets/javascripts/leaflet-iiif.js +323 -0
  129. package/vendor/assets/javascripts/nestable.js +645 -0
  130. package/vendor/assets/javascripts/parameterize.js +137 -0
  131. package/vendor/assets/javascripts/polyfill.min.js +4 -0
  132. package/vendor/assets/javascripts/sir-trevor.js +21639 -0
  133. package/vendor/assets/javascripts/tiny-slider.js +3218 -0
  134. package/vendor/assets/javascripts/typeahead.bundle.min.js +7 -0
  135. package/vendor/assets/stylesheets/bootstrap-tagsinput.css +46 -0
  136. package/vendor/assets/stylesheets/leaflet-areaselect.css +15 -0
  137. package/vendor/assets/stylesheets/sir-trevor/_icons.scss +6 -0
  138. package/vendor/assets/stylesheets/sir-trevor/_variables.scss +22 -0
  139. package/vendor/assets/stylesheets/sir-trevor/base.scss +17 -0
  140. package/vendor/assets/stylesheets/sir-trevor/block-addition-top.scss +95 -0
  141. package/vendor/assets/stylesheets/sir-trevor/block-addition.scss +72 -0
  142. package/vendor/assets/stylesheets/sir-trevor/block-controls.scss +34 -0
  143. package/vendor/assets/stylesheets/sir-trevor/block-positioner.scss +34 -0
  144. package/vendor/assets/stylesheets/sir-trevor/block-replacer.scss +43 -0
  145. package/vendor/assets/stylesheets/sir-trevor/block-ui.scss +120 -0
  146. package/vendor/assets/stylesheets/sir-trevor/block.scss +300 -0
  147. package/vendor/assets/stylesheets/sir-trevor/errors.scss +21 -0
  148. package/vendor/assets/stylesheets/sir-trevor/format-bar.scss +65 -0
  149. package/vendor/assets/stylesheets/sir-trevor/inputs.scss +45 -0
  150. package/vendor/assets/stylesheets/sir-trevor/main.scss +24 -0
  151. package/vendor/assets/stylesheets/sir-trevor/patterns/ui-popup.scss +38 -0
  152. package/vendor/assets/stylesheets/sir-trevor/utils.scss +10 -0
  153. package/vendor/assets/stylesheets/tiny-slider.css +1 -0
@@ -0,0 +1,3218 @@
1
+ // Includes an unreleased RTL support pull request: https://github.com/ganlanyuan/tiny-slider/pull/658
2
+ var tns = (function (){
3
+ var win = window;
4
+
5
+ var raf = win.requestAnimationFrame
6
+ || win.webkitRequestAnimationFrame
7
+ || win.mozRequestAnimationFrame
8
+ || win.msRequestAnimationFrame
9
+ || function(cb) { return setTimeout(cb, 16); };
10
+
11
+ var win$1 = window;
12
+
13
+ var caf = win$1.cancelAnimationFrame
14
+ || win$1.mozCancelAnimationFrame
15
+ || function(id){ clearTimeout(id); };
16
+
17
+ function extend() {
18
+ var obj, name, copy,
19
+ target = arguments[0] || {},
20
+ i = 1,
21
+ length = arguments.length;
22
+
23
+ for (; i < length; i++) {
24
+ if ((obj = arguments[i]) !== null) {
25
+ for (name in obj) {
26
+ copy = obj[name];
27
+
28
+ if (target === copy) {
29
+ continue;
30
+ } else if (copy !== undefined) {
31
+ target[name] = copy;
32
+ }
33
+ }
34
+ }
35
+ }
36
+ return target;
37
+ }
38
+
39
+ function checkStorageValue (value) {
40
+ return ['true', 'false'].indexOf(value) >= 0 ? JSON.parse(value) : value;
41
+ }
42
+
43
+ function setLocalStorage(storage, key, value, access) {
44
+ if (access) {
45
+ try { storage.setItem(key, value); } catch (e) {}
46
+ }
47
+ return value;
48
+ }
49
+
50
+ function getSlideId() {
51
+ var id = window.tnsId;
52
+ window.tnsId = !id ? 1 : id + 1;
53
+
54
+ return 'tns' + window.tnsId;
55
+ }
56
+
57
+ function getBody () {
58
+ var doc = document,
59
+ body = doc.body;
60
+
61
+ if (!body) {
62
+ body = doc.createElement('body');
63
+ body.fake = true;
64
+ }
65
+
66
+ return body;
67
+ }
68
+
69
+ var docElement = document.documentElement;
70
+
71
+ function setFakeBody (body) {
72
+ var docOverflow = '';
73
+ if (body.fake) {
74
+ docOverflow = docElement.style.overflow;
75
+ //avoid crashing IE8, if background image is used
76
+ body.style.background = '';
77
+ //Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible
78
+ body.style.overflow = docElement.style.overflow = 'hidden';
79
+ docElement.appendChild(body);
80
+ }
81
+
82
+ return docOverflow;
83
+ }
84
+
85
+ function resetFakeBody (body, docOverflow) {
86
+ if (body.fake) {
87
+ body.remove();
88
+ docElement.style.overflow = docOverflow;
89
+ // Trigger layout so kinetic scrolling isn't disabled in iOS6+
90
+ // eslint-disable-next-line
91
+ docElement.offsetHeight;
92
+ }
93
+ }
94
+
95
+ // get css-calc
96
+
97
+ function calc() {
98
+ var doc = document,
99
+ body = getBody(),
100
+ docOverflow = setFakeBody(body),
101
+ div = doc.createElement('div'),
102
+ result = false;
103
+
104
+ body.appendChild(div);
105
+ try {
106
+ var str = '(10px * 10)',
107
+ vals = ['calc' + str, '-moz-calc' + str, '-webkit-calc' + str],
108
+ val;
109
+ for (var i = 0; i < 3; i++) {
110
+ val = vals[i];
111
+ div.style.width = val;
112
+ if (div.offsetWidth === 100) {
113
+ result = val.replace(str, '');
114
+ break;
115
+ }
116
+ }
117
+ } catch (e) {}
118
+
119
+ body.fake ? resetFakeBody(body, docOverflow) : div.remove();
120
+
121
+ return result;
122
+ }
123
+
124
+ // get subpixel support value
125
+
126
+ function percentageLayout() {
127
+ // check subpixel layout supporting
128
+ var doc = document,
129
+ body = getBody(),
130
+ docOverflow = setFakeBody(body),
131
+ wrapper = doc.createElement('div'),
132
+ outer = doc.createElement('div'),
133
+ str = '',
134
+ count = 70,
135
+ perPage = 3,
136
+ supported = false;
137
+
138
+ wrapper.className = "tns-t-subp2";
139
+ outer.className = "tns-t-ct";
140
+
141
+ for (var i = 0; i < count; i++) {
142
+ str += '<div></div>';
143
+ }
144
+
145
+ outer.innerHTML = str;
146
+ wrapper.appendChild(outer);
147
+ body.appendChild(wrapper);
148
+
149
+ supported = Math.abs(wrapper.getBoundingClientRect().left - outer.children[count - perPage].getBoundingClientRect().left) < 2;
150
+
151
+ body.fake ? resetFakeBody(body, docOverflow) : wrapper.remove();
152
+
153
+ return supported;
154
+ }
155
+
156
+ function mediaquerySupport () {
157
+ if (window.matchMedia || window.msMatchMedia) {
158
+ return true;
159
+ }
160
+
161
+ var doc = document,
162
+ body = getBody(),
163
+ docOverflow = setFakeBody(body),
164
+ div = doc.createElement('div'),
165
+ style = doc.createElement('style'),
166
+ rule = '@media all and (min-width:1px){.tns-mq-test{position:absolute}}',
167
+ position;
168
+
169
+ style.type = 'text/css';
170
+ div.className = 'tns-mq-test';
171
+
172
+ body.appendChild(style);
173
+ body.appendChild(div);
174
+
175
+ if (style.styleSheet) {
176
+ style.styleSheet.cssText = rule;
177
+ } else {
178
+ style.appendChild(doc.createTextNode(rule));
179
+ }
180
+
181
+ position = window.getComputedStyle ? window.getComputedStyle(div).position : div.currentStyle['position'];
182
+
183
+ body.fake ? resetFakeBody(body, docOverflow) : div.remove();
184
+
185
+ return position === "absolute";
186
+ }
187
+
188
+ // create and append style sheet
189
+ function createStyleSheet (media, nonce) {
190
+ // Create the <style> tag
191
+ var style = document.createElement("style");
192
+ // style.setAttribute("type", "text/css");
193
+
194
+ // Add a media (and/or media query) here if you'd like!
195
+ // style.setAttribute("media", "screen")
196
+ // style.setAttribute("media", "only screen and (max-width : 1024px)")
197
+ if (media) { style.setAttribute("media", media); }
198
+
199
+ // Add nonce attribute for Content Security Policy
200
+ if (nonce) { style.setAttribute("nonce", nonce); }
201
+
202
+ // WebKit hack :(
203
+ // style.appendChild(document.createTextNode(""));
204
+
205
+ // Add the <style> element to the page
206
+ document.querySelector('head').appendChild(style);
207
+
208
+ return style.sheet ? style.sheet : style.styleSheet;
209
+ }
210
+
211
+ // cross browsers addRule method
212
+ function addCSSRule(sheet, selector, rules, index) {
213
+ // return raf(function() {
214
+ 'insertRule' in sheet ?
215
+ sheet.insertRule(selector + '{' + rules + '}', index) :
216
+ sheet.addRule(selector, rules, index);
217
+ // });
218
+ }
219
+
220
+ // cross browsers addRule method
221
+ function removeCSSRule(sheet, index) {
222
+ // return raf(function() {
223
+ 'deleteRule' in sheet ?
224
+ sheet.deleteRule(index) :
225
+ sheet.removeRule(index);
226
+ // });
227
+ }
228
+
229
+ function getCssRulesLength(sheet) {
230
+ var rule = ('insertRule' in sheet) ? sheet.cssRules : sheet.rules;
231
+ return rule.length;
232
+ }
233
+
234
+ function toDegree (y, x) {
235
+ return Math.atan2(y, x) * (180 / Math.PI);
236
+ }
237
+
238
+ function getTouchDirection(angle, range) {
239
+ var direction = false,
240
+ gap = Math.abs(90 - Math.abs(angle));
241
+
242
+ if (gap >= 90 - range) {
243
+ direction = 'horizontal';
244
+ } else if (gap <= range) {
245
+ direction = 'vertical';
246
+ }
247
+
248
+ return direction;
249
+ }
250
+
251
+ // https://toddmotto.com/ditch-the-array-foreach-call-nodelist-hack/
252
+ function forEach (arr, callback, scope) {
253
+ for (var i = 0, l = arr.length; i < l; i++) {
254
+ callback.call(scope, arr[i], i);
255
+ }
256
+ }
257
+
258
+ var classListSupport = 'classList' in document.createElement('_');
259
+
260
+ var hasClass = classListSupport ?
261
+ function (el, str) { return el.classList.contains(str); } :
262
+ function (el, str) { return el.className.indexOf(str) >= 0; };
263
+
264
+ var addClass = classListSupport ?
265
+ function (el, str) {
266
+ if (!hasClass(el, str)) { el.classList.add(str); }
267
+ } :
268
+ function (el, str) {
269
+ if (!hasClass(el, str)) { el.className += ' ' + str; }
270
+ };
271
+
272
+ var removeClass = classListSupport ?
273
+ function (el, str) {
274
+ if (hasClass(el, str)) { el.classList.remove(str); }
275
+ } :
276
+ function (el, str) {
277
+ if (hasClass(el, str)) { el.className = el.className.replace(str, ''); }
278
+ };
279
+
280
+ function hasAttr(el, attr) {
281
+ return el.hasAttribute(attr);
282
+ }
283
+
284
+ function getAttr(el, attr) {
285
+ return el.getAttribute(attr);
286
+ }
287
+
288
+ function isNodeList(el) {
289
+ // Only NodeList has the "item()" function
290
+ return typeof el.item !== "undefined";
291
+ }
292
+
293
+ function setAttrs(els, attrs) {
294
+ els = (isNodeList(els) || els instanceof Array) ? els : [els];
295
+ if (Object.prototype.toString.call(attrs) !== '[object Object]') { return; }
296
+
297
+ for (var i = els.length; i--;) {
298
+ for(var key in attrs) {
299
+ els[i].setAttribute(key, attrs[key]);
300
+ }
301
+ }
302
+ }
303
+
304
+ function removeAttrs(els, attrs) {
305
+ els = (isNodeList(els) || els instanceof Array) ? els : [els];
306
+ attrs = (attrs instanceof Array) ? attrs : [attrs];
307
+
308
+ var attrLength = attrs.length;
309
+ for (var i = els.length; i--;) {
310
+ for (var j = attrLength; j--;) {
311
+ els[i].removeAttribute(attrs[j]);
312
+ }
313
+ }
314
+ }
315
+
316
+ function arrayFromNodeList (nl) {
317
+ var arr = [];
318
+ for (var i = 0, l = nl.length; i < l; i++) {
319
+ arr.push(nl[i]);
320
+ }
321
+ return arr;
322
+ }
323
+
324
+ function hideElement(el, forceHide) {
325
+ if (el.style.display !== 'none') { el.style.display = 'none'; }
326
+ }
327
+
328
+ function showElement(el, forceHide) {
329
+ if (el.style.display === 'none') { el.style.display = ''; }
330
+ }
331
+
332
+ function isVisible(el) {
333
+ return window.getComputedStyle(el).display !== 'none';
334
+ }
335
+
336
+ function whichProperty(props){
337
+ if (typeof props === 'string') {
338
+ var arr = [props],
339
+ Props = props.charAt(0).toUpperCase() + props.substr(1),
340
+ prefixes = ['Webkit', 'Moz', 'ms', 'O'];
341
+
342
+ prefixes.forEach(function(prefix) {
343
+ if (prefix !== 'ms' || props === 'transform') {
344
+ arr.push(prefix + Props);
345
+ }
346
+ });
347
+
348
+ props = arr;
349
+ }
350
+
351
+ var el = document.createElement('fakeelement'),
352
+ len = props.length;
353
+ for(var i = 0; i < props.length; i++){
354
+ var prop = props[i];
355
+ if( el.style[prop] !== undefined ){ return prop; }
356
+ }
357
+
358
+ return false; // explicit for ie9-
359
+ }
360
+
361
+ function has3DTransforms(tf){
362
+ if (!tf) { return false; }
363
+ if (!window.getComputedStyle) { return false; }
364
+
365
+ var doc = document,
366
+ body = getBody(),
367
+ docOverflow = setFakeBody(body),
368
+ el = doc.createElement('p'),
369
+ has3d,
370
+ cssTF = tf.length > 9 ? '-' + tf.slice(0, -9).toLowerCase() + '-' : '';
371
+
372
+ cssTF += 'transform';
373
+
374
+ // Add it to the body to get the computed style
375
+ body.insertBefore(el, null);
376
+
377
+ el.style[tf] = 'translate3d(1px,1px,1px)';
378
+ has3d = window.getComputedStyle(el).getPropertyValue(cssTF);
379
+
380
+ body.fake ? resetFakeBody(body, docOverflow) : el.remove();
381
+
382
+ return (has3d !== undefined && has3d.length > 0 && has3d !== "none");
383
+ }
384
+
385
+ // get transitionend, animationend based on transitionDuration
386
+ // @propin: string
387
+ // @propOut: string, first-letter uppercase
388
+ // Usage: getEndProperty('WebkitTransitionDuration', 'Transition') => webkitTransitionEnd
389
+ function getEndProperty(propIn, propOut) {
390
+ var endProp = false;
391
+ if (/^Webkit/.test(propIn)) {
392
+ endProp = 'webkit' + propOut + 'End';
393
+ } else if (/^O/.test(propIn)) {
394
+ endProp = 'o' + propOut + 'End';
395
+ } else if (propIn) {
396
+ endProp = propOut.toLowerCase() + 'end';
397
+ }
398
+ return endProp;
399
+ }
400
+
401
+ // Test via a getter in the options object to see if the passive property is accessed
402
+ var supportsPassive = false;
403
+ try {
404
+ var opts = Object.defineProperty({}, 'passive', {
405
+ get: function() {
406
+ supportsPassive = true;
407
+ }
408
+ });
409
+ window.addEventListener("test", null, opts);
410
+ } catch (e) {}
411
+ var passiveOption = supportsPassive ? { passive: true } : false;
412
+
413
+ function addEvents(el, obj, preventScrolling) {
414
+ for (var prop in obj) {
415
+ var option = ['touchstart', 'touchmove'].indexOf(prop) >= 0 && !preventScrolling ? passiveOption : false;
416
+ el.addEventListener(prop, obj[prop], option);
417
+ }
418
+ }
419
+
420
+ function removeEvents(el, obj) {
421
+ for (var prop in obj) {
422
+ var option = ['touchstart', 'touchmove'].indexOf(prop) >= 0 ? passiveOption : false;
423
+ el.removeEventListener(prop, obj[prop], option);
424
+ }
425
+ }
426
+
427
+ function Events() {
428
+ return {
429
+ topics: {},
430
+ on: function (eventName, fn) {
431
+ this.topics[eventName] = this.topics[eventName] || [];
432
+ this.topics[eventName].push(fn);
433
+ },
434
+ off: function(eventName, fn) {
435
+ if (this.topics[eventName]) {
436
+ for (var i = 0; i < this.topics[eventName].length; i++) {
437
+ if (this.topics[eventName][i] === fn) {
438
+ this.topics[eventName].splice(i, 1);
439
+ break;
440
+ }
441
+ }
442
+ }
443
+ },
444
+ emit: function (eventName, data) {
445
+ data.type = eventName;
446
+ if (this.topics[eventName]) {
447
+ this.topics[eventName].forEach(function(fn) {
448
+ fn(data, eventName);
449
+ });
450
+ }
451
+ }
452
+ };
453
+ }
454
+
455
+ function jsTransform(element, attr, prefix, postfix, to, duration, callback) {
456
+ var tick = Math.min(duration, 10),
457
+ unit = (to.indexOf('%') >= 0) ? '%' : 'px',
458
+ to = to.replace(unit, ''),
459
+ from = Number(element.style[attr].replace(prefix, '').replace(postfix, '').replace(unit, '')),
460
+ positionTick = (to - from) / duration * tick,
461
+ running;
462
+
463
+ setTimeout(moveElement, tick);
464
+ function moveElement() {
465
+ duration -= tick;
466
+ from += positionTick;
467
+ element.style[attr] = prefix + from + unit + postfix;
468
+ if (duration > 0) {
469
+ setTimeout(moveElement, tick);
470
+ } else {
471
+ callback();
472
+ }
473
+ }
474
+ }
475
+
476
+ // Object.keys
477
+ if (!Object.keys) {
478
+ Object.keys = function(object) {
479
+ var keys = [];
480
+ for (var name in object) {
481
+ if (Object.prototype.hasOwnProperty.call(object, name)) {
482
+ keys.push(name);
483
+ }
484
+ }
485
+ return keys;
486
+ };
487
+ }
488
+
489
+ // ChildNode.remove
490
+ if(!("remove" in Element.prototype)){
491
+ Element.prototype.remove = function(){
492
+ if(this.parentNode) {
493
+ this.parentNode.removeChild(this);
494
+ }
495
+ };
496
+ }
497
+
498
+ var tns = function(options) {
499
+ options = extend({
500
+ container: '.slider',
501
+ mode: 'carousel',
502
+ axis: 'horizontal',
503
+ items: 1,
504
+ gutter: 0,
505
+ edgePadding: 0,
506
+ fixedWidth: false,
507
+ autoWidth: false,
508
+ viewportMax: false,
509
+ slideBy: 1,
510
+ center: false,
511
+ controls: true,
512
+ controlsPosition: 'top',
513
+ controlsText: ['prev', 'next'],
514
+ controlsContainer: false,
515
+ prevButton: false,
516
+ nextButton: false,
517
+ nav: true,
518
+ navPosition: 'top',
519
+ navContainer: false,
520
+ navAsThumbnails: false,
521
+ arrowKeys: false,
522
+ speed: 300,
523
+ autoplay: false,
524
+ autoplayPosition: 'top',
525
+ autoplayTimeout: 5000,
526
+ autoplayDirection: 'forward',
527
+ autoplayText: ['start', 'stop'],
528
+ autoplayHoverPause: false,
529
+ autoplayButton: false,
530
+ autoplayButtonOutput: true,
531
+ autoplayResetOnVisibility: true,
532
+ animateIn: 'tns-fadeIn',
533
+ animateOut: 'tns-fadeOut',
534
+ animateNormal: 'tns-normal',
535
+ animateDelay: false,
536
+ loop: true,
537
+ rewind: false,
538
+ autoHeight: false,
539
+ responsive: false,
540
+ lazyload: false,
541
+ lazyloadSelector: '.tns-lazy-img',
542
+ touch: true,
543
+ mouseDrag: false,
544
+ swipeAngle: 15,
545
+ nested: false,
546
+ preventActionWhenRunning: false,
547
+ preventScrollOnTouch: false,
548
+ freezable: true,
549
+ onInit: false,
550
+ useLocalStorage: true,
551
+ textDirection: 'ltr',
552
+ nonce: false
553
+ }, options || {});
554
+
555
+ var doc = document,
556
+ win = window,
557
+ KEYS = {
558
+ ENTER: 13,
559
+ SPACE: 32,
560
+ LEFT: 37,
561
+ RIGHT: 39
562
+ },
563
+ tnsStorage = {},
564
+ localStorageAccess = options.useLocalStorage;
565
+
566
+ if (localStorageAccess) {
567
+ // check browser version and local storage access
568
+ var browserInfo = navigator.userAgent;
569
+ var uid = new Date;
570
+
571
+ try {
572
+ tnsStorage = win.localStorage;
573
+ if (tnsStorage) {
574
+ tnsStorage.setItem(uid, uid);
575
+ localStorageAccess = tnsStorage.getItem(uid) == uid;
576
+ tnsStorage.removeItem(uid);
577
+ } else {
578
+ localStorageAccess = false;
579
+ }
580
+ if (!localStorageAccess) { tnsStorage = {}; }
581
+ } catch(e) {
582
+ localStorageAccess = false;
583
+ }
584
+
585
+ if (localStorageAccess) {
586
+ // remove storage when browser version changes
587
+ if (tnsStorage['tnsApp'] && tnsStorage['tnsApp'] !== browserInfo) {
588
+ ['tC', 'tPL', 'tMQ', 'tTf', 't3D', 'tTDu', 'tTDe', 'tADu', 'tADe', 'tTE', 'tAE'].forEach(function(item) { tnsStorage.removeItem(item); });
589
+ }
590
+ // update browserInfo
591
+ localStorage['tnsApp'] = browserInfo;
592
+ }
593
+ }
594
+
595
+ var CALC = tnsStorage['tC'] ? checkStorageValue(tnsStorage['tC']) : setLocalStorage(tnsStorage, 'tC', calc(), localStorageAccess),
596
+ PERCENTAGELAYOUT = tnsStorage['tPL'] ? checkStorageValue(tnsStorage['tPL']) : setLocalStorage(tnsStorage, 'tPL', percentageLayout(), localStorageAccess),
597
+ CSSMQ = tnsStorage['tMQ'] ? checkStorageValue(tnsStorage['tMQ']) : setLocalStorage(tnsStorage, 'tMQ', mediaquerySupport(), localStorageAccess),
598
+ TRANSFORM = tnsStorage['tTf'] ? checkStorageValue(tnsStorage['tTf']) : setLocalStorage(tnsStorage, 'tTf', whichProperty('transform'), localStorageAccess),
599
+ HAS3DTRANSFORMS = tnsStorage['t3D'] ? checkStorageValue(tnsStorage['t3D']) : setLocalStorage(tnsStorage, 't3D', has3DTransforms(TRANSFORM), localStorageAccess),
600
+ TRANSITIONDURATION = tnsStorage['tTDu'] ? checkStorageValue(tnsStorage['tTDu']) : setLocalStorage(tnsStorage, 'tTDu', whichProperty('transitionDuration'), localStorageAccess),
601
+ TRANSITIONDELAY = tnsStorage['tTDe'] ? checkStorageValue(tnsStorage['tTDe']) : setLocalStorage(tnsStorage, 'tTDe', whichProperty('transitionDelay'), localStorageAccess),
602
+ ANIMATIONDURATION = tnsStorage['tADu'] ? checkStorageValue(tnsStorage['tADu']) : setLocalStorage(tnsStorage, 'tADu', whichProperty('animationDuration'), localStorageAccess),
603
+ ANIMATIONDELAY = tnsStorage['tADe'] ? checkStorageValue(tnsStorage['tADe']) : setLocalStorage(tnsStorage, 'tADe', whichProperty('animationDelay'), localStorageAccess),
604
+ TRANSITIONEND = tnsStorage['tTE'] ? checkStorageValue(tnsStorage['tTE']) : setLocalStorage(tnsStorage, 'tTE', getEndProperty(TRANSITIONDURATION, 'Transition'), localStorageAccess),
605
+ ANIMATIONEND = tnsStorage['tAE'] ? checkStorageValue(tnsStorage['tAE']) : setLocalStorage(tnsStorage, 'tAE', getEndProperty(ANIMATIONDURATION, 'Animation'), localStorageAccess);
606
+
607
+ // get element nodes from selectors
608
+ var supportConsoleWarn = win.console && typeof win.console.warn === "function",
609
+ tnsList = ['container', 'controlsContainer', 'prevButton', 'nextButton', 'navContainer', 'autoplayButton'],
610
+ optionsElements = {};
611
+
612
+ tnsList.forEach(function(item) {
613
+ if (typeof options[item] === 'string') {
614
+ var str = options[item],
615
+ el = doc.querySelector(str);
616
+ optionsElements[item] = str;
617
+
618
+ if (el && el.nodeName) {
619
+ options[item] = el;
620
+ } else {
621
+ if (supportConsoleWarn) { console.warn('Can\'t find', options[item]); }
622
+ return;
623
+ }
624
+ }
625
+ });
626
+
627
+ // make sure at least 1 slide
628
+ if (options.container.children.length < 1) {
629
+ if (supportConsoleWarn) { console.warn('No slides found in', options.container); }
630
+ return;
631
+ }
632
+
633
+ // update options
634
+ var responsive = options.responsive,
635
+ nested = options.nested,
636
+ carousel = options.mode === 'carousel' ? true : false;
637
+
638
+ if (responsive) {
639
+ // apply responsive[0] to options and remove it
640
+ if (0 in responsive) {
641
+ options = extend(options, responsive[0]);
642
+ delete responsive[0];
643
+ }
644
+
645
+ var responsiveTem = {};
646
+ for (var key in responsive) {
647
+ var val = responsive[key];
648
+ // update responsive
649
+ // from: 300: 2
650
+ // to:
651
+ // 300: {
652
+ // items: 2
653
+ // }
654
+ val = typeof val === 'number' ? {items: val} : val;
655
+ responsiveTem[key] = val;
656
+ }
657
+ responsive = responsiveTem;
658
+ responsiveTem = null;
659
+ }
660
+
661
+ // update options
662
+ function updateOptions (obj) {
663
+ for (var key in obj) {
664
+ if (!carousel) {
665
+ if (key === 'slideBy') { obj[key] = 'page'; }
666
+ if (key === 'edgePadding') { obj[key] = false; }
667
+ if (key === 'autoHeight') { obj[key] = false; }
668
+ }
669
+
670
+ // update responsive options
671
+ if (key === 'responsive') { updateOptions(obj[key]); }
672
+ }
673
+ }
674
+ if (!carousel) { updateOptions(options); }
675
+
676
+
677
+ // === define and set variables ===
678
+ if (!carousel) {
679
+ options.axis = 'horizontal';
680
+ options.slideBy = 'page';
681
+ options.edgePadding = false;
682
+
683
+ var animateIn = options.animateIn,
684
+ animateOut = options.animateOut,
685
+ animateDelay = options.animateDelay,
686
+ animateNormal = options.animateNormal;
687
+ }
688
+
689
+ var horizontal = options.axis === 'horizontal' ? true : false,
690
+ outerWrapper = doc.createElement('div'),
691
+ innerWrapper = doc.createElement('div'),
692
+ middleWrapper,
693
+ container = options.container,
694
+ containerParent = container.parentNode,
695
+ containerHTML = container.outerHTML,
696
+ slideItems = container.children,
697
+ slideCount = slideItems.length,
698
+ breakpointZone,
699
+ windowWidth = getWindowWidth(),
700
+ isOn = false;
701
+ if (responsive) { setBreakpointZone(); }
702
+ if (carousel) { container.className += ' tns-vpfix'; }
703
+
704
+ // fixedWidth: viewport > rightBoundary > indexMax
705
+ var autoWidth = options.autoWidth,
706
+ fixedWidth = getOption('fixedWidth'),
707
+ edgePadding = getOption('edgePadding'),
708
+ gutter = getOption('gutter'),
709
+ viewport = getViewportWidth(),
710
+ center = getOption('center'),
711
+ items = !autoWidth ? Math.floor(getOption('items')) : 1,
712
+ slideBy = getOption('slideBy'),
713
+ viewportMax = options.viewportMax || options.fixedWidthViewportWidth,
714
+ arrowKeys = getOption('arrowKeys'),
715
+ speed = getOption('speed'),
716
+ rewind = options.rewind,
717
+ loop = rewind ? false : options.loop,
718
+ autoHeight = getOption('autoHeight'),
719
+ controls = getOption('controls'),
720
+ controlsText = getOption('controlsText'),
721
+ textDirection = getOption('textDirection'),
722
+ nav = getOption('nav'),
723
+ touch = getOption('touch'),
724
+ mouseDrag = getOption('mouseDrag'),
725
+ autoplay = getOption('autoplay'),
726
+ autoplayTimeout = getOption('autoplayTimeout'),
727
+ autoplayText = getOption('autoplayText'),
728
+ autoplayHoverPause = getOption('autoplayHoverPause'),
729
+ autoplayResetOnVisibility = getOption('autoplayResetOnVisibility'),
730
+ sheet = createStyleSheet(null, getOption('nonce')),
731
+ lazyload = options.lazyload,
732
+ lazyloadSelector = options.lazyloadSelector,
733
+ slidePositions, // collection of slide positions
734
+ slideItemsOut = [],
735
+ cloneCount = loop ? getCloneCountForLoop() : 0,
736
+ slideCountNew = !carousel ? slideCount + cloneCount : slideCount + cloneCount * 2,
737
+ hasRightDeadZone = (fixedWidth || autoWidth) && !loop ? true : false,
738
+ rightBoundary = fixedWidth ? getRightBoundary() : null,
739
+ updateIndexBeforeTransform = (!carousel || !loop) ? true : false,
740
+ // transform
741
+ transformAttr = horizontal ? 'left' : 'top',
742
+ transformPrefix = '',
743
+ transformPostfix = '',
744
+ // index
745
+ getIndexMax = (function () {
746
+ if (fixedWidth) {
747
+ return function() { return center && !loop ? slideCount - 1 : Math.ceil(- rightBoundary / (fixedWidth + gutter)); };
748
+ } else if (autoWidth) {
749
+ return function() {
750
+ for (var i = 0; i < slideCountNew; i++) {
751
+ if (slidePositions[i] >= - rightBoundary) { return i; }
752
+ }
753
+ };
754
+ } else {
755
+ return function() {
756
+ if (center && carousel && !loop) {
757
+ return slideCount - 1;
758
+ } else {
759
+ return loop || carousel ? Math.max(0, slideCountNew - Math.ceil(items)) : slideCountNew - 1;
760
+ }
761
+ };
762
+ }
763
+ })(),
764
+ index = getStartIndex(getOption('startIndex')),
765
+ indexCached = index,
766
+ displayIndex = getCurrentSlide(),
767
+ indexMin = 0,
768
+ indexMax = !autoWidth ? getIndexMax() : null,
769
+ // resize
770
+ resizeTimer,
771
+ preventActionWhenRunning = options.preventActionWhenRunning,
772
+ swipeAngle = options.swipeAngle,
773
+ moveDirectionExpected = swipeAngle ? '?' : true,
774
+ running = false,
775
+ onInit = options.onInit,
776
+ events = new Events(),
777
+ // id, class
778
+ newContainerClasses = ' tns-slider tns-' + options.mode,
779
+ slideId = container.id || getSlideId(),
780
+ disable = getOption('disable'),
781
+ disabled = false,
782
+ freezable = options.freezable,
783
+ freeze = freezable && !autoWidth ? getFreeze() : false,
784
+ frozen = false,
785
+ controlsEvents = {
786
+ 'click': onControlsClick,
787
+ 'keydown': onControlsKeydown
788
+ },
789
+ navEvents = {
790
+ 'click': onNavClick,
791
+ 'keydown': onNavKeydown
792
+ },
793
+ hoverEvents = {
794
+ 'mouseover': mouseoverPause,
795
+ 'mouseout': mouseoutRestart
796
+ },
797
+ visibilityEvent = {'visibilitychange': onVisibilityChange},
798
+ docmentKeydownEvent = {'keydown': onDocumentKeydown},
799
+ touchEvents = {
800
+ 'touchstart': onPanStart,
801
+ 'touchmove': onPanMove,
802
+ 'touchend': onPanEnd,
803
+ 'touchcancel': onPanEnd
804
+ }, dragEvents = {
805
+ 'mousedown': onPanStart,
806
+ 'mousemove': onPanMove,
807
+ 'mouseup': onPanEnd,
808
+ 'mouseleave': onPanEnd
809
+ },
810
+ hasControls = hasOption('controls'),
811
+ hasNav = hasOption('nav'),
812
+ navAsThumbnails = autoWidth ? true : options.navAsThumbnails,
813
+ hasAutoplay = hasOption('autoplay'),
814
+ hasTouch = hasOption('touch'),
815
+ hasMouseDrag = hasOption('mouseDrag'),
816
+ slideActiveClass = 'tns-slide-active',
817
+ slideClonedClass = 'tns-slide-cloned',
818
+ imgCompleteClass = 'tns-complete',
819
+ imgEvents = {
820
+ 'load': onImgLoaded,
821
+ 'error': onImgFailed
822
+ },
823
+ imgsComplete,
824
+ liveregionCurrent,
825
+ preventScroll = options.preventScrollOnTouch === 'force' ? true : false;
826
+
827
+ // controls
828
+ if (hasControls) {
829
+ var controlsContainer = options.controlsContainer,
830
+ controlsContainerHTML = options.controlsContainer ? options.controlsContainer.outerHTML : '',
831
+ prevButton = options.prevButton,
832
+ nextButton = options.nextButton,
833
+ prevButtonHTML = options.prevButton ? options.prevButton.outerHTML : '',
834
+ nextButtonHTML = options.nextButton ? options.nextButton.outerHTML : '',
835
+ prevIsButton,
836
+ nextIsButton;
837
+ }
838
+
839
+ // nav
840
+ if (hasNav) {
841
+ var navContainer = options.navContainer,
842
+ navContainerHTML = options.navContainer ? options.navContainer.outerHTML : '',
843
+ navItems,
844
+ pages = autoWidth ? slideCount : getPages(),
845
+ pagesCached = 0,
846
+ navClicked = -1,
847
+ navCurrentIndex = getCurrentNavIndex(),
848
+ navCurrentIndexCached = navCurrentIndex,
849
+ navActiveClass = 'tns-nav-active',
850
+ navStr = 'Carousel Page ',
851
+ navStrCurrent = ' (Current Slide)';
852
+ }
853
+
854
+ // autoplay
855
+ if (hasAutoplay) {
856
+ var autoplayDirection = options.autoplayDirection === 'forward' ? 1 : -1,
857
+ autoplayButton = options.autoplayButton,
858
+ autoplayButtonHTML = options.autoplayButton ? options.autoplayButton.outerHTML : '',
859
+ autoplayHtmlStrings = ['<span class=\'tns-visually-hidden\'>', ' animation</span>'],
860
+ autoplayTimer,
861
+ animating,
862
+ autoplayHoverPaused,
863
+ autoplayUserPaused,
864
+ autoplayVisibilityPaused;
865
+ }
866
+
867
+ if (hasTouch || hasMouseDrag) {
868
+ var initPosition = {},
869
+ lastPosition = {},
870
+ translateInit,
871
+ disX,
872
+ disY,
873
+ panStart = false,
874
+ rafIndex,
875
+ getDist = horizontal ?
876
+ function(a, b) { return a.x - b.x; } :
877
+ function(a, b) { return a.y - b.y; };
878
+ }
879
+
880
+ // disable slider when slidecount <= items
881
+ if (!autoWidth) { resetVariblesWhenDisable(disable || freeze); }
882
+
883
+ if (TRANSFORM) {
884
+ transformAttr = TRANSFORM;
885
+ transformPrefix = 'translate';
886
+
887
+ if (HAS3DTRANSFORMS) {
888
+ transformPrefix += horizontal ? '3d(' : '3d(0px, ';
889
+ transformPostfix = horizontal ? ', 0px, 0px)' : ', 0px)';
890
+ } else {
891
+ transformPrefix += horizontal ? 'X(' : 'Y(';
892
+ transformPostfix = ')';
893
+ }
894
+
895
+ }
896
+
897
+ if (carousel) { container.className = container.className.replace('tns-vpfix', ''); }
898
+ initStructure();
899
+ initSheet();
900
+ initSliderTransform();
901
+
902
+ // === COMMON FUNCTIONS === //
903
+ function resetVariblesWhenDisable (condition) {
904
+ if (condition) {
905
+ controls = nav = touch = mouseDrag = arrowKeys = autoplay = autoplayHoverPause = autoplayResetOnVisibility = false;
906
+ }
907
+ }
908
+
909
+ function getCurrentSlide () {
910
+ var tem = carousel ? index - cloneCount : index;
911
+ while (tem < 0) { tem += slideCount; }
912
+ return tem%slideCount + 1;
913
+ }
914
+
915
+ function getStartIndex (ind) {
916
+ ind = ind ? Math.max(0, Math.min(loop ? slideCount - 1 : slideCount - items, ind)) : 0;
917
+ return carousel ? ind + cloneCount : ind;
918
+ }
919
+
920
+ function getAbsIndex (i) {
921
+ if (i == null) { i = index; }
922
+
923
+ if (carousel) { i -= cloneCount; }
924
+ while (i < 0) { i += slideCount; }
925
+
926
+ return Math.floor(i%slideCount);
927
+ }
928
+
929
+ function getCurrentNavIndex () {
930
+ var absIndex = getAbsIndex(),
931
+ result;
932
+
933
+ result = navAsThumbnails ? absIndex :
934
+ fixedWidth || autoWidth ? Math.ceil((absIndex + 1) * pages / slideCount - 1) :
935
+ Math.floor(absIndex / items);
936
+
937
+ // set active nav to the last one when reaches the right edge
938
+ if (!loop && carousel && index === indexMax) { result = pages - 1; }
939
+
940
+ return result;
941
+ }
942
+
943
+ function getItemsMax () {
944
+ // fixedWidth or autoWidth while viewportMax is not available
945
+ if (autoWidth || (fixedWidth && !viewportMax)) {
946
+ return slideCount - 1;
947
+ // most cases
948
+ } else {
949
+ var str = fixedWidth ? 'fixedWidth' : 'items',
950
+ arr = [];
951
+
952
+ if (fixedWidth || options[str] < slideCount) { arr.push(options[str]); }
953
+
954
+ if (responsive) {
955
+ for (var bp in responsive) {
956
+ var tem = responsive[bp][str];
957
+ if (tem && (fixedWidth || tem < slideCount)) { arr.push(tem); }
958
+ }
959
+ }
960
+
961
+ if (!arr.length) { arr.push(0); }
962
+
963
+ return Math.ceil(fixedWidth ? viewportMax / Math.min.apply(null, arr) : Math.max.apply(null, arr));
964
+ }
965
+ }
966
+
967
+ function getCloneCountForLoop () {
968
+ var itemsMax = getItemsMax(),
969
+ result = carousel ? Math.ceil((itemsMax * 5 - slideCount)/2) : (itemsMax * 4 - slideCount);
970
+ result = Math.max(itemsMax, result);
971
+
972
+ return hasOption('edgePadding') ? result + 1 : result;
973
+ }
974
+
975
+ function getWindowWidth () {
976
+ return win.innerWidth || doc.documentElement.clientWidth || doc.body.clientWidth;
977
+ }
978
+
979
+ function getInsertPosition (pos) {
980
+ return pos === 'top' ? 'afterbegin' : 'beforeend';
981
+ }
982
+
983
+ function getClientWidth (el) {
984
+ if (el == null) { return; }
985
+ var div = doc.createElement('div'), rect, width;
986
+ el.appendChild(div);
987
+ rect = div.getBoundingClientRect();
988
+ width = rect.right - rect.left;
989
+ div.remove();
990
+ return width || getClientWidth(el.parentNode);
991
+ }
992
+
993
+ function getViewportWidth () {
994
+ var gap = edgePadding ? edgePadding * 2 - gutter : 0;
995
+ return getClientWidth(containerParent) - gap;
996
+ }
997
+
998
+ function hasOption (item) {
999
+ if (options[item]) {
1000
+ return true;
1001
+ } else {
1002
+ if (responsive) {
1003
+ for (var bp in responsive) {
1004
+ if (responsive[bp][item]) { return true; }
1005
+ }
1006
+ }
1007
+ return false;
1008
+ }
1009
+ }
1010
+
1011
+ // get option:
1012
+ // fixed width: viewport, fixedWidth, gutter => items
1013
+ // others: window width => all variables
1014
+ // all: items => slideBy
1015
+ function getOption (item, ww) {
1016
+ if (ww == null) { ww = windowWidth; }
1017
+
1018
+ if (item === 'items' && fixedWidth) {
1019
+ return Math.floor((viewport + gutter) / (fixedWidth + gutter)) || 1;
1020
+
1021
+ } else {
1022
+ var result = options[item];
1023
+
1024
+ if (responsive) {
1025
+ for (var bp in responsive) {
1026
+ // bp: convert string to number
1027
+ if (ww >= parseInt(bp)) {
1028
+ if (item in responsive[bp]) { result = responsive[bp][item]; }
1029
+ }
1030
+ }
1031
+ }
1032
+
1033
+ if (item === 'slideBy' && result === 'page') { result = getOption('items'); }
1034
+ if (!carousel && (item === 'slideBy' || item === 'items')) { result = Math.floor(result); }
1035
+
1036
+ return result;
1037
+ }
1038
+ }
1039
+
1040
+ function getSlideMarginLeft (i) {
1041
+ return CALC ?
1042
+ CALC + '(' + i * 100 + '% / ' + slideCountNew + ')' :
1043
+ i * 100 / slideCountNew + '%';
1044
+ }
1045
+
1046
+ function getInnerWrapperStyles (edgePaddingTem, gutterTem, fixedWidthTem, speedTem, autoHeightBP) {
1047
+ var str = '';
1048
+
1049
+ if (edgePaddingTem !== undefined) {
1050
+ var gap = edgePaddingTem;
1051
+ if (gutterTem) { gap -= gutterTem; }
1052
+ str = horizontal ?
1053
+ 'margin: 0 ' + gap + 'px 0 ' + edgePaddingTem + 'px;' :
1054
+ 'margin: ' + edgePaddingTem + 'px 0 ' + gap + 'px 0;';
1055
+ } else if (gutterTem && !fixedWidthTem) {
1056
+ var gutterTemUnit = '-' + gutterTem + 'px',
1057
+ dir = horizontal ? gutterTemUnit + ' 0 0' : '0 ' + gutterTemUnit + ' 0';
1058
+ str = 'margin: 0 ' + dir + ';';
1059
+ }
1060
+
1061
+ if (!carousel && autoHeightBP && TRANSITIONDURATION && speedTem) { str += getTransitionDurationStyle(speedTem); }
1062
+ return str;
1063
+ }
1064
+
1065
+ function getContainerWidth (fixedWidthTem, gutterTem, itemsTem) {
1066
+ if (fixedWidthTem) {
1067
+ return (fixedWidthTem + gutterTem) * slideCountNew + 'px';
1068
+ } else {
1069
+ return CALC ?
1070
+ CALC + '(' + slideCountNew * 100 + '% / ' + itemsTem + ')' :
1071
+ slideCountNew * 100 / itemsTem + '%';
1072
+ }
1073
+ }
1074
+
1075
+ function getSlideWidthStyle (fixedWidthTem, gutterTem, itemsTem) {
1076
+ var width;
1077
+
1078
+ if (fixedWidthTem) {
1079
+ width = (fixedWidthTem + gutterTem) + 'px';
1080
+ } else {
1081
+ if (!carousel) { itemsTem = Math.floor(itemsTem); }
1082
+ var dividend = carousel ? slideCountNew : itemsTem;
1083
+ width = CALC ?
1084
+ CALC + '(100% / ' + dividend + ')' :
1085
+ 100 / dividend + '%';
1086
+ }
1087
+
1088
+ width = 'width:' + width;
1089
+
1090
+ // inner slider: overwrite outer slider styles
1091
+ return nested !== 'inner' ? width + ';' : width + ' !important;';
1092
+ }
1093
+
1094
+ function getSlideGutterStyle (gutterTem) {
1095
+ var str = '';
1096
+
1097
+ // gutter maybe interger || 0
1098
+ // so can't use 'if (gutter)'
1099
+ if (gutterTem !== false) {
1100
+ var prop = horizontal ? 'padding-' : 'margin-',
1101
+ dir = horizontal ? 'right' : 'bottom';
1102
+ str = prop + dir + ': ' + gutterTem + 'px;';
1103
+ }
1104
+
1105
+ return str;
1106
+ }
1107
+
1108
+ function getCSSPrefix (name, num) {
1109
+ var prefix = name.substring(0, name.length - num).toLowerCase();
1110
+ if (prefix) { prefix = '-' + prefix + '-'; }
1111
+
1112
+ return prefix;
1113
+ }
1114
+
1115
+ function getTransitionDurationStyle (speed) {
1116
+ return getCSSPrefix(TRANSITIONDURATION, 18) + 'transition-duration:' + speed / 1000 + 's;';
1117
+ }
1118
+
1119
+ function getAnimationDurationStyle (speed) {
1120
+ return getCSSPrefix(ANIMATIONDURATION, 17) + 'animation-duration:' + speed / 1000 + 's;';
1121
+ }
1122
+
1123
+ function initStructure () {
1124
+ var classOuter = 'tns-outer',
1125
+ classInner = 'tns-inner',
1126
+ hasGutter = hasOption('gutter');
1127
+
1128
+ outerWrapper.className = classOuter;
1129
+ innerWrapper.className = classInner;
1130
+ outerWrapper.id = slideId + '-ow';
1131
+ innerWrapper.id = slideId + '-iw';
1132
+
1133
+ // set container properties
1134
+ if (container.id === '') { container.id = slideId; }
1135
+ newContainerClasses += PERCENTAGELAYOUT || autoWidth ? ' tns-subpixel' : ' tns-no-subpixel';
1136
+ newContainerClasses += CALC ? ' tns-calc' : ' tns-no-calc';
1137
+ if (autoWidth) { newContainerClasses += ' tns-autowidth'; }
1138
+ newContainerClasses += ' tns-' + options.axis;
1139
+ container.className += newContainerClasses;
1140
+
1141
+ // add constrain layer for carousel
1142
+ if (carousel) {
1143
+ middleWrapper = doc.createElement('div');
1144
+ middleWrapper.id = slideId + '-mw';
1145
+ middleWrapper.className = 'tns-ovh';
1146
+
1147
+ outerWrapper.appendChild(middleWrapper);
1148
+ middleWrapper.appendChild(innerWrapper);
1149
+ } else {
1150
+ outerWrapper.appendChild(innerWrapper);
1151
+ }
1152
+
1153
+ if (autoHeight) {
1154
+ var wp = middleWrapper ? middleWrapper : innerWrapper;
1155
+ wp.className += ' tns-ah';
1156
+ }
1157
+
1158
+ containerParent.insertBefore(outerWrapper, container);
1159
+ innerWrapper.appendChild(container);
1160
+
1161
+ // add id, class, aria attributes
1162
+ // before clone slides
1163
+ forEach(slideItems, function(item, i) {
1164
+ addClass(item, 'tns-item');
1165
+ if (!item.id) { item.id = slideId + '-item' + i; }
1166
+ if (!carousel && animateNormal) { addClass(item, animateNormal); }
1167
+ setAttrs(item, {
1168
+ 'aria-hidden': 'true',
1169
+ 'tabindex': '-1'
1170
+ });
1171
+ });
1172
+
1173
+ // ## clone slides
1174
+ // carousel: n + slides + n
1175
+ // gallery: slides + n
1176
+ if (cloneCount) {
1177
+ var fragmentBefore = doc.createDocumentFragment(),
1178
+ fragmentAfter = doc.createDocumentFragment();
1179
+
1180
+ for (var j = cloneCount; j--;) {
1181
+ var num = j%slideCount,
1182
+ cloneFirst = slideItems[num].cloneNode(true);
1183
+ addClass(cloneFirst, slideClonedClass);
1184
+ removeAttrs(cloneFirst, 'id');
1185
+ fragmentAfter.insertBefore(cloneFirst, fragmentAfter.firstChild);
1186
+
1187
+ if (carousel) {
1188
+ var cloneLast = slideItems[slideCount - 1 - num].cloneNode(true);
1189
+ addClass(cloneLast, slideClonedClass);
1190
+ removeAttrs(cloneLast, 'id');
1191
+ fragmentBefore.appendChild(cloneLast);
1192
+ }
1193
+ }
1194
+
1195
+ container.insertBefore(fragmentBefore, container.firstChild);
1196
+ container.appendChild(fragmentAfter);
1197
+ slideItems = container.children;
1198
+ }
1199
+
1200
+ }
1201
+
1202
+ function initSliderTransform () {
1203
+ // ## images loaded/failed
1204
+ if (hasOption('autoHeight') || autoWidth || !horizontal) {
1205
+ var imgs = container.querySelectorAll('img');
1206
+
1207
+ // add img load event listener
1208
+ forEach(imgs, function(img) {
1209
+ var src = img.src;
1210
+
1211
+ if (!lazyload) {
1212
+ // not data img
1213
+ if (src && src.indexOf('data:image') < 0) {
1214
+ img.src = '';
1215
+ addEvents(img, imgEvents);
1216
+ addClass(img, 'loading');
1217
+
1218
+ img.src = src;
1219
+ // data img
1220
+ } else {
1221
+ imgLoaded(img);
1222
+ }
1223
+ }
1224
+ });
1225
+
1226
+ // set imgsComplete
1227
+ raf(function(){ imgsLoadedCheck(arrayFromNodeList(imgs), function() { imgsComplete = true; }); });
1228
+
1229
+ // reset imgs for auto height: check visible imgs only
1230
+ if (hasOption('autoHeight')) { imgs = getImageArray(index, Math.min(index + items - 1, slideCountNew - 1)); }
1231
+
1232
+ lazyload ? initSliderTransformStyleCheck() : raf(function(){ imgsLoadedCheck(arrayFromNodeList(imgs), initSliderTransformStyleCheck); });
1233
+
1234
+ } else {
1235
+ // set container transform property
1236
+ if (carousel) { doContainerTransformSilent(); }
1237
+
1238
+ // update slider tools and events
1239
+ initTools();
1240
+ initEvents();
1241
+ }
1242
+ }
1243
+
1244
+ function initSliderTransformStyleCheck () {
1245
+ if (autoWidth && slideCount > 1) {
1246
+ // check styles application
1247
+ var num = loop ? index : slideCount - 1;
1248
+
1249
+ (function stylesApplicationCheck() {
1250
+ var left = slideItems[num].getBoundingClientRect().left;
1251
+ var right = slideItems[num - 1].getBoundingClientRect().right;
1252
+
1253
+ (Math.abs(left - right) <= 1) ?
1254
+ initSliderTransformCore() :
1255
+ setTimeout(function(){ stylesApplicationCheck(); }, 16);
1256
+ })();
1257
+
1258
+ } else {
1259
+ initSliderTransformCore();
1260
+ }
1261
+ }
1262
+
1263
+
1264
+ function initSliderTransformCore () {
1265
+ // run Fn()s which are rely on image loading
1266
+ if (!horizontal || autoWidth) {
1267
+ setSlidePositions();
1268
+
1269
+ if (autoWidth) {
1270
+ rightBoundary = getRightBoundary();
1271
+ if (freezable) { freeze = getFreeze(); }
1272
+ indexMax = getIndexMax(); // <= slidePositions, rightBoundary <=
1273
+ resetVariblesWhenDisable(disable || freeze);
1274
+ } else {
1275
+ updateContentWrapperHeight();
1276
+ }
1277
+ }
1278
+
1279
+ // set container transform property
1280
+ if (carousel) { doContainerTransformSilent(); }
1281
+
1282
+ // update slider tools and events
1283
+ initTools();
1284
+ initEvents();
1285
+ }
1286
+
1287
+ function initSheet () {
1288
+ // gallery:
1289
+ // set animation classes and left value for gallery slider
1290
+ if (!carousel) {
1291
+ for (var i = index, l = index + Math.min(slideCount, items); i < l; i++) {
1292
+ var item = slideItems[i];
1293
+ item.style.left = (i - index) * 100 / items + '%';
1294
+ addClass(item, animateIn);
1295
+ removeClass(item, animateNormal);
1296
+ }
1297
+ }
1298
+
1299
+ // #### LAYOUT
1300
+
1301
+ // ## INLINE-BLOCK VS FLOAT
1302
+
1303
+ // ## PercentageLayout:
1304
+ // slides: inline-block
1305
+ // remove blank space between slides by set font-size: 0
1306
+
1307
+ // ## Non PercentageLayout:
1308
+ // slides: float
1309
+ // margin-right: -100%
1310
+ // margin-left: ~
1311
+
1312
+ // Resource: https://docs.google.com/spreadsheets/d/147up245wwTXeQYve3BRSAD4oVcvQmuGsFteJOeA5xNQ/edit?usp=sharing
1313
+ if (horizontal) {
1314
+ if (PERCENTAGELAYOUT || autoWidth) {
1315
+ addCSSRule(sheet, '#' + slideId + ' > .tns-item', 'font-size:' + win.getComputedStyle(slideItems[0]).fontSize + ';', getCssRulesLength(sheet));
1316
+ addCSSRule(sheet, '#' + slideId, 'font-size:0;', getCssRulesLength(sheet));
1317
+ } else if (carousel) {
1318
+ forEach(slideItems, function (slide, i) {
1319
+ slide.style.marginLeft = getSlideMarginLeft(i);
1320
+ });
1321
+ }
1322
+ }
1323
+
1324
+
1325
+ // ## BASIC STYLES
1326
+ if (CSSMQ) {
1327
+ // middle wrapper style
1328
+ if (TRANSITIONDURATION) {
1329
+ var str = middleWrapper && options.autoHeight ? getTransitionDurationStyle(options.speed) : '';
1330
+ addCSSRule(sheet, '#' + slideId + '-mw', str, getCssRulesLength(sheet));
1331
+ }
1332
+
1333
+ // inner wrapper styles
1334
+ str = getInnerWrapperStyles(options.edgePadding, options.gutter, options.fixedWidth, options.speed, options.autoHeight);
1335
+ addCSSRule(sheet, '#' + slideId + '-iw', str, getCssRulesLength(sheet));
1336
+
1337
+ // container styles
1338
+ if (carousel) {
1339
+ str = horizontal && !autoWidth ? 'width:' + getContainerWidth(options.fixedWidth, options.gutter, options.items) + ';' : '';
1340
+ if (TRANSITIONDURATION) { str += getTransitionDurationStyle(speed); }
1341
+ addCSSRule(sheet, '#' + slideId, str, getCssRulesLength(sheet));
1342
+ }
1343
+
1344
+ // slide styles
1345
+ str = horizontal && !autoWidth ? getSlideWidthStyle(options.fixedWidth, options.gutter, options.items) : '';
1346
+ if (options.gutter) { str += getSlideGutterStyle(options.gutter); }
1347
+ // set gallery items transition-duration
1348
+ if (!carousel) {
1349
+ if (TRANSITIONDURATION) { str += getTransitionDurationStyle(speed); }
1350
+ if (ANIMATIONDURATION) { str += getAnimationDurationStyle(speed); }
1351
+ }
1352
+ if (str) { addCSSRule(sheet, '#' + slideId + ' > .tns-item', str, getCssRulesLength(sheet)); }
1353
+
1354
+ // non CSS mediaqueries: IE8
1355
+ // ## update inner wrapper, container, slides if needed
1356
+ // set inline styles for inner wrapper & container
1357
+ // insert stylesheet (one line) for slides only (since slides are many)
1358
+ } else {
1359
+ // middle wrapper styles
1360
+ update_carousel_transition_duration();
1361
+
1362
+ // inner wrapper styles
1363
+ innerWrapper.style.cssText = getInnerWrapperStyles(edgePadding, gutter, fixedWidth, autoHeight);
1364
+
1365
+ // container styles
1366
+ if (carousel && horizontal && !autoWidth) {
1367
+ container.style.width = getContainerWidth(fixedWidth, gutter, items);
1368
+ }
1369
+
1370
+ // slide styles
1371
+ var str = horizontal && !autoWidth ? getSlideWidthStyle(fixedWidth, gutter, items) : '';
1372
+ if (gutter) { str += getSlideGutterStyle(gutter); }
1373
+
1374
+ // append to the last line
1375
+ if (str) { addCSSRule(sheet, '#' + slideId + ' > .tns-item', str, getCssRulesLength(sheet)); }
1376
+ }
1377
+
1378
+ // ## MEDIAQUERIES
1379
+ if (responsive && CSSMQ) {
1380
+ for (var bp in responsive) {
1381
+ // bp: convert string to number
1382
+ bp = parseInt(bp);
1383
+
1384
+ var opts = responsive[bp],
1385
+ str = '',
1386
+ middleWrapperStr = '',
1387
+ innerWrapperStr = '',
1388
+ containerStr = '',
1389
+ slideStr = '',
1390
+ itemsBP = !autoWidth ? getOption('items', bp) : null,
1391
+ fixedWidthBP = getOption('fixedWidth', bp),
1392
+ speedBP = getOption('speed', bp),
1393
+ edgePaddingBP = getOption('edgePadding', bp),
1394
+ autoHeightBP = getOption('autoHeight', bp),
1395
+ gutterBP = getOption('gutter', bp);
1396
+
1397
+ // middle wrapper string
1398
+ if (TRANSITIONDURATION && middleWrapper && getOption('autoHeight', bp) && 'speed' in opts) {
1399
+ middleWrapperStr = '#' + slideId + '-mw{' + getTransitionDurationStyle(speedBP) + '}';
1400
+ }
1401
+
1402
+ // inner wrapper string
1403
+ if ('edgePadding' in opts || 'gutter' in opts) {
1404
+ innerWrapperStr = '#' + slideId + '-iw{' + getInnerWrapperStyles(edgePaddingBP, gutterBP, fixedWidthBP, speedBP, autoHeightBP) + '}';
1405
+ }
1406
+
1407
+ // container string
1408
+ if (carousel && horizontal && !autoWidth && ('fixedWidth' in opts || 'items' in opts || (fixedWidth && 'gutter' in opts))) {
1409
+ containerStr = 'width:' + getContainerWidth(fixedWidthBP, gutterBP, itemsBP) + ';';
1410
+ }
1411
+ if (TRANSITIONDURATION && 'speed' in opts) {
1412
+ containerStr += getTransitionDurationStyle(speedBP);
1413
+ }
1414
+ if (containerStr) {
1415
+ containerStr = '#' + slideId + '{' + containerStr + '}';
1416
+ }
1417
+
1418
+ // slide string
1419
+ if ('fixedWidth' in opts || (fixedWidth && 'gutter' in opts) || !carousel && 'items' in opts) {
1420
+ slideStr += getSlideWidthStyle(fixedWidthBP, gutterBP, itemsBP);
1421
+ }
1422
+ if ('gutter' in opts) {
1423
+ slideStr += getSlideGutterStyle(gutterBP);
1424
+ }
1425
+ // set gallery items transition-duration
1426
+ if (!carousel && 'speed' in opts) {
1427
+ if (TRANSITIONDURATION) { slideStr += getTransitionDurationStyle(speedBP); }
1428
+ if (ANIMATIONDURATION) { slideStr += getAnimationDurationStyle(speedBP); }
1429
+ }
1430
+ if (slideStr) { slideStr = '#' + slideId + ' > .tns-item{' + slideStr + '}'; }
1431
+
1432
+ // add up
1433
+ str = middleWrapperStr + innerWrapperStr + containerStr + slideStr;
1434
+
1435
+ if (str) {
1436
+ sheet.insertRule('@media (min-width: ' + bp / 16 + 'em) {' + str + '}', sheet.cssRules.length);
1437
+ }
1438
+ }
1439
+ }
1440
+ }
1441
+
1442
+ function initTools () {
1443
+ // == slides ==
1444
+ updateSlideStatus();
1445
+
1446
+ // == live region ==
1447
+ outerWrapper.insertAdjacentHTML('afterbegin', '<div class="tns-liveregion tns-visually-hidden" aria-live="polite" aria-atomic="true">slide <span class="current">' + getLiveRegionStr() + '</span> of ' + slideCount + '</div>');
1448
+ liveregionCurrent = outerWrapper.querySelector('.tns-liveregion .current');
1449
+
1450
+ // == autoplayInit ==
1451
+ if (hasAutoplay) {
1452
+ var txt = autoplay ? 'stop' : 'start';
1453
+ if (autoplayButton) {
1454
+ setAttrs(autoplayButton, {'data-action': txt});
1455
+ } else if (options.autoplayButtonOutput) {
1456
+ outerWrapper.insertAdjacentHTML(getInsertPosition(options.autoplayPosition), '<button type="button" data-action="' + txt + '">' + autoplayHtmlStrings[0] + txt + autoplayHtmlStrings[1] + autoplayText[0] + '</button>');
1457
+ autoplayButton = outerWrapper.querySelector('[data-action]');
1458
+ }
1459
+
1460
+ // add event
1461
+ if (autoplayButton) {
1462
+ addEvents(autoplayButton, {'click': toggleAutoplay});
1463
+ }
1464
+
1465
+ if (autoplay) {
1466
+ startAutoplay();
1467
+ if (autoplayHoverPause) { addEvents(container, hoverEvents); }
1468
+ if (autoplayResetOnVisibility) { addEvents(container, visibilityEvent); }
1469
+ }
1470
+ }
1471
+
1472
+ // == navInit ==
1473
+ if (hasNav) {
1474
+ var initIndex = !carousel ? 0 : cloneCount;
1475
+ // customized nav
1476
+ // will not hide the navs in case they're thumbnails
1477
+ if (navContainer) {
1478
+ setAttrs(navContainer, {'aria-label': 'Carousel Pagination'});
1479
+ navItems = navContainer.children;
1480
+ forEach(navItems, function(item, i) {
1481
+ setAttrs(item, {
1482
+ 'data-nav': i,
1483
+ 'tabindex': '-1',
1484
+ 'aria-label': navStr + (i + 1),
1485
+ 'aria-controls': slideId,
1486
+ });
1487
+ });
1488
+
1489
+ // generated nav
1490
+ } else {
1491
+ var navHtml = '',
1492
+ hiddenStr = navAsThumbnails ? '' : 'style="display:none"';
1493
+ for (var i = 0; i < slideCount; i++) {
1494
+ // hide nav items by default
1495
+ navHtml += '<button type="button" data-nav="' + i +'" tabindex="-1" aria-controls="' + slideId + '" ' + hiddenStr + ' aria-label="' + navStr + (i + 1) +'"></button>';
1496
+ }
1497
+ navHtml = '<div class="tns-nav" aria-label="Carousel Pagination">' + navHtml + '</div>';
1498
+ outerWrapper.insertAdjacentHTML(getInsertPosition(options.navPosition), navHtml);
1499
+
1500
+ navContainer = outerWrapper.querySelector('.tns-nav');
1501
+ navItems = navContainer.children;
1502
+ }
1503
+
1504
+ updateNavVisibility();
1505
+
1506
+ // add transition
1507
+ if (TRANSITIONDURATION) {
1508
+ var prefix = TRANSITIONDURATION.substring(0, TRANSITIONDURATION.length - 18).toLowerCase(),
1509
+ str = 'transition: all ' + speed / 1000 + 's';
1510
+
1511
+ if (prefix) {
1512
+ str = '-' + prefix + '-' + str;
1513
+ }
1514
+
1515
+ addCSSRule(sheet, '[aria-controls^=' + slideId + '-item]', str, getCssRulesLength(sheet));
1516
+ }
1517
+
1518
+ setAttrs(navItems[navCurrentIndex], {'aria-label': navStr + (navCurrentIndex + 1) + navStrCurrent});
1519
+ removeAttrs(navItems[navCurrentIndex], 'tabindex');
1520
+ addClass(navItems[navCurrentIndex], navActiveClass);
1521
+
1522
+ // add events
1523
+ addEvents(navContainer, navEvents);
1524
+ }
1525
+
1526
+
1527
+
1528
+ // == controlsInit ==
1529
+ if (hasControls) {
1530
+ if (!controlsContainer && (!prevButton || !nextButton)) {
1531
+ outerWrapper.insertAdjacentHTML(getInsertPosition(options.controlsPosition), '<div class="tns-controls" aria-label="Carousel Navigation" tabindex="0"><button type="button" data-controls="prev" tabindex="-1" aria-controls="' + slideId +'">' + controlsText[0] + '</button><button type="button" data-controls="next" tabindex="-1" aria-controls="' + slideId +'">' + controlsText[1] + '</button></div>');
1532
+
1533
+ controlsContainer = outerWrapper.querySelector('.tns-controls');
1534
+ }
1535
+
1536
+ if (!prevButton || !nextButton) {
1537
+ prevButton = controlsContainer.children[0];
1538
+ nextButton = controlsContainer.children[1];
1539
+ }
1540
+
1541
+ if (options.controlsContainer) {
1542
+ setAttrs(controlsContainer, {
1543
+ 'aria-label': 'Carousel Navigation',
1544
+ 'tabindex': '0'
1545
+ });
1546
+ }
1547
+
1548
+ if (options.controlsContainer || (options.prevButton && options.nextButton)) {
1549
+ setAttrs([prevButton, nextButton], {
1550
+ 'aria-controls': slideId,
1551
+ 'tabindex': '-1',
1552
+ });
1553
+ }
1554
+
1555
+ if (options.controlsContainer || (options.prevButton && options.nextButton)) {
1556
+ setAttrs(prevButton, {'data-controls' : 'prev'});
1557
+ setAttrs(nextButton, {'data-controls' : 'next'});
1558
+ }
1559
+
1560
+ prevIsButton = isButton(prevButton);
1561
+ nextIsButton = isButton(nextButton);
1562
+
1563
+ updateControlsStatus();
1564
+
1565
+ // add events
1566
+ if (controlsContainer) {
1567
+ addEvents(controlsContainer, controlsEvents);
1568
+ } else {
1569
+ addEvents(prevButton, controlsEvents);
1570
+ addEvents(nextButton, controlsEvents);
1571
+ }
1572
+ }
1573
+
1574
+ // hide tools if needed
1575
+ disableUI();
1576
+ }
1577
+
1578
+ function initEvents () {
1579
+ // add events
1580
+ if (carousel && TRANSITIONEND) {
1581
+ var eve = {};
1582
+ eve[TRANSITIONEND] = onTransitionEnd;
1583
+ addEvents(container, eve);
1584
+ }
1585
+
1586
+ if (touch) { addEvents(container, touchEvents, options.preventScrollOnTouch); }
1587
+ if (mouseDrag) { addEvents(container, dragEvents); }
1588
+ if (arrowKeys) { addEvents(doc, docmentKeydownEvent); }
1589
+
1590
+ if (nested === 'inner') {
1591
+ events.on('outerResized', function () {
1592
+ resizeTasks();
1593
+ events.emit('innerLoaded', info());
1594
+ });
1595
+ } else if (responsive || fixedWidth || autoWidth || autoHeight || !horizontal) {
1596
+ addEvents(win, {'resize': onResize});
1597
+ }
1598
+
1599
+ if (autoHeight) {
1600
+ if (nested === 'outer') {
1601
+ events.on('innerLoaded', doAutoHeight);
1602
+ } else if (!disable) { doAutoHeight(); }
1603
+ }
1604
+
1605
+ doLazyLoad();
1606
+ if (disable) { disableSlider(); } else if (freeze) { freezeSlider(); }
1607
+
1608
+ events.on('indexChanged', additionalUpdates);
1609
+ if (nested === 'inner') { events.emit('innerLoaded', info()); }
1610
+ if (typeof onInit === 'function') { onInit(info()); }
1611
+ isOn = true;
1612
+ }
1613
+
1614
+ function destroy () {
1615
+ // sheet
1616
+ sheet.disabled = true;
1617
+ if (sheet.ownerNode) { sheet.ownerNode.remove(); }
1618
+
1619
+ // remove win event listeners
1620
+ removeEvents(win, {'resize': onResize});
1621
+
1622
+ // arrowKeys, controls, nav
1623
+ if (arrowKeys) { removeEvents(doc, docmentKeydownEvent); }
1624
+ if (controlsContainer) { removeEvents(controlsContainer, controlsEvents); }
1625
+ if (navContainer) { removeEvents(navContainer, navEvents); }
1626
+
1627
+ // autoplay
1628
+ removeEvents(container, hoverEvents);
1629
+ removeEvents(container, visibilityEvent);
1630
+ if (autoplayButton) { removeEvents(autoplayButton, {'click': toggleAutoplay}); }
1631
+ if (autoplay) { clearInterval(autoplayTimer); }
1632
+
1633
+ // container
1634
+ if (carousel && TRANSITIONEND) {
1635
+ var eve = {};
1636
+ eve[TRANSITIONEND] = onTransitionEnd;
1637
+ removeEvents(container, eve);
1638
+ }
1639
+ if (touch) { removeEvents(container, touchEvents); }
1640
+ if (mouseDrag) { removeEvents(container, dragEvents); }
1641
+
1642
+ // cache Object values in options && reset HTML
1643
+ var htmlList = [containerHTML, controlsContainerHTML, prevButtonHTML, nextButtonHTML, navContainerHTML, autoplayButtonHTML];
1644
+
1645
+ tnsList.forEach(function(item, i) {
1646
+ var el = item === 'container' ? outerWrapper : options[item];
1647
+
1648
+ if (typeof el === 'object' && el) {
1649
+ var prevEl = el.previousElementSibling ? el.previousElementSibling : false,
1650
+ parentEl = el.parentNode;
1651
+ el.outerHTML = htmlList[i];
1652
+ options[item] = prevEl ? prevEl.nextElementSibling : parentEl.firstElementChild;
1653
+ }
1654
+ });
1655
+
1656
+
1657
+ // reset variables
1658
+ tnsList = animateIn = animateOut = animateDelay = animateNormal = horizontal = outerWrapper = innerWrapper = container = containerParent = containerHTML = slideItems = slideCount = breakpointZone = windowWidth = autoWidth = fixedWidth = edgePadding = gutter = viewport = items = slideBy = viewportMax = arrowKeys = speed = rewind = loop = autoHeight = sheet = lazyload = slidePositions = slideItemsOut = cloneCount = slideCountNew = hasRightDeadZone = rightBoundary = updateIndexBeforeTransform = transformAttr = transformPrefix = transformPostfix = getIndexMax = index = indexCached = indexMin = indexMax = resizeTimer = swipeAngle = moveDirectionExpected = running = onInit = events = newContainerClasses = slideId = disable = disabled = freezable = freeze = frozen = controlsEvents = navEvents = hoverEvents = visibilityEvent = docmentKeydownEvent = touchEvents = dragEvents = hasControls = hasNav = navAsThumbnails = hasAutoplay = hasTouch = hasMouseDrag = slideActiveClass = imgCompleteClass = imgEvents = imgsComplete = controls = controlsText = controlsContainer = controlsContainerHTML = prevButton = nextButton = prevIsButton = nextIsButton = nav = navContainer = navContainerHTML = navItems = pages = pagesCached = navClicked = navCurrentIndex = navCurrentIndexCached = navActiveClass = navStr = navStrCurrent = autoplay = autoplayTimeout = autoplayDirection = autoplayText = autoplayHoverPause = autoplayButton = autoplayButtonHTML = autoplayResetOnVisibility = autoplayHtmlStrings = autoplayTimer = animating = autoplayHoverPaused = autoplayUserPaused = autoplayVisibilityPaused = initPosition = lastPosition = translateInit = disX = disY = panStart = rafIndex = getDist = touch = mouseDrag = null;
1659
+ // check variables
1660
+ // [animateIn, animateOut, animateDelay, animateNormal, horizontal, outerWrapper, innerWrapper, container, containerParent, containerHTML, slideItems, slideCount, breakpointZone, windowWidth, autoWidth, fixedWidth, edgePadding, gutter, viewport, items, slideBy, viewportMax, arrowKeys, speed, rewind, loop, autoHeight, sheet, lazyload, slidePositions, slideItemsOut, cloneCount, slideCountNew, hasRightDeadZone, rightBoundary, updateIndexBeforeTransform, transformAttr, transformPrefix, transformPostfix, getIndexMax, index, indexCached, indexMin, indexMax, resizeTimer, swipeAngle, moveDirectionExpected, running, onInit, events, newContainerClasses, slideId, disable, disabled, freezable, freeze, frozen, controlsEvents, navEvents, hoverEvents, visibilityEvent, docmentKeydownEvent, touchEvents, dragEvents, hasControls, hasNav, navAsThumbnails, hasAutoplay, hasTouch, hasMouseDrag, slideActiveClass, imgCompleteClass, imgEvents, imgsComplete, controls, controlsText, controlsContainer, controlsContainerHTML, prevButton, nextButton, prevIsButton, nextIsButton, nav, navContainer, navContainerHTML, navItems, pages, pagesCached, navClicked, navCurrentIndex, navCurrentIndexCached, navActiveClass, navStr, navStrCurrent, autoplay, autoplayTimeout, autoplayDirection, autoplayText, autoplayHoverPause, autoplayButton, autoplayButtonHTML, autoplayResetOnVisibility, autoplayHtmlStrings, autoplayTimer, animating, autoplayHoverPaused, autoplayUserPaused, autoplayVisibilityPaused, initPosition, lastPosition, translateInit, disX, disY, panStart, rafIndex, getDist, touch, mouseDrag ].forEach(function(item) { if (item !== null) { console.log(item); } });
1661
+
1662
+ for (var a in this) {
1663
+ if (a !== 'rebuild') { this[a] = null; }
1664
+ }
1665
+ isOn = false;
1666
+ }
1667
+
1668
+ // === ON RESIZE ===
1669
+ // responsive || fixedWidth || autoWidth || !horizontal
1670
+ function onResize (e) {
1671
+ raf(function(){ resizeTasks(getEvent(e)); });
1672
+ }
1673
+
1674
+ function resizeTasks (e) {
1675
+ if (!isOn) { return; }
1676
+ if (nested === 'outer') { events.emit('outerResized', info(e)); }
1677
+ windowWidth = getWindowWidth();
1678
+ var bpChanged,
1679
+ breakpointZoneTem = breakpointZone,
1680
+ needContainerTransform = false;
1681
+
1682
+ if (responsive) {
1683
+ setBreakpointZone();
1684
+ bpChanged = breakpointZoneTem !== breakpointZone;
1685
+ // if (hasRightDeadZone) { needContainerTransform = true; } // *?
1686
+ if (bpChanged) { events.emit('newBreakpointStart', info(e)); }
1687
+ }
1688
+
1689
+ var indChanged,
1690
+ itemsChanged,
1691
+ itemsTem = items,
1692
+ disableTem = disable,
1693
+ freezeTem = freeze,
1694
+ arrowKeysTem = arrowKeys,
1695
+ controlsTem = controls,
1696
+ navTem = nav,
1697
+ touchTem = touch,
1698
+ mouseDragTem = mouseDrag,
1699
+ autoplayTem = autoplay,
1700
+ autoplayHoverPauseTem = autoplayHoverPause,
1701
+ autoplayResetOnVisibilityTem = autoplayResetOnVisibility,
1702
+ indexTem = index;
1703
+
1704
+ if (bpChanged) {
1705
+ var fixedWidthTem = fixedWidth,
1706
+ autoHeightTem = autoHeight,
1707
+ controlsTextTem = controlsText,
1708
+ centerTem = center,
1709
+ autoplayTextTem = autoplayText;
1710
+
1711
+ if (!CSSMQ) {
1712
+ var gutterTem = gutter,
1713
+ edgePaddingTem = edgePadding;
1714
+ }
1715
+ }
1716
+
1717
+ // get option:
1718
+ // fixed width: viewport, fixedWidth, gutter => items
1719
+ // others: window width => all variables
1720
+ // all: items => slideBy
1721
+ arrowKeys = getOption('arrowKeys');
1722
+ controls = getOption('controls');
1723
+ nav = getOption('nav');
1724
+ touch = getOption('touch');
1725
+ center = getOption('center');
1726
+ mouseDrag = getOption('mouseDrag');
1727
+ autoplay = getOption('autoplay');
1728
+ autoplayHoverPause = getOption('autoplayHoverPause');
1729
+ autoplayResetOnVisibility = getOption('autoplayResetOnVisibility');
1730
+
1731
+ if (bpChanged) {
1732
+ disable = getOption('disable');
1733
+ fixedWidth = getOption('fixedWidth');
1734
+ speed = getOption('speed');
1735
+ autoHeight = getOption('autoHeight');
1736
+ controlsText = getOption('controlsText');
1737
+ autoplayText = getOption('autoplayText');
1738
+ autoplayTimeout = getOption('autoplayTimeout');
1739
+
1740
+ if (!CSSMQ) {
1741
+ edgePadding = getOption('edgePadding');
1742
+ gutter = getOption('gutter');
1743
+ }
1744
+ }
1745
+ // update options
1746
+ resetVariblesWhenDisable(disable);
1747
+
1748
+ viewport = getViewportWidth(); // <= edgePadding, gutter
1749
+ if ((!horizontal || autoWidth) && !disable) {
1750
+ setSlidePositions();
1751
+ if (!horizontal) {
1752
+ updateContentWrapperHeight(); // <= setSlidePositions
1753
+ needContainerTransform = true;
1754
+ }
1755
+ }
1756
+ if (fixedWidth || autoWidth) {
1757
+ rightBoundary = getRightBoundary(); // autoWidth: <= viewport, slidePositions, gutter
1758
+ // fixedWidth: <= viewport, fixedWidth, gutter
1759
+ indexMax = getIndexMax(); // autoWidth: <= rightBoundary, slidePositions
1760
+ // fixedWidth: <= rightBoundary, fixedWidth, gutter
1761
+ }
1762
+
1763
+ if (bpChanged || fixedWidth) {
1764
+ items = getOption('items');
1765
+ slideBy = getOption('slideBy');
1766
+ itemsChanged = items !== itemsTem;
1767
+
1768
+ if (itemsChanged) {
1769
+ if (!fixedWidth && !autoWidth) { indexMax = getIndexMax(); } // <= items
1770
+ // check index before transform in case
1771
+ // slider reach the right edge then items become bigger
1772
+ updateIndex();
1773
+ }
1774
+ }
1775
+
1776
+ if (bpChanged) {
1777
+ if (disable !== disableTem) {
1778
+ if (disable) {
1779
+ disableSlider();
1780
+ } else {
1781
+ enableSlider(); // <= slidePositions, rightBoundary, indexMax
1782
+ }
1783
+ }
1784
+ }
1785
+
1786
+ if (freezable && (bpChanged || fixedWidth || autoWidth)) {
1787
+ freeze = getFreeze(); // <= autoWidth: slidePositions, gutter, viewport, rightBoundary
1788
+ // <= fixedWidth: fixedWidth, gutter, rightBoundary
1789
+ // <= others: items
1790
+
1791
+ if (freeze !== freezeTem) {
1792
+ if (freeze) {
1793
+ doContainerTransform(getContainerTransformValue(getStartIndex(0)));
1794
+ freezeSlider();
1795
+ } else {
1796
+ unfreezeSlider();
1797
+ needContainerTransform = true;
1798
+ }
1799
+ }
1800
+ }
1801
+
1802
+ resetVariblesWhenDisable(disable || freeze); // controls, nav, touch, mouseDrag, arrowKeys, autoplay, autoplayHoverPause, autoplayResetOnVisibility
1803
+ if (!autoplay) { autoplayHoverPause = autoplayResetOnVisibility = false; }
1804
+
1805
+ if (arrowKeys !== arrowKeysTem) {
1806
+ arrowKeys ?
1807
+ addEvents(doc, docmentKeydownEvent) :
1808
+ removeEvents(doc, docmentKeydownEvent);
1809
+ }
1810
+ if (controls !== controlsTem) {
1811
+ if (controls) {
1812
+ if (controlsContainer) {
1813
+ showElement(controlsContainer);
1814
+ } else {
1815
+ if (prevButton) { showElement(prevButton); }
1816
+ if (nextButton) { showElement(nextButton); }
1817
+ }
1818
+ } else {
1819
+ if (controlsContainer) {
1820
+ hideElement(controlsContainer);
1821
+ } else {
1822
+ if (prevButton) { hideElement(prevButton); }
1823
+ if (nextButton) { hideElement(nextButton); }
1824
+ }
1825
+ }
1826
+ }
1827
+ if (nav !== navTem) {
1828
+ if (nav) {
1829
+ showElement(navContainer);
1830
+ updateNavVisibility();
1831
+ } else {
1832
+ hideElement(navContainer);
1833
+ }
1834
+ }
1835
+ if (touch !== touchTem) {
1836
+ touch ?
1837
+ addEvents(container, touchEvents, options.preventScrollOnTouch) :
1838
+ removeEvents(container, touchEvents);
1839
+ }
1840
+ if (mouseDrag !== mouseDragTem) {
1841
+ mouseDrag ?
1842
+ addEvents(container, dragEvents) :
1843
+ removeEvents(container, dragEvents);
1844
+ }
1845
+ if (autoplay !== autoplayTem) {
1846
+ if (autoplay) {
1847
+ if (autoplayButton) { showElement(autoplayButton); }
1848
+ if (!animating && !autoplayUserPaused) { startAutoplay(); }
1849
+ } else {
1850
+ if (autoplayButton) { hideElement(autoplayButton); }
1851
+ if (animating) { stopAutoplay(); }
1852
+ }
1853
+ }
1854
+ if (autoplayHoverPause !== autoplayHoverPauseTem) {
1855
+ autoplayHoverPause ?
1856
+ addEvents(container, hoverEvents) :
1857
+ removeEvents(container, hoverEvents);
1858
+ }
1859
+ if (autoplayResetOnVisibility !== autoplayResetOnVisibilityTem) {
1860
+ autoplayResetOnVisibility ?
1861
+ addEvents(doc, visibilityEvent) :
1862
+ removeEvents(doc, visibilityEvent);
1863
+ }
1864
+
1865
+ if (bpChanged) {
1866
+ if (fixedWidth !== fixedWidthTem || center !== centerTem) { needContainerTransform = true; }
1867
+
1868
+ if (autoHeight !== autoHeightTem) {
1869
+ if (!autoHeight) { innerWrapper.style.height = ''; }
1870
+ }
1871
+
1872
+ if (controls && controlsText !== controlsTextTem) {
1873
+ prevButton.innerHTML = controlsText[0];
1874
+ nextButton.innerHTML = controlsText[1];
1875
+ }
1876
+
1877
+ if (autoplayButton && autoplayText !== autoplayTextTem) {
1878
+ var i = autoplay ? 1 : 0,
1879
+ html = autoplayButton.innerHTML,
1880
+ len = html.length - autoplayTextTem[i].length;
1881
+ if (html.substring(len) === autoplayTextTem[i]) {
1882
+ autoplayButton.innerHTML = html.substring(0, len) + autoplayText[i];
1883
+ }
1884
+ }
1885
+ } else {
1886
+ if (center && (fixedWidth || autoWidth)) { needContainerTransform = true; }
1887
+ }
1888
+
1889
+ if (itemsChanged || fixedWidth && !autoWidth) {
1890
+ pages = getPages();
1891
+ updateNavVisibility();
1892
+ }
1893
+
1894
+ indChanged = index !== indexTem;
1895
+ if (indChanged) {
1896
+ events.emit('indexChanged', info());
1897
+ needContainerTransform = true;
1898
+ } else if (itemsChanged) {
1899
+ if (!indChanged) { additionalUpdates(); }
1900
+ } else if (fixedWidth || autoWidth) {
1901
+ doLazyLoad();
1902
+ updateSlideStatus();
1903
+ updateLiveRegion();
1904
+ }
1905
+
1906
+ if (itemsChanged && !carousel) { updateGallerySlidePositions(); }
1907
+
1908
+ if (!disable && !freeze) {
1909
+ // non-mediaqueries: IE8
1910
+ if (bpChanged && !CSSMQ) {
1911
+ // middle wrapper styles
1912
+
1913
+ // inner wrapper styles
1914
+ if (edgePadding !== edgePaddingTem || gutter !== gutterTem) {
1915
+ innerWrapper.style.cssText = getInnerWrapperStyles(edgePadding, gutter, fixedWidth, speed, autoHeight);
1916
+ }
1917
+
1918
+ if (horizontal) {
1919
+ // container styles
1920
+ if (carousel) {
1921
+ container.style.width = getContainerWidth(fixedWidth, gutter, items);
1922
+ }
1923
+
1924
+ // slide styles
1925
+ var str = getSlideWidthStyle(fixedWidth, gutter, items) +
1926
+ getSlideGutterStyle(gutter);
1927
+
1928
+ // remove the last line and
1929
+ // add new styles
1930
+ removeCSSRule(sheet, getCssRulesLength(sheet) - 1);
1931
+ addCSSRule(sheet, '#' + slideId + ' > .tns-item', str, getCssRulesLength(sheet));
1932
+ }
1933
+ }
1934
+
1935
+ // auto height
1936
+ if (autoHeight) { doAutoHeight(); }
1937
+
1938
+ if (needContainerTransform) {
1939
+ doContainerTransformSilent();
1940
+ indexCached = index;
1941
+ }
1942
+ }
1943
+
1944
+ if (bpChanged) { events.emit('newBreakpointEnd', info(e)); }
1945
+ }
1946
+
1947
+
1948
+
1949
+
1950
+
1951
+ // === INITIALIZATION FUNCTIONS === //
1952
+ function getFreeze () {
1953
+ if (!fixedWidth && !autoWidth) {
1954
+ var a = center ? items - (items - 1) / 2 : items;
1955
+ return slideCount <= a;
1956
+ }
1957
+
1958
+ var width = fixedWidth ? (fixedWidth + gutter) * slideCount : slidePositions[slideCount],
1959
+ vp = edgePadding ? viewport + edgePadding * 2 : viewport + gutter;
1960
+
1961
+ if (center) {
1962
+ vp -= fixedWidth ? (viewport - fixedWidth) / 2 : (viewport - (slidePositions[index + 1] - slidePositions[index] - gutter)) / 2;
1963
+ }
1964
+
1965
+ return width <= vp;
1966
+ }
1967
+
1968
+ function setBreakpointZone () {
1969
+ breakpointZone = 0;
1970
+ for (var bp in responsive) {
1971
+ bp = parseInt(bp); // convert string to number
1972
+ if (windowWidth >= bp) { breakpointZone = bp; }
1973
+ }
1974
+ }
1975
+
1976
+ // (slideBy, indexMin, indexMax) => index
1977
+ var updateIndex = (function () {
1978
+ return loop ?
1979
+ carousel ?
1980
+ // loop + carousel
1981
+ function () {
1982
+ var leftEdge = indexMin,
1983
+ rightEdge = indexMax;
1984
+
1985
+ leftEdge += slideBy;
1986
+ rightEdge -= slideBy;
1987
+
1988
+ // adjust edges when has edge paddings
1989
+ // or fixed-width slider with extra space on the right side
1990
+ if (edgePadding) {
1991
+ leftEdge += 1;
1992
+ rightEdge -= 1;
1993
+ } else if (fixedWidth) {
1994
+ if ((viewport + gutter)%(fixedWidth + gutter)) { rightEdge -= 1; }
1995
+ }
1996
+
1997
+ if (cloneCount) {
1998
+ if (index > rightEdge) {
1999
+ index -= slideCount;
2000
+ } else if (index < leftEdge) {
2001
+ index += slideCount;
2002
+ }
2003
+ }
2004
+ } :
2005
+ // loop + gallery
2006
+ function() {
2007
+ if (index > indexMax) {
2008
+ while (index >= indexMin + slideCount) { index -= slideCount; }
2009
+ } else if (index < indexMin) {
2010
+ while (index <= indexMax - slideCount) { index += slideCount; }
2011
+ }
2012
+ } :
2013
+ // non-loop
2014
+ function() {
2015
+ index = Math.max(indexMin, Math.min(indexMax, index));
2016
+ };
2017
+ })();
2018
+
2019
+ function disableUI () {
2020
+ if (!autoplay && autoplayButton) { hideElement(autoplayButton); }
2021
+ if (!nav && navContainer) { hideElement(navContainer); }
2022
+ if (!controls) {
2023
+ if (controlsContainer) {
2024
+ hideElement(controlsContainer);
2025
+ } else {
2026
+ if (prevButton) { hideElement(prevButton); }
2027
+ if (nextButton) { hideElement(nextButton); }
2028
+ }
2029
+ }
2030
+ }
2031
+
2032
+ function enableUI () {
2033
+ if (autoplay && autoplayButton) { showElement(autoplayButton); }
2034
+ if (nav && navContainer) { showElement(navContainer); }
2035
+ if (controls) {
2036
+ if (controlsContainer) {
2037
+ showElement(controlsContainer);
2038
+ } else {
2039
+ if (prevButton) { showElement(prevButton); }
2040
+ if (nextButton) { showElement(nextButton); }
2041
+ }
2042
+ }
2043
+ }
2044
+
2045
+ function freezeSlider () {
2046
+ if (frozen) { return; }
2047
+
2048
+ // remove edge padding from inner wrapper
2049
+ if (edgePadding) { innerWrapper.style.margin = '0px'; }
2050
+
2051
+ // add class tns-transparent to cloned slides
2052
+ if (cloneCount) {
2053
+ var str = 'tns-transparent';
2054
+ for (var i = cloneCount; i--;) {
2055
+ if (carousel) { addClass(slideItems[i], str); }
2056
+ addClass(slideItems[slideCountNew - i - 1], str);
2057
+ }
2058
+ }
2059
+
2060
+ // update tools
2061
+ disableUI();
2062
+
2063
+ frozen = true;
2064
+ }
2065
+
2066
+ function unfreezeSlider () {
2067
+ if (!frozen) { return; }
2068
+
2069
+ // restore edge padding for inner wrapper
2070
+ // for mordern browsers
2071
+ if (edgePadding && CSSMQ) { innerWrapper.style.margin = ''; }
2072
+
2073
+ // remove class tns-transparent to cloned slides
2074
+ if (cloneCount) {
2075
+ var str = 'tns-transparent';
2076
+ for (var i = cloneCount; i--;) {
2077
+ if (carousel) { removeClass(slideItems[i], str); }
2078
+ removeClass(slideItems[slideCountNew - i - 1], str);
2079
+ }
2080
+ }
2081
+
2082
+ // update tools
2083
+ enableUI();
2084
+
2085
+ frozen = false;
2086
+ }
2087
+
2088
+ function disableSlider () {
2089
+ if (disabled) { return; }
2090
+
2091
+ sheet.disabled = true;
2092
+ container.className = container.className.replace(newContainerClasses.substring(1), '');
2093
+ removeAttrs(container, ['style']);
2094
+ if (loop) {
2095
+ for (var j = cloneCount; j--;) {
2096
+ if (carousel) { hideElement(slideItems[j]); }
2097
+ hideElement(slideItems[slideCountNew - j - 1]);
2098
+ }
2099
+ }
2100
+
2101
+ // vertical slider
2102
+ if (!horizontal || !carousel) { removeAttrs(innerWrapper, ['style']); }
2103
+
2104
+ // gallery
2105
+ if (!carousel) {
2106
+ for (var i = index, l = index + slideCount; i < l; i++) {
2107
+ var item = slideItems[i];
2108
+ removeAttrs(item, ['style']);
2109
+ removeClass(item, animateIn);
2110
+ removeClass(item, animateNormal);
2111
+ }
2112
+ }
2113
+
2114
+ // update tools
2115
+ disableUI();
2116
+
2117
+ disabled = true;
2118
+ }
2119
+
2120
+ function enableSlider () {
2121
+ if (!disabled) { return; }
2122
+
2123
+ sheet.disabled = false;
2124
+ container.className += newContainerClasses;
2125
+ doContainerTransformSilent();
2126
+
2127
+ if (loop) {
2128
+ for (var j = cloneCount; j--;) {
2129
+ if (carousel) { showElement(slideItems[j]); }
2130
+ showElement(slideItems[slideCountNew - j - 1]);
2131
+ }
2132
+ }
2133
+
2134
+ // gallery
2135
+ if (!carousel) {
2136
+ for (var i = index, l = index + slideCount; i < l; i++) {
2137
+ var item = slideItems[i],
2138
+ classN = i < index + items ? animateIn : animateNormal;
2139
+ item.style.left = (i - index) * 100 / items + '%';
2140
+ addClass(item, classN);
2141
+ }
2142
+ }
2143
+
2144
+ // update tools
2145
+ enableUI();
2146
+
2147
+ disabled = false;
2148
+ }
2149
+
2150
+ function updateLiveRegion () {
2151
+ var str = getLiveRegionStr();
2152
+ if (liveregionCurrent.innerHTML !== str) { liveregionCurrent.innerHTML = str; }
2153
+ }
2154
+
2155
+ function getLiveRegionStr () {
2156
+ var arr = getVisibleSlideRange(),
2157
+ start = arr[0] + 1,
2158
+ end = arr[1] + 1;
2159
+ return start === end ? start + '' : start + ' to ' + end;
2160
+ }
2161
+
2162
+ function getVisibleSlideRange (val) {
2163
+ if (val == null) { val = getContainerTransformValue(); }
2164
+ var start = index, end, rangestart, rangeend;
2165
+
2166
+ // get range start, range end for autoWidth and fixedWidth
2167
+ if (center || edgePadding) {
2168
+ if (autoWidth || fixedWidth) {
2169
+ rangestart = - (parseFloat(val) + edgePadding);
2170
+ rangeend = rangestart + viewport + edgePadding * 2;
2171
+ }
2172
+ } else {
2173
+ if (autoWidth) {
2174
+ rangestart = slidePositions[index];
2175
+ rangeend = rangestart + viewport;
2176
+ }
2177
+ }
2178
+
2179
+ // get start, end
2180
+ // - check auto width
2181
+ if (autoWidth) {
2182
+ slidePositions.forEach(function(point, i) {
2183
+ if (i < slideCountNew) {
2184
+ if ((center || edgePadding) && point <= rangestart + 0.5) { start = i; }
2185
+ if (rangeend - point >= 0.5) { end = i; }
2186
+ }
2187
+ });
2188
+
2189
+ // - check percentage width, fixed width
2190
+ } else {
2191
+
2192
+ if (fixedWidth) {
2193
+ var cell = fixedWidth + gutter;
2194
+ if (center || edgePadding) {
2195
+ start = Math.floor(rangestart/cell);
2196
+ end = Math.ceil(rangeend/cell - 1);
2197
+ } else {
2198
+ end = start + Math.ceil(viewport/cell) - 1;
2199
+ }
2200
+
2201
+ } else {
2202
+ if (center || edgePadding) {
2203
+ var a = items - 1;
2204
+ if (center) {
2205
+ start -= a / 2;
2206
+ end = index + a / 2;
2207
+ } else {
2208
+ end = index + a;
2209
+ }
2210
+
2211
+ if (edgePadding) {
2212
+ var b = edgePadding * items / viewport;
2213
+ start -= b;
2214
+ end += b;
2215
+ }
2216
+
2217
+ start = Math.floor(start);
2218
+ end = Math.ceil(end);
2219
+ } else {
2220
+ end = start + items - 1;
2221
+ }
2222
+ }
2223
+
2224
+ start = Math.max(start, 0);
2225
+ end = Math.min(end, slideCountNew - 1);
2226
+ }
2227
+
2228
+ return [start, end];
2229
+ }
2230
+
2231
+ function doLazyLoad () {
2232
+ if (lazyload && !disable) {
2233
+ var arg = getVisibleSlideRange();
2234
+ arg.push(lazyloadSelector);
2235
+
2236
+ getImageArray.apply(null, arg).forEach(function (img) {
2237
+ if (!hasClass(img, imgCompleteClass)) {
2238
+ // stop propagation transitionend event to container
2239
+ var eve = {};
2240
+ eve[TRANSITIONEND] = function (e) { e.stopPropagation(); };
2241
+ addEvents(img, eve);
2242
+
2243
+ addEvents(img, imgEvents);
2244
+
2245
+ // update src
2246
+ img.src = getAttr(img, 'data-src');
2247
+
2248
+ // update srcset
2249
+ var srcset = getAttr(img, 'data-srcset');
2250
+ if (srcset) { img.srcset = srcset; }
2251
+
2252
+ addClass(img, 'loading');
2253
+ }
2254
+ });
2255
+ }
2256
+ }
2257
+
2258
+ function onImgLoaded (e) {
2259
+ imgLoaded(getTarget(e));
2260
+ }
2261
+
2262
+ function onImgFailed (e) {
2263
+ imgFailed(getTarget(e));
2264
+ }
2265
+
2266
+ function imgLoaded (img) {
2267
+ addClass(img, 'loaded');
2268
+ imgCompleted(img);
2269
+ }
2270
+
2271
+ function imgFailed (img) {
2272
+ addClass(img, 'failed');
2273
+ imgCompleted(img);
2274
+ }
2275
+
2276
+ function imgCompleted (img) {
2277
+ addClass(img, imgCompleteClass);
2278
+ removeClass(img, 'loading');
2279
+ removeEvents(img, imgEvents);
2280
+ }
2281
+
2282
+ function getImageArray (start, end, imgSelector) {
2283
+ var imgs = [];
2284
+ if (!imgSelector) { imgSelector = 'img'; }
2285
+
2286
+ while (start <= end) {
2287
+ forEach(slideItems[start].querySelectorAll(imgSelector), function (img) { imgs.push(img); });
2288
+ start++;
2289
+ }
2290
+
2291
+ return imgs;
2292
+ }
2293
+
2294
+ // check if all visible images are loaded
2295
+ // and update container height if it's done
2296
+ function doAutoHeight () {
2297
+ var imgs = getImageArray.apply(null, getVisibleSlideRange());
2298
+ raf(function(){ imgsLoadedCheck(imgs, updateInnerWrapperHeight); });
2299
+ }
2300
+
2301
+ function imgsLoadedCheck (imgs, cb) {
2302
+ // execute callback function if all images are complete
2303
+ if (imgsComplete) { return cb(); }
2304
+
2305
+ // check image classes
2306
+ imgs.forEach(function (img, index) {
2307
+ if (!lazyload && img.complete) { imgCompleted(img); } // Check image.complete
2308
+ if (hasClass(img, imgCompleteClass)) { imgs.splice(index, 1); }
2309
+ });
2310
+
2311
+ // execute callback function if selected images are all complete
2312
+ if (!imgs.length) { return cb(); }
2313
+
2314
+ // otherwise execute this functiona again
2315
+ raf(function(){ imgsLoadedCheck(imgs, cb); });
2316
+ }
2317
+
2318
+ function additionalUpdates () {
2319
+ doLazyLoad();
2320
+ updateSlideStatus();
2321
+ updateLiveRegion();
2322
+ updateControlsStatus();
2323
+ updateNavStatus();
2324
+ }
2325
+
2326
+
2327
+ function update_carousel_transition_duration () {
2328
+ if (carousel && autoHeight) {
2329
+ middleWrapper.style[TRANSITIONDURATION] = speed / 1000 + 's';
2330
+ }
2331
+ }
2332
+
2333
+ function getMaxSlideHeight (slideStart, slideRange) {
2334
+ var heights = [];
2335
+ for (var i = slideStart, l = Math.min(slideStart + slideRange, slideCountNew); i < l; i++) {
2336
+ heights.push(slideItems[i].offsetHeight);
2337
+ }
2338
+
2339
+ return Math.max.apply(null, heights);
2340
+ }
2341
+
2342
+ // update inner wrapper height
2343
+ // 1. get the max-height of the visible slides
2344
+ // 2. set transitionDuration to speed
2345
+ // 3. update inner wrapper height to max-height
2346
+ // 4. set transitionDuration to 0s after transition done
2347
+ function updateInnerWrapperHeight () {
2348
+ var maxHeight = autoHeight ? getMaxSlideHeight(index, items) : getMaxSlideHeight(cloneCount, slideCount),
2349
+ wp = middleWrapper ? middleWrapper : innerWrapper;
2350
+
2351
+ if (wp.style.height !== maxHeight) { wp.style.height = maxHeight + 'px'; }
2352
+ }
2353
+
2354
+ // get the distance from the top edge of the first slide to each slide
2355
+ // (init) => slidePositions
2356
+ function setSlidePositions () {
2357
+ slidePositions = [0];
2358
+ var attr = horizontal ? 'left' : 'top',
2359
+ attr2 = horizontal ? 'right' : 'bottom',
2360
+ base = slideItems[0].getBoundingClientRect()[attr];
2361
+
2362
+ forEach(slideItems, function(item, i) {
2363
+ // skip the first slide
2364
+ if (i) { slidePositions.push(item.getBoundingClientRect()[attr] - base); }
2365
+ // add the end edge
2366
+ if (i === slideCountNew - 1) { slidePositions.push(item.getBoundingClientRect()[attr2] - base); }
2367
+ });
2368
+ }
2369
+
2370
+ // update slide
2371
+ function updateSlideStatus () {
2372
+ var range = getVisibleSlideRange(),
2373
+ start = range[0],
2374
+ end = range[1];
2375
+
2376
+ forEach(slideItems, function(item, i) {
2377
+ // show slides
2378
+ if (i >= start && i <= end) {
2379
+ if (hasAttr(item, 'aria-hidden')) {
2380
+ removeAttrs(item, ['aria-hidden', 'tabindex']);
2381
+ addClass(item, slideActiveClass);
2382
+ }
2383
+ // hide slides
2384
+ } else {
2385
+ if (!hasAttr(item, 'aria-hidden')) {
2386
+ setAttrs(item, {
2387
+ 'aria-hidden': 'true',
2388
+ 'tabindex': '-1'
2389
+ });
2390
+ removeClass(item, slideActiveClass);
2391
+ }
2392
+ }
2393
+ });
2394
+ }
2395
+
2396
+ // gallery: update slide position
2397
+ function updateGallerySlidePositions () {
2398
+ var l = index + Math.min(slideCount, items);
2399
+ for (var i = slideCountNew; i--;) {
2400
+ var item = slideItems[i];
2401
+
2402
+ if (i >= index && i < l) {
2403
+ // add transitions to visible slides when adjusting their positions
2404
+ addClass(item, 'tns-moving');
2405
+
2406
+ item.style.left = (i - index) * 100 / items + '%';
2407
+ addClass(item, animateIn);
2408
+ removeClass(item, animateNormal);
2409
+ } else if (item.style.left) {
2410
+ item.style.left = '';
2411
+ addClass(item, animateNormal);
2412
+ removeClass(item, animateIn);
2413
+ }
2414
+
2415
+ // remove outlet animation
2416
+ removeClass(item, animateOut);
2417
+ }
2418
+
2419
+ // removing '.tns-moving'
2420
+ setTimeout(function() {
2421
+ forEach(slideItems, function(el) {
2422
+ removeClass(el, 'tns-moving');
2423
+ });
2424
+ }, 300);
2425
+ }
2426
+
2427
+ // set tabindex on Nav
2428
+ function updateNavStatus () {
2429
+ // get current nav
2430
+ if (nav) {
2431
+ navCurrentIndex = navClicked >= 0 ? navClicked : getCurrentNavIndex();
2432
+ navClicked = -1;
2433
+
2434
+ if (navCurrentIndex !== navCurrentIndexCached) {
2435
+ var navPrev = navItems[navCurrentIndexCached],
2436
+ navCurrent = navItems[navCurrentIndex];
2437
+
2438
+ setAttrs(navPrev, {
2439
+ 'tabindex': '-1',
2440
+ 'aria-label': navStr + (navCurrentIndexCached + 1)
2441
+ });
2442
+ removeClass(navPrev, navActiveClass);
2443
+
2444
+ setAttrs(navCurrent, {'aria-label': navStr + (navCurrentIndex + 1) + navStrCurrent});
2445
+ removeAttrs(navCurrent, 'tabindex');
2446
+ addClass(navCurrent, navActiveClass);
2447
+
2448
+ navCurrentIndexCached = navCurrentIndex;
2449
+ }
2450
+ }
2451
+ }
2452
+
2453
+ function getLowerCaseNodeName (el) {
2454
+ return el.nodeName.toLowerCase();
2455
+ }
2456
+
2457
+ function isButton (el) {
2458
+ return getLowerCaseNodeName(el) === 'button';
2459
+ }
2460
+
2461
+ function isAriaDisabled (el) {
2462
+ return el.getAttribute('aria-disabled') === 'true';
2463
+ }
2464
+
2465
+ function disEnableElement (isButton, el, val) {
2466
+ if (isButton) {
2467
+ el.disabled = val;
2468
+ } else {
2469
+ el.setAttribute('aria-disabled', val.toString());
2470
+ }
2471
+ }
2472
+
2473
+ // set 'disabled' to true on controls when reach the edges
2474
+ function updateControlsStatus () {
2475
+ if (!controls || rewind || loop) { return; }
2476
+
2477
+ var prevDisabled = (prevIsButton) ? prevButton.disabled : isAriaDisabled(prevButton),
2478
+ nextDisabled = (nextIsButton) ? nextButton.disabled : isAriaDisabled(nextButton),
2479
+ disablePrev = (index <= indexMin) ? true : false,
2480
+ disableNext = (!rewind && index >= indexMax) ? true : false;
2481
+
2482
+ if (disablePrev && !prevDisabled) {
2483
+ disEnableElement(prevIsButton, prevButton, true);
2484
+ }
2485
+ if (!disablePrev && prevDisabled) {
2486
+ disEnableElement(prevIsButton, prevButton, false);
2487
+ }
2488
+ if (disableNext && !nextDisabled) {
2489
+ disEnableElement(nextIsButton, nextButton, true);
2490
+ }
2491
+ if (!disableNext && nextDisabled) {
2492
+ disEnableElement(nextIsButton, nextButton, false);
2493
+ }
2494
+ }
2495
+
2496
+ // set duration
2497
+ function resetDuration (el, str) {
2498
+ if (TRANSITIONDURATION) { el.style[TRANSITIONDURATION] = str; }
2499
+ }
2500
+
2501
+ function getSliderWidth () {
2502
+ return fixedWidth ? (fixedWidth + gutter) * slideCountNew : slidePositions[slideCountNew];
2503
+ }
2504
+
2505
+ function getCenterGap (num) {
2506
+ if (num == null) { num = index; }
2507
+
2508
+ var gap = edgePadding ? gutter : 0;
2509
+ return autoWidth ? ((viewport - gap) - (slidePositions[num + 1] - slidePositions[num] - gutter))/2 :
2510
+ fixedWidth ? (viewport - fixedWidth) / 2 :
2511
+ (items - 1) / 2;
2512
+ }
2513
+
2514
+ function getRightBoundary () {
2515
+ var gap = edgePadding ? gutter : 0,
2516
+ result = (viewport + gap) - getSliderWidth();
2517
+
2518
+ if (center && !loop) {
2519
+ result = fixedWidth ? - (fixedWidth + gutter) * (slideCountNew - 1) - getCenterGap() :
2520
+ getCenterGap(slideCountNew - 1) - slidePositions[slideCountNew - 1];
2521
+ }
2522
+ if (result > 0) { result = 0; }
2523
+
2524
+ return result;
2525
+ }
2526
+
2527
+ function getContainerTransformValue (num) {
2528
+ if (num == null) { num = index; }
2529
+
2530
+ var val;
2531
+ if (horizontal && !autoWidth) {
2532
+ if (fixedWidth) {
2533
+ val = - (fixedWidth + gutter) * num;
2534
+ if (center) { val += getCenterGap(); }
2535
+ } else {
2536
+ var denominator = TRANSFORM ? slideCountNew : items;
2537
+ if (center) { num -= getCenterGap(); }
2538
+ val = - num * 100 / denominator;
2539
+ }
2540
+ } else {
2541
+ val = - slidePositions[num];
2542
+ if (center && autoWidth) {
2543
+ val += getCenterGap();
2544
+ }
2545
+ }
2546
+
2547
+ if (hasRightDeadZone) { val = Math.max(val, rightBoundary); }
2548
+
2549
+ val += (horizontal && !autoWidth && !fixedWidth) ? '%' : 'px';
2550
+
2551
+ return val;
2552
+ }
2553
+
2554
+ function doContainerTransformSilent (val) {
2555
+ resetDuration(container, '0s');
2556
+ doContainerTransform(val);
2557
+ }
2558
+
2559
+ function doContainerTransform (val) {
2560
+ if (val == null) { val = getContainerTransformValue(); }
2561
+ if (textDirection === 'rtl' && val.charAt(0) === '-') {
2562
+ val = val.substr(1);
2563
+ }
2564
+ container.style[transformAttr] = transformPrefix + val + transformPostfix;
2565
+ }
2566
+
2567
+ function animateSlide (number, classOut, classIn, isOut) {
2568
+ var l = number + items;
2569
+ if (!loop) { l = Math.min(l, slideCountNew); }
2570
+
2571
+ for (var i = number; i < l; i++) {
2572
+ var item = slideItems[i];
2573
+
2574
+ // set item positions
2575
+ if (!isOut) { item.style.left = (i - index) * 100 / items + '%'; }
2576
+
2577
+ if (animateDelay && TRANSITIONDELAY) {
2578
+ item.style[TRANSITIONDELAY] = item.style[ANIMATIONDELAY] = animateDelay * (i - number) / 1000 + 's';
2579
+ }
2580
+ removeClass(item, classOut);
2581
+ addClass(item, classIn);
2582
+
2583
+ if (isOut) { slideItemsOut.push(item); }
2584
+ }
2585
+ }
2586
+
2587
+ // make transfer after click/drag:
2588
+ // 1. change 'transform' property for mordern browsers
2589
+ // 2. change 'left' property for legacy browsers
2590
+ var transformCore = (function () {
2591
+ return carousel ?
2592
+ function () {
2593
+ resetDuration(container, '');
2594
+ if (TRANSITIONDURATION || !speed) {
2595
+ // for morden browsers with non-zero duration or
2596
+ // zero duration for all browsers
2597
+ doContainerTransform();
2598
+ // run fallback function manually
2599
+ // when duration is 0 / container is hidden
2600
+ if (!speed || !isVisible(container)) { onTransitionEnd(); }
2601
+
2602
+ } else {
2603
+ // for old browser with non-zero duration
2604
+ jsTransform(container, transformAttr, transformPrefix, transformPostfix, getContainerTransformValue(), speed, onTransitionEnd);
2605
+ }
2606
+
2607
+ if (!horizontal) { updateContentWrapperHeight(); }
2608
+ } :
2609
+ function () {
2610
+ slideItemsOut = [];
2611
+
2612
+ var eve = {};
2613
+ eve[TRANSITIONEND] = eve[ANIMATIONEND] = onTransitionEnd;
2614
+ removeEvents(slideItems[indexCached], eve);
2615
+ addEvents(slideItems[index], eve);
2616
+
2617
+ animateSlide(indexCached, animateIn, animateOut, true);
2618
+ animateSlide(index, animateNormal, animateIn);
2619
+
2620
+ // run fallback function manually
2621
+ // when transition or animation not supported / duration is 0
2622
+ if (!TRANSITIONEND || !ANIMATIONEND || !speed || !isVisible(container)) { onTransitionEnd(); }
2623
+ };
2624
+ })();
2625
+
2626
+ function render (e, sliderMoved) {
2627
+ if (updateIndexBeforeTransform) { updateIndex(); }
2628
+
2629
+ // render when slider was moved (touch or drag) even though index may not change
2630
+ if (index !== indexCached || sliderMoved) {
2631
+ // events
2632
+ events.emit('indexChanged', info());
2633
+ events.emit('transitionStart', info());
2634
+ if (autoHeight) { doAutoHeight(); }
2635
+
2636
+ // pause autoplay when click or keydown from user
2637
+ if (animating && e && ['click', 'keydown'].indexOf(e.type) >= 0) { stopAutoplay(); }
2638
+
2639
+ running = true;
2640
+ transformCore();
2641
+ }
2642
+ }
2643
+
2644
+ /*
2645
+ * Transfer prefixed properties to the same format
2646
+ * CSS: -Webkit-Transform => webkittransform
2647
+ * JS: WebkitTransform => webkittransform
2648
+ * @param {string} str - property
2649
+ *
2650
+ */
2651
+ function strTrans (str) {
2652
+ return str.toLowerCase().replace(/-/g, '');
2653
+ }
2654
+
2655
+ // AFTER TRANSFORM
2656
+ // Things need to be done after a transfer:
2657
+ // 1. check index
2658
+ // 2. add classes to visible slide
2659
+ // 3. disable controls buttons when reach the first/last slide in non-loop slider
2660
+ // 4. update nav status
2661
+ // 5. lazyload images
2662
+ // 6. update container height
2663
+ function onTransitionEnd (event) {
2664
+ // check running on gallery mode
2665
+ // make sure trantionend/animationend events run only once
2666
+ if (carousel || running) {
2667
+ events.emit('transitionEnd', info(event));
2668
+
2669
+ if (!carousel && slideItemsOut.length > 0) {
2670
+ for (var i = 0; i < slideItemsOut.length; i++) {
2671
+ var item = slideItemsOut[i];
2672
+ // set item positions
2673
+ item.style.left = '';
2674
+
2675
+ if (ANIMATIONDELAY && TRANSITIONDELAY) {
2676
+ item.style[ANIMATIONDELAY] = '';
2677
+ item.style[TRANSITIONDELAY] = '';
2678
+ }
2679
+ removeClass(item, animateOut);
2680
+ addClass(item, animateNormal);
2681
+ }
2682
+ }
2683
+
2684
+ /* update slides, nav, controls after checking ...
2685
+ * => legacy browsers who don't support 'event'
2686
+ * have to check event first, otherwise event.target will cause an error
2687
+ * => or 'gallery' mode:
2688
+ * + event target is slide item
2689
+ * => or 'carousel' mode:
2690
+ * + event target is container,
2691
+ * + event.property is the same with transform attribute
2692
+ */
2693
+ if (!event ||
2694
+ !carousel && event.target.parentNode === container ||
2695
+ event.target === container && strTrans(event.propertyName) === strTrans(transformAttr)) {
2696
+
2697
+ if (!updateIndexBeforeTransform) {
2698
+ var indexTem = index;
2699
+ updateIndex();
2700
+ if (index !== indexTem) {
2701
+ events.emit('indexChanged', info());
2702
+
2703
+ doContainerTransformSilent();
2704
+ }
2705
+ }
2706
+
2707
+ if (nested === 'inner') { events.emit('innerLoaded', info()); }
2708
+ running = false;
2709
+ indexCached = index;
2710
+ }
2711
+ }
2712
+
2713
+ }
2714
+
2715
+ // # ACTIONS
2716
+ function goTo (targetIndex, e) {
2717
+ if (freeze) { return; }
2718
+
2719
+ // prev slideBy
2720
+ if (targetIndex === 'prev') {
2721
+ onControlsClick(e, -1);
2722
+
2723
+ // next slideBy
2724
+ } else if (targetIndex === 'next') {
2725
+ onControlsClick(e, 1);
2726
+
2727
+ // go to exact slide
2728
+ } else {
2729
+ if (running) {
2730
+ if (preventActionWhenRunning) { return; } else { onTransitionEnd(); }
2731
+ }
2732
+
2733
+ var absIndex = getAbsIndex(),
2734
+ indexGap = 0;
2735
+
2736
+ if (targetIndex === 'first') {
2737
+ indexGap = - absIndex;
2738
+ } else if (targetIndex === 'last') {
2739
+ indexGap = carousel ? slideCount - items - absIndex : slideCount - 1 - absIndex;
2740
+ } else {
2741
+ if (typeof targetIndex !== 'number') { targetIndex = parseInt(targetIndex); }
2742
+
2743
+ if (!isNaN(targetIndex)) {
2744
+ // from directly called goTo function
2745
+ if (!e) { targetIndex = Math.max(0, Math.min(slideCount - 1, targetIndex)); }
2746
+
2747
+ indexGap = targetIndex - absIndex;
2748
+ }
2749
+ }
2750
+
2751
+ // gallery: make sure new page won't overlap with current page
2752
+ if (!carousel && indexGap && Math.abs(indexGap) < items) {
2753
+ var factor = indexGap > 0 ? 1 : -1;
2754
+ indexGap += (index + indexGap - slideCount) >= indexMin ? slideCount * factor : slideCount * 2 * factor * -1;
2755
+ }
2756
+
2757
+ index += indexGap;
2758
+
2759
+ // make sure index is in range
2760
+ if (carousel && loop) {
2761
+ if (index < indexMin) { index += slideCount; }
2762
+ if (index > indexMax) { index -= slideCount; }
2763
+ }
2764
+
2765
+ // if index is changed, start rendering
2766
+ if (getAbsIndex(index) !== getAbsIndex(indexCached)) {
2767
+ render(e);
2768
+ }
2769
+
2770
+ }
2771
+ }
2772
+
2773
+ // on controls click
2774
+ function onControlsClick (e, dir) {
2775
+ if (running) {
2776
+ if (preventActionWhenRunning) { return; } else { onTransitionEnd(); }
2777
+ }
2778
+ var passEventObject;
2779
+
2780
+ if (!dir) {
2781
+ e = getEvent(e);
2782
+ var target = getTarget(e);
2783
+
2784
+ while (target !== controlsContainer && [prevButton, nextButton].indexOf(target) < 0) { target = target.parentNode; }
2785
+
2786
+ var targetIn = [prevButton, nextButton].indexOf(target);
2787
+ if (targetIn >= 0) {
2788
+ passEventObject = true;
2789
+ dir = targetIn === 0 ? -1 : 1;
2790
+ }
2791
+ }
2792
+
2793
+ if (rewind) {
2794
+ if (index === indexMin && dir === -1) {
2795
+ goTo('last', e);
2796
+ return;
2797
+ } else if (index === indexMax && dir === 1) {
2798
+ goTo('first', e);
2799
+ return;
2800
+ }
2801
+ }
2802
+
2803
+ if (dir) {
2804
+ index += slideBy * dir;
2805
+ if (autoWidth) { index = Math.floor(index); }
2806
+ // pass e when click control buttons or keydown
2807
+ render((passEventObject || (e && e.type === 'keydown')) ? e : null);
2808
+ }
2809
+ }
2810
+
2811
+ // on nav click
2812
+ function onNavClick (e) {
2813
+ if (running) {
2814
+ if (preventActionWhenRunning) { return; } else { onTransitionEnd(); }
2815
+ }
2816
+
2817
+ e = getEvent(e);
2818
+ var target = getTarget(e), navIndex;
2819
+
2820
+ // find the clicked nav item
2821
+ while (target !== navContainer && !hasAttr(target, 'data-nav')) { target = target.parentNode; }
2822
+ if (hasAttr(target, 'data-nav')) {
2823
+ var navIndex = navClicked = Number(getAttr(target, 'data-nav')),
2824
+ targetIndexBase = fixedWidth || autoWidth ? navIndex * slideCount / pages : navIndex * items,
2825
+ targetIndex = navAsThumbnails ? navIndex : Math.min(Math.ceil(targetIndexBase), slideCount - 1);
2826
+ goTo(targetIndex, e);
2827
+
2828
+ if (navCurrentIndex === navIndex) {
2829
+ if (animating) { stopAutoplay(); }
2830
+ navClicked = -1; // reset navClicked
2831
+ }
2832
+ }
2833
+ }
2834
+
2835
+ // autoplay functions
2836
+ function setAutoplayTimer () {
2837
+ autoplayTimer = setInterval(function () {
2838
+ onControlsClick(null, autoplayDirection);
2839
+ }, autoplayTimeout);
2840
+
2841
+ animating = true;
2842
+ }
2843
+
2844
+ function stopAutoplayTimer () {
2845
+ clearInterval(autoplayTimer);
2846
+ animating = false;
2847
+ }
2848
+
2849
+ function updateAutoplayButton (action, txt) {
2850
+ setAttrs(autoplayButton, {'data-action': action});
2851
+ autoplayButton.innerHTML = autoplayHtmlStrings[0] + action + autoplayHtmlStrings[1] + txt;
2852
+ }
2853
+
2854
+ function startAutoplay () {
2855
+ setAutoplayTimer();
2856
+ if (autoplayButton) { updateAutoplayButton('stop', autoplayText[1]); }
2857
+ }
2858
+
2859
+ function stopAutoplay () {
2860
+ stopAutoplayTimer();
2861
+ if (autoplayButton) { updateAutoplayButton('start', autoplayText[0]); }
2862
+ }
2863
+
2864
+ // programaitcally play/pause the slider
2865
+ function play () {
2866
+ if (autoplay && !animating) {
2867
+ startAutoplay();
2868
+ autoplayUserPaused = false;
2869
+ }
2870
+ }
2871
+ function pause () {
2872
+ if (animating) {
2873
+ stopAutoplay();
2874
+ autoplayUserPaused = true;
2875
+ }
2876
+ }
2877
+
2878
+ function toggleAutoplay () {
2879
+ if (animating) {
2880
+ stopAutoplay();
2881
+ autoplayUserPaused = true;
2882
+ } else {
2883
+ startAutoplay();
2884
+ autoplayUserPaused = false;
2885
+ }
2886
+ }
2887
+
2888
+ function onVisibilityChange () {
2889
+ if (doc.hidden) {
2890
+ if (animating) {
2891
+ stopAutoplayTimer();
2892
+ autoplayVisibilityPaused = true;
2893
+ }
2894
+ } else if (autoplayVisibilityPaused) {
2895
+ setAutoplayTimer();
2896
+ autoplayVisibilityPaused = false;
2897
+ }
2898
+ }
2899
+
2900
+ function mouseoverPause () {
2901
+ if (animating) {
2902
+ stopAutoplayTimer();
2903
+ autoplayHoverPaused = true;
2904
+ }
2905
+ }
2906
+
2907
+ function mouseoutRestart () {
2908
+ if (autoplayHoverPaused) {
2909
+ setAutoplayTimer();
2910
+ autoplayHoverPaused = false;
2911
+ }
2912
+ }
2913
+
2914
+ // keydown events on document
2915
+ function onDocumentKeydown (e) {
2916
+ e = getEvent(e);
2917
+ var keyIndex = [KEYS.LEFT, KEYS.RIGHT].indexOf(e.keyCode);
2918
+
2919
+ if (keyIndex >= 0) {
2920
+ onControlsClick(e, keyIndex === 0 ? -1 : 1);
2921
+ }
2922
+ }
2923
+
2924
+ // on key control
2925
+ function onControlsKeydown (e) {
2926
+ e = getEvent(e);
2927
+ var keyIndex = [KEYS.LEFT, KEYS.RIGHT].indexOf(e.keyCode);
2928
+
2929
+ if (keyIndex >= 0) {
2930
+ if (keyIndex === 0) {
2931
+ if (!prevButton.disabled) { onControlsClick(e, -1); }
2932
+ } else if (!nextButton.disabled) {
2933
+ onControlsClick(e, 1);
2934
+ }
2935
+ }
2936
+ }
2937
+
2938
+ // set focus
2939
+ function setFocus (el) {
2940
+ el.focus();
2941
+ }
2942
+
2943
+ // on key nav
2944
+ function onNavKeydown (e) {
2945
+ e = getEvent(e);
2946
+ var curElement = doc.activeElement;
2947
+ if (!hasAttr(curElement, 'data-nav')) { return; }
2948
+
2949
+ // var code = e.keyCode,
2950
+ var keyIndex = [KEYS.LEFT, KEYS.RIGHT, KEYS.ENTER, KEYS.SPACE].indexOf(e.keyCode),
2951
+ navIndex = Number(getAttr(curElement, 'data-nav'));
2952
+
2953
+ if (keyIndex >= 0) {
2954
+ if (keyIndex === 0) {
2955
+ if (navIndex > 0) { setFocus(navItems[navIndex - 1]); }
2956
+ } else if (keyIndex === 1) {
2957
+ if (navIndex < pages - 1) { setFocus(navItems[navIndex + 1]); }
2958
+ } else {
2959
+ navClicked = navIndex;
2960
+ goTo(navIndex, e);
2961
+ }
2962
+ }
2963
+ }
2964
+
2965
+ function getEvent (e) {
2966
+ e = e || win.event;
2967
+ return isTouchEvent(e) ? e.changedTouches[0] : e;
2968
+ }
2969
+ function getTarget (e) {
2970
+ return e.target || win.event.srcElement;
2971
+ }
2972
+
2973
+ function isTouchEvent (e) {
2974
+ return e.type.indexOf('touch') >= 0;
2975
+ }
2976
+
2977
+ function preventDefaultBehavior (e) {
2978
+ e.preventDefault ? e.preventDefault() : e.returnValue = false;
2979
+ }
2980
+
2981
+ function getMoveDirectionExpected () {
2982
+ return getTouchDirection(toDegree(lastPosition.y - initPosition.y, lastPosition.x - initPosition.x), swipeAngle) === options.axis;
2983
+ }
2984
+
2985
+ function onPanStart (e) {
2986
+ if (running) {
2987
+ if (preventActionWhenRunning) { return; } else { onTransitionEnd(); }
2988
+ }
2989
+
2990
+ if (autoplay && animating) { stopAutoplayTimer(); }
2991
+
2992
+ panStart = true;
2993
+ if (rafIndex) {
2994
+ caf(rafIndex);
2995
+ rafIndex = null;
2996
+ }
2997
+
2998
+ var $ = getEvent(e);
2999
+ events.emit(isTouchEvent(e) ? 'touchStart' : 'dragStart', info(e));
3000
+
3001
+ if (!isTouchEvent(e) && ['img', 'a'].indexOf(getLowerCaseNodeName(getTarget(e))) >= 0) {
3002
+ preventDefaultBehavior(e);
3003
+ }
3004
+
3005
+ lastPosition.x = initPosition.x = $.clientX;
3006
+ lastPosition.y = initPosition.y = $.clientY;
3007
+ if (carousel) {
3008
+ translateInit = parseFloat(container.style[transformAttr].replace(transformPrefix, ''));
3009
+ resetDuration(container, '0s');
3010
+ }
3011
+ }
3012
+
3013
+ function onPanMove (e) {
3014
+ if (panStart) {
3015
+ var $ = getEvent(e);
3016
+ lastPosition.x = $.clientX;
3017
+ lastPosition.y = $.clientY;
3018
+
3019
+ if (carousel) {
3020
+ if (!rafIndex) { rafIndex = raf(function(){ panUpdate(e); }); }
3021
+ } else {
3022
+ if (moveDirectionExpected === '?') { moveDirectionExpected = getMoveDirectionExpected(); }
3023
+ if (moveDirectionExpected) { preventScroll = true; }
3024
+ }
3025
+
3026
+ if ((typeof e.cancelable !== 'boolean' || e.cancelable) && preventScroll) {
3027
+ e.preventDefault();
3028
+ }
3029
+ }
3030
+ }
3031
+
3032
+ function panUpdate (e) {
3033
+ if (!moveDirectionExpected) {
3034
+ panStart = false;
3035
+ return;
3036
+ }
3037
+ caf(rafIndex);
3038
+ if (panStart) { rafIndex = raf(function(){ panUpdate(e); }); }
3039
+
3040
+ if (moveDirectionExpected === '?') { moveDirectionExpected = getMoveDirectionExpected(); }
3041
+ if (moveDirectionExpected) {
3042
+ if (!preventScroll && isTouchEvent(e)) { preventScroll = true; }
3043
+
3044
+ try {
3045
+ if (e.type) { events.emit(isTouchEvent(e) ? 'touchMove' : 'dragMove', info(e)); }
3046
+ } catch(err) {}
3047
+
3048
+ var x = translateInit,
3049
+ dist = getDist(lastPosition, initPosition);
3050
+ if (!horizontal || fixedWidth || autoWidth) {
3051
+ x += dist;
3052
+ x += 'px';
3053
+ } else {
3054
+ var percentageX = TRANSFORM ? dist * items * 100 / ((viewport + gutter) * slideCountNew): dist * 100 / (viewport + gutter);
3055
+ x += percentageX;
3056
+ x += '%';
3057
+ }
3058
+
3059
+ container.style[transformAttr] = transformPrefix + x + transformPostfix;
3060
+ }
3061
+ }
3062
+
3063
+ function onPanEnd (e) {
3064
+ if (panStart) {
3065
+ if (rafIndex) {
3066
+ caf(rafIndex);
3067
+ rafIndex = null;
3068
+ }
3069
+ if (carousel) { resetDuration(container, ''); }
3070
+ panStart = false;
3071
+
3072
+ var $ = getEvent(e);
3073
+ lastPosition.x = $.clientX;
3074
+ lastPosition.y = $.clientY;
3075
+ var dist = getDist(lastPosition, initPosition);
3076
+
3077
+ if (Math.abs(dist)) {
3078
+ // drag vs click
3079
+ if (!isTouchEvent(e)) {
3080
+ // prevent "click"
3081
+ var target = getTarget(e);
3082
+ addEvents(target, {'click': function preventClick (e) {
3083
+ preventDefaultBehavior(e);
3084
+ removeEvents(target, {'click': preventClick});
3085
+ }});
3086
+ }
3087
+
3088
+ if (carousel) {
3089
+ rafIndex = raf(function() {
3090
+ if (horizontal && !autoWidth) {
3091
+ var indexMoved = - dist * items / (viewport + gutter);
3092
+ indexMoved = dist > 0 ? Math.floor(indexMoved) : Math.ceil(indexMoved);
3093
+ if (textDirection === 'rtl') {
3094
+ index += indexMoved * -1;
3095
+ } else {
3096
+ index += indexMoved;
3097
+ }
3098
+ } else {
3099
+ var moved = - (translateInit + dist);
3100
+ if (moved <= 0) {
3101
+ index = indexMin;
3102
+ } else if (moved >= slidePositions[slideCountNew - 1]) {
3103
+ index = indexMax;
3104
+ } else {
3105
+ var i = 0;
3106
+ while (i < slideCountNew && moved >= slidePositions[i]) {
3107
+ index = i;
3108
+ if (moved > slidePositions[i] && dist < 0) { index += 1; }
3109
+ i++;
3110
+ }
3111
+ }
3112
+ }
3113
+
3114
+ render(e, dist);
3115
+ events.emit(isTouchEvent(e) ? 'touchEnd' : 'dragEnd', info(e));
3116
+ });
3117
+ } else {
3118
+ if (moveDirectionExpected) {
3119
+ onControlsClick(e, dist > 0 ? -1 : 1);
3120
+ }
3121
+ }
3122
+ }
3123
+ }
3124
+
3125
+ // reset
3126
+ if (options.preventScrollOnTouch === 'auto') { preventScroll = false; }
3127
+ if (swipeAngle) { moveDirectionExpected = '?'; }
3128
+ if (autoplay && !animating) { setAutoplayTimer(); }
3129
+ }
3130
+
3131
+ // === RESIZE FUNCTIONS === //
3132
+ // (slidePositions, index, items) => vertical_conentWrapper.height
3133
+ function updateContentWrapperHeight () {
3134
+ var wp = middleWrapper ? middleWrapper : innerWrapper;
3135
+ wp.style.height = slidePositions[index + items] - slidePositions[index] + 'px';
3136
+ }
3137
+
3138
+ function getPages () {
3139
+ var rough = fixedWidth ? (fixedWidth + gutter) * slideCount / viewport : slideCount / items;
3140
+ return Math.min(Math.ceil(rough), slideCount);
3141
+ }
3142
+
3143
+ /*
3144
+ * 1. update visible nav items list
3145
+ * 2. add "hidden" attributes to previous visible nav items
3146
+ * 3. remove "hidden" attrubutes to new visible nav items
3147
+ */
3148
+ function updateNavVisibility () {
3149
+ if (!nav || navAsThumbnails) { return; }
3150
+
3151
+ if (pages !== pagesCached) {
3152
+ var min = pagesCached,
3153
+ max = pages,
3154
+ fn = showElement;
3155
+
3156
+ if (pagesCached > pages) {
3157
+ min = pages;
3158
+ max = pagesCached;
3159
+ fn = hideElement;
3160
+ }
3161
+
3162
+ while (min < max) {
3163
+ fn(navItems[min]);
3164
+ min++;
3165
+ }
3166
+
3167
+ // cache pages
3168
+ pagesCached = pages;
3169
+ }
3170
+ }
3171
+
3172
+ function info (e) {
3173
+ return {
3174
+ container: container,
3175
+ slideItems: slideItems,
3176
+ navContainer: navContainer,
3177
+ navItems: navItems,
3178
+ controlsContainer: controlsContainer,
3179
+ hasControls: hasControls,
3180
+ prevButton: prevButton,
3181
+ nextButton: nextButton,
3182
+ items: items,
3183
+ slideBy: slideBy,
3184
+ cloneCount: cloneCount,
3185
+ slideCount: slideCount,
3186
+ slideCountNew: slideCountNew,
3187
+ index: index,
3188
+ indexCached: indexCached,
3189
+ displayIndex: getCurrentSlide(),
3190
+ navCurrentIndex: navCurrentIndex,
3191
+ navCurrentIndexCached: navCurrentIndexCached,
3192
+ pages: pages,
3193
+ pagesCached: pagesCached,
3194
+ sheet: sheet,
3195
+ isOn: isOn,
3196
+ event: e || {},
3197
+ };
3198
+ }
3199
+
3200
+ return {
3201
+ version: '2.9.3',
3202
+ getInfo: info,
3203
+ events: events,
3204
+ goTo: goTo,
3205
+ play: play,
3206
+ pause: pause,
3207
+ isOn: isOn,
3208
+ updateSliderHeight: updateInnerWrapperHeight,
3209
+ refresh: initSliderTransform,
3210
+ destroy: destroy,
3211
+ rebuild: function() {
3212
+ return tns(extend(options, optionsElements));
3213
+ }
3214
+ };
3215
+ };
3216
+
3217
+ return tns;
3218
+ })();