PageSourceSearch

https://predplatne.touchit.sk/js/libs.js?v=2

js touchit.sk collected 2026-09-24 09:18:42 UTC 1,146,286 bytes, 25,124 lines download raw bytes

1/*! JsRender v0.9.76 (Beta): http://jsviews.com/#jsrender */
2/*! **VERSION FOR WEB** (For NODE.JS see http://jsviews.com/download/jsrender-node.js) */
3/*
4 * Best-of-breed templating in browser or on Node.js.
5 * Does not require jQuery, or HTML DOM
6 * Integrates with JsViews (http://jsviews.com/#jsviews)
7 *
8 * Copyright 2016, Boris Moore
9 * Released under the MIT License.
10 */
11
12//jshint -W018, -W041
13
14(function(factory, global) {
15	// global var is the this object, which is window when running in the usual browser environment
16	var $ = global.jQuery;
17
18	if (typeof exports === "object") { // CommonJS e.g. Browserify
19		module.exports = $
20			? factory(global, $)
21			: function($) { // If no global jQuery, take optional jQuery passed as parameter: require('jsrender')(jQuery)
22				if ($ && !$.fn) {
23					throw "Provide jQuery or null";
24				}
25				return factory(global, $);
26			};
27	} else if (typeof define === "function" && define.amd) { // AMD script loader, e.g. RequireJS
28		define(function() {
29			return factory(global);
30		});
31	} else { // Browser using plain <script> tag
32		factory(global, false);
33	}
34} (
35
36// factory (for jsrender.js)
37function(global, $) {
38"use strict";
39
40//========================== Top-level vars ==========================
41
42// global var is the this object, which is window when running in the usual browser environment
43var setGlobals = $ === false; // Only set globals if script block in browser (not AMD and not CommonJS)
44
45$ = $ && $.fn ? $ : global.jQuery; // $ is jQuery passed in by CommonJS loader (Browserify), or global jQuery.
46
47var versionNumber = "v0.9.76",
48	jsvStoreName, rTag, rTmplString, topView, $views,
49
50//TODO	tmplFnsCache = {},
51	$isFunction, $isArray, $templates, $converters, $helpers, $tags, $sub, $subSettings, $subSettingsAdvanced, $viewsSettings, delimOpenChar0, delimOpenChar1, delimCloseChar0, delimCloseChar1, linkChar, setting, baseOnError,
52
53	rPath = /^(!*?)(?:null|true|false|\d[\d.]*|([\w$]+|\.|~([\w$]+)|#(view|([\w$]+))?)([\w$.^]*?)(?:[.[^]([\w$]+)\]?)?)$/g,
54	//        not                               object     helper    view  viewProperty pathTokens      leafToken
55
56	rParams = /(\()(?=\s*\()|(?:([([])\s*)?(?:(\^?)(!*?[#~]?[\w$.^]+)?\s*((\+\+|--)|\+|-|&&|\|\||===|!==|==|!=|<=|>=|[<>%*:?\/]|(=))\s*|(!*?[#~]?[\w$.^]+)([([])?)|(,\s*)|(\(?)\\?(?:(')|("))|(?:\s*(([)\]])(?=\s*[.^]|\s*$|[^([])|[)\]])([([]?))|(\s+)/g,
57	//          lftPrn0        lftPrn        bound            path    operator err                                                eq             path2       prn    comma   lftPrn2   apos quot      rtPrn rtPrnDot                           prn2  space
58	// (left paren? followed by (path? followed by operator) or (path followed by left paren?)) or comma or apos or quot or right paren or space
59
60	isRenderCall,
61	rNewLine = /[ \t]*(\r\n|\n|\r)/g,
62	rUnescapeQuotes = /\\(['"])/g,
63	rEscapeQuotes = /['"\\]/g, // Escape quotes and \ character
64	rBuildHash = /(?:\x08|^)(onerror:)?(?:(~?)(([\w$_\.]+):)?([^\x08]+))\x08(,)?([^\x08]+)/gi,
65	rTestElseIf = /^if\s/,
66	rFirstElem = /<(\w+)[>\s]/,
67	rAttrEncode = /[\x00`><"'&=]/g, // Includes > encoding since rConvertMarkers in JsViews does not skip > characters in attribute strings
68	rIsHtml = /[\x00`><\"'&=]/,
69	rHasHandlers = /^on[A-Z]|^convert(Back)?$/,
70	rHtmlEncode = rAttrEncode,
71	viewId = 0,
72	charEntities = {
73		"&": "&amp;",
74		"<": "&lt;",
75		">": "&gt;",
76		"\x00": "&#0;",
77		"'": "&#39;",
78		'"': "&#34;",
79		"`": "&#96;",
80		"=": "&#61;"
81	},
82	HTML = "html",
83	OBJECT = "object",
84	tmplAttr = "data-jsv-tmpl",
85	jsvTmpl = "jsvTmpl",
86	indexStr = "For #index in nested block use #getIndex().",
87	$render = {},
88
89	jsr = global.jsrender,
90	jsrToJq = jsr && $ && !$.render, // JsRender already loaded, without jQuery. but we will re-load it now to attach to jQuery
91
92	jsvStores = {
93		template: {
94			compile: compileTmpl
95		},
96		tag: {
97			compile: compileTag
98		},
99		viewModel: {
100			compile: compileViewModel
101		},
102		helper: {},
103		converter: {}
104	};
105
106	// views object ($.views if jQuery is loaded, jsrender.views if no jQuery, e.g. in Node.js)
107	$views = {
108		jsviews: versionNumber,
109		sub: {
110			// subscription, e.g. JsViews integration
111			View: View,
112			Err: JsViewsError,
113			tmplFn: tmplFn,
114			parse: parseParams,
115			extend: $extend,
116			extendCtx: extendCtx,
117			syntaxErr: syntaxError,
118			onStore: {},
119			addSetting: addSetting,
120			settings: {
121				allowCode: false
122			},
123			advSet: noop, // Update advanced settings
124			_ths: tagHandlersFromProps,
125			_tg: function() {}, // Constructor for tagDef
126			_cnvt: convertVal,
127			_tag: renderTag,
128			_er: error,
129			_err: onRenderError,
130			_html: htmlEncode,
131			_sq: function(token) {
132				if (token === "constructor") {
133					syntaxError("");
134				}
135				return token;
136			}
137		},
138		settings: {
139			delimiters: $viewsDelimiters,
140			advanced: function(value) {
141				return value
142					? (
143							$extend($subSettingsAdvanced, value),
144							$sub.advSet(),
145							$viewsSettings
146						)
147						: $subSettingsAdvanced;
148				}
149		},
150		map: dataMap // If jsObservable loaded first, use that definition of dataMap
151	};
152
153function getDerivedMethod(baseMethod, method) {
154	return function() {
155		var ret,
156			tag = this,
157			prevBase = tag.base;
158
159		tag.base = baseMethod; // Within method call, calling this.base will call the base method
160		ret = method.apply(tag, arguments); // Call the method
161		tag.base = prevBase; // Replace this.base to be the base method of the previous call, for chained calls
162		return ret;
163	};
164}
165
166function getMethod(baseMethod, method) {
167	// For derived methods (or handlers declared declaratively as in {{:foo onChange=~fooChanged}} replace by a derived method, to allow using this.base(...)
168	// or this.baseApply(arguments) to call the base implementation. (Equivalent to this._super(...) and this._superApply(arguments) in jQuery UI)
169	if ($isFunction(method)) {
170		method = getDerivedMethod(
171				!baseMethod
172					? noop // no base method implementation, so use noop as base method
173					: baseMethod._d
174						? baseMethod // baseMethod is a derived method, so us it
175						: getDerivedMethod(noop, baseMethod), // baseMethod is not derived so make its base method be the noop method
176				method
177			);
178		method._d = 1; // Add flag that this is a derived method
179	}
180	return method;
181}
182
183function tagHandlersFromProps(tag, tagCtx) {
184	for (var prop in tagCtx.props) {
185		if (rHasHandlers.test(prop)) {
186			tag[prop] = getMethod(tag[prop], tagCtx.props[prop]);
187			// Copy over the onFoo props, convert and convertBack from tagCtx.props to tag (overrides values in tagDef).
188			// Note: unsupported scenario: if handlers are dynamically added ^onFoo=expression this will work, but dynamically removing will not work.
189		}
190	}
191}
192
193function retVal(val) {
194	return val;
195}
196
197function noop() {
198	return "";
199}
200
201function dbgBreak(val) {
202	// Usage examples: {{dbg:...}}, {{:~dbg(...)}}, {{dbg .../}}, {^{for ... onAfterLink=~dbg}} etc.
203	try {
204		console.log("JsRender dbg breakpoint: " + val);
205		throw "dbg breakpoint"; // To break here, stop on caught exceptions.
206	}
207	catch (e) {}
208	return this.base ? this.baseApply(arguments) : val;
209}
210
211function JsViewsError(message) {
212	// Error exception type for JsViews/JsRender
213	// Override of $.views.sub.Error is possible
214	this.name = ($.link ? "JsViews" : "JsRender") + " Error";
215	this.message = message || this.name;
216}
217
218function $extend(target, source) {
219	for (var name in source) {
220		target[name] = source[name];
221	}
222	return target;
223}
224
225(JsViewsError.prototype = new Error()).constructor = JsViewsError;
226
227//========================== Top-level functions ==========================
228
229//===================
230// views.delimiters
231//===================
232
233function $viewsDelimiters(openChars, closeChars, link) {
234	// Set the tag opening and closing delimiters and 'link' character. Default is "{{", "}}" and "^"
235	// openChars, closeChars: opening and closing strings, each with two characters
236	if (!openChars) {
237		return $subSettings.delimiters;
238	}
239
240	$subSettings.delimiters = [openChars, closeChars, linkChar = link ? link.charAt(0) : linkChar];
241
242	delimOpenChar0 = openChars.charAt(0); // Escape the characters - since they could be regex special characters
243	delimOpenChar1 = openChars.charAt(1);
244	delimCloseChar0 = closeChars.charAt(0);
245	delimCloseChar1 = closeChars.charAt(1);
246	openChars = "\\" + delimOpenChar0 + "(\\" + linkChar + ")?\\" + delimOpenChar1; // Default is "{^{"
247	closeChars = "\\" + delimCloseChar0 + "\\" + delimCloseChar1;                   // Default is "}}"
248	// Build regex with new delimiters
249	//          [tag    (followed by / space or })  or cvtr+colon or html or code] followed by space+params then convertBack?
250	rTag = "(?:(\\w+(?=[\\/\\s\\" + delimCloseChar0 + "]))|(\\w+)?(:)|(>)|(\\*))\\s*((?:[^\\"
251		+ delimCloseChar0 + "]|\\" + delimCloseChar0 + "(?!\\" + delimCloseChar1 + "))*?)";
252
253	// make rTag available to JsViews (or other components) for parsing binding expressions
254	$sub.rTag = "(?:" + rTag + ")";
255	//                        { ^? {   tag+params slash?  or closingTag                                                   or comment
256	rTag = new RegExp("(?:" + openChars + rTag + "(\\/)?|\\" + delimOpenChar0 + "(\\" + linkChar + ")?\\" + delimOpenChar1 + "(?:(?:\\/(\\w+))\\s*|!--[\\s\\S]*?--))" + closeChars, "g");
257
258	// Default:  bind     tagName         cvt   cln html code    params            slash   bind2         closeBlk  comment
259	//      /(?:{(\^)?{(?:(\w+(?=[\/\s}]))|(\w+)?(:)|(>)|(\*))\s*((?:[^}]|}(?!}))*?)(\/)?|{(\^)?{(?:(?:\/(\w+))\s*|!--[\s\S]*?--))}}
260
261	rTmplString = new RegExp("<.*>|([^\\\\]|^)[{}]|" + openChars + ".*" + closeChars);
262	// rTmplString looks for html tags or { or } char not preceded by \\, or JsRender tags {{xxx}}. Each of these strings are considered
263	// NOT to be jQuery selectors
264	return $viewsSettings;
265}
266
267//=========
268// View.get
269//=========
270
271function getView(inner, type) { //view.get(inner, type)
272	if (!type && inner !== true) {
273		// view.get(type)
274		type = inner;
275		inner = undefined;
276	}
277
278	var views, i, l, found,
279		view = this,
280		root = !type || type === "root";
281		// If type is undefined, returns root view (view under top view).
282
283	if (inner) {
284		// Go through views - this one, and all nested ones, depth-first - and return first one with given type.
285		// If type is undefined, i.e. view.get(true), return first child view.
286		found = type && view.type === type && view;
287		if (!found) {
288			views = view.views;
289			if (view._.useKey) {
290				for (i in views) {
291					if (found = type ? views[i].get(inner, type) : views[i]) {
292						break;
293					}
294				}
295			} else {
296				for (i = 0, l = views.length; !found && i < l; i++) {
297					found = type ? views[i].get(inner, type) : views[i];
298				}
299			}
300		}
301	} else if (root) {
302		// Find root view. (view whose parent is top view)
303		while (view.parent) {
304			found = view;
305			view = view.parent;
306		}
307	} else {
308		while (view && !found) {
309			// Go through views - this one, and all parent ones - and return first one with given type.
310			found = view.type === type ? view : undefined;
311			view = view.parent;
312		}
313	}
314	return found;
315}
316
317function getNestedIndex() {
318	var view = this.get("item");
319	return view ? view.index : undefined;
320}
321
322getNestedIndex.depends = function() {
323	return [this.get("item"), "index"];
324};
325
326function getIndex() {
327	return this.index;
328}
329
330getIndex.depends = "index";
331
332//==========
333// View.hlp
334//==========
335
336function getHelper(helper) {
337	// Helper method called as view.hlp(key) from compiled template, for helper functions or template parameters ~foo
338	var wrapped,
339		view = this,
340		ctx = view.linkCtx,
341		res = (view.ctx || {})[helper];
342
343	if (res === undefined && ctx && ctx.ctx) {
344		res = ctx.ctx[helper];
345	}
346	if (res === undefined) {
347		res = $helpers[helper];
348	}
349
350	if (res) {
351		if ($isFunction(res) && !res._wrp) {
352			// If it is of type function, and not already wrapped, we will wrap it, so if called with no this pointer it will be called with the
353			// view as 'this' context. If the helper ~foo() was in a data-link expression, the view will have a 'temporary' linkCtx property too.
354			// Note that helper functions on deeper paths will have specific this pointers, from the preceding path.
355			// For example, ~util.foo() will have the ~util object as 'this' pointer
356			wrapped = function() {
357				return res.apply((!this || this === global) ? view : this, arguments);
358			};
359			wrapped._wrp = view;
360			$extend(wrapped, res); // Attach same expandos (if any) to the wrapped function
361		}
362	}
363	return wrapped || res;
364}
365
366function getTemplate(tmpl) {
367	return tmpl && (tmpl.fn
368		? tmpl
369		: this.getRsc("templates", tmpl) || $templates(tmpl)); // not yet compiled
370}
371
372//==============
373// views._cnvt
374//==============
375
376function convertVal(converter, view, tagCtx, onError) {
377	// self is template object or linkCtx object
378	var tag, value,
379		// if tagCtx is an integer, then it is the key for the compiled function to return the boundTag tagCtx
380		boundTag = typeof tagCtx === "number" && view.tmpl.bnds[tagCtx-1],
381		linkCtx = view.linkCtx; // For data-link="{cvt:...}"...
382
383	if (onError !== undefined) {
384		tagCtx = onError = {props: {}, args: [onError]};
385	} else if (boundTag) {
386		tagCtx = boundTag(view.data, view, $sub);
387	}
388
389	value = tagCtx.args[0];
390	if (converter || boundTag) {
391		tag = linkCtx && linkCtx.tag;
392		if (!tag) {
393			tag = $extend(new $sub._tg(), {
394				_: {
395					inline: !linkCtx,
396					bnd: boundTag,
397					unlinked: true
398				},
399				tagName: ":",
400				cvt: converter,
401				flow: true,
402				tagCtx: tagCtx
403			});
404			if (linkCtx) {
405				linkCtx.tag = tag;
406				tag.linkCtx = linkCtx;
407			}
408			tagCtx.ctx = extendCtx(tagCtx.ctx, (linkCtx ? linkCtx.view : view).ctx);
409		}
410		tag._er = onError && value;
411		tagHandlersFromProps(tag, tagCtx);
412
413		tagCtx.view = view;
414
415		tag.ctx = tagCtx.ctx || {};
416		tagCtx.ctx = undefined;
417
418		value = tag.cvtArgs(tag.convert || converter !== "true" && converter)[0]; // If there is a convertBack but no convert, converter will be "true"
419
420		// Call onRender (used by JsViews if present, to add binding annotations around rendered content)
421		value = boundTag && view._.onRender
422			? view._.onRender(value, view, tag)
423			: value;
424	}
425	return value != undefined ? value : "";
426}
427
428function convertArgs(converter) {
429	var tag = this,
430		tagCtx = tag.tagCtx,
431		view = tagCtx.view,
432		args = tagCtx.args;
433
434	converter = tag.convert || converter;
435	converter = converter && ("" + converter === converter
436		? (view.getRsc("converters", converter) || error("Unknown converter: '" + converter + "'"))
437		: converter);
438
439	args = !args.length && !tagCtx.index // On the opening tag with no args, bind to the current data context
440		? [view.data]
441		: converter
442			? args.slice() // If there is a converter, use a copy of the tagCtx.args array for rendering, and replace the args[0] in
443			// the copied array with the converted value. But we do not modify the value of tag.tagCtx.args[0] (the original args array)
444			: args; // If no converter, get the original tagCtx.args
445
446	if (converter) {
447		if (converter.depends) {
448			tag.depends = $sub.getDeps(tag.depends, tag, converter.depends, converter);
449		}
450		args[0] = converter.apply(tag, args);
451	}
452	return args;
453}
454
455//=============
456// views._tag
457//=============
458
459function getResource(resourceType, itemName) {
460	var res, store,
461		view = this;
462	while ((res === undefined) && view) {
463		store = view.tmpl && view.tmpl[resourceType];
464		res = store && store[itemName];
465		view = view.parent;
466	}
467	return res || $views[resourceType][itemName];
468}
469
470function renderTag(tagName, parentView, tmpl, tagCtxs, isUpdate, onError) {
471	parentView = parentView || topView;
472	var tag, tag_, tagDef, template, tags, attr, parentTag, i, l, itemRet, tagCtx, tagCtxCtx, content, callInit, mapDef, thisMap, args, props, initialTmpl, tagDataMap,
473		ret = "",
474		linkCtx = parentView.linkCtx || 0,
475		ctx = parentView.ctx,
476		parentTmpl = tmpl || parentView.tmpl,
477		// if tagCtx is an integer, then it is the key for the compiled function to return the boundTag tagCtxs
478		boundTag = typeof tagCtxs === "number" && parentView.tmpl.bnds[tagCtxs-1];
479
480	if (tagName._is === "tag") {
481		tag = tagName;
482		tagName = tag.tagName;
483		tagCtxs = tag.tagCtxs;
484		template = tag.template;
485	} else {
486		tagDef = parentView.getRsc("tags", tagName) || error("Unknown tag: {{" + tagName + "}} ");
487		template = tagDef.template;
488	}
489
490	if (onError !== undefined) {
491		ret += onError;
492		tagCtxs = onError = [{props: {}, args: []}];
493	} else if (boundTag) {
494		tagCtxs = boundTag(parentView.data, parentView, $sub);
495	}
496
497	l = tagCtxs.length;
498	for (i = 0; i < l; i++) {
499		tagCtx = tagCtxs[i];
500		if (!linkCtx || !linkCtx.tag || i && !linkCtx.tag._.inline || tag._er) {
501			// Initialize tagCtx
502			// For block tags, tagCtx.tmpl is an integer > 0
503			if (content = parentTmpl.tmpls && tagCtx.tmpl) {
504				content = tagCtx.content = parentTmpl.tmpls[content - 1];
505			}
506			tagCtx.index = i;
507			tagCtx.tmpl = content; // Set the tmpl property to the content of the block tag
508			tagCtx.render = renderContent;
509			tagCtx.view = parentView;
510			tagCtx.ctx = extendCtx(tagCtx.ctx, ctx); // Clone and extend parentView.ctx
511		}
512		if (tmpl = tagCtx.props.tmpl) {
513			// If the tmpl property is overridden, set the value (when initializing, or, in case of binding: ^tmpl=..., when updating)
514			tagCtx.tmpl = parentView.getTmpl(tmpl);
515		}
516
517		if (!tag) {
518			// This will only be hit for initial tagCtx (not for {{else}}) - if the tag instance does not exist yet
519			// Instantiate tag if it does not yet exist
520			// If the tag has not already been instantiated, we will create a new instance.
521			// ~tag will access the tag, even within the rendering of the template content of this tag.
522			// From child/descendant tags, can access using ~tag.parent, or ~parentTags.tagName
523			tag = new tagDef._ctr();
524			callInit = !!tag.init;
525
526			tag.parent = parentTag = ctx && ctx.tag;
527			tag.tagCtxs = tagCtxs;
528			tagDataMap = tag.dataMap;
529
530			if (linkCtx) {
531				tag._.inline = false;
532				linkCtx.tag = tag;
533				tag.linkCtx = linkCtx;
534			}
535			if (tag._.bnd = boundTag || linkCtx.fn) {
536				// Bound if {^{tag...}} or data-link="{tag...}"
537				tag._.arrVws = {};
538			} else if (tag.dataBoundOnly) {
539				error("{^{" + tagName + "}} tag must be data-bound");
540			}
541			//TODO better perf for childTags() - keep child tag.tags array, (and remove child, when disposed)
542			// tag.tags = [];
543		}
544		tagCtxs = tag.tagCtxs;
545		tagDataMap = tag.dataMap;
546
547		tagCtx.tag = tag;
548		if (tagDataMap && tagCtxs) {
549			tagCtx.map = tagCtxs[i].map; // Copy over the compiled map instance from the previous tagCtxs to the refreshed ones
550		}
551		if (!tag.flow) {
552			tagCtxCtx = tagCtx.ctx = tagCtx.ctx || {};
553
554			// tags hash: tag.ctx.tags, merged with parentView.ctx.tags,
555			tags = tag.parents = tagCtxCtx.parentTags = ctx && extendCtx(tagCtxCtx.parentTags, ctx.parentTags) || {};
556			if (parentTag) {
557				tags[parentTag.tagName] = parentTag;
558				//TODO better perf for childTags: parentTag.tags.push(tag);
559			}
560			tags[tag.tagName] = tagCtxCtx.tag = tag;
561		}
562	}
563	if (!(tag._er = onError)) {
564		tagHandlersFromProps(tag, tagCtxs[0]);
565		tag.rendering = {}; // Provide object for state during render calls to tag and elses. (Used by {{if}} and {{for}}...)
566		for (i = 0; i < l; i++) {
567			tagCtx = tag.tagCtx = tagCtxs[i];
568			props = tagCtx.props;
569			args = tag.cvtArgs();
570
571			if (mapDef = props.dataMap || tagDataMap) {
572				if (args.length || props.dataMap) {
573					thisMap = tagCtx.map;
574					if (!thisMap || thisMap.src !== args[0] || isUpdate) {
575						if (thisMap && thisMap.src) {
576							thisMap.unmap();
576 // only called if observable map - not when only used in JsRender, e.g. by {{props}}
577						}
578						thisMap = tagCtx.map = mapDef.map(args[0], props, undefined, !tag._.bnd);
579					}
580					args = [thisMap.tgt];
581				}
582			}
583			tag.ctx = tagCtx.ctx;
584
585			if (!i) {
586				if (callInit) {
587					initialTmpl = tag.template;
588					tag.init(tagCtx, linkCtx, tag.ctx);
589					callInit = undefined;
590				}
591				if (linkCtx) {
592					// Set attr on linkCtx to ensure outputting to the correct target attribute.
593					// Setting either linkCtx.attr or this.attr in the init() allows per-instance choice of target attrib.
594					linkCtx.attr = tag.attr = linkCtx.attr || tag.attr;
595				}
596				attr = tag.attr;
597				tag._.noVws = attr && attr !== HTML;
598			}
599
600			itemRet = undefined;
601			if (tag.render) {
602				itemRet = tag.render.apply(tag, args);
603			}
604			if (!args.length) {
605				args = [parentView]; // no arguments - (e.g. {{else}}) get data context from view.
606			}
607			if (itemRet === undefined) {
608				itemRet = tagCtx.render(args[0], true) || (isUpdate ? undefined : "");
609			}
610			// No return value from render, and no template/content tagCtx.render(...), so return undefined
611			ret = ret ? ret + (itemRet || "") : itemRet; // If no rendered content, this will be undefined
612		}
613		tag.rendering = undefined;
614	}
615	tag.tagCtx = tagCtxs[0];
616	tag.ctx = tag.tagCtx.ctx;
617
618	if (tag._.noVws) {
619			if (tag._.inline) {
620			// inline tag with attr set to "text" will insert HTML-encoded content - as if it was element-based innerText
621			ret = attr === "text"
622				? $converters.html(ret)
623				: "";
624		}
625	}
626	return boundTag && parentView._.onRender
627		// Call onRender (used by JsViews if present, to add binding annotations around rendered content)
628		? parentView._.onRender(ret, parentView, tag)
629		: ret;
630}
631
632//=================
633// View constructor
634//=================
635
636function View(context, type, parentView, data, template, key, onRender, contentTmpl) {
637	// Constructor for view object in view hierarchy. (Augmented by JsViews if JsViews is loaded)
638	var views, parentView_, tag, self_,
639		self = this,
640		isArray = type === "array";
641
642	self.content = contentTmpl;
643	self.views = isArray ? [] : {};
644	self.parent = parentView;
645	self.type = type || "top";
646	self.data = data;
647	self.tmpl = template;
648	// If the data is an array, this is an 'array view' with a views array for each child 'item view'
649	// If the data is not an array, this is an 'item view' with a views 'hash' object for any child nested views
650	// ._.useKey is non zero if is not an 'array view' (owning a data array). Use this as next key for adding to child views hash
651	self_ = self._ = {
652		key: 0,
653		useKey: isArray ? 0 : 1,
654		id: "" + viewId++,
655		onRender: onRender,
656		bnds: {}
657	};
658	self.linked = !!onRender;
659	if (parentView) {
660		views = parentView.views;
661		parentView_ = parentView._;
662		if (parentView_.useKey) {
663			// Parent is not an 'array view'. Add this view to its views object
664			// self._key = is the key in the parent view hash
665			views[self_.key = "_" + parentView_.useKey++] = self;
666			self.index = indexStr;
667			self.getIndex = getNestedIndex;
668		} else if (views.length === (self_.key = self.index = key)) { // Parent is an 'array view'. Add this view to its views array
669			views.push(self); // Adding to end of views array. (Using push when possible - better perf than splice)
670		} else {
671			views.splice(key, 0, self); // Inserting in views array
672		}
673		// If no context was passed in, use parent context
674		// If context was passed in, it should have been merged already with parent context
675		self.ctx = context || parentView.ctx;
676	} else {
677		self.ctx = context;
678	}
679}
680
681View.prototype = {
682	get: getView,
683	getIndex: getIndex,
684	getRsc: getResource,
685	getTmpl: getTemplate,
686	hlp: getHelper,
687	_is: "view"
688};
689
690//====================================================
691// Registration
692//====================================================
693
694function compileChildResources(parentTmpl) {
695	var storeName, resources, resourceName, resource, settings, compile, onStore;
696	for (storeName in jsvStores) {
697		settings = jsvStores[storeName];
698		if ((compile = settings.compile) && (resources = parentTmpl[storeName + "s"])) {
699			for (resourceName in resources) {
700				// compile child resource declarations (templates, tags, tags["for"] or helpers)
701				resource = resources[resourceName] = compile(resourceName, resources[resourceName], parentTmpl, 0);
702				resource._is = storeName;
702 // Only do this for compiled objects (tags, templates...)
703				if (resource && (onStore = $sub.onStore[storeName])) {
704					// e.g. JsViews integration
705					onStore(resourceName, resource, compile);
706				}
707			}
708		}
709	}
710}
711
712//===============
713// compileTag
714//===============
715
716function compileTag(name, tagDef, parentTmpl) {
717	var tmpl, baseTag, prop,
718		compiledDef = new $sub._tg();
719
720	function Tag() {
721		var tag = this;
722		tag._ = {
723			inline: true,
724			unlinked: true
725		};
726
727		tag.tagName = name;
728	}
729
730	if ($isFunction(tagDef)) {
731		// Simple tag declared as function. No presenter instantation.
732		tagDef = {
733			depends: tagDef.depends,
734			render: tagDef
735		};
736	} else if ("" + tagDef === tagDef) {
737		tagDef = {template: tagDef};
738	}
739	if (baseTag = tagDef.baseTag) {
740		tagDef.flow = !!tagDef.flow; // Set flow property, so defaults to false even if baseTag has flow=true
741		tagDef.baseTag = baseTag = "" + baseTag === baseTag
742			? (parentTmpl && parentTmpl.tags[baseTag] || $tags[baseTag])
743			: baseTag;
744
745		compiledDef = $extend(compiledDef, baseTag);
746
747		for (prop in tagDef) {
748			compiledDef[prop] = getMethod(baseTag[prop], tagDef[prop]);
749		}
750	} else {
751		compiledDef = $extend(compiledDef, tagDef);
752	}
753
754	// Tag declared as object, used as the prototype for tag instantiation (control/presenter)
755	if ((tmpl = compiledDef.template) !== undefined) {
756		compiledDef.template = "" + tmpl === tmpl ? ($templates[tmpl] || $templates(tmpl)) : tmpl;
757	}
758	if (compiledDef.init !== false) {
759		// Set init: false on tagDef if you want to provide just a render method, or render and template, but no constructor or prototype.
760		// so equivalent to setting tag to render function, except you can also provide a template.
761		(Tag.prototype = compiledDef).constructor = compiledDef._ctr = Tag;
762	}
763
764	if (parentTmpl) {
765		compiledDef._parentTmpl = parentTmpl;
766	}
767	return compiledDef;
768}
769
770function baseApply(args) {
771	// In derived method (or handler declared declaratively as in {{:foo onChange=~fooChanged}} can call base method,
772	// using this.baseApply(arguments) (Equivalent to this._superApply(arguments) in jQuery UI)
773	return this.base.apply(this, args);
774}
775
776//===============
777// compileTmpl
778//===============
779
780function compileTmpl(name, tmpl, parentTmpl, options) {
781	// tmpl is either a template object, a selector for a template script block, the name of a compiled template, or a template object
782
783	//==== nested functions ====
784	function lookupTemplate(value) {
785		// If value is of type string - treat as selector, or name of compiled template
786		// Return the template object, if already compiled, or the markup string
787		var currentName, tmpl;
788		if (("" + value === value) || value.nodeType > 0 && (elem = value)) {
789			if (!elem) {
790				if (/^\.\/[^\\:*?"<>]*$/.test(value)) {
791					// tmpl="./some/file.html"
792					// If the template is not named, use "./some/file.html" as name.
793					if (tmpl = $templates[name = name || value]) {
794						value = tmpl;
795					} else {
796						// BROWSER-SPECIFIC CODE (not on Node.js):
797						// Look for server-generated script block with id "./some/file.html"
798						elem = document.getElementById(value);
799					}
800				} else if ($.fn && !rTmplString.test(value)) {
801					try {
802						elem = $(document).find(value)[0]; // if jQuery is loaded, test for selector returning elements, and get first element
803					} catch (e) {}
804				}// END BROWSER-SPECIFIC CODE
805			} //BROWSER-SPECIFIC CODE
806			if (elem) {
807				// Generally this is a script element.
808				// However we allow it to be any element, so you can for example take the content of a div,
809				// use it as a template, and replace it by the same content rendered against data.
810				// e.g. for linking the content of a div to a container, and using the initial content as template:
811				// $.link("#content", model, {tmpl: "#content"});
812				if (options) {
813					// We will compile a new template using the markup in the script element
814					value = elem.innerHTML;
815				} else {
816					// We will cache a single copy of the compiled template, and associate it with the name
817					// (renaming from a previous name if there was one).
818					currentName = elem.getAttribute(tmplAttr);
819					if (currentName) {
820						if (currentName !== jsvTmpl) {
821							value = $templates[currentName];
822							delete $templates[currentName];
823						} else if ($.fn) {
824							value = $.data(elem)[jsvTmpl];
825						}
826					} else {
827						name = name || ($.fn ? jsvTmpl : value);
828						value = compileTmpl(name, elem.innerHTML, parentTmpl, options);
829					}
830					value.tmplName = name = name || currentName;
831					if (name !== jsvTmpl) {
832						$templates[name] = value;
833					}
834					elem.setAttribute(tmplAttr, name);
835					if ($.fn) {
836						$.data(elem, jsvTmpl, value);
837					}
838				}
839			} // END BROWSER-SPECIFIC CODE
840			elem = undefined;
841		} else if (!value.fn) {
842			value = undefined;
843			// If value is not a string. HTML element, or compiled template, return undefined
844		}
845		return value;
846	}
847
848	var elem, compiledTmpl,
849		tmplOrMarkup = tmpl = tmpl || "";
850
851	//==== Compile the template ====
852	if (options === 0) {
853		options = undefined;
854		tmplOrMarkup = lookupTemplate(tmplOrMarkup); // Top-level compile so do a template lookup
855	}
856
857	// If options, then this was already compiled from a (script) element template declaration.
858	// If not, then if tmpl is a template object, use it for options
859	options = options || (tmpl.markup ? tmpl : {});
860	options.tmplName = name;
861	if (parentTmpl) {
862		options._parentTmpl = parentTmpl;
863	}
864	// If tmpl is not a markup string or a selector string, then it must be a template object
865	// In that case, get it from the markup property of the object
866	if (!tmplOrMarkup && tmpl.markup && (tmplOrMarkup = lookupTemplate(tmpl.markup))) {
867		if (tmplOrMarkup.fn) {
868			// If the string references a compiled template object, need to recompile to merge any modified options
869			tmplOrMarkup = tmplOrMarkup.markup;
870		}
871	}
872	if (tmplOrMarkup !== undefined) {
873		if (tmplOrMarkup.fn || tmpl.fn) {
874			// tmpl is already compiled, so use it
875			if (tmplOrMarkup.fn) {
876				compiledTmpl = tmplOrMarkup;
877			}
878		} else {
879			// tmplOrMarkup is a markup string, not a compiled template
880			// Create template object
881			tmpl = tmplObject(tmplOrMarkup, options);
882			// Compile to AST and then to compiled function
883			tmplFn(tmplOrMarkup.replace(rEscapeQuotes, "\\$&"), tmpl);
884		}
885		if (!compiledTmpl) {
886			compileChildResources(options);
887
888			compiledTmpl = $extend(function() {
889				return tmpl.render.apply(tmpl, arguments);
890			}, tmpl);
891		}
892		if (name && !parentTmpl && name !== jsvTmpl) {
893			$render[name] = compiledTmpl;
894		}
895		return compiledTmpl;
896	}
897}
898
899//==== /end of function compileTmpl ====
900
901//=================
902// compileViewModel
903//=================
904
905function getDefaultVal(defaultVal, data) {
906	return $.isFunction(defaultVal)
907		? defaultVal.call(data)
908		: defaultVal;
909}
910
911function unmapArray(modelArr) {
912		var i, arr = [],
913			l = modelArr.length;
914		for (i=0; i<l; i++) {
915			arr.push(modelArr[i].unmap());
916		}
917		return arr;
918}
919
920function compileViewModel(name, type) {
921	var i, constructor,
922		viewModels = this,
923		getters = type.getters,
924		extend = type.extend,
925		id = type.id,
926		proto = $.extend({
927			_is: name || "unnamed",
928			unmap: unmap,
929			merge: merge
930		}, extend),
931		args = "",
932		body = "",
933		l = getters ? getters.length : 0,
934		$observable = $.observable,
935		getterNames = {};
936
937	function GetNew(args) {
938		constructor.apply(this, args);
939	}
940
941	function vm() {
942		return new GetNew(arguments);
943	}
944
945	function iterate(data, action) {
946		var j, getterType, defaultVal, prop, ob,
947			m = getters.length;
948		for (j=0; j<m; j++) {
949			prop = getters[j];
950			getterType = undefined;
951			if (prop + "" !== prop) {
952				getterType = prop;
953				prop = getterType.getter;
954			}
955			if ((ob = data[prop]) === undefined && getterType && (defaultVal = getterType.defaultVal) !== undefined) {
956				ob = getDefaultVal(defaultVal, data);
957			}
958			action(ob, getterType && viewModels[getterType.type], prop);
959		}
960	}
961
962	function map(data) {
963		data = data + "" === data
964			? JSON.parse(data) // Accept JSON string
965			: data;            // or object/array
966		var i, j,  l, m, prop,
967			ob = data,
968			arr = [];
969
970		if ($.isArray(data)) {
971			data = data || [];
972			l = data.length;
973			for (i=0; i<l; i++) {
974				arr.push(this.map(data[i]));
975			}
976			arr._is = name;
977			arr.unmap = unmap;
978			arr.merge = merge;
979			return arr;
980		}
981
982		if (data) {
983			iterate(data, function(ob, viewModel) {
984				if (viewModel) { // Iterate to build getters arg array (value, or mapped value)
985					ob = viewModel.map(ob);
986				}
987				arr.push(ob);
988			});
989
990			ob = this.apply(this, arr); // Insantiate this View Model, passing getters args array to constructor
991			for (prop in data) { // Copy over any other properties. that are not get/set properties
992				if (!getterNames[prop]) {
993					ob[prop] = data[prop];
994				}
995			}
996		}
997		return ob;
998	}
999
1000	function merge(data) {
1001		data = data + "" === data
1002			? JSON.parse(data) // Accept JSON string
1003			: data;            // or object/array
1004		var i, j, l, m, prop, mod, found, assigned, ob, newModArr,
1005			model = this;
1006
1007		if ($.isArray(model)) {
1008			assigned = {};
1009			newModArr = [];
1010			l = data.length;
1011			m = model.length;
1012			for (i=0; i<l; i++) {
1013				ob = data[i];
1014				found = false;
1015				for (j=0; j<m && !found; j++) {
1016					if (assigned[j]) {
1017						continue;
1018					}
1019					mod = model[j];
1020
1021					if (id) {
1022						assigned[j] = found = id + "" === id
1023						? (ob[id] && (getterNames[id] ? mod[id]() : mod[id]) === ob[id])
1024						: id(mod, ob);
1025					}
1026				}
1027				if (found) {
1028					mod.merge(ob);
1029					newModArr.push(mod);
1030				} else {
1031					newModArr.push(vm.map(ob));
1032				}
1033			}
1034			if ($observable) {
1035				$observable(model).refresh(newModArr);
1036			} else {
1037				model.splice.apply(model, [0, model.length].concat(newModArr));
1038			}
1039			return;
1040		}
1041		iterate(data, function(ob, viewModel, getter) {
1042			if (viewModel) {
1043				model[getter]().merge(ob); // Update typed property
1044			} else {
1045				model[getter](ob); // Update non-typed property
1046			}
1047		});
1048		for (prop in data) {
1049			if (!getterNames[prop]) {
1050				model[prop] = data[prop];
1051			}
1052		}
1053	}
1054
1055	function unmap() {
1056		var ob, prop, i, l, getterType, arr, value,
1057			model = this;
1058
1059		if ($.isArray(model)) {
1060			return unmapArray(model);
1061		}
1062		ob = {};
1063		l = getters.length;
1064		for (i=0; i<l; i++) {
1065			prop = getters[i];
1066			getterType = undefined;
1067			if (prop + "" !== prop) {
1068				getterType = prop;
1069				prop = getterType.getter;
1070			}
1071			value = model[prop]();
1072			ob[prop] = getterType && value && viewModels[getterType.type]
1073				? $.isArray(value)
1074					? unmapArray(value)
1075					: value.unmap()
1076				: value;
1077		}
1078		for (prop in model) {
1079			if (prop !== "_is" && !getterNames[prop] && (prop.charAt(0) !== "_" || !getterNames[prop.slice(1)]) && !$.isFunction(model[prop])) {
1080				ob[prop] = model[prop];
1081			}
1082		}
1083		return ob;
1084	}
1085
1086	GetNew.prototype = proto;
1087
1088	for (i=0; i<l; i++) {
1089		(function(getter) {
1090			getter = getter.getter || getter;
1091			getterNames[getter] = i+1;
1092			var privField = "_" + getter;
1093
1094			args += (args ? "," : "") + getter;
1095			body += "this." + privField + " = " + getter + ";\n";
1096			proto[getter] = proto[getter] || function(val) {
1097				if (!arguments.length) {
1098					return this[privField]; // If there is no argument, use as a getter
1099				}
1100				if ($observable) {
1101					$observable(this).setProperty(getter, val);
1102				} else {
1103					this[privField] = val;
1104				}
1105			};
1106
1107			if ($observable) {
1108				proto[getter].set = proto[getter].set || function(val) {
1109					this[privField] = val; // Setter called by observable property change
1110				};
1111			}
1112		})(getters[i]);
1113	}
1114
1115	constructor = new Function(args, body.slice(0, -1));
1116	constructor.prototype = proto;
1117	proto.constructor = constructor;
1118
1119	vm.map = map;
1120	vm.getters = getters;
1121	vm.extend = extend;
1122	vm.id = id;
1123	return vm;
1124}
1125
1126function tmplObject(markup, options) {
1127	// Template object constructor
1128	var htmlTag,
1129		wrapMap = $subSettingsAdvanced._wm || {}, // Only used in JsViews. Otherwise empty: {}
1130		tmpl = $extend(
1131			{
1132				tmpls: [],
1133				links: {}, // Compiled functions for link expressions
1134				bnds: [],
1135				_is: "template",
1136				render: renderContent
1137			},
1138			options
1139		);
1140
1141	tmpl.markup = markup;
1142	if (!options.htmlTag) {
1143		// Set tmpl.tag to the top-level HTML tag used in the template, if any...
1144		htmlTag = rFirstElem.exec(markup);
1145		tmpl.htmlTag = htmlTag ? htmlTag[1].toLowerCase() : "";
1146	}
1147	htmlTag = wrapMap[tmpl.htmlTag];
1148	if (htmlTag && htmlTag !== wrapMap.div) {
1149		// When using JsViews, we trim templates which are inserted into HTML contexts where text nodes are not rendered (i.e. not 'Phrasing Content').
1150		// Currently not trimmed for <li> tag. (Not worth adding perf cost)
1151		tmpl.markup = $.trim(tmpl.markup);
1152	}
1153
1154	return tmpl;
1155}
1156
1157//==============
1158// registerStore
1159//==============
1160
1161function registerStore(storeName, storeSettings) {
1162
1163	function theStore(name, item, parentTmpl) {
1164		// The store is also the function used to add items to the store. e.g. $.templates, or $.views.tags
1165
1166		// For store of name 'thing', Call as:
1167		//    $.views.things(items[, parentTmpl]),
1168		// or $.views.things(name, item[, parentTmpl])
1169
1170		var onStore, compile, itemName, thisStore;
1171		if (name && typeof name === OBJECT && !name.nodeType && !name.markup && !name.getTgt && !(storeName === "viewModel" && name.getters || name.extend)) {
1172			// Call to $.views.things(items[, parentTmpl]),
1173
1174			// Adding items to the store
1175			// If name is a hash, then item is parentTmpl. Iterate over hash and call store for key.
1176			for (itemName in name) {
1177				theStore(itemName, name[itemName], item);
1178			}
1179			return item || $views;
1180		}
1181		// Adding a single unnamed item to the store
1182		if (item === undefined) {
1183			item = name;
1184			name = undefined;
1185		}
1186		if (name && "" + name !== name) { // name must be a string
1187			parentTmpl = item;
1188			item = name;
1189			name = undefined;
1190		}
1191		thisStore = parentTmpl
1192			? storeName === "viewModel"
1193				? parentTmpl
1194				: (parentTmpl[storeNames] = parentTmpl[storeNames] || {})
1195			: theStore;
1196		compile = storeSettings.compile;
1197		if (item === null) {
1198			// If item is null, delete this entry
1199			if (name) {
1200				delete thisStore[name];
1201			}
1202		} else {
1203			item = compile ? compile.call(thisStore, name, item, parentTmpl, 0) : item;
1204			if (name) {
1205				thisStore[name] = item;
1206			}
1207		}
1208		if (compile && item) {
1209			item._is = storeName;
1209 // Only do this for compiled objects (tags, templates...)
1210		}
1211		if (item && (onStore = $sub.onStore[storeName])) {
1212			// e.g. JsViews integration
1213			onStore(name, item, compile);
1214		}
1215		return item;
1216	}
1217
1218	var storeNames = storeName + "s";
1219
1220	$views[storeNames] = theStore;
1221}
1222
1223function addSetting(st) {
1224	$viewsSettings[st] = function(value) {
1225		return arguments.length
1226			? ($subSettings[st] = value, $viewsSettings)
1227			: $subSettings[st];
1228	};
1229}
1230
1231//=========
1232// dataMap
1233//=========
1234
1235function dataMap(mapDef) {
1236	function Map(source, options) {
1237		this.tgt = mapDef.getTgt(source, options);
1238	}
1239
1240	if ($isFunction(mapDef)) {
1241		// Simple map declared as function
1242		mapDef = {
1243			getTgt: mapDef
1244		};
1245	}
1246
1247	if (mapDef.baseMap) {
1248		mapDef = $extend($extend({}, mapDef.baseMap), mapDef);
1249	}
1250
1251	mapDef.map = function(source, options) {
1252		return new Map(source, options);
1253	};
1254	return mapDef;
1255}
1256
1257//==============
1258// renderContent
1259//==============
1260
1261function renderContent(data, context, noIteration, parentView, key, onRender) {
1262	var i, l, tag, tmpl, tagCtx, isTopRenderCall, prevData, prevIndex,
1263		view = parentView,
1264		result = "";
1265
1266	if (context === true) {
1267		noIteration = context; // passing boolean as second param - noIteration
1268		context = undefined;
1269	} else if (typeof context !== OBJECT) {
1270		context = undefined; // context must be a boolean (noIteration) or a plain object
1271	}
1272
1273	if (tag = this.tag) {
1274		// This is a call from renderTag or tagCtx.render(...)
1275		tagCtx = this;
1276		view = view || tagCtx.view;
1277		tmpl = view.getTmpl(tag.template || tagCtx.tmpl);
1278		if (!arguments.length) {
1279			data = view;
1280		}
1281	} else {
1282		// This is a template.render(...) call
1283		tmpl = this;
1284	}
1285
1286	if (tmpl) {
1287		if (!view && data && data._is === "view") {
1288			view = data; // When passing in a view to render or link (and not passing in a parent view) use the passed-in view as parentView
1289		}
1290
1291		if (view) {
1292			if (data === view) {
1293				// Inherit the data from the parent view.
1294				// This may be the contents of an {{if}} block
1295				data = view.data;
1296			}
1297		}
1298
1299		isTopRenderCall = !view;
1300		isRenderCall = isRenderCall || isTopRenderCall;
1301		if (!view) {
1302			(context = context || {}).root = data; // Provide ~root as shortcut to top-level data.
1303		}
1304		if (!isRenderCall || $subSettingsAdvanced.useViews || tmpl.useViews || view && view !== topView) {
1305			result = renderWithViews(tmpl, data, context, noIteration, view, key, onRender, tag);
1306		} else {
1307			if (view) { // In a block
1308				prevData = view.data;
1309				prevIndex = view.index;
1310				view.index = indexStr;
1311			} else {
1312				view = topView;
1313				view.data = data;
1314				view.ctx = context;
1315			}
1316			if ($isArray(data) && !noIteration) {
1317				// Create a view for the array, whose child views correspond to each data item. (Note: if key and parentView are passed in
1318				// along with parent view, treat as insert -e.g. from view.addViews - so parentView is already the view item for array)
1319				for (i = 0, l = data.length; i < l; i++) {
1320					view.index = i;
1321					view.data = data[i];
1322					result += tmpl.fn(data[i], view, $sub);
1323				}
1324			} else {
1325				view.data = data;
1326				result += tmpl.fn(data, view, $sub);
1327			}
1328			view.data = prevData;
1329			view.index = prevIndex;
1330		}
1331		if (isTopRenderCall) {
1332			isRenderCall = undefined;
1333		}
1334	}
1335	return result;
1336}
1337
1338function renderWithViews(tmpl, data, context, noIteration, view, key, onRender, tag) {
1339	function setItemVar(item) {
1340		// When itemVar is specified, set modified ctx with user-named ~item
1341		newCtx = $extend({}, context);
1342		newCtx[itemVar] = item;
1343	}
1344
1345	// Render template against data as a tree of subviews (nested rendered template instances), or as a string (top-level template).
1346	// If the data is the parent view, treat as noIteration, re-render with the same data context.
1347	var i, l, newView, childView, itemResult, swapContent, contentTmpl, outerOnRender, tmplName, itemVar, newCtx, tagCtx,
1348		result = "";
1349
1350	if (tag) {
1351		// This is a call from renderTag or tagCtx.render(...)
1352		tmplName = tag.tagName;
1353		tagCtx = tag.tagCtx;
1354		context = context ? extendCtx(context, tag.ctx) : tag.ctx;
1355
1356		if (tmpl === view.content) { // {{xxx tmpl=#content}}
1357			contentTmpl = tmpl !== view.ctx._wrp // We are rendering the #content
1358				? view.ctx._wrp // #content was the tagCtx.props.tmpl wrapper of the block content - so within this view, #content will now be the view.ctx._wrp block content
1359				: undefined; // #content was the view.ctx._wrp block content - so within this view, there is no longer any #content to wrap.
1360		} else if (tmpl !== tagCtx.content) {
1361			if (tmpl === tag.template) { // Rendering {{tag}} tag.template, replacing block content.
1362				contentTmpl = tagCtx.tmpl; // Set #content to block content (or wrapped block content if tagCtx.props.tmpl is set)
1363				context._wrp = tagCtx.content; // Pass wrapped block content to nested views
1364			} else { // Rendering tagCtx.props.tmpl wrapper
1365				contentTmpl = tagCtx.content || view.content; // Set #content to wrapped block content
1366			}
1367		} else {
1368			contentTmpl = view.content; // Nested views inherit same wrapped #content property
1369		}
1370
1371		if (tagCtx.props.link === false) {
1372			// link=false setting on block tag
1373			// We will override inherited value of link by the explicit setting link=false taken from props
1374			// The child views of an unlinked view are also unlinked. So setting child back to true will not have any effect.
1375			context = context || {};
1376			context.link = false;
1377		}
1378
1379		if (itemVar = tagCtx.props.itemVar) {
1380			if (itemVar.charAt(0) !== "~") {
1381				syntaxError("Use itemVar='~myItem'");
1382			}
1383			itemVar = itemVar.slice(1);
1384		}
1385	}
1386
1387	if (view) {
1388		onRender = onRender || view._.onRender;
1389		context = extendCtx(context, view.ctx);
1390	}
1391
1392	if (key === true) {
1393		swapContent = true;
1394		key = 0;
1395	}
1396
1397	// If link===false, do not call onRender, so no data-linking marker nodes
1398	if (onRender && (context && context.link === false || tag && tag._.noVws)) {
1399		onRender = undefined;
1400	}
1401	outerOnRender = onRender;
1402	if (onRender === true) {
1403		// Used by view.refresh(). Don't create a new wrapper view.
1404		outerOnRender = undefined;
1405		onRender = view._.onRender;
1406	}
1407	// Set additional context on views created here, (as modified context inherited from the parent, and to be inherited by child views)
1408	context = tmpl.helpers
1409		? extendCtx(tmpl.helpers, context)
1410		: context;
1411
1412	newCtx = context;
1413	if ($isArray(data) && !noIteration) {
1414		// Create a view for the array, whose child views correspond to each data item. (Note: if key and view are passed in
1415		// along with parent view, treat as insert -e.g. from view.addViews - so view is already the view item for array)
1416		newView = swapContent
1417			? view
1418			: (key !== undefined && view)
1419				|| new View(context, "array", view, data, tmpl, key, onRender);
1420		if (view && view._.useKey) {
1421			// Parent is not an 'array view'
1422			newView._.bnd = !tag || tag._.bnd && tag; // For array views that are data bound for collection change events, set the
1423			// view._.bnd property to true for top-level link() or data-link="{for}", or to the tag instance for a data-bound tag, e.g. {^{for ...}}
1424		}
1425		if (itemVar) {
1426			newView.it = itemVar;
1427		}
1428		itemVar = newView.it;
1429		for (i = 0, l = data.length; i < l; i++) {
1430			// Create a view for each data item.
1431			if (itemVar) {
1432				setItemVar(data[i]); // use modified ctx with user-named ~item
1433			}
1434			childView = new View(newCtx, "item", newView, data[i], tmpl, (key || 0) + i, onRender, contentTmpl);
1435
1436			itemResult = tmpl.fn(data[i], childView, $sub);
1437			result += newView._.onRender ? newView._.onRender(itemResult, childView) : itemResult;
1438		}
1439	} else {
1440		// Create a view for singleton data object. The type of the view will be the tag name, e.g. "if" or "myTag" except for
1441		// "item", "array" and "data" views. A "data" view is from programmatic render(object) against a 'singleton'.
1442		if (itemVar) {
1443			setItemVar(data);
1444		}
1445		newView = swapContent ? view : new View(newCtx, tmplName || "data", view, data, tmpl, key, onRender, contentTmpl);
1446		if (tag && !tag.flow) {
1447			newView.tag = tag;
1448		}
1449		result += tmpl.fn(data, newView, $sub);
1450	}
1451	return outerOnRender ? outerOnRender(result, newView) : result;
1452}
1453
1454//===========================
1455// Build and compile template
1456//===========================
1457
1458// Generate a reusable function that will serve to render a template against data
1459// (Compile AST then build template function)
1460
1461function onRenderError(e, view, fallback) {
1462	var message = fallback !== undefined
1463		? $isFunction(fallback)
1464			? fallback.call(view.data, e, view)
1465			: fallback || ""
1466		: "{Error: " + e.message + "}";
1467
1468	if ($subSettings.onError && (fallback = $subSettings.onError.call(view.data, e, fallback && message, view)) !== undefined) {
1469		message = fallback; // There is a settings.debugMode(handler) onError override. Call it, and use return value (if any) to replace message
1470	}
1471
1472	return view && !view.linkCtx ? $converters.html(message) : message;
1473}
1474
1475function error(message) {
1476	throw new $sub.Err(message);
1477}
1478
1479function syntaxError(message) {
1480	error("Syntax error\n" + message);
1481}
1482
1483function tmplFn(markup, tmpl, isLinkExpr, convertBack, hasElse) {
1484	// Compile markup to AST (abtract syntax tree) then build the template function code from the AST nodes
1485	// Used for compiling templates, and also by JsViews to build functions for data link expressions
1486
1487	//==== nested functions ====
1488	function pushprecedingContent(shift) {
1489		shift -= loc;
1490		if (shift) {
1491			content.push(markup.substr(loc, shift).replace(rNewLine, "\\n"));
1492		}
1493	}
1494
1495	function blockTagCheck(tagName, block) {
1496		if (tagName) {
1497			tagName += '}}';
1498			//			'{{include}} block has {{/for}} with no open {{for}}'
1499			syntaxError((
1500				block
1501					? '{{' + block + '}} block has {{/' + tagName + ' without {{' + tagName
1502					: 'Unmatched or missing {{/' + tagName) + ', in template:\n' + markup);
1503		}
1504	}
1505
1506	function parseTag(all, bind, tagName, converter, colon, html, codeTag, params, slash, bind2, closeBlock, index) {
1507/*
1508
1509     bind     tagName         cvt   cln html code    params            slash   bind2         closeBlk  comment
1510/(?:{(\^)?{(?:(\w+(?=[\/\s}]))|(\w+)?(:)|(>)|(\*))\s*((?:[^}]|}(?!}))*?)(\/)?|{(\^)?{(?:(?:\/(\w+))\s*|!--[\s\S]*?--))}}/g
1511
1512(?:
1513  {(\^)?{            bind
1514  (?:
1515    (\w+             tagName
1516      (?=[\/\s}])
1517    )
1518    |
1519    (\w+)?(:)        converter colon
1520    |
1521    (>)              html
1522    |
1523    (\*)             codeTag
1524  )
1525  \s*
1526  (                  params
1527    (?:[^}]|}(?!}))*?
1528  )
1529  (\/)?              slash
1530  |
1531  {(\^)?{            bind2
1532  (?:
1533    (?:\/(\w+))\s*   closeBlock
1534    |
1535    !--[\s\S]*?--    comment
1536  )
1537)
1538}}/g
1539
1540*/
1541		if (codeTag && bind || slash && !tagName || params && params.slice(-1) === ":" || bind2) {
1542			syntaxError(all);
1543		}
1544
1545		// Build abstract syntax tree (AST): [tagName, converter, params, content, hash, bindings, contentMarkup]
1546		if (html) {
1547			colon = ":";
1548			converter = HTML;
1549		}
1550		slash = slash || isLinkExpr && !hasElse;
1551
1552		var pathBindings = (bind || isLinkExpr) && [[]],
1553			props = "",
1554			args = "",
1555			ctxProps = "",
1556			paramsArgs = "",
1557			paramsProps = "",
1558			paramsCtxProps = "",
1559			onError = "",
1560			useTrigger = "",
1561			// Block tag if not self-closing and not {{:}} or {{>}} (special case) and not a data-link expression
1562			block = !slash && !colon;
1563
1564		//==== nested helper function ====
1565		tagName = tagName || (params = params || "#data", colon); // {{:}} is equivalent to {{:#data}}
1566		pushprecedingContent(index);
1567		loc = index + all.length; // location marker - parsed up to here
1568		if (codeTag) {
1569			if (allowCode) {
1570				content.push(["*", "\n" + params.replace(/^:/, "ret+= ").replace(rUnescapeQuotes, "$1") + ";\n"]);
1571			}
1572		} else if (tagName) {
1573			if (tagName === "else") {
1574				if (rTestElseIf.test(params)) {
1575					syntaxError('for "{{else if expr}}" use "{{else expr}}"');
1576				}
1577				pathBindings = current[7] && [[]];
1578				current[8] = markup.substring(current[8], index); // contentMarkup for block tag
1579				current = stack.pop();
1580				content = current[2];
1581				block = true;
1582			}
1583			if (params) {
1584				// remove newlines from the params string, to avoid compiled code errors for unterminated strings
1585				parseParams(params.replace(rNewLine, " "), pathBindings, tmpl)
1586					.replace(rBuildHash, function(all, onerror, isCtx, key, keyToken, keyValue, arg, param) {
1587						key = "'" + keyToken + "':";
1588						if (arg) {
1589							args += keyValue + ",";
1590							paramsArgs += "'" + param + "',";
1591						} else if (isCtx) {
1592							ctxProps += key + keyValue + ",";
1593							paramsCtxProps += key + "'" + param + "',";
1594						} else if (onerror) {
1595							onError += keyValue;
1596						} else {
1597							if (keyToken === "trigger") {
1598								useTrigger += keyValue;
1599							}
1600							props += key + keyValue + ",";
1601							paramsProps += key + "'" + param + "',";
1602							hasHandlers = hasHandlers || rHasHandlers.test(keyToken);
1603						}
1604						return "";
1605					}).slice(0, -1);
1606			}
1607
1608			if (pathBindings && pathBindings[0]) {
1609				pathBindings.pop(); // Remove the bindings that was prepared for next arg. (There is always an extra one ready).
1610			}
1611
1612			newNode = [
1613					tagName,
1614					converter || !!convertBack || hasHandlers || "",
1615					block && [],
1616					parsedParam(paramsArgs || (tagName === ":" ? "'#data'," : ""), paramsProps, paramsCtxProps), // {{:}} equivalent to {{:#data}}
1617					parsedParam(args || (tagName === ":" ? "data," : ""), props, ctxProps),
1618					onError,
1619					useTrigger,
1620					pathBindings || 0
1621				];
1622			content.push(newNode);
1623			if (block) {
1624				stack.push(current);
1625				current = newNode;
1626				current[8] = loc; // Store current location of open tag, to be able to add contentMarkup when we reach closing tag
1627			}
1628		} else if (closeBlock) {
1629			blockTagCheck(closeBlock !== current[0] && current[0] !== "else" && closeBlock, current[0]);
1630			current[8] = markup.substring(current[8], index); // contentMarkup for block tag
1631			current = stack.pop();
1632		}
1633		blockTagCheck(!current && closeBlock);
1634		content = current[2];
1635	}
1636	//==== /end of nested functions ====
1637
1638	var result, newNode, hasHandlers,
1639		allowCode = $subSettings.allowCode || tmpl && tmpl.allowCode
1640			|| $viewsSettings.allowCode === true, // include direct setting of settings.allowCode true for backward compat only
1641		astTop = [],
1642		loc = 0,
1643		stack = [],
1644		content = astTop,
1645		current = [,,astTop];
1646
1647	if (allowCode) {
1648		tmpl.allowCode = allowCode;
1649	}
1650
1651//TODO	result = tmplFnsCache[markup]; // Only cache if template is not named and markup length < ...,
1652//and there are no bindings or subtemplates?? Consider standard optimization for data-link="a.b.c"
1653//		if (result) {
1654//			tmpl.fn = result;
1655//		} else {
1656
1657//		result = markup;
1658	if (isLinkExpr) {
1659		if (convertBack !== undefined) {
1660			markup = markup.slice(0, -convertBack.length - 2) + delimCloseChar1;
1661		}
1662		markup = delimOpenChar0 + markup + delimCloseChar1;
1663	}
1664
1665	blockTagCheck(stack[0] && stack[0][2].pop()[0]);
1666	// Build the AST (abstract syntax tree) under astTop
1667	markup.replace(rTag, parseTag);
1668
1669	pushprecedingContent(markup.length);
1670
1671	if (loc = astTop[astTop.length - 1]) {
1672		blockTagCheck("" + loc !== loc && (+loc[8] === loc[8]) && loc[0]);
1673	}
1674//			result = tmplFnsCache[markup] = buildCode(astTop, tmpl);
1675//		}
1676
1677	if (isLinkExpr) {
1678		result = buildCode(astTop, markup, isLinkExpr);
1679		setPaths(result, [astTop[0][7]]); // With data-link expressions, pathBindings array is astTop[0][7]
1680	} else {
1681		result = buildCode(astTop, tmpl);
1682	}
1683	return result;
1684}
1685
1686function setPaths(fn, pathsArr) {
1687	var key, paths,
1688		i = 0,
1689		l = pathsArr.length;
1690	fn.deps = [];
1691	for (; i < l; i++) {
1692		paths = pathsArr[i];
1693		for (key in paths) {
1694			if (key !== "_jsvto" && paths[key].length) {
1695				fn.deps = fn.deps.concat(paths[key]); // deps is the concatenation of the paths arrays for the different bindings
1696			}
1697		}
1698	}
1699	fn.paths = paths; // The array of paths arrays for the different bindings
1700}
1701
1702function parsedParam(args, props, ctx) {
1703	return [args.slice(0, -1), props.slice(0, -1), ctx.slice(0, -1)];
1704}
1705
1706function paramStructure(parts, type) {
1707	return '\n\t'
1708		+ (type
1709			? type + ':{'
1710			: '')
1711		+ 'args:[' + parts[0] + ']'
1712		+ (parts[1] || !type
1713			? ',\n\tprops:{' + parts[1] + '}'
1714			: "")
1715		+ (parts[2] ? ',\n\tctx:{' + parts[2] + '}' : "");
1716}
1717
1718function parseParams(params, pathBindings, tmpl) {
1719
1720	function parseTokens(all, lftPrn0, lftPrn, bound, path, operator, err, eq, path2, prn, comma, lftPrn2, apos, quot, rtPrn, rtPrnDot, prn2, space, index, full) {
1721	// /(\()(?=\s*\()|(?:([([])\s*)?(?:(\^?)(!*?[#~]?[\w$.^]+)?\s*((\+\+|--)|\+|-|&&|\|\||===|!==|==|!=|<=|>=|[<>%*:?\/]|(=))\s*|(!*?[#~]?[\w$.^]+)([([])?)|(,\s*)|(\(?)\\?(?:(')|("))|(?:\s*(([)\]])(?
1721=\s*[.^]|\s*$|[^([])|[)\]])([([]?))|(\s+)/g,
1722	//   lftPrn0        lftPrn        bound            path    operator err                                                eq             path2       prn    comma   lftPrn2   apos quot      rtPrn rtPrnDot                        prn2  space
1723		// (left paren? followed by (path? followed by operator) or (path followed by paren?)) or comma or apos or quot or right paren or space
1724		bound = bindings && bound;
1725		if (bound && !eq) {
1726			path = bound + path; // e.g. some.fn(...)^some.path - so here path is "^some.path"
1727		}
1728		operator = operator || "";
1729		lftPrn = lftPrn || lftPrn0 || lftPrn2;
1730		path = path || path2;
1731		// Could do this - but not worth perf cost?? :-
1732		// if (!path.lastIndexOf("#data.", 0)) { path = path.slice(6); } // If path starts with "#data.", remove that.
1733		prn = prn || prn2 || "";
1734
1735		var expr, exprFn, binds, theOb, newOb,
1736			rtSq = ")";
1737
1738		if (prn === "[") {
1739			prn  ="[j._sq(";
1740			rtSq = ")]";
1741		}
1742
1743		function parsePath(allPath, not, object, helper, view, viewProperty, pathTokens, leafToken) {
1744			//rPath = /^(!*?)(?:null|true|false|\d[\d.]*|([\w$]+|\.|~([\w$]+)|#(view|([\w$]+))?)([\w$.^]*?)(?:[.[^]([\w$]+)\]?)?)$/g,
1745			//          not                               object     helper    view  viewProperty pathTokens      leafToken
1746			var subPath = object === ".";
1747			if (object) {
1748				path = path.slice(not.length);
1749				if (/^\.?constructor$/.test(leafToken||path)) {
1750					syntaxError(allPath);
1751				}
1752				if (!subPath) {
1753					allPath = (helper
1754							? 'view.hlp("' + helper + '")'
1755							: view
1756								? "view"
1757								: "data")
1758						+ (leafToken
1759							? (viewProperty
1760								? "." + viewProperty
1761								: helper
1762									? ""
1763									: (view ? "" : "." + object)
1764								) + (pathTokens || "")
1765							: (leafToken = helper ? "" : view ? viewProperty || "" : object, ""));
1766
1767					allPath = allPath + (leafToken ? "." + leafToken : "");
1768
1769					allPath = not + (allPath.slice(0, 9) === "view.data"
1770						? allPath.slice(5) // convert #view.data... to data...
1771						: allPath);
1772				}
1773				if (bindings) {
1774					binds = named === "linkTo" ? (bindto = pathBindings._jsvto = pathBindings._jsvto || []) : bndCtx.bd;
1775					if (theOb = subPath && binds[binds.length-1]) {
1776						if (theOb._jsv) {
1777							while (theOb.sb) {
1778								theOb = theOb.sb;
1779							}
1780							if (theOb.bnd) {
1781								path = "^" + path.slice(1);
1782							}
1783							theOb.sb = path;
1784							theOb.bnd = theOb.bnd || path.charAt(0) === "^";
1785						}
1786					} else {
1787						binds.push(path);
1788					}
1789					pathStart[parenDepth] = index + (subPath ? 1 : 0);
1790				}
1791			}
1792			return allPath;
1793		}
1794
1795		if (err && !aposed && !quoted) {
1796			syntaxError(params);
1797		} else {
1798			if (bindings && rtPrnDot && !aposed && !quoted) {
1799				// This is a binding to a path in which an object is returned by a helper/data function/expression, e.g. foo()^x.y or (a?b:c)^x.y
1800				// We create a compiled function to get the object instance (which will be called when the dependent data of the subexpression changes, to return the new object, and trigger re-binding of the subsequent path)
1801				if (!named || boundName || bindto) {
1802					expr = pathStart[parenDepth - 1];
1803					if (full.length - 1 > index - (expr || 0)) { // We need to compile a subexpression
1804						expr = full.slice(expr, index + all.length);
1805						if (exprFn !== true) { // If not reentrant call during compilation
1806							binds = bindto || bndStack[parenDepth-1].bd;
1807							// Insert exprOb object, to be used during binding to return the computed object
1808							theOb = binds[binds.length-1];
1809							if (theOb && theOb.prm) {
1810								while (theOb.sb && theOb.sb.prm) {
1811									theOb = theOb.sb;
1812								}
1813								newOb = theOb.sb = {path: theOb.sb, bnd: theOb.bnd};
1814							} else {
1815								binds.push(newOb = {path: binds.pop()}); // Insert exprOb object, to be used during binding to return the computed object
1816							}											 // (e.g. "some.object()" in "some.object().a.b" - to be used as context for binding the following tokens "a.b")
1817						}
1818						rtPrnDot = delimOpenChar1 + ":" + expr // The parameter or function subexpression
1819							+ " onerror=''" // set onerror='' in order to wrap generated code with a try catch - returning '' as object instance if there is an error/missing parent
1820							+ delimCloseChar0;
1821						exprFn = tmplLinks[rtPrnDot];
1822						if (!exprFn) {
1823							tmplLinks[rtPrnDot] = true; // Flag that this exprFn (for rtPrnDot) is being compiled
1824							tmplLinks[rtPrnDot] = exprFn = tmplFn(rtPrnDot, tmpl, true); // Compile the expression (or use cached copy already in tmpl.links)
1825						}
1826						if (exprFn !== true && newOb) {
1827							// If not reentrant call during compilation
1828							newOb._jsv = exprFn;
1829							newOb.prm = bndCtx.bd;
1830							newOb.bnd = newOb.bnd || newOb.path && newOb.path.indexOf("^") >= 0;
1831						}
1832					}
1833				}
1834			}
1835			return (aposed
1836				// within single-quoted string
1837				? (aposed = !apos, (aposed ? all : lftPrn2 + '"'))
1838				: quoted
1839				// within double-quoted string
1840					? (quoted = !quot, (quoted ? all : lftPrn2 + '"'))
1841					:
1842				(
1843					(lftPrn
1844						? (pathStart[parenDepth] = index++, bndCtx = bndStack[++parenDepth] = {bd: []}, lftPrn)
1845						: "")
1846					+ (space
1847						? (parenDepth
1848							? ""
1849				// New arg or prop - so insert backspace \b (\x08) as separator for named params, used subsequently by rBuildHash, and prepare new bindings array
1850							: (paramIndex = full.slice(paramIndex, index), named
1851								? (named = boundName = bindto = false, "\b")
1852								: "\b,") + paramIndex + (paramIndex = index + all.length, bindings && pathBindings.push(bndCtx.bd = []), "\b")
1853						)
1854						: eq
1855				// named param. Remove bindings for arg and create instead bindings array for prop
1856							? (parenDepth && syntaxError(params), bindings && pathBindings.pop(), named = path, boundName = bound, paramIndex = index + all.length, bound && (bindings = bndCtx.bd = pathBindings[named] = []), path + ':')
1857							: path
1858				// path
1859								? (path.split("^").join(".").replace(rPath, parsePath)
1860									+ (prn
1861				// some.fncall(
1862										? (bndCtx = bndStack[++parenDepth] = {bd: []}, fnCall[parenDepth] = rtSq, prn)
1863										: operator)
1864								)
1865								: operator
1866				// operator
1867									? operator
1868									: rtPrn
1869				// function
1870										? ((rtPrn = fnCall[parenDepth] || rtPrn, fnCall[parenDepth] = false, bndCtx = bndStack[--parenDepth], rtPrn)
1871											+ (prn // rtPrn and prn, e.g )( in (a)() or a()(), or )[ in a()[]
1872												? (bndCtx = bndStack[++parenDepth], fnCall[parenDepth] = rtSq, prn)
1873												: "")
1874										)
1875										: comma
1876											? (fnCall[parenDepth] || syntaxError(params), ",") // We don't allow top-level literal arrays or objects
1877											: lftPrn0
1878												? ""
1879												: (aposed = apos, quoted = quot, '"')
1880				))
1881			);
1882		}
1883	}
1884
1885	var named, bindto, boundName,
1886		quoted, // boolean for string content in double quotes
1887		aposed, // or in single quotes
1888		bindings = pathBindings && pathBindings[0], // bindings array for the first arg
1889		bndCtx = {bd: bindings},
1890		bndStack = {0: bndCtx},
1891		paramIndex = 0, // list,
1892		tmplLinks = tmpl ? tmpl.links : bindings && (bindings.links = bindings.links || {}),
1893		// The following are used for tracking path parsing including nested paths, such as "a.b(c^d + (e))^f", and chained computed paths such as
1894		// "a.b().c^d().e.f().g" - which has four chained paths, "a.b()", "^c.d()", ".e.f()" and ".g"
1895		parenDepth = 0,
1896		fnCall = {}, // We are in a function call
1897		pathStart = {}, // tracks the start of the current path such as c^d() in the above example
1898		result = (params + (tmpl ? " " : "")).replace(rParams, parseTokens);
1899
1900	return !parenDepth && result || syntaxError(params); // Syntax error if unbalanced parens in params expression
1901}
1902
1903function buildCode(ast, tmpl, isLinkExpr) {
1904	// Build the template function code from the AST nodes, and set as property on the passed-in template object
1905	// Used for compiling templates, and also by JsViews to build functions for data link expressions
1906	var i, node, tagName, converter, tagCtx, hasTag, hasEncoder, getsVal, hasCnvt, useCnvt, tmplBindings, pathBindings, params, boundOnErrStart, boundOnErrEnd,
1907		tagRender, nestedTmpls, tmplName, nestedTmpl, tagAndElses, content, markup, nextIsElse, oldCode, isElse, isGetVal, tagCtxFn, onError, tagStart, trigger,
1908		tmplBindingKey = 0,
1909		useViews = $subSettingsAdvanced.useViews || tmpl.useViews || tmpl.tags || tmpl.templates || tmpl.helpers || tmpl.converters,
1910		code = "",
1911		tmplOptions = {},
1912		l = ast.length;
1913
1914	if ("" + tmpl === tmpl) {
1915		tmplName = isLinkExpr ? 'data-link="' + tmpl.replace(rNewLine, " ").slice(1, -1) + '"' : tmpl;
1916		tmpl = 0;
1917	} else {
1918		tmplName = tmpl.tmplName || "unnamed";
1919		if (tmpl.allowCode) {
1920			tmplOptions.allowCode = true;
1921		}
1922		if (tmpl.debug) {
1923			tmplOptions.debug = true;
1924		}
1925		tmplBindings = tmpl.bnds;
1926		nestedTmpls = tmpl.tmpls;
1927	}
1928	for (i = 0; i < l; i++) {
1929		// AST nodes: [0: tagName, 1: converter, 2: content, 3: params, 4: code, 5: onError, 6: trigger, 7:pathBindings, 8: contentMarkup]
1930		node = ast[i];
1931
1932		// Add newline for each callout to t() c() etc. and each markup string
1933		if ("" + node === node) {
1934			// a markup string to be inserted
1935			code += '\n+"' + node + '"';
1936		} else {
1937			// a compiled tag expression to be inserted
1938			tagName = node[0];
1939			if (tagName === "*") {
1940				// Code tag: {{* }}
1941				code += ";\n" + node[1] + "\nret=ret";
1942			} else {
1943				converter = node[1];
1944				content = !isLinkExpr && node[2];
1945				tagCtx = paramStructure(node[3], 'params') + '},' + paramStructure(params = node[4]);
1946				onError = node[5];
1947				trigger = node[6];
1948				markup = node[8] && node[8].replace(rUnescapeQuotes, "$1");
1949				if (isElse = tagName === "else") {
1950					if (pathBindings) {
1951						pathBindings.push(node[7]);
1952					}
1953				} else {
1954					tmplBindingKey = 0;
1955					if (tmplBindings && (pathBindings = node[7])) { // Array of paths, or false if not data-bound
1956						pathBindings = [pathBindings];
1957						tmplBindingKey = tmplBindings.push(1); // Add placeholder in tmplBindings for compiled function
1958					}
1959				}
1960				useViews = useViews || params[1] || params[2] || pathBindings || /view.(?!index)/.test(params[0]);
1961				// useViews is for perf optimization. For render() we only use views if necessary - for the more advanced scenarios.
1962				// We use views if there are props, contextual properties or args with #... (other than #index) - but you can force
1963				// using the full view infrastructure, (and pay a perf price) by opting in: Set useViews: true on the template, manually...
1964				if (isGetVal = tagName === ":") {
1965					if (converter) {
1966						tagName = converter === HTML ? ">" : converter + tagName;
1967					}
1968				} else {
1969					if (content) { // TODO optimize - if content.length === 0 or if there is a tmpl="..." specified - set content to null / don't run this compilation code - since content won't get used!!
1970						// Create template object for nested template
1971						nestedTmpl = tmplObject(markup, tmplOptions);
1972						nestedTmpl.tmplName = tmplName + "/" + tagName;
1973						// Compile to AST and then to compiled function
1974						nestedTmpl.useViews = nestedTmpl.useViews || useViews;
1975						buildCode(content, nestedTmpl);
1976						useViews = nestedTmpl.useViews;
1977						nestedTmpls.push(nestedTmpl);
1978					}
1979
1980					if (!isElse) {
1981						// This is not an else tag.
1982						tagAndElses = tagName;
1983						useViews = useViews || tagName && (!$tags[tagName] || !$tags[tagName].flow);
1984						// Switch to a new code string for this bound tag (and its elses, if it has any) - for returning the tagCtxs array
1985						oldCode = code;
1986						code = "";
1987					}
1988					nextIsElse = ast[i + 1];
1989					nextIsElse = nextIsElse && nextIsElse[0] === "else";
1990				}
1991				tagStart = onError ? ";\ntry{\nret+=" : "\n+";
1992				boundOnErrStart = "";
1993				boundOnErrEnd = "";
1994
1995				if (isGetVal && (pathBindings || trigger || converter && converter !== HTML)) {
1996					// For convertVal we need a compiled function to return the new tagCtx(s)
1997					tagCtxFn = new Function("data,view,j,u", " // " + tmplName + " " + tmplBindingKey + " " + tagName
1998										+ "\nreturn {" + tagCtx + "};");
1999					tagCtxFn._er = onError;
2000					tagCtxFn._tag = tagName;
2001
2002					if (isLinkExpr) {
2003						return tagCtxFn;
2004					}
2005
2006					setPaths(tagCtxFn, pathBindings);
2007					tagRender = 'c("' + converter + '",view,';
2008					useCnvt = true;
2009					boundOnErrStart = tagRender + tmplBindingKey + ",";
2010					boundOnErrEnd = ")";
2011				}
2012				code += (isGetVal
2013					? (isLinkExpr ? (onError ? "try{\n" : "") + "return " : tagStart) + (useCnvt // Call _cnvt if there is a converter: {{cnvt: ... }} or {^{cnvt: ... }}
2014						? (useCnvt = undefined, useViews = hasCnvt = true, tagRender + (pathBindings
2015							? ((tmplBindings[tmplBindingKey - 1] = tagCtxFn), tmplBindingKey) // Store the compiled tagCtxFn in tmpl.bnds, and pass the key to convertVal()
2016							: "{" + tagCtx + "}") + ")")
2017						: tagName === ">"
2018							? (hasEncoder = true, "h(" + params[0] + ")")
2019							: (getsVal = true, "((v=" + params[0] + ')!=null?v:"")') // Strict equality just for data-link="title{:expr}" so expr=null will remove title attribute
2020					)
2021					: (hasTag = true, "\n{view:view,tmpl:" // Add this tagCtx to the compiled code for the tagCtxs to be passed to renderTag()
2022						+ (content ? nestedTmpls.length : "0") + "," // For block tags, pass in the key (nestedTmpls.length) to the nested content template
2023						+ tagCtx + "},"));
2024
2025				if (tagAndElses && !nextIsElse) {
2026					// This is a data-link expression or an inline tag without any elses, or the last {{else}} of an inline tag
2027					// We complete the code for returning the tagCtxs array
2028					code = "[" + code.slice(0, -1) + "]";
2029					tagRender = 't("' + tagAndElses + '",view,this,';
2030					if (isLinkExpr || pathBindings) {
2031						// This is a bound tag (data-link expression or inline bound tag {^{tag ...}}) so we store a compiled tagCtxs function in tmp.bnds
2032						code = new Function("data,view,j,u", " // " + tmplName + " " + tmplBindingKey + " " + tagAndElses + "\nreturn " + code + ";");
2033						code._er = onError;
2034						code._tag = tagAndElses;
2035						if (pathBindings) {
2036							setPaths(tmplBindings[tmplBindingKey - 1] = code, pathBindings);
2037						}
2038						if (isLinkExpr) {
2039							return code; // For a data-link expression we return the compiled tagCtxs function
2040						}
2041						boundOnErrStart = tagRender + tmplBindingKey + ",undefined,";
2042						boundOnErrEnd = ")";
2043					}
2044
2045					// This is the last {{else}} for an inline tag.
2046					// For a bound tag, pass the tagCtxs fn lookup key to renderTag.
2047					// For an unbound tag, include the code directly for evaluating tagCtxs array
2048					code = oldCode + tagStart + tagRender + (tmplBindingKey || code) + ")";
2049					pathBindings = 0;
2050					tagAndElses = 0;
2051				}
2052				if (onError) {
2053					useViews = true;
2054					code += ';\n}catch(e){ret' + (isLinkExpr ? "urn " : "+=") + boundOnErrStart + 'j._err(e,view,' + onError + ')' + boundOnErrEnd + ';}' + (isLinkExpr ? "" : 'ret=ret');
2055				}
2056			}
2057		}
2058	}
2059	// Include only the var references that are needed in the code
2060	code = "// " + tmplName
2061
2062		+ "\nvar v"
2063		+ (hasTag ? ",t=j._tag" : "")                // has tag
2064		+ (hasCnvt ? ",c=j._cnvt" : "")              // converter
2065		+ (hasEncoder ? ",h=j._html" : "")           // html converter
2066		+ (isLinkExpr ? ";\n" : ',ret=""\n')
2067		+ (tmplOptions.debug ? "debugger;" : "")
2068		+ code
2069		+ (isLinkExpr ? "\n" : ";\nreturn ret;");
2070
2071	if ($subSettings.debugMode !== false) {
2072		code = "try {\n" + code + "\n}catch(e){\nreturn j._err(e, view);\n}";
2073	}
2074
2075	try {
2076		code = new Function("data,view,j,u", code);
2077	} catch (e) {
2078		syntaxError("Compiled template code:\n\n" + code + '\n: "' + e.message + '"');
2079	}
2080	if (tmpl) {
2081		tmpl.fn = code;
2082		tmpl.useViews = !!useViews;
2083	}
2084	return code;
2085}
2086
2087//==========
2088// Utilities
2089//==========
2090
2091// Merge objects, in particular contexts which inherit from parent contexts
2092function extendCtx(context, parentContext) {
2093	// Return copy of parentContext, unless context is defined and is different, in which case return a new merged context
2094	// If neither context nor parentContext are defined, return undefined
2095	return context && context !== parentContext
2096		? (parentContext
2097			? $extend($extend({}, parentContext), context)
2098			: context)
2099		: parentContext && $extend({}, parentContext);
2100}
2101
2102// Get character entity for HTML and Attribute encoding
2103function getCharEntity(ch) {
2104	return charEntities[ch] || (charEntities[ch] = "&#" + ch.charCodeAt(0) + ";");
2105}
2106
2107function getTargetProps(source) {
2108	// this pointer is theMap - which has tagCtx.props too
2109	// arguments: tagCtx.args.
2110	var key, prop,
2111		props = [];
2112
2113	if (typeof source === OBJECT) {
2114		for (key in source) {
2115			prop = source[key];
2116			if (!prop || !prop.toJSON || prop.toJSON()) {
2117				if (!$isFunction(prop)) {
2118					props.push({key: key, prop: prop});
2119				}
2120			}
2121		}
2122	}
2123	return props;
2124}
2125
2126function $fnRender(data, context, noIteration) {
2127	var tmplElem = this.jquery && (this[0] || error('Unknown template: "' + this.selector + '"')),
2128		tmpl = tmplElem.getAttribute(tmplAttr);
2129
2130	return renderContent.call(tmpl ? $.data(tmplElem)[jsvTmpl] : $templates(tmplElem), data, context, noIteration);
2131}
2132
2133//========================== Register converters ==========================
2134
2135function htmlEncode(text) {
2136	// HTML encode: Replace < > & ' and " by corresponding entities.
2137	return text != undefined ? rIsHtml.test(text) && ("" + text).replace(rHtmlEncode, getCharEntity) || text : "";
2138}
2139
2140//========================== Initialize ==========================
2141
2142$sub = $views.sub;
2143$viewsSettings = $views.settings;
2144
2145if (!(jsr || $ && $.render)) {
2146	// JsRender not already loaded, or loaded without jQuery, and we are now moving from jsrender namespace to jQuery namepace
2147	for (jsvStoreName in jsvStores) {
2148		registerStore(jsvStoreName, jsvStores[jsvStoreName]);
2149	}
2150
2151	$converters = $views.converters;
2152	$helpers = $views.helpers;
2153	$tags = $views.tags;
2154
2155	$sub._tg.prototype = {
2156		baseApply: baseApply,
2157		cvtArgs: convertArgs
2158	};
2159
2160	topView = $sub.topView = new View();
2161
2162	//BROWSER-SPECIFIC CODE
2163	if ($) {
2164
2165		////////////////////////////////////////////////////////////////////////////////////////////////
2166		// jQuery (= $) is loaded
2167
2168		$.fn.render = $fnRender;
2169
2170		if ($.observable) {
2171			$extend($sub, $.views.sub); // jquery.observable.js was loaded before jsrender.js
2172			$views.map = $.views.map;
2173		}
2174
2175	} else {
2176		////////////////////////////////////////////////////////////////////////////////////////////////
2177		// jQuery is not loaded.
2178
2179		$ = {};
2180
2181		if (setGlobals) {
2182			global.jsrender = $; // We are loading jsrender.js from a script element, not AMD or CommonJS, so set global
2183		}
2184
2185		// Error warning if jsrender.js is used as template engine on Node.js (e.g. Express or Hapi...)
2186		// Use jsrender-node.js instead...
2187		$.renderFile = $.__express = $.compile = function() { throw "Node.js: use npm jsrender, or jsrender-node.js"; };
2188
2189		//END BROWSER-SPECIFIC CODE
2190		$.isFunction = function(ob) {
2191			return typeof ob === "function";
2192		};
2193
2194		$.isArray = Array.isArray || function(obj) {
2195			return ({}.toString).call(obj) === "[object Array]";
2196		};
2197
2198		$sub._jq = function(jq) { // private method to move from JsRender APIs from jsrender namespace to jQuery namespace
2199			if (jq !== $) {
2200				$extend(jq, $); // map over from jsrender namespace to jQuery namespace
2201				$ = jq;
2202				$.fn.render = $fnRender;
2203				delete $.jsrender;
2204			}
2205		};
2206
2207		$.jsrender = versionNumber;
2208	}
2209
2210	$subSettings = $sub.settings;
2211	$subSettings.allowCode = false;
2212	$isFunction = $.isFunction;
2213	$isArray = $.isArray;
2214	$.render = $render;
2215	$.views = $views;
2216	$.templates = $templates = $views.templates;
2217
2218	for (setting in $subSettings) {
2219		addSetting(setting);
2220	}
2221
2222	($viewsSettings.debugMode = function(debugMode) {
2223		return debugMode === undefined
2224			? $subSettings.debugMode
2225			: (
2226				$subSettings.debugMode = debugMode,
2227				$subSettings.onError = debugMode + "" === debugMode
2228					? new Function("", "return '" + debugMode + "';" )
2229					: $isFunction(debugMode)
2230						? debugMode
2231						: undefined,
2232				$viewsSettings);
2233	})(false); // jshint ignore:line
2234
2235	$subSettingsAdvanced = $subSettings.advanced = {
2236		useViews: false,
2237		_jsv: false // For global access to JsViews store
2238	};
2239
2240	//========================== Register tags ==========================
2241
2242	$tags({
2243		"if": {
2244			render: function(val) {
2245				// This function is called once for {{if}} and once for each {{else}}.
2246				// We will use the tag.rendering object for carrying rendering state across the calls.
2247				// If not done (a previous block has not been rendered), look at expression for this block and render the block if expression is truthy
2248				// Otherwise return ""
2249				var self = this,
2250					tagCtx = self.tagCtx,
2251					ret = (self.rendering.done || !val && (arguments.length || !tagCtx.index))
2252						? ""
2253						: (self.rendering.done = true, self.selected = tagCtx.index,
2254							// Test is satisfied, so render content on current context. We call tagCtx.render() rather than return undefined
2255							// (which would also render the tmpl/content on the current context but would iterate if it is an array)
2256							tagCtx.render(tagCtx.view, true)); // no arg, so renders against parentView.data
2257				return ret;
2258			},
2259			flow: true
2260		},
2261		"for": {
2262			render: function(val) {
2263				// This function is called once for {{for}} and once for each {{else}}.
2264				// We will use the tag.rendering object for carrying rendering state across the calls.
2265				var finalElse = !arguments.length,
2266					value,
2267					self = this,
2268					tagCtx = self.tagCtx,
2269					result = "",
2270					done = 0;
2271
2272				if (!self.rendering.done) {
2273					value = finalElse ? tagCtx.view.data : val; // For the final else, defaults to current data without iteration.
2274					if (value !== undefined) {
2275						result += tagCtx.render(value, finalElse); // Iterates except on final else, if data is an array. (Use {{include}} to compose templates without array iteration)
2276						done += $isArray(value) ? value.length : 1;
2277					}
2278					if (self.rendering.done = done) {
2279						self.selected = tagCtx.index;
2280					}
2281					// If nothing was rendered we will look at the next {{else}}. Otherwise, we are done.
2282				}
2283				return result;
2284			},
2285			flow: true
2286		},
2287		props: {
2288			baseTag: "for",
2289			dataMap: dataMap(getTargetProps),
2290			flow: true
2291		},
2292		include: {
2293			flow: true
2294		},
2295		"*": {
2296			// {{* code... }} - Ignored if template.allowCode and $.views.settings.allowCode are false. Otherwise include code in compiled template
2297			render: retVal,
2298			flow: true
2299		},
2300		":*": {
2301			// {{:* returnedExpression }} - Ignored if template.allowCode and $.views.settings.allowCode are false. Otherwise include code in compiled template
2302			render: retVal,
2303			flow: true
2304		},
2305		dbg: $helpers.dbg = $converters.dbg = dbgBreak // Register {{dbg/}}, {{dbg:...}} and ~dbg() to throw and catch, as breakpoints for debugging.
2306	});
2307
2308	$converters({
2309		html: htmlEncode,
2310		attr: htmlEncode, // Includes > encoding since rConvertMarkers in JsViews does not skip > characters in attribute strings
2311		url: function(text) {
2312			// URL encoding helper.
2313			return text != undefined ? encodeURI("" + text) : text === null ? text : ""; // null returns null, e.g. to remove attribute. undefined returns ""
2314		}
2315	});
2316}
2317//========================== Define default delimiters ==========================
2318$subSettings = $sub.settings;
2319$viewsSettings.delimiters("{{", "}}", "^");
2320
2321if (jsrToJq) { // Moving from jsrender namespace to jQuery namepace - copy over the stored items (templates, converters, helpers...)
2322	jsr.views.sub._jq($);
2323}
2324return $ || jsr;
2325}, window));
2326
2327(function (global, factory) {
2328    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
2329        typeof define === 'function' && define.amd ? define(factory) :
2330            global.moment = factory()
2331}(this, function () { 'use strict';
2332
2333    var hookCallback;
2334
2335    function utils_hooks__hooks () {
2336        return hookCallback.apply(null, arguments);
2337    }
2338
2339    // This is done to register the method called with moment()
2340    // without creating circular dependencies.
2341    function setHookCallback (callback) {
2342        hookCallback = callback;
2343    }
2344
2345    function isArray(input) {
2346        return Object.prototype.toString.call(input) === '[object Array]';
2347    }
2348
2349    function isDate(input) {
2350        return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
2351    }
2352
2353    function map(arr, fn) {
2354        var res = [], i;
2355        for (i = 0; i < arr.length; ++i) {
2356            res.push(fn(arr[i], i));
2357        }
2358        return res;
2359    }
2360
2361    function hasOwnProp(a, b) {
2362        return Object.prototype.hasOwnProperty.call(a, b);
2363    }
2364
2365    function extend(a, b) {
2366        for (var i in b) {
2367            if (hasOwnProp(b, i)) {
2368                a[i] = b[i];
2369            }
2370        }
2371
2372        if (hasOwnProp(b, 'toString')) {
2373            a.toString = b.toString;
2374        }
2375
2376        if (hasOwnProp(b, 'valueOf')) {
2377            a.valueOf = b.valueOf;
2378        }
2379
2380        return a;
2381    }
2382
2383    function create_utc__createUTC (input, format, locale, strict) {
2384        return createLocalOrUTC(input, format, locale, strict, true).utc();
2385    }
2386
2387    function defaultParsingFlags() {
2388        // We need to deep clone this object.
2389        return {
2390            empty           : false,
2391            unusedTokens    : [],
2392            unusedInput     : [],
2393            overflow        : -2,
2394            charsLeftOver   : 0,
2395            nullInput       : false,
2396            invalidMonth    : null,
2397            invalidFormat   : false,
2398            userInvalidated : false,
2399            iso             : false
2400        };
2401    }
2402
2403    function getParsingFlags(m) {
2404        if (m._pf == null) {
2405            m._pf = defaultParsingFlags();
2406        }
2407        return m._pf;
2408    }
2409
2410    function valid__isValid(m) {
2411        if (m._isValid == null) {
2412            var flags = getParsingFlags(m);
2413            m._isValid = !isNaN(m._d.getTime()) &&
2414                flags.overflow < 0 &&
2415                !flags.empty &&
2416                !flags.invalidMonth &&
2417                !flags.invalidWeekday &&
2418                !flags.nullInput &&
2419                !flags.invalidFormat &&
2420                !flags.userInvalidated;
2421
2422            if (m._strict) {
2423                m._isValid = m._isValid &&
2424                    flags.charsLeftOver === 0 &&
2425                    flags.unusedTokens.length === 0 &&
2426                    flags.bigHour === undefined;
2427            }
2428        }
2429        return m._isValid;
2430    }
2431
2432    function valid__createInvalid (flags) {
2433        var m = create_utc__createUTC(NaN);
2434        if (flags != null) {
2435            extend(getParsingFlags(m), flags);
2436        }
2437        else {
2438            getParsingFlags(m).userInvalidated = true;
2439        }
2440
2441        return m;
2442    }
2443
2444    var momentProperties = utils_hooks__hooks.momentProperties = [];
2445
2446    function copyConfig(to, from) {
2447        var i, prop, val;
2448
2449        if (typeof from._isAMomentObject !== 'undefined') {
2450            to._isAMomentObject = from._isAMomentObject;
2451        }
2452        if (typeof from._i !== 'undefined') {
2453            to._i = from._i;
2454        }
2455        if (typeof from._f !== 'undefined') {
2456            to._f = from._f;
2457        }
2458        if (typeof from._l !== 'undefined') {
2459            to._l = from._l;
2460        }
2461        if (typeof from._strict !== 'undefined') {
2462            to._strict = from._strict;
2463        }
2464        if (typeof from._tzm !== 'undefined') {
2465            to._tzm = from._tzm;
2466        }
2467        if (typeof from._isUTC !== 'undefined') {
2468            to._isUTC = from._isUTC;
2469        }
2470        if (typeof from._offset !== 'undefined') {
2471            to._offset = from._offset;
2472        }
2473        if (typeof from._pf !== 'undefined') {
2474            to._pf = getParsingFlags(from);
2475        }
2476        if (typeof from._locale !== 'undefined') {
2477            to._locale = from._locale;
2478        }
2479
2480        if (momentProperties.length > 0) {
2481            for (i in momentProperties) {
2482                prop = momentProperties[i];
2483                val = from[prop];
2484                if (typeof val !== 'undefined') {
2485                    to[prop] = val;
2486                }
2487            }
2488        }
2489
2490        return to;
2491    }
2492
2493    var updateInProgress = false;
2494
2495    // Moment prototype object
2496    function Moment(config) {
2497        copyConfig(this, config);
2498        this._d = new Date(config._d != null ? config._d.getTime() : NaN);
2499        // Prevent infinite loop in case updateOffset creates new moment
2500        // objects.
2501        if (updateInProgress === false) {
2502            updateInProgress = true;
2503            utils_hooks__hooks.updateOffset(this);
2504            updateInProgress = false;
2505        }
2506    }
2507
2508    function isMoment (obj) {
2509        return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);
2510    }
2511
2512    function absFloor (number) {
2513        if (number < 0) {
2514            return Math.ceil(number);
2515        } else {
2516            return Math.floor(number);
2517        }
2518    }
2519
2520    function toInt(argumentForCoercion) {
2521        var coercedNumber = +argumentForCoercion,
2522            value = 0;
2523
2524        if (coercedNumber !== 0 && isFinite(coercedNumber)) {
2525            value = absFloor(coercedNumber);
2526        }
2527
2528        return value;
2529    }
2530
2531    function compareArrays(array1, array2, dontConvert) {
2532        var len = Math.min(array1.length, array2.length),
2533            lengthDiff = Math.abs(array1.length - array2.length),
2534            diffs = 0,
2535            i;
2536        for (i = 0; i < len; i++) {
2537            if ((dontConvert && array1[i] !== array2[i]) ||
2538                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
2539                diffs++;
2540            }
2541        }
2542        return diffs + lengthDiff;
2543    }
2544
2545    function Locale() {
2546    }
2547
2548    var locales = {};
2549    var globalLocale;
2550
2551    function normalizeLocale(key) {
2552        return key ? key.toLowerCase().replace('_', '-') : key;
2553    }
2554
2555    // pick the locale from the array
2556    // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list tr
2556ying each
2557    // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
2558    function chooseLocale(names) {
2559        var i = 0, j, next, locale, split;
2560
2561        while (i < names.length) {
2562            split = normalizeLocale(names[i]).split('-');
2563            j = split.length;
2564            next = normalizeLocale(names[i + 1]);
2565            next = next ? next.split('-') : null;
2566            while (j > 0) {
2567                locale = loadLocale(split.slice(0, j).join('-'));
2568                if (locale) {
2569                    return locale;
2570                }
2571                if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
2572                    //the next array item is better than a shallower substring of this one
2573                    break;
2574                }
2575                j--;
2576            }
2577            i++;
2578        }
2579        return null;
2580    }
2581
2582    function loadLocale(name) {
2583        var oldLocale = null;
2584        // TODO: Find a better way to register and load all the locales in Node
2585        if (!locales[name] && typeof module !== 'undefined' &&
2586            module && module.exports) {
2587            try {
2588                oldLocale = globalLocale._abbr;
2589                require('./locale/' + name);
2590                // because defineLocale currently also sets the global locale, we
2591                // want to undo that for lazy loaded locales
2592                locale_locales__getSetGlobalLocale(oldLocale);
2593            } catch (e) { }
2594        }
2595        return locales[name];
2596    }
2597
2598    // This function will load locale and then set the global locale.  If
2599    // no arguments are passed in, it will simply return the current global
2600    // locale key.
2601    function locale_locales__getSetGlobalLocale (key, values) {
2602        var data;
2603        if (key) {
2604            if (typeof values === 'undefined') {
2605                data = locale_locales__getLocale(key);
2606            }
2607            else {
2608                data = defineLocale(key, values);
2609            }
2610
2611            if (data) {
2612                // moment.duration._locale = moment._locale = data;
2613                globalLocale = data;
2614            }
2615        }
2616
2617        return globalLocale._abbr;
2618    }
2619
2620    function defineLocale (name, values) {
2621        if (values !== null) {
2622            values.abbr = name;
2623            locales[name] = locales[name] || new Locale();
2624            locales[name].set(values);
2625
2626            // backwards compat for now: also set the locale
2627            locale_locales__getSetGlobalLocale(name);
2628
2629            return locales[name];
2630        } else {
2631            // useful for testing
2632            delete locales[name];
2633            return null;
2634        }
2635    }
2636
2637    // returns locale data
2638    function locale_locales__getLocale (key) {
2639        var locale;
2640
2641        if (key && key._locale && key._locale._abbr) {
2642            key = key._locale._abbr;
2643        }
2644
2645        if (!key) {
2646            return globalLocale;
2647        }
2648
2649        if (!isArray(key)) {
2650            //short-circuit everything else
2651            locale = loadLocale(key);
2652            if (locale) {
2653                return locale;
2654            }
2655            key = [key];
2656        }
2657
2658        return chooseLocale(key);
2659    }
2660
2661    var aliases = {};
2662
2663    function addUnitAlias (unit, shorthand) {
2664        var lowerCase = unit.toLowerCase();
2665        aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
2666    }
2667
2668    function normalizeUnits(units) {
2669        return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
2670    }
2671
2672    function normalizeObjectUnits(inputObject) {
2673        var normalizedInput = {},
2674            normalizedProp,
2675            prop;
2676
2677        for (prop in inputObject) {
2678            if (hasOwnProp(inputObject, prop)) {
2679                normalizedProp = normalizeUnits(prop);
2680                if (normalizedProp) {
2681                    normalizedInput[normalizedProp] = inputObject[prop];
2682                }
2683            }
2684        }
2685
2686        return normalizedInput;
2687    }
2688
2689    function makeGetSet (unit, keepTime) {
2690        return function (value) {
2691            if (value != null) {
2692                get_set__set(this, unit, value);
2693                utils_hooks__hooks.updateOffset(this, keepTime);
2694                return this;
2695            } else {
2696                return get_set__get(this, unit);
2697            }
2698        };
2699    }
2700
2701    function get_set__get (mom, unit) {
2702        return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]();
2703    }
2704
2705    function get_set__set (mom, unit, value) {
2706        return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
2707    }
2708
2709    // MOMENTS
2710
2711    function getSet (units, value) {
2712        var unit;
2713        if (typeof units === 'object') {
2714            for (unit in units) {
2715                this.set(unit, units[unit]);
2716            }
2717        } else {
2718            units = normalizeUnits(units);
2719            if (typeof this[units] === 'function') {
2720                return this[units](value);
2721            }
2722        }
2723        return this;
2724    }
2725
2726    function zeroFill(number, targetLength, forceSign) {
2727        var absNumber = '' + Math.abs(number),
2728            zerosToFill = targetLength - absNumber.length,
2729            sign = number >= 0;
2730        return (sign ? (forceSign ? '+' : '') : '-') +
2731            Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
2732    }
2733
2734    var formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,9}
vendor: 12,557 bytes, lines 2734-3106
2734|x|X|zz?|ZZ?|.)/g;
2735
2736    var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
2737
2738    var formatFunctions = {};
2739
2740    var formatTokenFunctions = {};
2741
2742    // token:    'M'
2743    // padded:   ['MM', 2]
2744    // ordinal:  'Mo'
2745    // callback: function () { this.month() + 1 }
2746    function addFormatToken (token, padded, ordinal, callback) {
2747        var func = callback;
2748        if (typeof callback === 'string') {
2749            func = function () {
2750                return this[callback]();
2751            };
2752        }
2753        if (token) {
2754            formatTokenFunctions[token] = func;
2755        }
2756        if (padded) {
2757            formatTokenFunctions[padded[0]] = function () {
2758                return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
2759            };
2760        }
2761        if (ordinal) {
2762            formatTokenFunctions[ordinal] = function () {
2763                return this.localeData().ordinal(func.apply(this, arguments), token);
2764            };
2765        }
2766    }
2767
2768    function removeFormattingTokens(input) {
2769        if (input.match(/\[[\s\S]/)) {
2770            return input.replace(/^\[|\]$/g, '');
2771        }
2772        return input.replace(/\\/g, '');
2773    }
2774
2775    function makeFormatFunction(format) {
2776        var array = format.match(formattingTokens), i, length;
2777
2778        for (i = 0, length = array.length; i < length; i++) {
2779            if (formatTokenFunctions[array[i]]) {
2780                array[i] = formatTokenFunctions[array[i]];
2781            } else {
2782                array[i] = removeFormattingTokens(array[i]);
2783            }
2784        }
2785
2786        return function (mom) {
2787            var output = '';
2788            for (i = 0; i < length; i++) {
2789                output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
2790            }
2791            return output;
2792        };
2793    }
2794
2795    // format date using native date object
2796    function formatMoment(m, format) {
2797        if (!m.isValid()) {
2798            return m.localeData().invalidDate();
2799        }
2800
2801        format = expandFormat(format, m.localeData());
2802        formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);
2803
2804        return formatFunctions[format](m);
2805    }
2806
2807    function expandFormat(format, locale) {
2808        var i = 5;
2809
2810        function replaceLongDateFormatTokens(input) {
2811            return locale.longDateFormat(input) || input;
2812        }
2813
2814        localFormattingTokens.lastIndex = 0;
2815        while (i >= 0 && localFormattingTokens.test(format)) {
2816            format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
2817            localFormattingTokens.lastIndex = 0;
2818            i -= 1;
2819        }
2820
2821        return format;
2822    }
2823
2824    var match1         = /\d/;            //       0 - 9
2825    var match2         = /\d\d/;          //      00 - 99
2826    var match3         = /\d{3}/;         //     000 - 999
2827    var match4         = /\d{4}/;         //    0000 - 9999
2828    var match6         = /[+-]?\d{6}/;    // -999999 - 999999
2829    var match1to2      = /\d\d?/;         //       0 - 99
2830    var match1to3      = /\d{1,3}/;       //       0 - 999
2831    var match1to4      = /\d{1,4}/;       //       0 - 9999
2832    var match1to6      = /[+-]?\d{1,6}/;  // -999999 - 999999
2833
2834    var matchUnsigned  = /\d+/;           //       0 - inf
2835    var matchSigned    = /[+-]?\d+/;      //    -inf - inf
2836
2837    var matchOffset    = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
2838
2839    var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
2840
2841    // any word (or two) characters or numbers including two/three word month in arabic.
2842    var matchWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i;
2843
2844    var regexes = {};
2845
2846    function isFunction (sth) {
2847        // https://github.com/moment/moment/issues/2325
2848        return typeof sth === 'function' &&
2849            Object.prototype.toString.call(sth) === '[object Function]';
2850    }
2851
2852
2853    function addRegexToken (token, regex, strictRegex) {
2854        regexes[token] = isFunction(regex) ? regex : function (isStrict) {
2855            return (isStrict && strictRegex) ? strictRegex : regex;
2856        };
2857    }
2858
2859    function getParseRegexForToken (token, config) {
2860        if (!hasOwnProp(regexes, token)) {
2861            return new RegExp(unescapeFormat(token));
2862        }
2863
2864        return regexes[token](config._strict, config._locale);
2865    }
2866
2867    // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
2868    function unescapeFormat(s) {
2869        return s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
2870            return p1 || p2 || p3 || p4;
2871        }).replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
2872    }
2873
2874    var tokens = {};
2875
2876    function addParseToken (token, callback) {
2877        var i, func = callback;
2878        if (typeof token === 'string') {
2879            token = [token];
2880        }
2881        if (typeof callback === 'number') {
2882            func = function (input, array) {
2883                array[callback] = toInt(input);
2884            };
2885        }
2886        for (i = 0; i < token.length; i++) {
2887            tokens[token[i]] = func;
2888        }
2889    }
2890
2891    function addWeekParseToken (token, callback) {
2892        addParseToken(token, function (input, array, config, token) {
2893            config._w = config._w || {};
2894            callback(input, config._w, config, token);
2895        });
2896    }
2897
2898    function addTimeToArrayFromToken(token, input, config) {
2899        if (input != null && hasOwnProp(tokens, token)) {
2900            tokens[token](input, config._a, config, token);
2901        }
2902    }
2903
2904    var YEAR = 0;
2905    var MONTH = 1;
2906    var DATE = 2;
2907    var HOUR = 3;
2908    var MINUTE = 4;
2909    var SECOND = 5;
2910    var MILLISECOND = 6;
2911
2912    function daysInMonth(year, month) {
2913        return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
2914    }
2915
2916    // FORMATTING
2917
2918    addFormatToken('M', ['MM', 2], 'Mo', function () {
2919        return this.month() + 1;
2920    });
2921
2922    addFormatToken('MMM', 0, 0, function (format) {
2923        return this.localeData().monthsShort(this, format);
2924    });
2925
2926    addFormatToken('MMMM', 0, 0, function (format) {
2927        return this.localeData().months(this, format);
2928    });
2929
2930    // ALIASES
2931
2932    addUnitAlias('month', 'M');
2933
2934    // PARSING
2935
2936    addRegexToken('M',    match1to2);
2937    addRegexToken('MM',   match1to2, match2);
2938    addRegexToken('MMM',  matchWord);
2939    addRegexToken('MMMM', matchWord);
2940
2941    addParseToken(['M', 'MM'], function (input, array) {
2942        array[MONTH] = toInt(input) - 1;
2943    });
2944
2945    addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
2946        var month = config._locale.monthsParse(input, token, config._strict);
2947        // if we didn't find a month name, mark the date as invalid.
2948        if (month != null) {
2949            array[MONTH] = month;
2950        } else {
2951            getParsingFlags(config).invalidMonth = input;
2952        }
2953    });
2954
2955    // LOCALES
2956
2957    var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
2958    function localeMonths (m) {
2959        return this._months[m.month()];
2960    }
2961
2962    var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
2963    function localeMonthsShort (m) {
2964        return this._monthsShort[m.month()];
2965    }
2966
2967    function localeMonthsParse (monthName, format, strict) {
2968        var i, mom, regex;
2969
2970        if (!this._monthsParse) {
2971            this._monthsParse = [];
2972            this._longMonthsParse = [];
2973            this._shortMonthsParse = [];
2974        }
2975
2976        for (i = 0; i < 12; i++) {
2977            // make the regex if we don't have it already
2978            mom = create_utc__createUTC([2000, i]);
2979            if (strict && !this._longMonthsParse[i]) {
2980                this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
2981                this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
2982            }
2983            if (!strict && !this._monthsParse[i]) {
2984                regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
2985                this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
2986            }
2987            // test the regex
2988            if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
2989                return i;
2990            } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
2991                return i;
2992            } else if (!strict && this._monthsParse[i].test(monthName)) {
2993                return i;
2994            }
2995        }
2996    }
2997
2998    // MOMENTS
2999
3000    function setMonth (mom, value) {
3001        var dayOfMonth;
3002
3003        // TODO: Move this out of here!
3004        if (typeof value === 'string') {
3005            value = mom.localeData().monthsParse(value);
3006            // TODO: Another silent failure?
3007            if (typeof value !== 'number') {
3008                return mom;
3009            }
3010        }
3011
3012        dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
3013        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
3014        return mom;
3015    }
3016
3017    function getSetMonth (value) {
3018        if (value != null) {
3019            setMonth(this, value);
3020            utils_hooks__hooks.updateOffset(this, true);
3021            return this;
3022        } else {
3023            return get_set__get(this, 'Month');
3024        }
3025    }
3026
3027    function getDaysInMonth () {
3028        return daysInMonth(this.year(), this.month());
3029    }
3030
3031    function checkOverflow (m) {
3032        var overflow;
3033        var a = m._a;
3034
3035        if (a && getParsingFlags(m).overflow === -2) {
3036            overflow =
3037                a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :
3038                    a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :
3039                        a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :
3040                            a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :
3041                                a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :
3042                                    a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :
3043                                        -1;
3044
3045            if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
3046                overflow = DATE;
3047            }
3048
3049            getParsingFlags(m).overflow = overflow;
3050        }
3051
3052        return m;
3053    }
3054
3055    function warn(msg) {
3056        if (utils_hooks__hooks.suppressDeprecationWarnings === false && typeof console !== 'undefined' && console.warn) {
3057            console.warn('Deprecation warning: ' + msg);
3058        }
3059    }
3060
3061    function deprecate(msg, fn) {
3062        var firstTime = true;
3063
3064        return extend(function () {
3065            if (firstTime) {
3066                warn(msg + '\n' + (new Error()).stack);
3067                firstTime = false;
3068            }
3069            return fn.apply(this, arguments);
3070        }, fn);
3071    }
3072
3073    var deprecations = {};
3074
3075    function deprecateSimple(name, msg) {
3076        if (!deprecations[name]) {
3077            warn(msg);
3078            deprecations[name] = true;
3079        }
3080    }
3081
3082    utils_hooks__hooks.suppressDeprecationWarnings = false;
3083
3084    var from_string__isoRegex = /^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
3085
3086    var isoDates = [
3087        ['YYYYYY-MM-DD', /[+-]\d{6}-\d{2}-\d{2}/],
3088        ['YYYY-MM-DD', /\d{4}-\d{2}-\d{2}/],
3089        ['GGGG-[W]WW-E', /\d{4}-W\d{2}-\d/],
3090        ['GGGG-[W]WW', /\d{4}-W\d{2}/],
3091        ['YYYY-DDD', /\d{4}-\d{3}/]
3092    ];
3093
3094    // iso time formats and regexes
3095    var isoTimes = [
3096        ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d+/],
3097        ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/],
3098        ['HH:mm', /(T| )\d\d:\d\d/],
3099        ['HH', /(T| )\d\d/]
3100    ];
3101
3102    var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;
3103
3104    // date from iso format
3105    function configFromISO(config) {
3106        var i, l,
3107            string = config._i,
3108            match = from_string__isoRegex.exec(string);
3109
3110        if (match) {
3111            getParsingFlags(config).iso = true;
3112            for (i = 0, l = isoDates.length; i < l; i++) {
3113                if (isoDates[i][1].exec(string)) {
3114                    config._f = isoDates[i][0];
3115                    break;
3116                }
3117            }
3118            for (i = 0, l = isoTimes.length; i < l; i++) {
3119                if (isoTimes[i][1].exec(string)) {
3120                    // match[6] should be 'T' or space
3121                    config._f += (match[6] || ' ') + isoTimes[i][0];
3122                    break;
3123                }
3124            }
3125            if (string.match(matchOffset)) {
3126                config._f += 'Z';
3127            }
3128            configFromStringAndFormat(config);
3129        } else {
3130            config._isValid = false;
3131        }
3132    }
3133
3134    // date from iso format or fallback
3135    function configFromString(config) {
3136        var matched = aspNetJsonRegex.exec(config._i);
3137
3138        if (matched !== null) {
3139            config._d = new Date(+matched[1]);
3140            return;
3141        }
3142
3143        configFromISO(config);
3144        if (config._isValid === false) {
3145            delete config._isValid;
3146            utils_hooks__hooks.createFromInputFallback(config);
3147        }
3148    }
3149
3150    utils_hooks__hooks.createFromInputFallback = deprecate(
3151        'moment construction falls back to js Date. This is ' +
3152        'discouraged and will be removed in upcoming major ' +
3153        'release. Please refer to ' +
3154        'https://github.com/moment/moment/issues/1407 for more info.',
3155        function (config) {
3156            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
3157        }
3158    );
3159
3160    function createDate (y, m, d, h, M, s, ms) {
3161        //can't just apply() to create a date:
3162        //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply
3163        var date = new Date(y, m, d, h, M, s, ms);
3164
3165        //the date constructor doesn't accept years < 1970
3166        if (y < 1970) {
3167            date.setFullYear(y);
3168        }
3169        return date;
3170    }
3171
3172    function createUTCDate (y) {
3173        var date = new Date(Date.UTC.apply(null, arguments));
3174        if (y < 1970) {
3175            date.setUTCFullYear(y);
3176        }
3177        return date;
3178    }
3179
3180    addFormatToken(0, ['YY', 2], 0, function () {
3181        return this.year() % 100;
3182    });
3183
3184    addFormatToken(0, ['YYYY',   4],       0, 'year');
3185    addFormatToken(0, ['YYYYY',  5],       0, 'year');
3186    addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');
3187
3188    // ALIASES
3189
3190    addUnitAlias('year', 'y');
3191
3192    // PARSING
3193
3194    addRegexToken('Y',      matchSigned);
3195    addRegexToken('YY',     match1to2, match2);
3196    addRegexToken('YYYY',   match1to4, match4);
3197    addRegexToken('YYYYY',  match1to6, match6);
3198    addRegexToken('YYYYYY', match1to6, match6);
3199
3200    addParseToken(['YYYYY', 'YYYYYY'], YEAR);
3201    addParseToken('YYYY', function (input, array) {
3202        array[YEAR] = input.length === 2 ? utils_hooks__hooks.parseTwoDigitYear(input) : toInt(input);
3203    });
3204    addParseToken('YY', function (input, array) {
3205        array[YEAR] = utils_hooks__hooks.parseTwoDigitYear(input);
3206    });
3207
3208    // HELPERS
3209
3210    function daysInYear(year) {
3211        return isLeapYear(year) ? 366 : 365;
3212    }
3213
3214    function isLeapYear(year) {
3215        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
3216    }
3217
3218    // HOOKS
3219
3220    utils_hooks__hooks.parseTwoDigitYear = function (input) {
3221        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
3222    };
3223
3224    // MOMENTS
3225
3226    var getSetYear = makeGetSet('FullYear', false);
3227
3228    function getIsLeapYear () {
3229        return isLeapYear(this.year());
3230    }
3231
3232    addFormatToken('w', ['ww', 2], 'wo', 'week');
3233    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
3234
3235    // ALIASES
3236
3237    addUnitAlias('week', 'w');
3238    addUnitAlias('isoWeek', 'W');
3239
3240    // PARSING
3241
3242    addRegexToken('w',  match1to2);
3243    addRegexToken('ww', match1to2, match2);
3244    addRegexToken('W',  match1to2);
3245    addRegexToken('WW', match1to2, match2);
3246
3247    addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
3248        week[token.substr(0, 1)] = toInt(input);
3249    });
3250
3251    // HELPERS
3252
3253    // firstDayOfWeek       0 = sun, 6 = sat
3254    //                      the day of the week that starts the week
3255    //                      (usually sunday or monday)
3256    // firstDayOfWeekOfYear 0 = sun, 6 = sat
3257    //                      the first week is the week that contains the first
3258    //                      of this day of the week
3259    //                      (eg. ISO weeks use thursday (4))
3260    function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {
3261        var end = firstDayOfWeekOfYear - firstDayOfWeek,
3262            daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),
3263            adjustedMoment;
3264
3265
3266        if (daysToDayOfWeek > end) {
3267            daysToDayOfWeek -= 7;
3268        }
3269
3270        if (daysToDayOfWeek < end - 7) {
3271            daysToDayOfWeek += 7;
3272        }
3273
3274        adjustedMoment = local__createLocal(mom).add(daysToDayOfWeek, 'd');
3275        return {
3276            week: Math.ceil(adjustedMoment.dayOfYear() / 7),
3277            year: adjustedMoment.year()
3278        };
3279    }
3280
3281    // LOCALES
3282
3283    function localeWeek (mom) {
3284        return weekOfYear(mom, this._week.dow, this._week.doy).week;
3285    }
3286
3287    var defaultLocaleWeek = {
3288        dow : 0, // Sunday is the first day of the week.
3289        doy : 6  // The week that contains Jan 1st is the first week of the year.
3290    };
3291
3292    function localeFirstDayOfWeek () {
3293        return this._week.dow;
3294    }
3295
3296    function localeFirstDayOfYear () {
3297        return this._week.doy;
3298    }
3299
3300    // MOMENTS
3301
3302    function getSetWeek (input) {
3303        var week = this.localeData().week(this);
3304        return input == null ? week : this.add((input - week) * 7, 'd');
3305    }
3306
3307    function getSetISOWeek (input) {
3308        var week = weekOfYear(this, 1, 4).week;
3309        return input == null ? week : this.add((input - week) * 7, 'd');
3310    }
3311
3312    addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
3313
3314    // ALIASES
3315
3316    addUnitAlias('dayOfYear', 'DDD');
3317
3318    // PARSING
3319
3320    addRegexToken('DDD',  match1to3);
3321    addRegexToken('DDDD', match3);
3322    addParseToken(['DDD', 'DDDD'], function (input, array, config) {
3323        config._dayOfYear = toInt(input);
3324    });
3325
3326    // HELPERS
3327
3328    //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
3329    function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {
3330        var week1Jan = 6 + firstDayOfWeek - firstDayOfWeekOfYear, janX = createUTCDate(year, 0, 1 + week1Jan), d = janX.getUTCDay(), dayOfYear;
3331        if (d < firstDayOfWeek) {
3332            d += 7;
3333        }
3334
3335        weekday = weekday != null ? 1 * weekday : firstDayOfWeek;
3336
3337        dayOfYear = 1 + week1Jan + 7 * (week - 1) - d + weekday;
3338
3339        return {
3340            year: dayOfYear > 0 ? year : year - 1,
3341            dayOfYear: dayOfYear > 0 ?  dayOfYear : daysInYear(year - 1) + dayOfYear
3342        };
3343    }
3344
3345    // MOMENTS
3346
3347    function getSetDayOfYear (input) {
3348        var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
3349        return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
3350    }
3351
3352    // Pick the first defined of two or three arguments.
3353    function defaults(a, b, c) {
3354        if (a != null) {
3355            return a;
3356        }
3357        if (b != null) {
3358            return b;
3359        }
3360        return c;
3361    }
3362
3363    function currentDateArray(config) {
3364        var now = new Date();
3365        if (config._useUTC) {
3366            return [now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()];
3367        }
3368        return [now.getFullYear(), now.getMonth(), now.getDate()];
3369    }
3370
3371    // convert an array to a date.
3372    // the array should mirror the parameters below
3373    // note: all values past the year are optional and will default to the lowest possible value.
3374    // [year, month, day , hour, minute, second, millisecond]
3375    function configFromArray (config) {
3376        var i, date, input = [], currentDate, yearToUse;
3377
3378        if (config._d) {
3379            return;
3380        }
3381
3382        currentDate = currentDateArray(config);
3383
3384        //compute day of the year from weeks and weekdays
3385        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
3386            dayOfYearFromWeekInfo(config);
3387        }
3388
3389        //if the day of the year is set, figure out what it is
3390        if (config._dayOfYear) {
3391            yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
3392
3393            if (config._dayOfYear > daysInYear(yearToUse)) {
3394                getParsingFlags(config)._overflowDayOfYear = true;
3395            }
3396
3397            date = createUTCDate(yearToUse, 0, config._dayOfYear);
3398            config._a[MONTH] = date.getUTCMonth();
3399            config._a[DATE] = date.getUTCDate();
3400        }
3401
3402        // Default to current date.
3403        // * if no year, month, day of month are given, default to today
3404        // * if day of month is given, default month and year
3405        // * if month is given, default only year
3406        // * if year is given, don't default anything
3407        for (i = 0; i < 3 && config._a[i] == null; ++i) {
vendor: 14,053 bytes, lines 3408-3824
3408            config._a[i] = input[i] = currentDate[i];
3409        }
3410
3411        // Zero out whatever was not defaulted, including time
3412        for (; i < 7; i++) {
3413            config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
3414        }
3415
3416        // Check for 24:00:00.000
3417        if (config._a[HOUR] === 24 &&
3418            config._a[MINUTE] === 0 &&
3419            config._a[SECOND] === 0 &&
3420            config._a[MILLISECOND] === 0) {
3421            config._nextDay = true;
3422            config._a[HOUR] = 0;
3423        }
3424
3425        config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
3426        // Apply timezone offset from input. The actual utcOffset can be changed
3427        // with parseZone.
3428        if (config._tzm != null) {
3429            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
3430        }
3431
3432        if (config._nextDay) {
3433            config._a[HOUR] = 24;
3434        }
3435    }
3436
3437    function dayOfYearFromWeekInfo(config) {
3438        var w, weekYear, week, weekday, dow, doy, temp;
3439
3440        w = config._w;
3441        if (w.GG != null || w.W != null || w.E != null) {
3442            dow = 1;
3443            doy = 4;
3444
3445            // TODO: We need to take the current isoWeekYear, but that depends on
3446            // how we interpret now (local, utc, fixed offset). So create
3447            // a now version of current config (take local/utc/offset flags, and
3448            // create now).
3449            weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(local__createLocal(), 1, 4).year);
3450            week = defaults(w.W, 1);
3451            weekday = defaults(w.E, 1);
3452        } else {
3453            dow = config._locale._week.dow;
3454            doy = config._locale._week.doy;
3455
3456            weekYear = defaults(w.gg, config._a[YEAR], weekOfYear(local__createLocal(), dow, doy).year);
3457            week = defaults(w.w, 1);
3458
3459            if (w.d != null) {
3460                // weekday -- low day numbers are considered next week
3461                weekday = w.d;
3462                if (weekday < dow) {
3463                    ++week;
3464                }
3465            } else if (w.e != null) {
3466                // local weekday -- counting starts from begining of week
3467                weekday = w.e + dow;
3468            } else {
3469                // default to begining of week
3470                weekday = dow;
3471            }
3472        }
3473        temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow);
3474
3475        config._a[YEAR] = temp.year;
3476        config._dayOfYear = temp.dayOfYear;
3477    }
3478
3479    utils_hooks__hooks.ISO_8601 = function () {};
3480
3481    // date from string and format string
3482    function configFromStringAndFormat(config) {
3483        // TODO: Move this to another part of the creation flow to prevent circular deps
3484        if (config._f === utils_hooks__hooks.ISO_8601) {
3485            configFromISO(config);
3486            return;
3487        }
3488
3489        config._a = [];
3490        getParsingFlags(config).empty = true;
3491
3492        // This array is used to make a Date, either with `new Date` or `Date.UTC`
3493        var string = '' + config._i,
3494            i, parsedInput, tokens, token, skipped,
3495            stringLength = string.length,
3496            totalParsedInputLength = 0;
3497
3498        tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
3499
3500        for (i = 0; i < tokens.length; i++) {
3501            token = tokens[i];
3502            parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
3503            if (parsedInput) {
3504                skipped = string.substr(0, string.indexOf(parsedInput));
3505                if (skipped.length > 0) {
3506                    getParsingFlags(config).unusedInput.push(skipped);
3507                }
3508                string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
3509                totalParsedInputLength += parsedInput.length;
3510            }
3511            // don't parse if it's not a known token
3512            if (formatTokenFunctions[token]) {
3513                if (parsedInput) {
3514                    getParsingFlags(config).empty = false;
3515                }
3516                else {
3517                    getParsingFlags(config).unusedTokens.push(token);
3518                }
3519                addTimeToArrayFromToken(token, parsedInput, config);
3520            }
3521            else if (config._strict && !parsedInput) {
3522                getParsingFlags(config).unusedTokens.push(token);
3523            }
3524        }
3525
3526        // add remaining unparsed input length to the string
3527        getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
3528        if (string.length > 0) {
3529            getParsingFlags(config).unusedInput.push(string);
3530        }
3531
3532        // clear _12h flag if hour is <= 12
3533        if (getParsingFlags(config).bigHour === true &&
3534            config._a[HOUR] <= 12 &&
3535            config._a[HOUR] > 0) {
3536            getParsingFlags(config).bigHour = undefined;
3537        }
3538        // handle meridiem
3539        config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);
3540
3541        configFromArray(config);
3542        checkOverflow(config);
3543    }
3544
3545
3546    function meridiemFixWrap (locale, hour, meridiem) {
3547        var isPm;
3548
3549        if (meridiem == null) {
3550            // nothing to do
3551            return hour;
3552        }
3553        if (locale.meridiemHour != null) {
3554            return locale.meridiemHour(hour, meridiem);
3555        } else if (locale.isPM != null) {
3556            // Fallback
3557            isPm = locale.isPM(meridiem);
3558            if (isPm && hour < 12) {
3559                hour += 12;
3560            }
3561            if (!isPm && hour === 12) {
3562                hour = 0;
3563            }
3564            return hour;
3565        } else {
3566            // this is not supposed to happen
3567            return hour;
3568        }
3569    }
3570
3571    function configFromStringAndArray(config) {
3572        var tempConfig,
3573            bestMoment,
3574
3575            scoreToBeat,
3576            i,
3577            currentScore;
3578
3579        if (config._f.length === 0) {
3580            getParsingFlags(config).invalidFormat = true;
3581            config._d = new Date(NaN);
3582            return;
3583        }
3584
3585        for (i = 0; i < config._f.length; i++) {
3586            currentScore = 0;
3587            tempConfig = copyConfig({}, config);
3588            if (config._useUTC != null) {
3589                tempConfig._useUTC = config._useUTC;
3590            }
3591            tempConfig._f = config._f[i];
3592            configFromStringAndFormat(tempConfig);
3593
3594            if (!valid__isValid(tempConfig)) {
3595                continue;
3596            }
3597
3598            // if there is any input that was not parsed add a penalty for that format
3599            currentScore += getParsingFlags(tempConfig).charsLeftOver;
3600
3601            //or tokens
3602            currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
3603
3604            getParsingFlags(tempConfig).score = currentScore;
3605
3606            if (scoreToBeat == null || currentScore < scoreToBeat) {
3607                scoreToBeat = currentScore;
3608                bestMoment = tempConfig;
3609            }
3610        }
3611
3612        extend(config, bestMoment || tempConfig);
3613    }
3614
3615    function configFromObject(config) {
3616        if (config._d) {
3617            return;
3618        }
3619
3620        var i = normalizeObjectUnits(config._i);
3621        config._a = [i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond];
3622
3623        configFromArray(config);
3624    }
3625
3626    function createFromConfig (config) {
3627        var res = new Moment(checkOverflow(prepareConfig(config)));
3628        if (res._nextDay) {
3629            // Adding is smart enough around DST
3630            res.add(1, 'd');
3631            res._nextDay = undefined;
3632        }
3633
3634        return res;
3635    }
3636
3637    function prepareConfig (config) {
3638        var input = config._i,
3639            format = config._f;
3640
3641        config._locale = config._locale || locale_locales__getLocale(config._l);
3642
3643        if (input === null || (format === undefined && input === '')) {
3644            return valid__createInvalid({nullInput: true});
3645        }
3646
3647        if (typeof input === 'string') {
3648            config._i = input = config._locale.preparse(input);
3649        }
3650
3651        if (isMoment(input)) {
3652            return new Moment(checkOverflow(input));
3653        } else if (isArray(format)) {
3654            configFromStringAndArray(config);
3655        } else if (format) {
3656            configFromStringAndFormat(config);
3657        } else if (isDate(input)) {
3658            config._d = input;
3659        } else {
3660            configFromInput(config);
3661        }
3662
3663        return config;
3664    }
3665
3666    function configFromInput(config) {
3667        var input = config._i;
3668        if (input === undefined) {
3669            config._d = new Date();
3670        } else if (isDate(input)) {
3671            config._d = new Date(+input);
3672        } else if (typeof input === 'string') {
3673            configFromString(config);
3674        } else if (isArray(input)) {
3675            config._a = map(input.slice(0), function (obj) {
3676                return parseInt(obj, 10);
3677            });
3678            configFromArray(config);
3679        } else if (typeof(input) === 'object') {
3680            configFromObject(config);
3681        } else if (typeof(input) === 'number') {
3682            // from milliseconds
3683            config._d = new Date(input);
3684        } else {
3685            utils_hooks__hooks.createFromInputFallback(config);
3686        }
3687    }
3688
3689    function createLocalOrUTC (input, format, locale, strict, isUTC) {
3690        var c = {};
3691
3692        if (typeof(locale) === 'boolean') {
3693            strict = locale;
3694            locale = undefined;
3695        }
3696        // object construction must be done this way.
3697        // https://github.com/moment/moment/issues/1423
3698        c._isAMomentObject = true;
3699        c._useUTC = c._isUTC = isUTC;
3700        c._l = locale;
3701        c._i = input;
3702        c._f = format;
3703        c._strict = strict;
3704
3705        return createFromConfig(c);
3706    }
3707
3708    function local__createLocal (input, format, locale, strict) {
3709        return createLocalOrUTC(input, format, locale, strict, false);
3710    }
3711
3712    var prototypeMin = deprecate(
3713        'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',
3714        function () {
3715            var other = local__createLocal.apply(null, arguments);
3716            return other < this ? this : other;
3717        }
3718    );
3719
3720    var prototypeMax = deprecate(
3721        'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',
3722        function () {
3723            var other = local__createLocal.apply(null, arguments);
3724            return other > this ? this : other;
3725        }
3726    );
3727
3728    // Pick a moment m from moments so that m[fn](other) is true for all
3729    // other. This relies on the function fn to be transitive.
3730    //
3731    // moments should either be an array of moment objects or an array, whose
3732    // first element is an array of moment objects.
3733    function pickBy(fn, moments) {
3734        var res, i;
3735        if (moments.length === 1 && isArray(moments[0])) {
3736            moments = moments[0];
3737        }
3738        if (!moments.length) {
3739            return local__createLocal();
3740        }
3741        res = moments[0];
3742        for (i = 1; i < moments.length; ++i) {
3743            if (!moments[i].isValid() || moments[i][fn](res)) {
3744                res = moments[i];
3745            }
3746        }
3747        return res;
3748    }
3749
3750    // TODO: Use [].sort instead?
3751    function min () {
3752        var args = [].slice.call(arguments, 0);
3753
3754        return pickBy('isBefore', args);
3755    }
3756
3757    function max () {
3758        var args = [].slice.call(arguments, 0);
3759
3760        return pickBy('isAfter', args);
3761    }
3762
3763    function Duration (duration) {
3764        var normalizedInput = normalizeObjectUnits(duration),
3765            years = normalizedInput.year || 0,
3766            quarters = normalizedInput.quarter || 0,
3767            months = normalizedInput.month || 0,
3768            weeks = normalizedInput.week || 0,
3769            days = normalizedInput.day || 0,
3770            hours = normalizedInput.hour || 0,
3771            minutes = normalizedInput.minute || 0,
3772            seconds = normalizedInput.second || 0,
3773            milliseconds = normalizedInput.millisecond || 0;
3774
3775        // representation for dateAddRemove
3776        this._milliseconds = +milliseconds +
3777            seconds * 1e3 + // 1000
3778            minutes * 6e4 + // 1000 * 60
3779            hours * 36e5; // 1000 * 60 * 60
3780        // Because of dateAddRemove treats 24 hours as different from a
3781        // day when working around DST, we need to store them separately
3782        this._days = +days +
3783            weeks * 7;
3784        // It is impossible translate months into days without knowing
3785        // which months you are are talking about, so we have to store
3786        // it separately.
3787        this._months = +months +
3788            quarters * 3 +
3789            years * 12;
3790
3791        this._data = {};
3792
3793        this._locale = locale_locales__getLocale();
3794
3795        this._bubble();
3796    }
3797
3798    function isDuration (obj) {
3799        return obj instanceof Duration;
3800    }
3801
3802    function offset (token, separator) {
3803        addFormatToken(token, 0, 0, function () {
3804            var offset = this.utcOffset();
3805            var sign = '+';
3806            if (offset < 0) {
3807                offset = -offset;
3808                sign = '-';
3809            }
3810            return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);
3811        });
3812    }
3813
3814    offset('Z', ':');
3815    offset('ZZ', '');
3816
3817    // PARSING
3818
3819    addRegexToken('Z',  matchOffset);
3820    addRegexToken('ZZ', matchOffset);
3821    addParseToken(['Z', 'ZZ'], function (input, array, config) {
3822        config._useUTC = true;
3823        config._tzm = offsetFromString(input);
3824    });
3825
3826    // HELPERS
3827
3828    // timezone chunker
3829    // '+10:00' > ['10',  '00']
3830    // '-1530'  > ['-15', '30']
3831    var chunkOffset = /([\+\-]|\d\d)/gi;
3832
3833    function offsetFromString(string) {
3834        var matches = ((string || '').match(matchOffset) || []);
3835        var chunk   = matches[matches.length - 1] || [];
3836        var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];
3837        var minutes = +(parts[1] * 60) + toInt(parts[2]);
3838
3839        return parts[0] === '+' ? minutes : -minutes;
3840    }
3841
3842    // Return a moment from input, that is local/utc/zone equivalent to model.
3843    function cloneWithOffset(input, model) {
3844        var res, diff;
3845        if (model._isUTC) {
3846            res = model.clone();
3847            diff = (isMoment(input) || isDate(input) ? +input : +local__createLocal(input)) - (+res);
3848            // Use low-level api, because this fn is low-level api.
3849            res._d.setTime(+res._d + diff);
3850            utils_hooks__hooks.updateOffset(res, false);
3851            return res;
3852        } else {
3853            return local__createLocal(input).local();
3854        }
3855    }
3856
3857    function getDateOffset (m) {
3858        // On Firefox.24 Date#getTimezoneOffset returns a floating point.
3859        // https://github.com/moment/moment/pull/1871
3860        return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
3861    }
3862
3863    // HOOKS
3864
3865    // This function will be called whenever a moment is mutated.
3866    // It is intended to keep the offset in sync with the timezone.
3867    utils_hooks__hooks.updateOffset = function () {};
3868
3869    // MOMENTS
3870
3871    // keepLocalTime = true means only change the timezone, without
3872    // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
3873    // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
3874    // +0200, so we adjust the time as needed, to be valid.
3875    //
3876    // Keeping the time actually adds/subtracts (one hour)
3877    // from the actual represented time. That is why we call updateOffset
3878    // a second time. In case it wants us to change the offset again
3879    // _changeInProgress == true case, then we have to adjust, because
3880    // there is no such time in the given timezone.
3881    function getSetOffset (input, keepLocalTime) {
3882        var offset = this._offset || 0,
3883            localAdjust;
3884        if (input != null) {
3885            if (typeof input === 'string') {
3886                input = offsetFromString(input);
3887            }
3888            if (Math.abs(input) < 16) {
3889                input = input * 60;
3890            }
3891            if (!this._isUTC && keepLocalTime) {
3892                localAdjust = getDateOffset(this);
3893            }
3894            this._offset = input;
3895            this._isUTC = true;
3896            if (localAdjust != null) {
3897                this.add(localAdjust, 'm');
3898            }
3899            if (offset !== input) {
3900                if (!keepLocalTime || this._changeInProgress) {
3901                    add_subtract__addSubtract(this, create__createDuration(input - offset, 'm'), 1, false);
3902                } else if (!this._changeInProgress) {
3903                    this._changeInProgress = true;
3904                    utils_hooks__hooks.updateOffset(this, true);
3905                    this._changeInProgress = null;
3906                }
3907            }
3908            return this;
3909        } else {
3910            return this._isUTC ? offset : getDateOffset(this);
3911        }
3912    }
3913
3914    function getSetZone (input, keepLocalTime) {
3915        if (input != null) {
3916            if (typeof input !== 'string') {
3917                input = -input;
3918            }
3919
3920            this.utcOffset(input, keepLocalTime);
3921
3922            return this;
3923        } else {
3924            return -this.utcOffset();
3925        }
3926    }
3927
3928    function setOffsetToUTC (keepLocalTime) {
3929        return this.utcOffset(0, keepLocalTime);
3930    }
3931
3932    function setOffsetToLocal (keepLocalTime) {
3933        if (this._isUTC) {
3934            this.utcOffset(0, keepLocalTime);
3935            this._isUTC = false;
3936
3937            if (keepLocalTime) {
3938                this.subtract(getDateOffset(this), 'm');
3939            }
3940        }
3941        return this;
3942    }
3943
3944    function setOffsetToParsedOffset () {
3945        if (this._tzm) {
3946            this.utcOffset(this._tzm);
3947        } else if (typeof this._i === 'string') {
3948            this.utcOffset(offsetFromString(this._i));
3949        }
3950        return this;
3951    }
3952
3953    function hasAlignedHourOffset (input) {
3954        input = input ? local__createLocal(input).utcOffset() : 0;
3955
3956        return (this.utcOffset() - input) % 60 === 0;
3957    }
3958
3959    function isDaylightSavingTime () {
3960        return (
3961            this.utcOffset() > this.clone().month(0).utcOffset() ||
3962            this.utcOffset() > this.clone().month(5).utcOffset()
3963        );
3964    }
3965
3966    function isDaylightSavingTimeShifted () {
3967        if (typeof this._isDSTShifted !== 'undefined') {
3968            return this._isDSTShifted;
3969        }
3970
3971        var c = {};
3972
3973        copyConfig(c, this);
3974        c = prepareConfig(c);
3975
3976        if (c._a) {
3977            var other = c._isUTC ? create_utc__createUTC(c._a) : local__createLocal(c._a);
3978            this._isDSTShifted = this.isValid() &&
3979                compareArrays(c._a, other.toArray()) > 0;
3980        } else {
3981            this._isDSTShifted = false;
3982        }
3983
3984        return this._isDSTShifted;
3985    }
3986
3987    function isLocal () {
3988        return !this._isUTC;
3989    }
3990
3991    function isUtcOffset () {
3992        return this._isUTC;
3993    }
3994
3995    function isUtc () {
3996        return this._isUTC && this._offset === 0;
3997    }
3998
3999    var aspNetRegex = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/;
4000
4001    // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
4002    // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
4003    var create__isoRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/;
4004
4005    function create__createDuration (input, key) {
4006        var duration = input,
4007        // matching against regexp is expensive, do it on demand
4008            match = null,
4009            sign,
4010            ret,
4011            diffRes;
4012
4013        if (isDuration(input)) {
4014            duration = {
4015                ms : input._milliseconds,
4016                d  : input._days,
4017                M  : input._months
4018            };
4019        } else if (typeof input === 'number') {
4020            duration = {};
4021            if (key) {
4022                duration[key] = input;
4023            } else {
4024                duration.milliseconds = input;
4025            }
4026        } else if (!!(match = aspNetRegex.exec(input))) {
4027            sign = (match[1] === '-') ? -1 : 1;
4028            duration = {
4029                y  : 0,
4030                d  : toInt(match[DATE])        * sign,
4031                h  : toInt(match[HOUR])        * sign,
4032                m  : toInt(match[MINUTE])      * sign,
4033                s  : toInt(match[SECOND])      * sign,
4034                ms : toInt(match[MILLISECOND]) * sign
4035            };
4036        } else if (!!(match = create__isoRegex.exec(input))) {
4037            sign = (match[1] === '-') ? -1 : 1;
4038            duration = {
4039                y : parseIso(match[2], sign),
4040                M : parseIso(match[3], sign),
4041                d : parseIso(match[4], sign),
4042                h : parseIso(match[5], sign),
4043                m : parseIso(match[6], sign),
4044                s : parseIso(match[7], sign),
4045                w : parseIso(match[8], sign)
4046            };
4047        } else if (duration == null) {// checks for null or undefined
4048            duration = {};
4049        } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {
4050            diffRes = momentsDifference(local__createLocal(duration.from), local__createLocal(duration.to));
4051
4052            duration = {};
4053            duration.ms = diffRes.milliseconds;
4054            duration.M = diffRes.months;
4055        }
4056
4057        ret = new Duration(duration);
4058
4059        if (isDuration(input) && hasOwnProp(input, '_locale')) {
4060            ret._locale = input._locale;
4061        }
4062
4063        return ret;
4064    }
4065
4066    create__createDuration.fn = Duration.prototype;
4067
4068    function parseIso (inp, sign) {
4069        // We'd normally use ~~inp for this, but unfortunately it also
4070        // converts floats to ints.
4071        // inp may be undefined, so careful calling replace on it.
4072        var res = inp && parseFloat(inp.replace(',', '.'));
4073        // apply sign while we're at it
4074        return (isNaN(res) ? 0 : res) * sign;
4075    }
4076
4077    function positiveMomentsDifference(base, other) {
4078        var res = {milliseconds: 0, months: 0};
4079
4080        res.months = other.month() - base.month() +
4081            (other.year() - base.year()) * 12;
4082        if (base.clone().add(res.months, 'M').isAfter(other)) {
4083            --res.months;
4084        }
4085
4086        res.milliseconds = +other - +(base.clone().add(res.months, 'M'));
4087
4088        return res;
4089    }
4090
4091    function momentsDifference(base, other) {
4092        var res;
4093        other = cloneWithOffset(other, base);
4094        if (base.isBefore(other)) {
4095            res = positiveMomentsDifference(base, other);
4096        } else {
4097            res = positiveMomentsDifference(other, base);
4098            res.milliseconds = -res.milliseconds;
4099            res.months = -res.months;
4100        }
4101
4102        return res;
4103    }
4104
4105    function createAdder(direction, name) {
4106        return function (val, period) {
4107            var dur, tmp;
4108            //invert the arguments, but complain about it
4109            if (period !== null && !isNaN(+period)) {
4110                deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period).');
4111                tmp = val; val = period; period = tmp;
4112            }
4113
4114            val = typeof val === 'string' ? +val : val;
4115            dur = create__createDuration(val, period);
4116            add_subtract__addSubtract(this, dur, direction);
4117            return this;
4118        };
4119    }
4120
4121    function add_subtract__addSubtract (mom, duration, isAdding, updateOffset) {
4122        var milliseconds = duration._milliseconds,
4123            days = duration._days,
4124            months = duration._months;
4125        updateOffset = updateOffset == null ? true : updateOffset;
4126
4127        if (milliseconds) {
4128            mom._d.setTime(+mom._d + milliseconds * isAdding);
4129        }
4130        if (days) {
4131            get_set__set(mom, 'Date', get_set__get(mom, 'Date') + days * isAdding);
4132        }
4133        if (months) {
4134            setMonth(mom, get_set__get(mom, 'Month') + months * isAdding);
4135        }
4136        if (updateOffset) {
4137            utils_hooks__hooks.updateOffset(mom, days || months);
4138        }
4139    }
4140
4141    var add_subtract__add      = createAdder(1, 'add');
4142    var add_subtract__subtract = createAdder(-1, 'subtract');
4143
4144    function moment_calendar__calendar (time, formats) {
4145        // We want to compare the start of today, vs this.
4146        // Getting start-of-today depends on whether we're local/utc/offset or not.
4147        var now = time || local__createLocal(),
4148            sod = cloneWithOffset(now, this).startOf('day'),
4149            diff = this.diff(sod, 'days', true),
4150            format = diff < -6 ? 'sameElse' :
4151                diff < -1 ? 'lastWeek' :
4152                    diff < 0 ? 'lastDay' :
4153                        diff < 1 ? 'sameDay' :
4154                            diff < 2 ? 'nextDay' :
4155                                diff < 7 ? 'nextWeek' : 'sameElse';
4156        return this.format(formats && formats[format] || this.localeData().calendar(format, this, local__createLocal(now)));
4157    }
4158
4159    function clone () {
4160        return new Moment(this);
4161    }
4162
4163    function isAfter (input, units) {
4164        var inputMs;
4165        units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');
4166        if (units === 'millisecond') {
4167            input = isMoment(input) ? input : local__createLocal(input);
4168            return +this > +input;
4169        } else {
4170            inputMs = isMoment(input) ? +input : +local__createLocal(input);
4171            return inputMs < +this.clone().startOf(units);
4172        }
4173    }
4174
4175    function isBefore (input, units) {
4176        var inputMs;
4177        units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');
4178        if (units === 'millisecond') {
4179            input = isMoment(input) ? input : local__createLocal(input);
4180            return +this < +input;
4181        } else {
4182            inputMs = isMoment(input) ? +input : +local__createLocal(input);
4183            return +this.clone().endOf(units) < inputMs;
4184        }
4185    }
4186
4187    function isBetween (from, to, units) {
4188        return this.isAfter(from, units) && this.isBefore(to, units);
4189    }
4190
4191    function isSame (input, units) {
4192        var inputMs;
4193        units = normalizeUnits(units || 'millisecond');
4194        if (units === 'millisecond') {
4195            input = isMoment(input) ? input : local__createLocal(input);
4196            return +this === +input;
4197        } else {
4198            inputMs = +local__createLocal(input);
4199            return +(this.clone().startOf(units)) <= inputMs && inputMs <= +(this.clone().endOf(units));
4200        }
4201    }
4202
4203    function diff (input, units, asFloat) {
4204        var that = cloneWithOffset(input, this),
4205            zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4,
4206            delta, output;
4207
4208        units = normalizeUnits(units);
4209
4210        if (units === 'year' || units === 'month' || units === 'quarter') {
4211            output = monthDiff(this, that);
4212            if (units === 'quarter') {
4213                output = output / 3;
4214            } else if (units === 'year') {
4215                output = output / 12;
4216            }
4217        } else {
4218            delta = this - that;
4219            output = units === 'second' ? delta / 1e3 : // 1000
4220                units === 'minute' ? delta / 6e4 : // 1000 * 60
4221                    units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60
4222                        units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst
4223                            units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst
4224                                delta;
4225        }
4226        return asFloat ? output : absFloor(output);
4227    }
4228
4229    function monthDiff (a, b) {
4230        // difference in months
4231        var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),
4232        // b is in (anchor - 1 month, anchor + 1 month)
4233            anchor = a.clone().add(wholeMonthDiff, 'months'),
4234            anchor2, adjust;
4235
4236        if (b - anchor < 0) {
4237            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
4238            // linear across the month
4239            adjust = (b - anchor) / (anchor - anchor2);
4240        } else {
4241            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
4242            // linear across the month
4243            adjust = (b - anchor) / (anchor2 - anchor);
4244        }
4245
4246        return -(wholeMonthDiff + adjust);
4247    }
4248
4249    utils_hooks__hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
4250
4251    function toString () {
4252        return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
4253    }
4254
4255    function moment_format__toISOString () {
4256        var m = this.clone().utc();
4257        if (0 < m.year() && m.year() <= 9999) {
4258            if ('function' === typeof Date.prototype.toISOString) {
4259                // native implementation is ~50x faster, use it when we can
4260                return this.toDate().toISOString();
4261            } else {
4262                return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
4263            }
4264        } else {
4265            return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
4266        }
4267    }
4268
4269    function moment_format__format (inputString) {
4270        var output = formatMoment(this, inputString || utils_hooks__hooks.defaultFormat);
4271        return this.localeData().postformat(output);
4272    }
4273
4274    function from (time, withoutSuffix) {
4275        if (!this.isValid()) {
4276            return this.localeData().invalidDate();
4277        }
4278        return create__createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
4279    }
4280
4281    function fromNow (withoutSuffix) {
4282        return this.from(local__createLocal(), withoutSuffix);
4283    }
4284
4285    function to (time, withoutSuffix) {
4286        if (!this.isValid()) {
4287            return this.localeData().invalidDate();
4288        }
4289        return create__createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);
4290    }
4291
4292    function toNow (withoutSuffix) {
4293        return this.to(local__createLocal(), withoutSuffix);
4294    }
4295
4296    function locale (key) {
4297        var newLocaleData;
4298
4299        if (key === undefined) {
4300            return this._locale._abbr;
4301        } else {
4302            newLocaleData = locale_locales__getLocale(key);
4303            if (newLocaleData != null) {
4304                this._locale = newLocaleData;
4305            }
4306            return this;
4307        }
4308    }
4309
4310    var lang = deprecate(
4311        'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
4312        function (key) {
4313            if (key === undefined) {
4314                return this.localeData();
4315            } else {
4316                return this.locale(key);
4317            }
4318        }
4319    );
4320
4321    function localeData () {
4322        return this._locale;
4323    }
4324
4325    function startOf (units) {
4326        units = normalizeUnits(units);
4327        // the following switch intentionally omits break keywords
4328        // to utilize falling through the cases.
4329        switch (units) {
4330            case 'year':
4331                this.month(0);
4332            /* falls through */
4333            case 'quarter':
4334            case 'month':
4335                this.date(1);
4336            /* falls through */
4337            case 'week':
4338            case 'isoWeek':
4339            case 'day':
4340                this.hours(0);
4341            /* falls through */
4342            case 'hour':
4343                this.minutes(0);
4344            /* falls through */
4345            case 'minute':
4346                this.seconds(0);
4347            /* falls through */
4348            case 'second':
4349                this.milliseconds(0);
4350        }
4351
4352        // weeks are a special case
4353        if (units === 'week') {
4354            this.weekday(0);
4355        }
4356        if (units === 'isoWeek') {
4357            this.isoWeekday(1);
4358        }
4359
4360        // quarters are also special
4361        if (units === 'quarter') {
4362            this.month(Math.floor(this.month() / 3) * 3);
4363        }
4364
4365        return this;
4366    }
4367
4368    function endOf (units) {
4369        units = normalizeUnits(units);
4370        if (units === undefined || units === 'millisecond') {
4371            return this;
4372        }
4373        return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
4374    }
4375
4376    function to_type__valueOf () {
4377        return +this._d - ((this._offset || 0) * 60000);
4378    }
4379
4380    function unix () {
4381        return Math.floor(+this / 1000);
4382    }
4383
4384    function toDate () {
4385        return this._offset ? new Date(+this) : this._d;
4386    }
4387
4388    function toArray () {
4389        var m = this;
4390        return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
4391    }
4392
4393    function toObject () {
4394        var m = this;
4395        return {
4396            years: m.year(),
4397            months: m.month(),
4398            date: m.date(),
4399            hours: m.hours(),
4400            minutes: m.minutes(),
4401            seconds: m.seconds(),
4402            milliseconds: m.milliseconds()
4403        };
4404    }
4405
4406    function moment_valid__isValid () {
4407        return valid__isValid(this);
4408    }
4409
4410    function parsingFlags () {
4411        return extend({}, getParsingFlags(this));
4412    }
4413
4414    function invalidAt () {
4415        return getParsingFlags(this).overflow;
4416    }
4417
4418    addFormatToken(0, ['gg', 2], 0, function () {
4419        return this.weekYear() % 100;
4420    });
4421
4422    addFormatToken(0, ['GG', 2], 0, function () {
4423        return this.isoWeekYear() % 100;
4424    });
4425
4426    function addWeekYearFormatToken (token, getter) {
4427        addFormatToken(0, [token, token.length], 0, getter);
4428    }
4429
4430    addWeekYearFormatToken('gggg',     'weekYear');
4431    addWeekYearFormatToken('ggggg',    'weekYear');
4432    addWeekYearFormatToken('GGGG',  'isoWeekYear');
4433    addWeekYearFormatToken('GGGGG', 'isoWeekYear');
4434
4435    // ALIASES
4436
4437    addUnitAlias('weekYear', 'gg');
4438    addUnitAlias('isoWeekYear', 'GG');
4439
4440    // PARSING
4441
4442    addRegexToken('G',      matchSigned);
4443    addRegexToken('g',      matchSigned);
4444    addRegexToken('GG',     match1to2, match2);
4445    addRegexToken('gg',     match1to2, match2);
4446    addRegexToken('GGGG',   match1to4, match4);
4447    addRegexToken('gggg',   match1to4, match4);
4448    addRegexToken('GGGGG',  match1to6, match6);
4449    addRegexToken('ggggg',  match1to6, match6);
4450
4451    addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
4452        week[token.substr(0, 2)] = toInt(input);
4453    });
4454
4455    addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
4456        week[token] = utils_hooks__hooks.parseTwoDigitYear(input);
4457    });
4458
4459    // HELPERS
4460
4461    function weeksInYear(year, dow, doy) {
4462        return weekOfYear(local__createLocal([year, 11, 31 + dow - doy]), dow, doy).week;
4463    }
4464
4465    // MOMENTS
4466
4467    function getSetWeekYear (input) {
4468        var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year;
4469        return input == null ? year : this.add((input - year), 'y');
4470    }
4471
4472    function getSetISOWeekYear (input) {
4473        var year = weekOfYear(this, 1, 4).year;
4474        return input == null ? year : this.add((input - year), 'y');
4475    }
4476
4477    function getISOWeeksInYear () {
4478        return weeksInYear(this.year(), 1, 4);
4479    }
4480
4481    function getWeeksInYear () {
4482        var weekInfo = this.localeData()._week;
4483        return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
4484    }
4485
4486    addFormatToken('Q', 0, 0, 'quarter');
4487
4488    // ALIASES
4489
4490    addUnitAlias('quarter', 'Q');
4491
4492    // PARSING
4493
4494    addRegexToken('Q', match1);
vendor: 1,763 bytes, lines 4495-4559
4495    addParseToken('Q', function (input, array) {
4496        array[MONTH] = (toInt(input) - 1) * 3;
4497    });
4498
4499    // MOMENTS
4500
4501    function getSetQuarter (input) {
4502        return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
4503    }
4504
4505    addFormatToken('D', ['DD', 2], 'Do', 'date');
4506
4507    // ALIASES
4508
4509    addUnitAlias('date', 'D');
4510
4511    // PARSING
4512
4513    addRegexToken('D',  match1to2);
4514    addRegexToken('DD', match1to2, match2);
4515    addRegexToken('Do', function (isStrict, locale) {
4516        return isStrict ? locale._ordinalParse : locale._ordinalParseLenient;
4517    });
4518
4519    addParseToken(['D', 'DD'], DATE);
4520    addParseToken('Do', function (input, array) {
4521        array[DATE] = toInt(input.match(match1to2)[0], 10);
4522    });
4523
4524    // MOMENTS
4525
4526    var getSetDayOfMonth = makeGetSet('Date', true);
4527
4528    addFormatToken('d', 0, 'do', 'day');
4529
4530    addFormatToken('dd', 0, 0, function (format) {
4531        return this.localeData().weekdaysMin(this, format);
4532    });
4533
4534    addFormatToken('ddd', 0, 0, function (format) {
4535        return this.localeData().weekdaysShort(this, format);
4536    });
4537
4538    addFormatToken('dddd', 0, 0, function (format) {
4539        return this.localeData().weekdays(this, format);
4540    });
4541
4542    addFormatToken('e', 0, 0, 'weekday');
4543    addFormatToken('E', 0, 0, 'isoWeekday');
4544
4545    // ALIASES
4546
4547    addUnitAlias('day', 'd');
4548    addUnitAlias('weekday', 'e');
4549    addUnitAlias('isoWeekday', 'E');
4550
4551    // PARSING
4552
4553    addRegexToken('d',    match1to2);
4554    addRegexToken('e',    match1to2);
4555    addRegexToken('E',    match1to2);
4556    addRegexToken('dd',   matchWord);
4557    addRegexToken('ddd',  matchWord);
4558    addRegexToken('dddd', matchWord);
4559
4560    addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config) {
4561        var weekday = config._locale.weekdaysParse(input);
4562        // if we didn't get a weekday name, mark the date as invalid
4563        if (weekday != null) {
4564            week.d = weekday;
4565        } else {
4566            getParsingFlags(config).invalidWeekday = input;
4567        }
4568    });
4569
4570    addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
4571        week[token] = toInt(input);
4572    });
4573
4574    // HELPERS
4575
4576    function parseWeekday(input, locale) {
4577        if (typeof input !== 'string') {
4578            return input;
4579        }
4580
4581        if (!isNaN(input)) {
4582            return parseInt(input, 10);
4583        }
4584
4585        input = locale.weekdaysParse(input);
4586        if (typeof input === 'number') {
4587            return input;
4588        }
4589
4590        return null;
4591    }
4592
4593    // LOCALES
4594
4595    var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
4596    function localeWeekdays (m) {
4597        return this._weekdays[m.day()];
4598    }
4599
4600    var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
4601    function localeWeekdaysShort (m) {
4602        return this._weekdaysShort[m.day()];
4603    }
4604
4605    var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
4606    function localeWeekdaysMin (m) {
4607        return this._weekdaysMin[m.day()];
4608    }
4609
4610    function localeWeekdaysParse (weekdayName) {
4611        var i, mom, regex;
4612
4613        this._weekdaysParse = this._weekdaysParse || [];
4614
4615        for (i = 0; i < 7; i++) {
4616            // make the regex if we don't have it already
4617            if (!this._weekdaysParse[i]) {
4618                mom = local__createLocal([2000, 1]).day(i);
4619                regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
4620                this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
4621            }
4622            // test the regex
4623            if (this._weekdaysParse[i].test(weekdayName)) {
4624                return i;
4625            }
4626        }
4627    }
4628
4629    // MOMENTS
4630
4631    function getSetDayOfWeek (input) {
4632        var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
4633        if (input != null) {
4634            input = parseWeekday(input, this.localeData());
4635            return this.add(input - day, 'd');
4636        } else {
4637            return day;
4638        }
4639    }
4640
4641    function getSetLocaleDayOfWeek (input) {
4642        var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
4643        return input == null ? weekday : this.add(input - weekday, 'd');
4644    }
4645
4646    function getSetISODayOfWeek (input) {
4647        // behaves the same as moment#day except
4648        // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
4649        // as a setter, sunday should belong to the previous week.
4650        return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);
4651    }
4652
4653    addFormatToken('H', ['HH', 2], 0, 'hour');
4654    addFormatToken('h', ['hh', 2], 0, function () {
4655        return this.hours() % 12 || 12;
4656    });
4657
4658    function meridiem (token, lowercase) {
4659        addFormatToken(token, 0, 0, function () {
4660            return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
4661        });
4662    }
4663
4664    meridiem('a', true);
4665    meridiem('A', false);
4666
4667    // ALIASES
4668
4669    addUnitAlias('hour', 'h');
4670
4671    // PARSING
4672
4673    function matchMeridiem (isStrict, locale) {
4674        return locale._meridiemParse;
4675    }
4676
4677    addRegexToken('a',  matchMeridiem);
4678    addRegexToken('A',  matchMeridiem);
4679    addRegexToken('H',  match1to2);
4680    addRegexToken('h',  match1to2);
4681    addRegexToken('HH', match1to2, match2);
4682    addRegexToken('hh', match1to2, match2);
4683
4684    addParseToken(['H', 'HH'], HOUR);
4685    addParseToken(['a', 'A'], function (input, array, config) {
4686        config._isPm = config._locale.isPM(input);
4687        config._meridiem = input;
4688    });
4689    addParseToken(['h', 'hh'], function (input, array, config) {
4690        array[HOUR] = toInt(input);
4691        getParsingFlags(config).bigHour = true;
4692    });
vendor: 9,779 bytes, lines 4693-4969
4693
4694    // LOCALES
4695
4696    function localeIsPM (input) {
4697        // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
4698        // Using charAt should be more compatible.
4699        return ((input + '').toLowerCase().charAt(0) === 'p');
4700    }
4701
4702    var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;
4703    function localeMeridiem (hours, minutes, isLower) {
4704        if (hours > 11) {
4705            return isLower ? 'pm' : 'PM';
4706        } else {
4707            return isLower ? 'am' : 'AM';
4708        }
4709    }
4710
4711
4712    // MOMENTS
4713
4714    // Setting the hour should keep the time, because the user explicitly
4715    // specified which hour he wants. So trying to maintain the same hour (in
4716    // a new timezone) makes sense. Adding/subtracting hours does not follow
4717    // this rule.
4718    var getSetHour = makeGetSet('Hours', true);
4719
4720    addFormatToken('m', ['mm', 2], 0, 'minute');
4721
4722    // ALIASES
4723
4724    addUnitAlias('minute', 'm');
4725
4726    // PARSING
4727
4728    addRegexToken('m',  match1to2);
4729    addRegexToken('mm', match1to2, match2);
4730    addParseToken(['m', 'mm'], MINUTE);
4731
4732    // MOMENTS
4733
4734    var getSetMinute = makeGetSet('Minutes', false);
4735
4736    addFormatToken('s', ['ss', 2], 0, 'second');
4737
4738    // ALIASES
4739
4740    addUnitAlias('second', 's');
4741
4742    // PARSING
4743
4744    addRegexToken('s',  match1to2);
4745    addRegexToken('ss', match1to2, match2);
4746    addParseToken(['s', 'ss'], SECOND);
4747
4748    // MOMENTS
4749
4750    var getSetSecond = makeGetSet('Seconds', false);
4751
4752    addFormatToken('S', 0, 0, function () {
4753        return ~~(this.millisecond() / 100);
4754    });
4755
4756    addFormatToken(0, ['SS', 2], 0, function () {
4757        return ~~(this.millisecond() / 10);
4758    });
4759
4760    addFormatToken(0, ['SSS', 3], 0, 'millisecond');
4761    addFormatToken(0, ['SSSS', 4], 0, function () {
4762        return this.millisecond() * 10;
4763    });
4764    addFormatToken(0, ['SSSSS', 5], 0, function () {
4765        return this.millisecond() * 100;
4766    });
4767    addFormatToken(0, ['SSSSSS', 6], 0, function () {
4768        return this.millisecond() * 1000;
4769    });
4770    addFormatToken(0, ['SSSSSSS', 7], 0, function () {
4771        return this.millisecond() * 10000;
4772    });
4773    addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
4774        return this.millisecond() * 100000;
4775    });
4776    addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
4777        return this.millisecond() * 1000000;
4778    });
4779
4780
4781    // ALIASES
4782
4783    addUnitAlias('millisecond', 'ms');
4784
4785    // PARSING
4786
4787    addRegexToken('S',    match1to3, match1);
4788    addRegexToken('SS',   match1to3, match2);
4789    addRegexToken('SSS',  match1to3, match3);
4790
4791    var token;
4792    for (token = 'SSSS'; token.length <= 9; token += 'S') {
4793        addRegexToken(token, matchUnsigned);
4794    }
4795
4796    function parseMs(input, array) {
4797        array[MILLISECOND] = toInt(('0.' + input) * 1000);
4798    }
4799
4800    for (token = 'S'; token.length <= 9; token += 'S') {
4801        addParseToken(token, parseMs);
4802    }
4803    // MOMENTS
4804
4805    var getSetMillisecond = makeGetSet('Milliseconds', false);
4806
4807    addFormatToken('z',  0, 0, 'zoneAbbr');
4808    addFormatToken('zz', 0, 0, 'zoneName');
4809
4810    // MOMENTS
4811
4812    function getZoneAbbr () {
4813        return this._isUTC ? 'UTC' : '';
4814    }
4815
4816    function getZoneName () {
4817        return this._isUTC ? 'Coordinated Universal Time' : '';
4818    }
4819
4820    var momentPrototype__proto = Moment.prototype;
4821
4822    momentPrototype__proto.add          = add_subtract__add;
4823    momentPrototype__proto.calendar     = moment_calendar__calendar;
4824    momentPrototype__proto.clone        = clone;
4825    momentPrototype__proto.diff         = diff;
4826    momentPrototype__proto.endOf        = endOf;
4827    momentPrototype__proto.format       = moment_format__format;
4828    momentPrototype__proto.from         = from;
4829    momentPrototype__proto.fromNow      = fromNow;
4830    momentPrototype__proto.to           = to;
4831    momentPrototype__proto.toNow        = toNow;
4832    momentPrototype__proto.get          = getSet;
4833    momentPrototype__proto.invalidAt    = invalidAt;
4834    momentPrototype__proto.isAfter      = isAfter;
4835    momentPrototype__proto.isBefore     = isBefore;
4836    momentPrototype__proto.isBetween    = isBetween;
4837    momentPrototype__proto.isSame       = isSame;
4838    momentPrototype__proto.isValid      = moment_valid__isValid;
4839    momentPrototype__proto.lang         = lang;
4840    momentPrototype__proto.locale       = locale;
4841    momentPrototype__proto.localeData   = localeData;
4842    momentPrototype__proto.max          = prototypeMax;
4843    momentPrototype__proto.min          = prototypeMin;
4844    momentPrototype__proto.parsingFlags = parsingFlags;
4845    momentPrototype__proto.set          = getSet;
4846    momentPrototype__proto.startOf      = startOf;
4847    momentPrototype__proto.subtract     = add_subtract__subtract;
4848    momentPrototype__proto.toArray      = toArray;
4849    momentPrototype__proto.toObject     = toObject;
4850    momentPrototype__proto.toDate       = toDate;
4851    momentPrototype__proto.toISOString  = moment_format__toISOString;
4852    momentPrototype__proto.toJSON       = moment_format__toISOString;
4853    momentPrototype__proto.toString     = toString;
4854    momentPrototype__proto.unix         = unix;
4855    momentPrototype__proto.valueOf      = to_type__valueOf;
4856
4857    // Year
4858    momentPrototype__proto.year       = getSetYear;
4859    momentPrototype__proto.isLeapYear = getIsLeapYear;
4860
4861    // Week Year
4862    momentPrototype__proto.weekYear    = getSetWeekYear;
4863    momentPrototype__proto.isoWeekYear = getSetISOWeekYear;
4864
4865    // Quarter
4866    momentPrototype__proto.quarter = momentPrototype__proto.quarters = getSetQuarter;
4867
4868    // Month
4869    momentPrototype__proto.month       = getSetMonth;
4870    momentPrototype__proto.daysInMonth = getDaysInMonth;
4871
4872    // Week
4873    momentPrototype__proto.week           = momentPrototype__proto.weeks        = getSetWeek;
4874    momentPrototype__proto.isoWeek        = momentPrototype__proto.isoWeeks     = getSetISOWeek;
4875    momentPrototype__proto.weeksInYear    = getWeeksInYear;
4876    momentPrototype__proto.isoWeeksInYear = getISOWeeksInYear;
4877
4878    // Day
4879    momentPrototype__proto.date       = getSetDayOfMonth;
4880    momentPrototype__proto.day        = momentPrototype__proto.days             = getSetDayOfWeek;
4881    momentPrototype__proto.weekday    = getSetLocaleDayOfWeek;
4882    momentPrototype__proto.isoWeekday = getSetISODayOfWeek;
4883    momentPrototype__proto.dayOfYear  = getSetDayOfYear;
4884
4885    // Hour
4886    momentPrototype__proto.hour = momentPrototype__proto.hours = getSetHour;
4887
4888    // Minute
4889    momentPrototype__proto.minute = momentPrototype__proto.minutes = getSetMinute;
4890
4891    // Second
4892    momentPrototype__proto.second = momentPrototype__proto.seconds = getSetSecond;
4893
4894    // Millisecond
4895    momentPrototype__proto.millisecond = momentPrototype__proto.milliseconds = getSetMillisecond;
4896
4897    // Offset
4898    momentPrototype__proto.utcOffset            = getSetOffset;
4899    momentPrototype__proto.utc                  = setOffsetToUTC;
4900    momentPrototype__proto.local                = setOffsetToLocal;
4901    momentPrototype__proto.parseZone            = setOffsetToParsedOffset;
4902    momentPrototype__proto.hasAlignedHourOffset = hasAlignedHourOffset;
4903    momentPrototype__proto.isDST                = isDaylightSavingTime;
4904    momentPrototype__proto.isDSTShifted         = isDaylightSavingTimeShifted;
4905    momentPrototype__proto.isLocal              = isLocal;
4906    momentPrototype__proto.isUtcOffset          = isUtcOffset;
4907    momentPrototype__proto.isUtc                = isUtc;
4908    momentPrototype__proto.isUTC                = isUtc;
4909
4910    // Timezone
4911    momentPrototype__proto.zoneAbbr = getZoneAbbr;
4912    momentPrototype__proto.zoneName = getZoneName;
4913
4914    // Deprecations
4915    momentPrototype__proto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
4916    momentPrototype__proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
4917    momentPrototype__proto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);
4918    momentPrototype__proto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779', getSetZone);
4919
4920    var momentPrototype = momentPrototype__proto;
4921
4922    function moment_moment__createUnix (input) {
4923        return local__createLocal(input * 1000);
4924    }
4925
4926    function moment_moment__createInZone () {
4927        return local__createLocal.apply(null, arguments).parseZone();
4928    }
4929
4930    var defaultCalendar = {
4931        sameDay : '[Today at] LT',
4932        nextDay : '[Tomorrow at] LT',
4933        nextWeek : 'dddd [at] LT',
4934        lastDay : '[Yesterday at] LT',
4935        lastWeek : '[Last] dddd [at] LT',
4936        sameElse : 'L'
4937    };
4938
4939    function locale_calendar__calendar (key, mom, now) {
4940        var output = this._calendar[key];
4941        return typeof output === 'function' ? output.call(mom, now) : output;
4942    }
4943
4944    var defaultLongDateFormat = {
4945        LTS  : 'h:mm:ss A',
4946        LT   : 'h:mm A',
4947        L    : 'MM/DD/YYYY',
4948        LL   : 'MMMM D, YYYY',
4949        LLL  : 'MMMM D, YYYY h:mm A',
4950        LLLL : 'dddd, MMMM D, YYYY h:mm A'
4951    };
4952
4953    function longDateFormat (key) {
4954        var format = this._longDateFormat[key],
4955            formatUpper = this._longDateFormat[key.toUpperCase()];
4956
4957        if (format || !formatUpper) {
4958            return format;
4959        }
4960
4961        this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
4962            return val.slice(1);
4963        });
4964
4965        return this._longDateFormat[key];
4966    }
4967
4968    var defaultInvalidDate = 'Invalid date';
4969
4970    function invalidDate () {
4971        return this._invalidDate;
4972    }
4973
4974    var defaultOrdinal = '%d';
4975    var defaultOrdinalParse = /\d{1,2}/;
4976
4977    function ordinal (number) {
4978        return this._ordinal.replace('%d', number);
4979    }
4980
4981    function preParsePostFormat (string) {
4982        return string;
4983    }
4984
4985    var defaultRelativeTime = {
4986        future : 'in %s',
4987        past   : '%s ago',
4988        s  : 'a few seconds',
4989        m  : 'a minute',
4990        mm : '%d minutes',
4991        h  : 'an hour',
4992        hh : '%d hours',
4993        d  : 'a day',
4994        dd : '%d days',
4995        M  : 'a month',
4996        MM : '%d months',
4997        y  : 'a year',
4998        yy : '%d years'
4999    };
5000
5001    function relative__relativeTime (number, withoutSuffix, string, isFuture) {
5002        var output = this._relativeTime[string];
5003        return (typeof output === 'function') ?
5004            output(number, withoutSuffix, string, isFuture) :
5005            output.replace(/%d/i, number);
5006    }
5007
5008    function pastFuture (diff, output) {
5009        var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
5010        return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);
5011    }
5012
5013    function locale_set__set (config) {
5014        var prop, i;
5015        for (i in config) {
5016            prop = config[i];
5017            if (typeof prop === 'function') {
5018                this[i] = prop;
5019            } else {
5020                this['_' + i] = prop;
5021            }
5022        }
5023        // Lenient ordinal parsing accepts just a number in addition to
5024        // number + (possibly) stuff coming from _ordinalParseLenient.
5025        this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + (/\d{1,2}/).source);
5026    }
5027
5028    var prototype__proto = Locale.prototype;
5029
5030    prototype__proto._calendar       = defaultCalendar;
5031    prototype__proto.calendar        = locale_calendar__calendar;
5032    prototype__proto._longDateFormat = defaultLongDateFormat;
5033    prototype__proto.longDateFormat  = longDateFormat;
5034    prototype__proto._invalidDate    = defaultInvalidDate;
5035    prototype__proto.invalidDate     = invalidDate;
5036    prototype__proto._ordinal        = defaultOrdinal;
5037    prototype__proto.ordinal         = ordinal;
5038    prototype__proto._ordinalParse   = defaultOrdinalParse;
5039    prototype__proto.preparse        = preParsePostFormat;
5040    prototype__proto.postformat      = preParsePostFormat;
5041    prototype__proto._relativeTime   = defaultRelativeTime;
5042    prototype__proto.relativeTime    = relative__relativeTime;
5043    prototype__proto.pastFuture      = pastFuture;
5044    prototype__proto.set             = locale_set__set;
5045
5046    // Month
5047    prototype__proto.months       =        localeMonths;
5048    prototype__proto._months      = defaultLocaleMonths;
5049    prototype__proto.monthsShort  =        localeMonthsShort;
5050    prototype__proto._monthsShort = defaultLocaleMonthsShort;
5051    prototype__proto.monthsParse  =        localeMonthsParse;
5052
5053    // Week
5054    prototype__proto.week = localeWeek;
5055    prototype__proto._week = defaultLocaleWeek;
5056    prototype__proto.firstDayOfYear = localeFirstDayOfYear;
5057    prototype__proto.firstDayOfWeek = localeFirstDayOfWeek;
5058
5059    // Day of Week
5060    prototype__proto.weekdays       =        localeWeekdays;
5061    prototype__proto._weekdays      = defaultLocaleWeekdays;
5062    prototype__proto.weekdaysMin    =        localeWeekdaysMin;
5063    prototype__proto._weekdaysMin   = defaultLocaleWeekdaysMin;
5064    prototype__proto.weekdaysShort  =        localeWeekdaysShort;
5065    prototype__proto._weekdaysShort = defaultLocaleWeekdaysShort;
5066    prototype__proto.weekdaysParse  =        localeWeekdaysParse;
5067
5068    // Hours
5069    prototype__proto.isPM = localeIsPM;
5070    prototype__proto._meridiemParse = defaultLocaleMeridiemParse;
5071    prototype__proto.meridiem = localeMeridiem;
5072
5073    function lists__get (format, index, field, setter) {
5074        var locale = locale_locales__getLocale();
5075        var utc = create_utc__createUTC().set(setter, index);
5076        return locale[field](utc, format);
5077    }
5078
5079    function list (format, index, field, count, setter) {
5080        if (typeof format === 'number') {
5081            index = format;
5082            format = undefined;
5083        }
5084
5085        format = format || '';
5086
5087        if (index != null) {
5088            return lists__get(format, index, field, setter);
5089        }
5090
5091        var i;
5092        var out = [];
5093        for (i = 0; i < count; i++) {
5094            out[i] = lists__get(format, i, field, setter);
5095        }
5096        return out;
5097    }
5098
5099    function lists__listMonths (format, index) {
5100        return list(format, index, 'months', 12, 'month');
5101    }
5102
5103    function lists__listMonthsShort (format, index) {
5104        return list(format, index, 'monthsShort', 12, 'month');
5105    }
5106
5107    function lists__listWeekdays (format, index) {
5108        return list(format, index, 'weekdays', 7, 'day');
5109    }
5110
5111    function lists__listWeekdaysShort (format, index) {
5112        return list(format, index, 'weekdaysShort', 7, 'day');
5113    }
5114
5115    function lists__listWeekdaysMin (format, index) {
5116        return list(format, index, 'weekdaysMin', 7, 'day');
5117    }
5118
5119    locale_locales__getSetGlobalLocale('en', {
5120        ordinalParse: /\d{1,2}(th|st|nd|rd)/,
5121        ordinal : function (number) {
5122            var b = number % 10,
5123                output = (toInt(number % 100 / 10) === 1) ? 'th' :
5124                    (b === 1) ? 'st' :
5125                        (b === 2) ? 'nd' :
5126                            (b === 3) ? 'rd' : 'th';
5127            return number + output;
5128        }
5129    });
vendor: 7,121 bytes, lines 5130-5330
5130
5131    // Side effect imports
5132    utils_hooks__hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', locale_locales__getSetGlobalLocale);
5133    utils_hooks__hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', locale_locales__getLocale);
5134
5135    var mathAbs = Math.abs;
5136
5137    function duration_abs__abs () {
5138        var data           = this._data;
5139
5140        this._milliseconds = mathAbs(this._milliseconds);
5141        this._days         = mathAbs(this._days);
5142        this._months       = mathAbs(this._months);
5143
5144        data.milliseconds  = mathAbs(data.milliseconds);
5145        data.seconds       = mathAbs(data.seconds);
5146        data.minutes       = mathAbs(data.minutes);
5147        data.hours         = mathAbs(data.hours);
5148        data.months        = mathAbs(data.months);
5149        data.years         = mathAbs(data.years);
5150
5151        return this;
5152    }
5153
5154    function duration_add_subtract__addSubtract (duration, input, value, direction) {
5155        var other = create__createDuration(input, value);
5156
5157        duration._milliseconds += direction * other._milliseconds;
5158        duration._days         += direction * other._days;
5159        duration._months       += direction * other._months;
5160
5161        return duration._bubble();
5162    }
5163
5164    // supports only 2.0-style add(1, 's') or add(duration)
5165    function duration_add_subtract__add (input, value) {
5166        return duration_add_subtract__addSubtract(this, input, value, 1);
5167    }
5168
5169    // supports only 2.0-style subtract(1, 's') or subtract(duration)
5170    function duration_add_subtract__subtract (input, value) {
5171        return duration_add_subtract__addSubtract(this, input, value, -1);
5172    }
5173
5174    function absCeil (number) {
5175        if (number < 0) {
5176            return Math.floor(number);
5177        } else {
5178            return Math.ceil(number);
5179        }
5180    }
5181
5182    function bubble () {
5183        var milliseconds = this._milliseconds;
5184        var days         = this._days;
5185        var months       = this._months;
5186        var data         = this._data;
5187        var seconds, minutes, hours, years, monthsFromDays;
5188
5189        // if we have a mix of positive and negative values, bubble down first
5190        // check: https://github.com/moment/moment/issues/2166
5191        if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||
5192            (milliseconds <= 0 && days <= 0 && months <= 0))) {
5193            milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
5194            days = 0;
5195            months = 0;
5196        }
5197
5198        // The following code bubbles up values, see the tests for
5199        // examples of what that means.
5200        data.milliseconds = milliseconds % 1000;
5201
5202        seconds           = absFloor(milliseconds / 1000);
5203        data.seconds      = seconds % 60;
5204
5205        minutes           = absFloor(seconds / 60);
5206        data.minutes      = minutes % 60;
5207
5208        hours             = absFloor(minutes / 60);
5209        data.hours        = hours % 24;
5210
5211        days += absFloor(hours / 24);
5212
5213        // convert days to months
5214        monthsFromDays = absFloor(daysToMonths(days));
5215        months += monthsFromDays;
5216        days -= absCeil(monthsToDays(monthsFromDays));
5217
5218        // 12 months -> 1 year
5219        years = absFloor(months / 12);
5220        months %= 12;
5221
5222        data.days   = days;
5223        data.months = months;
5224        data.years  = years;
5225
5226        return this;
5227    }
5228
5229    function daysToMonths (days) {
5230        // 400 years have 146097 days (taking into account leap year rules)
5231        // 400 years have 12 months === 4800
5232        return days * 4800 / 146097;
5233    }
5234
5235    function monthsToDays (months) {
5236        // the reverse of daysToMonths
5237        return months * 146097 / 4800;
5238    }
5239
5240    function as (units) {
5241        var days;
5242        var months;
5243        var milliseconds = this._milliseconds;
5244
5245        units = normalizeUnits(units);
5246
5247        if (units === 'month' || units === 'year') {
5248            days   = this._days   + milliseconds / 864e5;
5249            months = this._months + daysToMonths(days);
5250            return units === 'month' ? months : months / 12;
5251        } else {
5252            // handle milliseconds separately because of floating point math errors (issue #1867)
5253            days = this._days + Math.round(monthsToDays(this._months));
5254            switch (units) {
5255                case 'week'   : return days / 7     + milliseconds / 6048e5;
5256                case 'day'    : return days         + milliseconds / 864e5;
5257                case 'hour'   : return days * 24    + milliseconds / 36e5;
5258                case 'minute' : return days * 1440  + milliseconds / 6e4;
5259                case 'second' : return days * 86400 + milliseconds / 1000;
5260                // Math.floor prevents floating point math errors here
5261                case 'millisecond': return Math.floor(days * 864e5) + milliseconds;
5262                default: throw new Error('Unknown unit ' + units);
5263            }
5264        }
5265    }
5266
5267    // TODO: Use this.as('ms')?
5268    function duration_as__valueOf () {
5269        return (
5270            this._milliseconds +
5271            this._days * 864e5 +
5272            (this._months % 12) * 2592e6 +
5273            toInt(this._months / 12) * 31536e6
5274        );
5275    }
5276
5277    function makeAs (alias) {
5278        return function () {
5279            return this.as(alias);
5280        };
5281    }
5282
5283    var asMilliseconds = makeAs('ms');
5284    var asSeconds      = makeAs('s');
5285    var asMinutes      = makeAs('m');
5286    var asHours        = makeAs('h');
5287    var asDays         = makeAs('d');
5288    var asWeeks        = makeAs('w');
5289    var asMonths       = makeAs('M');
5290    var asYears        = makeAs('y');
5291
5292    function duration_get__get (units) {
5293        units = normalizeUnits(units);
5294        return this[units + 's']();
5295    }
5296
5297    function makeGetter(name) {
5298        return function () {
5299            return this._data[name];
5300        };
5301    }
5302
5303    var milliseconds = makeGetter('milliseconds');
5304    var seconds      = makeGetter('seconds');
5305    var minutes      = makeGetter('minutes');
5306    var hours        = makeGetter('hours');
5307    var days         = makeGetter('days');
5308    var duration_get__months       = makeGetter('months');
5309    var years        = makeGetter('years');
5310
5311    function weeks () {
5312        return absFloor(this.days() / 7);
5313    }
5314
5315    var round = Math.round;
5316    var thresholds = {
5317        s: 45,  // seconds to minute
5318        m: 45,  // minutes to hour
5319        h: 22,  // hours to day
5320        d: 26,  // days to month
5321        M: 11   // months to year
5322    };
5323
5324    // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
5325    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
5326        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
5327    }
5328
5329    function duration_humanize__relativeTime (posNegDuration, withoutSuffix, locale) {
5330        var duration = create__createDuration(posNegDuration).abs();
5331        var seconds  = round(duration.as('s'));
5332        var minutes  = round(duration.as('m'));
5333        var hours    = round(duration.as('h'));
5334        var days     = round(duration.as('d'));
5335        var months   = round(duration.as('M'));
5336        var years    = round(duration.as('y'));
5337
5338        var a = seconds < thresholds.s && ['s', seconds]  ||
5339            minutes === 1          && ['m']           ||
5340            minutes < thresholds.m && ['mm', minutes] ||
5341            hours   === 1          && ['h']           ||
5342            hours   < thresholds.h && ['hh', hours]   ||
5343            days    === 1          && ['d']           ||
5344            days    < thresholds.d && ['dd', days]    ||
5345            months  === 1          && ['M']           ||
5346            months  < thresholds.M && ['MM', months]  ||
5347            years   === 1          && ['y']           || ['yy', years];
5348
5349        a[2] = withoutSuffix;
5350        a[3] = +posNegDuration > 0;
5351        a[4] = locale;
5352        return substituteTimeAgo.apply(null, a);
5353    }
5354
5355    // This function allows you to set a threshold for relative time strings
5356    function duration_humanize__getSetRelativeTimeThreshold (threshold, limit) {
5357        if (thresholds[threshold] === undefined) {
5358            return false;
5359        }
5360        if (limit === undefined) {
5361            return thresholds[threshold];
5362        }
5363        thresholds[threshold] = limit;
5364        return true;
5365    }
5366
5367    function humanize (withSuffix) {
5368        var locale = this.localeData();
5369        var output = duration_humanize__relativeTime(this, !withSuffix, locale);
5370
5371        if (withSuffix) {
5372            output = locale.pastFuture(+this, output);
5373        }
5374
5375        return locale.postformat(output);
5376    }
5377
5378    var iso_string__abs = Math.abs;
5379
5380    function iso_string__toISOString() {
5381        // for ISO strings we do not use the normal bubbling rules:
5382        //  * milliseconds bubble up until they become hours
5383        //  * days do not bubble at all
5384        //  * months bubble up until they become years
5385        // This is because there is no context-free conversion between hours and days
5386        // (think of clock changes)
5387        // and also not between days and months (28-31 days per month)
5388        var seconds = iso_string__abs(this._milliseconds) / 1000;
5389        var days         = iso_string__abs(this._days);
5390        var months       = iso_string__abs(this._months);
5391        var minutes, hours, years;
5392
5393        // 3600 seconds -> 60 minutes -> 1 hour
5394        minutes           = absFloor(seconds / 60);
5395        hours             = absFloor(minutes / 60);
5396        seconds %= 60;
5397        minutes %= 60;
5398
5399        // 12 months -> 1 year
5400        years  = absFloor(months / 12);
5401        months %= 12;
5402
5403
5404        // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
5405        var Y = years;
5406        var M = months;
5407        var D = days;
5408        var h = hours;
5409        var m = minutes;
5410        var s = seconds;
5411        var total = this.asSeconds();
5412
5413        if (!total) {
5414            // this is the same as C#'s (Noda) and python (isodate)...
5415            // but not other JS (goog.date)
5416            return 'P0D';
5417        }
5418
5419        return (total < 0 ? '-' : '') +
5420            'P' +
5421            (Y ? Y + 'Y' : '') +
5422            (M ? M + 'M' : '') +
5423            (D ? D + 'D' : '') +
5424            ((h || m || s) ? 'T' : '') +
5425            (h ? h + 'H' : '') +
5426            (m ? m + 'M' : '') +
5427            (s ? s + 'S' : '');
5428    }
5429
5430    var duration_prototype__proto = Duration.prototype;
5431
5432    duration_prototype__proto.abs            = duration_abs__abs;
5433    duration_prototype__proto.add            = duration_add_subtract__add;
5434    duration_prototype__proto.subtract       = duration_add_subtract__subtract;
5435    duration_prototype__proto.as             = as;
5436    duration_prototype__proto.asMilliseconds = asMilliseconds;
5437    duration_prototype__proto.asSeconds      = asSeconds;
5438    duration_prototype__proto.asMinutes      = asMinutes;
5439    duration_prototype__proto.asHours        = asHours;
5440    duration_prototype__proto.asDays         = asDays;
5441    duration_prototype__proto.asWeeks        = asWeeks;
5442    duration_prototype__proto.asMonths       = asMonths;
5443    duration_prototype__proto.asYears        = asYears;
5444    duration_prototype__proto.valueOf        = duration_as__valueOf;
5445    duration_prototype__proto._bubble        = bubble;
5446    duration_prototype__proto.get            = duration_get__get;
5447    duration_prototype__proto.milliseconds   = milliseconds;
5448    duration_prototype__proto.seconds        = seconds;
5449    duration_prototype__proto.minutes        = minutes;
5450    duration_prototype__proto.hours          = hours;
5451    duration_prototype__proto.days           = days;
5452    duration_prototype__proto.weeks          = weeks;
5453    duration_prototype__proto.months         = duration_get__months;
5454    duration_prototype__proto.years          = years;
5455    duration_prototype__proto.humanize       = humanize;
5456    duration_prototype__proto.toISOString    = iso_string__toISOString;
5457    duration_prototype__proto.toString       = iso_string__toISOString;
5458    duration_prototype__proto.toJSON         = iso_string__toISOString;
5459    duration_prototype__proto.locale         = locale;
5460    duration_prototype__proto.localeData     = localeData;
5461
5462    // Deprecations
5463    duration_prototype__proto.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', iso_string__toISOString);
5464    duration_prototype__proto.lang = lang;
5465
5466    // Side effect imports
5467
5468    addFormatToken('X', 0, 0, 'unix');
5469    addFormatToken('x', 0, 0, 'valueOf');
5470
5471    // PARSING
5472
5473    addRegexToken('x', matchSigned);
5474    addRegexToken('X', matchTimestamp);
5475    addParseToken('X', function (input, array, config) {
5476        config._d = new Date(parseFloat(input, 10) * 1000);
5477    });
5478    addParseToken('x', function (input, array, config) {
5479        config._d = new Date(toInt(input));
5480    });
5481
5482    // Side effect imports
5483
5484    ;
5485
5486    //! moment.js
5487    //! version : 2.10.6
5488    //! authors : Tim Wood, Iskren Chernev, Moment.js contributors
5489    //! license : MIT
5490    //! momentjs.com
5491
5492    utils_hooks__hooks.version = '2.10.6';
5493
5494    setHookCallback(local__createLocal);
5495
5496    utils_hooks__hooks.fn                    = momentPrototype;
5497    utils_hooks__hooks.min                   = min;
5498    utils_hooks__hooks.max                   = max;
5499    utils_hooks__hooks.utc                   = create_utc__createUTC;
5500    utils_hooks__hooks.unix                  = moment_moment__createUnix;
5501    utils_hooks__hooks.months                = lists__listMonths;
5502    utils_hooks__hooks.isDate                = isDate;
5503    utils_hooks__hooks.locale                = locale_locales__getSetGlobalLocale;
5504    utils_hooks__hooks.invalid               = valid__createInvalid;
5505    utils_hooks__hooks.duration              = create__createDuration;
5506    utils_hooks__hooks.isMoment              = isMoment;
5507    utils_hooks__hooks.weekdays              = lists__listWeekdays;
5508    utils_hooks__hooks.parseZone             = moment_moment__createInZone;
5509    utils_hooks__hooks.localeData            = locale_locales__getLocale;
5510    utils_hooks__hooks.isDuration            = isDuration;
5511    utils_hooks__hooks.monthsShort           = lists__listMonthsShort;
5512    utils_hooks__hooks.weekdaysMin           = lists__listWeekdaysMin;
5513    utils_hooks__hooks.defineLocale          = defineLocale;
5514    utils_hooks__hooks.weekdaysShort         = lists__listWeekdaysShort;
5515    utils_hooks__hooks.normalizeUnits        = normalizeUnits;
5516    utils_hooks__hooks.relativeTimeThreshold = duration_humanize__getSetRelativeTimeThreshold;
5517
5518    var _moment__default = utils_hooks__hooks;
5519
5520    //! moment.js locale configuration
5521    //! locale : afrikaans (af)
5522    //! author : Werner Mollentze : https://github.com/wernerm
5523
5524    var af = _moment__default.defineLocale('af', {
5525        months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'),
5526        monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'),
5527        weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'),
5528        weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'),
5529        weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'),
5530        meridiemParse: /vm|nm/i,
5531        isPM : function (input) {
5532            return /^nm$/i.test(input);
5533        },
5534        meridiem : function (hours, minutes, isLower) {
5535            if (hours < 12) {
5536                return isLower ? 'vm' : 'VM';
5537            } else {
5538                return isLower ? 'nm' : 'NM';
5539            }
5540        },
5541        longDateFormat : {
5542            LT : 'HH:mm',
5543            LTS : 'HH:mm:ss',
5544            L : 'DD/MM/YYYY',
5545            LL : 'D MMMM YYYY',
5546            LLL : 'D MMMM YYYY HH:mm',
5547            LLLL : 'dddd, D MMMM YYYY HH:mm'
5548        },
5549        calendar : {
5550            sameDay : '[Vandag om] LT',
5551            nextDay : '[Môre om] LT',
5552            nextWeek : 'dddd [om] LT',
5553            lastDay : '[Gister om] LT',
5554            lastWeek : '[Laas] dddd [om] LT',
5555            sameElse : 'L'
5556        },
5557        relativeTime : {
5558            future : 'oor %s',
5559            past : '%s gelede',
5560            s : '\'n paar sekondes',
5561            m : '\'n minuut',
5562            mm : '%d minute',
5563            h : '\'n uur',
5564            hh : '%d ure',
5565            d : '\'n dag',
5566            dd : '%d dae',
5567            M : '\'n maand',
5568            MM : '%d maande',
5569            y : '\'n jaar',
5570            yy : '%d jaar'
5571        },
5572        ordinalParse: /\d{1,2}(ste|de)/,
5573        ordinal : function (number) {
5574            return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter
5575        },
5576        week : {
5577            dow : 1, // Maandag is die eerste dag van die week.
5578            doy : 4  // Die week wat die 4de Januarie bevat is die eerste week van die jaar.
5579        }
5580    });
5581
5582    //! moment.js locale configuration
5583    //! locale : Moroccan Arabic (ar-ma)
5584    //! author : ElFadili Yassine : https://github.com/ElFadiliY
5585    //! author : Abdel Said : https://github.com/abdelsaid
5586
5587    var ar_ma = _moment__default.defineLocale('ar-ma', {
5588        months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),
5589        monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),
5590        weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
5591        weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),
5592        weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
5593        longDateFormat : {
5594            LT : 'HH:mm',
5595            LTS : 'HH:mm:ss',
5596            L : 'DD/MM/YYYY',
5597            LL : 'D MMMM YYYY',
5598            LLL : 'D MMMM YYYY HH:mm',
5599            LLLL : 'dddd D MMMM YYYY HH:mm'
5600        },
5601        calendar : {
5602            sameDay: '[اليوم على الساعة] LT',
5603            nextDay: '[غدا على الساعة] LT',
5604            nextWeek: 'dddd [على الساعة] LT',
5605            lastDay: '[أمس على الساعة] LT',
5606            lastWeek: 'dddd [على الساعة] LT',
5607            sameElse: 'L'
5608        },
5609        relativeTime : {
5610            future : 'في %s',
5611            past : 'منذ %s',
5612            s : 'ثوان',
5613            m : 'دقيقة',
5614            mm : '%d دقائق',
5615            h : 'ساعة',
5616            hh : '%d ساعات',
5617            d : 'يوم',
5618            dd : '%d أيام',
5619            M : 'شهر',
5620            MM : '%d أشهر',
5621            y : 'سنة',
5622            yy : '%d سنوات'
5623        },
5624        week : {
5625            dow : 6, // Saturday is the first day of the week.
5626            doy : 12  // The week that contains Jan 1st is the first week of the year.
5627        }
5628    });
5629
5630    //! moment.js locale configuration
5631    //! locale : Arabic Saudi Arabia (ar-sa)
5632    //! author : Suhail Alkowaileet : https://github.com/xsoh
5633
5634    var ar_sa__symbolMap = {
5635        '1': 'Ù¡',
5636        '2': 'Ù¢',
5637        '3': 'Ù£',
5638        '4': 'Ù¤',
5639        '5': 'Ù¥',
5640        '6': 'Ù¦',
5641        '7': 'Ù§',
5642        '8': 'Ù¨',
5643        '9': 'Ù©',
5644        '0': 'Ù '
5645    }, ar_sa__numberMap = {
5646        'Ù¡': '1',
5647        'Ù¢': '2',
5648        'Ù£': '3',
5649        'Ù¤': '4',
5650        'Ù¥': '5',
5651        'Ù¦': '6',
5652        'Ù§': '7',
5653        'Ù¨': '8',
5654        'Ù©': '9',
5655        'Ù ': '0'
5656    };
5657
5658    var ar_sa = _moment__default.defineLocale('ar-sa', {
5659        months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
5660        monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
5661        weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
5662        weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
5663        weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
5664        longDateFormat : {
5665            LT : 'HH:mm',
5666            LTS : 'HH:mm:ss',
5667            L : 'DD/MM/YYYY',
5668            LL : 'D MMMM YYYY',
5669            LLL : 'D MMMM YYYY HH:mm',
5670            LLLL : 'dddd D MMMM YYYY HH:mm'
5671        },
5672        meridiemParse: /ص|م/,
5673        isPM : function (input) {
5674            return 'م' === input;
5675        },
5676        meridiem : function (hour, minute, isLower) {
5677            if (hour < 12) {
5678                return 'ص';
5679            } else {
5680                return 'م';
5681            }
5682        },
5683        calendar : {
5684            sameDay: '[اليوم على الساعة] LT',
5685            nextDay: '[غدا على الساعة] LT',
5686            nextWeek: 'dddd [على الساعة] LT',
5687            lastDay: '[أمس على الساعة] LT',
5688            lastWeek: 'dddd [على الساعة] LT',
5689            sameElse: 'L'
5690        },
5691        relativeTime : {
5692            future : 'في %s',
5693            past : 'منذ %s',
5694            s : 'ثوان',
5695            m : 'دقيقة',
5696            mm : '%d دقائق',
5697            h : 'ساعة',
5698            hh : '%d ساعات',
5699            d : 'يوم',
5700            dd : '%d أيام',
5701            M : 'شهر',
5702            MM : '%d أشهر',
5703            y : 'سنة',
5704            yy : '%d سنوات'
5705        },
5706        preparse: function (string) {
5707            return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {
5708                return ar_sa__numberMap[match];
5709            }).replace(/،/g, ',');
5710        },
5711        postformat: function (string) {
5712            return string.replace(/\d/g, function (match) {
5713                return ar_sa__symbolMap[match];
5714            }).replace(/,/g, '،');
5715        },
5716        week : {
5717            dow : 6, // Saturday is the first day of the week.
5718            doy : 12  // The week that contains Jan 1st is the first week of the year.
5719        }
5720    });
5721
5722    //! moment.js locale configuration
5723    //! locale  : Tunisian Arabic (ar-tn)
5724
5725    var ar_tn = _moment__default.defineLocale('ar-tn', {
5726        months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
5727        monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
5728        weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
5729        weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
5730        weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),
5731        longDateFormat: {
5732            LT: 'HH:mm',
5733            LTS: 'HH:mm:ss',
5734            L: 'DD/MM/YYYY',
5735            LL: 'D MMMM YYYY',
5736            LLL: 'D MMMM YYYY HH:mm',
5737            LLLL: 'dddd D MMMM YYYY HH:mm'
5738        },
5739        calendar: {
5740            sameDay: '[اليوم على الساعة] LT',
5741            nextDay: '[غدا على الساعة] LT',
5742            nextWeek: 'dddd [على الساعة] LT',
5743            lastDay: '[أمس على الساعة] LT',
5744            lastWeek: 'dddd [على الساعة] LT',
5745            sameElse: 'L'
5746        },
5747        relativeTime: {
5748            future: 'في %s',
5749            past: 'منذ %s',
5750            s: 'ثوان',
5751            m: 'دقيقة',
5752            mm: '%d دقائق',
5753            h: 'ساعة',
5754            hh: '%d ساعات',
5755            d: 'يوم',
5756            dd: '%d أيام',
5757            M: 'شهر',
5758            MM: '%d أشهر',
5759            y: 'سنة',
5760            yy: '%d سنوات'
5761        },
5762        week: {
5763            dow: 1, // Monday is the first day of the week.
5764            doy: 4 // The week that contains Jan 4th is the first week of the year.
5765        }
5766    });
5767
5768    //! moment.js locale configuration
5769    //! Locale: Arabic (ar)
5770    //! Author: Abdel Said: https://github.com/abdelsaid
5771    //! Changes in months, weekdays: Ahmed Elkhatib
5772    //! Native plural forms: forabi https://github.com/forabi
5773
5774    var ar__symbolMap = {
5775        '1': 'Ù¡',
5776        '2': 'Ù¢',
5777        '3': 'Ù£',
5778        '4': 'Ù¤',
5779        '5': 'Ù¥',
5780        '6': 'Ù¦',
5781        '7': 'Ù§',
5782        '8': 'Ù¨',
5783        '9': 'Ù©',
5784        '0': 'Ù '
5785    }, ar__numberMap = {
5786        'Ù¡': '1',
5787        'Ù¢': '2',
5788        'Ù£': '3',
5789        'Ù¤': '4',
5790        'Ù¥': '5',
5791        'Ù¦': '6',
5792        'Ù§': '7',
5793        'Ù¨': '8',
5794        'Ù©': '9',
5795        'Ù ': '0'
5796    }, pluralForm = function (n) {
5797        return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;
5798    }, plurals = {
5799        s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],
5800        m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],
5801        h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],
5802        d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],
5803        M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],
5804        y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']
5805    }, pluralize = function (u) {
5806        return function (number, withoutSuffix, string, isFuture) {
5807            var f = pluralForm(number),
5808                str = plurals[u][pluralForm(number)];
5809            if (f === 2) {
5810                str = str[withoutSuffix ? 0 : 1];
5811            }
5812            return str.replace(/%d/i, number);
5813        };
5814    }, ar__months = [
5815        'كانون الثاني يناير',
5816        'شباط فبراير',
5817        'آذار مارس',
5818        'نيسان أبريل',
5819        'أيار مايو',
5820        'حزيران يونيو',
5821        'تموز يوليو',
5822        'آب أغسطس',
5823        'أيلول سبتمبر',
5824        'تشرين الأول أكتوبر',
5825        'تشرين الثاني نوفمبر',
5826        'كانون الأول ديسمبر'
5827    ];
5828
5829    var ar = _moment__default.defineLocale('ar', {
5830        months : ar__months,
5831        monthsShort : ar__months,
5832        weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
5833        weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
5834        weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
5835        longDateFormat : {
5836            LT : 'HH:mm',
5837            LTS : 'HH:mm:ss',
5838            L : 'D/\u200FM/\u200FYYYY',
5839            LL : 'D MMMM YYYY',
5840            LLL : 'D MMMM YYYY HH:mm',
5841            LLLL : 'dddd D MMMM YYYY HH:mm'
5842        },
5843        meridiemParse: /ص|م/,
5844        isPM : function (input) {
5845            return 'م' === input;
5846        },
5847        meridiem : function (hour, minute, isLower) {
5848            if (hour < 12) {
5849                return 'ص';
5850            } else {
5851                return 'م';
5852            }
5853        },
5854        calendar : {
5855            sameDay: '[اليوم عند الساعة] LT',
5856            nextDay: '[غدًا عند الساعة] LT',
5857            nextWeek: 'dddd [عند الساعة] LT',
5858            lastDay: '[أمس عند الساعة] LT',
5859            lastWeek: 'dddd [عند الساعة] LT',
5860            sameElse: 'L'
5861        },
5862        relativeTime : {
5863            future : 'بعد %s',
5864            past : 'منذ %s',
5865            s : pluralize('s'),
5866            m : pluralize('m'),
5867            mm : pluralize('m'),
5868            h : pluralize('h'),
5869            hh : pluralize('h'),
5870            d : pluralize('d'),
5871            dd : pluralize('d'),
5872            M : pluralize('M'),
5873            MM : pluralize('M'),
5874            y : pluralize('y'),
5875            yy : pluralize('y')
5876        },
5877        preparse: function (string) {
5878            return string.replace(/\u200f/g, '').replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {
5879                return ar__numberMap[match];
5880            }).replace(/،/g, ',');
5881        },
5882        postformat: function (string) {
5883            return string.replace(/\d/g, function (match) {
5884                return ar__symbolMap[match];
5885            }).replace(/,/g, '،');
5886        },
5887        week : {
5888            dow : 6, // Saturday is the first day of the week.
5889            doy : 12  // The week that contains Jan 1st is the first week of the year.
5890        }
5891    });
5892
5893    //! moment.js locale configuration
5894    //! locale : azerbaijani (az)
5895    //! author : topchiyev : https://github.com/topchiyev
5896
5897    var az__suffixes = {
5898        1: '-inci',
5899        5: '-inci',
5900        8: '-inci',
5901        70: '-inci',
5902        80: '-inci',
5903        2: '-nci',
5904        7: '-nci',
5905        20: '-nci',
5906        50: '-nci',
5907        3: '-üncü',
5908        4: '-üncü',
5909        100: '-üncü',
5910        6: '-ncı',
5911        9: '-uncu',
5912        10: '-uncu',
5913        30: '-uncu',
5914        60: '-ıncı',
5915        90: '-ıncı'
5916    };
5917
5918    var az = _moment__default.defineLocale('az', {
5919        months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'),
5920        monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'),
5921        weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'),
5922        weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'),
5923        weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'),
5924        longDateFormat : {
5925            LT : 'HH:mm',
5926            LTS : 'HH:mm:ss',
5927            L : 'DD.MM.YYYY',
5928            LL : 'D MMMM YYYY',
5929            LLL : 'D MMMM YYYY HH:mm',
5930            LLLL : 'dddd, D MMMM YYYY HH:mm'
5931        },
5932        calendar : {
5933            sameDay : '[bugün saat] LT',
5934            nextDay : '[sabah saat] LT',
5935            nextWeek : '[gələn həftə] dddd [saat] LT',
5936            lastDay : '[dünən] LT',
5937            lastWeek : '[keçən həftə] dddd [saat] LT',
5938            sameElse : 'L'
5939        },
5940        relativeTime : {
5941            future : '%s sonra',
5942            past : '%s əvvəl',
5943            s : 'birneçə saniyyə',
5944            m : 'bir dəqiqə',
5945            mm : '%d dəqiqə',
5946            h : 'bir saat',
5947            hh : '%d saat',
5948            d : 'bir gün',
5949            dd : '%d gün',
5950            M : 'bir ay',
5951            MM : '%d ay',
5952            y : 'bir il',
5953            yy : '%d il'
5954        },
5955        meridiemParse: /gecə|səhər|gündüz|axşam/,
5956        isPM : function (input) {
5957            return /^(gündüz|axşam)$/.test(input);
5958        },
5959        meridiem : function (hour, minute, isLower) {
5960            if (hour < 4) {
5961                return 'gecə';
5962            } else if (hour < 12) {
5963                return 'səhər';
5964            } else if (hour < 17) {
5965                return 'gündüz';
5966            } else {
5967                return 'axşam';
5968            }
5969        },
5970        ordinalParse: /\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,
5971        ordinal : function (number) {
5972            if (number === 0) {  // special case for zero
5973                return number + '-ıncı';
5974            }
5975            var a = number % 10,
5976                b = number % 100 - a,
5977                c = number >= 100 ? 100 : null;
5978            return number + (az__suffixes[a] || az__suffixes[b] || az__suffixes[c]);
5979        },
5980        week : {
5981            dow : 1, // Monday is the first day of the week.
5982            doy : 7  // The week that contains Jan 1st is the first week of the year.
5983        }
5984    });
5985
5986    //! moment.js locale configuration
5987    //! locale : belarusian (be)
5988    //! author : Dmitry Demidov : https://github.com/demidov91
5989    //! author: Praleska: http://praleska.pro/
5990    //! Author : Menelion Elensúle : https://github.com/Oire
5991
5992    function be__plural(word, num) {
5993        var forms = word.split('_');
5994        return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);
5995    }
5996    function be__relativeTimeWithPlural(number, withoutSuffix, key) {
5997        var format = {
5998            'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін',
5999            'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін',
6000            'dd': 'дзень_дні_дзён',
6001            'MM': 'месяц_месяцы_месяцаў',
6002            'yy': 'год_гады_гадоў'
6003        };
6004        if (key === 'm') {
6005            return withoutSuffix ? 'хвіліна' : 'хвіліну';
6006        }
6007        else if (key === 'h') {
6008            return withoutSuffix ? 'гадзіна' : 'гадзіну';
6009        }
6010        else {
6011            return number + ' ' + be__plural(format[key], +number);
6012        }
6013    }
6014    function be__monthsCaseReplace(m, format) {
6015        var months = {
6016                'nominative': 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_'),
6017                'accusative': 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_')
6018            },
6019            nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ?
6020                'accusative' :
6021                'nominative';
6022        return months[nounCase][m.month()];
6023    }
6024    function be__weekdaysCaseReplace(m, format) {
6025        var weekdays = {
6026                'nominative': 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'),
6027                'accusative': 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_')
6028            },
6029            nounCase = (/\[ ?[Вв] ?(?:мінулую|наступную)? ?\] ?dddd/).test(format) ?
6030                'accusative' :
6031                'nominative';
6032        return weekdays[nounCase][m.day()];
6033    }
6034
6035    var be = _moment__default.defineLocale('be', {
6036        months : be__monthsCaseReplace,
6037        monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'),
6038        weekdays : be__weekdaysCaseReplace,
6039        weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),
6040        weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),
6041        longDateFormat : {
6042            LT : 'HH:mm',
6043            LTS : 'HH:mm:ss',
6044            L : 'DD.MM.YYYY',
6045            LL : 'D MMMM YYYY г.',
6046            LLL : 'D MMMM YYYY г., HH:mm',
6047            LLLL : 'dddd, D MMMM YYYY г., HH:mm'
6048        },
6049        calendar : {
6050            sameDay: '[Сёння ў] LT',
6051            nextDay: '[Заўтра ў] LT',
6052            lastDay: '[Учора ў] LT',
6053            nextWeek: function () {
6054                return '[У] dddd [ў] LT';
6055            },
6056            lastWeek: function () {
6057                switch (this.day()) {
6058                    case 0:
6059                    case 3:
6060                    case 5:
6061                    case 6:
6062                        return '[У мінулую] dddd [ў] LT';
6063                    case 1:
6064                    case 2:
6065                    case 4:
6066                        return '[У мінулы] dddd [ў] LT';
6067                }
6068            },
6069            sameElse: 'L'
6070        },
6071        relativeTime : {
6072            future : 'праз %s',
6073            past : '%s таму',
6074            s : 'некалькі секунд',
6075            m : be__relativeTimeWithPlural,
6076            mm : be__relativeTimeWithPlural,
6077            h : be__relativeTimeWithPlural,
6078            hh : be__relativeTimeWithPlural,
6079            d : 'дзень',
6080            dd : be__relativeTimeWithPlural,
6081            M : 'месяц',
6082            MM : be__relativeTimeWithPlural,
6083            y : 'год',
6084            yy : be__relativeTimeWithPlural
6085        },
6086        meridiemParse: /ночы|раніцы|дня|вечара/,
6087        isPM : function (input) {
6088            return /^(дня|вечара)$/.test(input);
6089        },
6090        meridiem : function (hour, minute, isLower) {
6091            if (hour < 4) {
6092                return 'ночы';
6093            } else if (hour < 12) {
6094                return 'раніцы';
6095            } else if (hour < 17) {
6096                return 'дня';
6097            } else {
6098                return 'вечара';
6099            }
6100        },
6101        ordinalParse: /\d{1,2}-(і|ы|га)/,
6102        ordinal: function (number, period) {
6103            switch (period) {
6104                case 'M':
6105                case 'd':
6106                case 'DDD':
6107                case 'w':
6108                case 'W':
6109                    return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы';
6110                case 'D':
6111                    return number + '-га';
6112                default:
6113                    return number;
6114            }
6115        },
6116        week : {
6117            dow : 1, // Monday is the first day of the week.
6118            doy : 7  // The week that contains Jan 1st is the first week of the year.
6119        }
6120    });
6121
6122    //! moment.js locale configuration
6123    //! locale : bulgarian (bg)
6124    //! author : Krasen Borisov : https://github.com/kraz
6125
6126    var bg = _moment__default.defineLocale('bg', {
6127        months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'),
6128        monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'),
6129        weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'),
6130        weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'),
6131        weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
6132        longDateFormat : {
6133            LT : 'H:mm',
6134            LTS : 'H:mm:ss',
6135            L : 'D.MM.YYYY',
6136            LL : 'D MMMM YYYY',
6137            LLL : 'D MMMM YYYY H:mm',
6138            LLLL : 'dddd, D MMMM YYYY H:mm'
6139        },
6140        calendar : {
6141            sameDay : '[Днес в] LT',
6142            nextDay : '[Утре в] LT',
6143            nextWeek : 'dddd [в] LT',
6144            lastDay : '[Вчера в] LT',
6145            lastWeek : function () {
6146                switch (this.day()) {
6147                    case 0:
6148                    case 3:
6149                    case 6:
6150                        return '[В изминалата] dddd [в] LT';
6151                    case 1:
6152                    case 2:
6153                    case 4:
6154                    case 5:
6155                        return '[В изминалия] dddd [в] LT';
6156                }
6157            },
6158            sameElse : 'L'
6159        },
6160        relativeTime : {
6161            future : 'след %s',
6162            past : 'преди %s',
6163            s : 'няколко секунди',
6164            m : 'минута',
6165            mm : '%d минути',
6166            h : 'час',
6167            hh : '%d часа',
6168            d : 'ден',
6169            dd : '%d дни',
6170            M : 'месец',
6171            MM : '%d месеца',
6172            y : 'година',
6173            yy : '%d години'
6174        },
6175        ordinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/,
6176        ordinal : function (number) {
6177            var lastDigit = number % 10,
6178                last2Digits = number % 100;
6179            if (number === 0) {
6180                return number + '-ев';
6181            } else if (last2Digits === 0) {
6182                return number + '-ен';
6183            } else if (last2Digits > 10 && last2Digits < 20) {
6184                return number + '-ти';
6185            } else if (lastDigit === 1) {
6186                return number + '-ви';
6187            } else if (lastDigit === 2) {
6188                return number + '-ри';
6189            } else if (lastDigit === 7 || lastDigit === 8) {
6190                return number + '-ми';
6191            } else {
6192                return number + '-ти';
6193            }
6194        },
6195        week : {
6196            dow : 1, // Monday is the first day of the week.
6197            doy : 7  // The week that contains Jan 1st is the first week of the year.
6198        }
6199    });
6200
6201    //! moment.js locale configuration
6202    //! locale : Bengali (bn)
6203    //! author : Kaushik Gandhi : https://github.com/kaushikgandhi
6204
6205    var bn__symbolMap = {
6206            '1': 'à§§',
6207            '2': '২',
6208            '3': 'à§©',
6209            '4': '৪',
6210            '5': 'à§«',
6211            '6': '৬',
6212            '7': 'à§­',
6213            '8': 'à§®',
6214            '9': '৯',
6215            '0': '০'
6216        },
6217        bn__numberMap = {
6218            'à§§': '1',
6219            '২': '2',
6220            'à§©': '3',
6221            '৪': '4',
6222            'à§«': '5',
6223            '৬': '6',
6224            'à§­': '7',
6225            'à§®': '8',
6226            '৯': '9',
6227            '০': '0'
6228        };
6229
6230    var bn = _moment__default.defineLocale('bn', {
6231        months : 'জানুয়ারী_ফেবুয়ারী_মার্চ_এপ্রিল_মে_জুন_জুলাই_অগাস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'),
6232        monthsShort : 'জানু_ফেব_মার্চ_এপর_মে_জুন_জুল_অগ_সেপ্ট_অক্টো_নভ_ডিসেম্'.split('_'),
6233        weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পত্তিবার_শুক্রুবার_শনিবার'.split('_'),
6234        weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পত্তি_শুক্রু_শনি'.split('_'),
6235        weekdaysMin : 'রব_সম_মঙ্গ_বু_ব্রিহ_শু_শনি'.split('_'),
6236        longDateFormat : {
6237            LT : 'A h:mm সময়',
6238            LTS : 'A h:mm:ss সময়',
6239            L : 'DD/MM/YYYY',
6240            LL : 'D MMMM YYYY',
6241            LLL : 'D MMMM YYYY, A h:mm সময়',
6242            LLLL : 'dddd, D MMMM YYYY, A h:mm সময়'
6243        },
6244        calendar : {
6245            sameDay : '[আজ] LT',
6246            nextDay : '[আগামীকাল] LT',
6247            nextWeek : 'dddd, LT',
6248            lastDay : '[গতকাল] LT',
6249            lastWeek : '[গত] dddd, LT',
6250            sameElse : 'L'
6251        },
6252        relativeTime : {
6253            future : '%s পরে',
6254            past : '%s আগে',
6255            s : 'কএক সেকেন্ড',
6256            m : 'এক মিনিট',
6257            mm : '%d মিনিট',
6258            h : 'এক ঘন্টা',
6259            hh : '%d ঘন্টা',
6260            d : 'এক দিন',
6261            dd : '%d দিন',
6262            M : 'এক মাস',
6263            MM : '%d মাস',
6264            y : 'এক বছর',
6265            yy : '%d বছর'
6266        },
6267        preparse: function (string) {
6268            return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) {
6269                return bn__numberMap[match];
6270            });
6271        },
6272        postformat: function (string) {
6273            return string.replace(/\d/g, function (match) {
6274                return bn__symbolMap[match];
6275            });
6276        },
6277        meridiemParse: /রাত|সকাল|দুপুর|বিকেল|রাত/,
6278        isPM: function (input) {
6279            return /^(দুপুর|বিকেল|রাত)$/.test(input);
6280        },
6281        //Bengali is a vast language its spoken
6282        //in different forms in various parts of the world.
6283        //I have just generalized with most common one used
6284        meridiem : function (hour, minute, isLower) {
6285            if (hour < 4) {
6286                return 'রাত';
6287            } else if (hour < 10) {
6288                return 'সকাল';
6289            } else if (hour < 17) {
6290                return 'দুপুর';
6291            } else if (hour < 20) {
6292                return 'বিকেল';
6293            } else {
6294                return 'রাত';
6295            }
6296        },
6297        week : {
6298            dow : 0, // Sunday is the first day of the week.
6299            doy : 6  // The week that contains Jan 1st is the first week of the year.
6300        }
6301    });
6302
6303    //! moment.js locale configuration
6304    //! locale : tibetan (bo)
6305    //! author : Thupten N. Chakrishar : https://github.com/vajradog
6306
6307    var bo__symbolMap = {
6308            '1': '༡',
6309            '2': '༢',
6310            '3': '༣',
6311            '4': '༤',
6312            '5': '༥',
6313            '6': '༦',
6314            '7': '༧',
6315            '8': '༨',
6316            '9': '༩',
6317            '0': '༠'
6318        },
6319        bo__numberMap = {
6320            '༡': '1',
6321            '༢': '2',
6322            '༣': '3',
6323            '༤': '4',
6324            '༥': '5',
6325            '༦': '6',
6326            '༧': '7',
6327            '༨': '8',
6328            '༩': '9',
6329            '༠': '0'
6330        };
6331
6332    var bo = _moment__default.defineLocale('bo', {
6333        months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),
6334        monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),
6335        weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'),
6336        weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),
6337        weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),
6338        longDateFormat : {
6339            LT : 'A h:mm',
6340            LTS : 'A h:mm:ss',
6341            L : 'DD/MM/YYYY',
6342            LL : 'D MMMM YYYY',
6343            LLL : 'D MMMM YYYY, A h:mm',
6344            LLLL : 'dddd, D MMMM YYYY, A h:mm'
6345        },
6346        calendar : {
6347            sameDay : '[དི་རིང] LT',
6348            nextDay : '[སང་ཉིན] LT',
6349            nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT',
6350            lastDay : '[ཁ་སང] LT',
6351            lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT',
6352            sameElse : 'L'
6353        },
6354        relativeTime : {
6355            future : '%s ལ་',
6356            past : '%s སྔན་ལ',
6357            s : 'ལམ་སང',
6358            m : 'སྐར་མ་གཅིག',
6359            mm : '%d སྐར་མ',
6360            h : 'ཆུ་ཚོད་གཅིག',
6361            hh : '%d ཆུ་ཚོད',
6362            d : 'ཉིན་གཅིག',
6363            dd : '%d ཉིན་',
6364            M : 'ཟླ་བ་གཅིག',
6365            MM : '%d ཟླ་བ',
6366            y : 'ལོ་གཅིག',
6367            yy : '%d ལོ'
6368        },
6369        preparse: function (string) {
6370            return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) {
6371                return bo__numberMap[match];
6372            });
6373        },
6374        postformat: function (string) {
6375            return string.replace(/\d/g, function (match) {
6376                return bo__symbolMap[match];
6377            });
6378        },
6379        meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,
6380        isPM: function (input) {
6381            return /^(ཉིན་གུང|དགོང་དག|མཚན་མོ)$/.test(input);
6382        },
6383        meridiem : function (hour, minute, isLower) {
6384            if (hour < 4) {
6385                return 'མཚན་མོ';
6386            } else if (hour < 10) {
6387                return 'ཞོགས་ཀས';
6388            } else if (hour < 17) {
6389                return 'ཉིན་གུང';
6390            } else if (hour < 20) {
6391                return 'དགོང་དག';
6392            } else {
6393                return 'མཚན་མོ';
6394            }
6395        },
6396        week : {
6397            dow : 0, // Sunday is the first day of the week.
6398            doy : 6  // The week that contains Jan 1st is the first week of the year.
6399        }
6400    });
6401
6402    //! moment.js locale configuration
6403    //! locale : breton (br)
6404    //! author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou
6405
6406    function relativeTimeWithMutation(number, withoutSuffix, key) {
6407        var format = {
6408            'mm': 'munutenn',
6409            'MM': 'miz',
6410            'dd': 'devezh'
6411        };
6412        return number + ' ' + mutation(format[key], number);
6413    }
6414    function specialMutationForYears(number) {
6415        switch (lastNumber(number)) {
6416            case 1:
6417            case 3:
6418            case 4:
6419            case 5:
6420            case 9:
6421                return number + ' bloaz';
6422            default:
6423                return number + ' vloaz';
6424        }
6425    }
6426    function lastNumber(number) {
6427        if (number > 9) {
6428            return lastNumber(number % 10);
6429        }
6430        return number;
6431    }
6432    function mutation(text, number) {
6433        if (number === 2) {
6434            return softMutation(text);
6435        }
6436        return text;
6437    }
6438    function softMutation(text) {
6439        var mutationTable = {
6440            'm': 'v',
6441            'b': 'v',
6442            'd': 'z'
6443        };
6444        if (mutationTable[text.charAt(0)] === undefined) {
6445            return text;
6446        }
6447        return mutationTable[text.charAt(0)] + text.substring(1);
6448    }
6449
6450    var br = _moment__default.defineLocale('br', {
6451        months : 'Genver_C\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'),
6452        monthsShort : 'Gen_C\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'),
6453        weekdays : 'Sul_Lun_Meurzh_Merc\'her_Yaou_Gwener_Sadorn'.split('_'),
6454        weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'),
6455        weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'),
6456        longDateFormat : {
6457            LT : 'h[e]mm A',
6458            LTS : 'h[e]mm:ss A',
6459            L : 'DD/MM/YYYY',
6460            LL : 'D [a viz] MMMM YYYY',
6461            LLL : 'D [a viz] MMMM YYYY h[e]mm A',
6462            LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A'
6463        },
6464        calendar : {
6465            sameDay : '[Hiziv da] LT',
6466            nextDay : '[Warc\'hoazh da] LT',
6467            nextWeek : 'dddd [da] LT',
6468            lastDay : '[Dec\'h da] LT',
6469            lastWeek : 'dddd [paset da] LT',
6470            sameElse : 'L'
6471        },
6472        relativeTime : {
6473            future : 'a-benn %s',
6474            past : '%s \'zo',
6475            s : 'un nebeud segondennoù',
6476            m : 'ur vunutenn',
6477            mm : relativeTimeWithMutation,
6478            h : 'un eur',
6479            hh : '%d eur',
6480            d : 'un devezh',
6481            dd : relativeTimeWithMutation,
6482            M : 'ur miz',
6483            MM : relativeTimeWithMutation,
6484            y : 'ur bloaz',
6485            yy : specialMutationForYears
6486        },
6487        ordinalParse: /\d{1,2}(añ|vet)/,
6488        ordinal : function (number) {
6489            var output = (number === 1) ? 'añ' : 'vet';
6490            return number + output;
6491        },
6492        week : {
6493            dow : 1, // Monday is the first day of the week.
6494            doy : 4  // The week that contains Jan 4th is the first week of the year.
6495        }
6496    });
6497
6498    //! moment.js locale configuration
6499    //! locale : bosnian (bs)
6500    //! author : Nedim Cholich : https://github.com/frontyard
6501    //! based on (hr) translation by Bojan Marković
6502
6503    function bs__translate(number, withoutSuffix, key) {
6504        var result = number + ' ';
6505        switch (key) {
6506            case 'm':
6507                return withoutSuffix ? 'jedna minuta' : 'jedne minute';
6508            case 'mm':
6509                if (number === 1) {
6510                    result += 'minuta';
6511                } else if (number === 2 || number === 3 || number === 4) {
6512                    result += 'minute';
6513                } else {
6514                    result += 'minuta';
6515                }
6516                return result;
6517            case 'h':
6518                return withoutSuffix ? 'jedan sat' : 'jednog sata';
6519            case 'hh':
6520                if (number === 1) {
6521                    result += 'sat';
6522                } else if (number === 2 || number === 3 || number === 4) {
6523                    result += 'sata';
6524                } else {
6525                    result += 'sati';
6526                }
6527                return result;
6528            case 'dd':
6529                if (number === 1) {
6530                    result += 'dan';
6531                } else {
6532                    result += 'dana';
6533                }
6534                return result;
6535            case 'MM':
6536                if (number === 1) {
6537                    result += 'mjesec';
6538                } else if (number === 2 || number === 3 || number === 4) {
6539                    result += 'mjeseca';
6540                } else {
6541                    result += 'mjeseci';
6542                }
6543                return result;
6544            case 'yy':
6545                if (number === 1) {
6546                    result += 'godina';
6547                } else if (number === 2 || number === 3 || number === 4) {
6548                    result += 'godine';
6549                } else {
6550                    result += 'godina';
6551                }
6552                return result;
6553        }
6554    }
6555
6556    var bs = _moment__default.defineLocale('bs', {
6557        months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'),
6558        monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'),
6559        weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),
6560        weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),
6561        weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),
6562        longDateFormat : {
6563            LT : 'H:mm',
6564            LTS : 'H:mm:ss',
6565            L : 'DD. MM. YYYY',
6566            LL : 'D. MMMM YYYY',
6567            LLL : 'D. MMMM YYYY H:mm',
6568            LLLL : 'dddd, D. MMMM YYYY H:mm'
6569        },
6570        calendar : {
6571            sameDay  : '[danas u] LT',
6572            nextDay  : '[sutra u] LT',
6573            nextWeek : function () {
6574                switch (this.day()) {
6575                    case 0:
6576                        return '[u] [nedjelju] [u] LT';
6577                    case 3:
6578                        return '[u] [srijedu] [u] LT';
6579                    case 6:
6580                        return '[u] [subotu] [u] LT';
6581                    case 1:
6582                    case 2:
6583                    case 4:
6584                    case 5:
6585                        return '[u] dddd [u] LT';
6586                }
6587            },
6588            lastDay  : '[jučer u] LT',
6589            lastWeek : function () {
6590                switch (this.day()) {
6591                    case 0:
6592                    case 3:
6593                        return '[prošlu] dddd [u] LT';
6594                    case 6:
6595                        return '[prošle] [subote] [u] LT';
6596                    case 1:
6597                    case 2:
6598                    case 4:
6599                    case 5:
6600                        return '[prošli] dddd [u] LT';
6601                }
6602            },
6603            sameElse : 'L'
6604        },
6605        relativeTime : {
6606            future : 'za %s',
6607            past   : 'prije %s',
6608            s      : 'par sekundi',
6609            m      : bs__translate,
6610            mm     : bs__translate,
6611            h      : bs__translate,
6612            hh     : bs__translate,
6613            d      : 'dan',
6614            dd     : bs__translate,
6615            M      : 'mjesec',
6616            MM     : bs__translate,
6617            y      : 'godinu',
6618            yy     : bs__translate
6619        },
6620        ordinalParse: /\d{1,2}\./,
6621        ordinal : '%d.',
6622        week : {
6623            dow : 1, // Monday is the first day of the week.
6624            doy : 7  // The week that contains Jan 1st is the first week of the year.
6625        }
6626    });
6627
6628    //! moment.js locale configuration
6629    //! locale : catalan (ca)
6630    //! author : Juan G. Hurtado : https://github.com/juanghurtado
6631
6632    var ca = _moment__default.defineLocale('ca', {
6633        months : 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'),
6634        monthsShort : 'gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.'.split('_'),
6635        weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'),
6636        weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'),
6637        weekdaysMin : 'Dg_Dl_Dt_Dc_Dj_Dv_Ds'.split('_'),
6638        longDateFormat : {
6639            LT : 'H:mm',
6640            LTS : 'LT:ss',
6641            L : 'DD/MM/YYYY',
6642            LL : 'D MMMM YYYY',
6643            LLL : 'D MMMM YYYY H:mm',
6644            LLLL : 'dddd D MMMM YYYY H:mm'
6645        },
6646        calendar : {
6647            sameDay : function () {
6648                return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
6649            },
6650            nextDay : function () {
6651                return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
6652            },
6653            nextWeek : function () {
6654                return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
6655            },
6656            lastDay : function () {
6657                return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
6658            },
6659            lastWeek : function () {
6660                return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
6661            },
6662            sameElse : 'L'
6663        },
6664        relativeTime : {
6665            future : 'en %s',
6666            past : 'fa %s',
6667            s : 'uns segons',
6668            m : 'un minut',
6669            mm : '%d minuts',
6670            h : 'una hora',
6671            hh : '%d hores',
6672            d : 'un dia',
6673            dd : '%d dies',
6674            M : 'un mes',
6675            MM : '%d mesos',
6676            y : 'un any',
6677            yy : '%d anys'
6678        },
6679        ordinalParse: /\d{1,2}(r|n|t|è|a)/,
6680        ordinal : function (number, period) {
6681            var output = (number === 1) ? 'r' :
6682                (number === 2) ? 'n' :
6683                    (number === 3) ? 'r' :
6684                        (number === 4) ? 't' : 'è';
6685            if (period === 'w' || period === 'W') {
6686                output = 'a';
6687            }
6688            return number + output;
6689        },
6690        week : {
6691            dow : 1, // Monday is the first day of the week.
6692            doy : 4  // The week that contains Jan 4th is the first week of the year.
6693        }
6694    });
6695
6696    //! moment.js locale configuration
6697    //! locale : czech (cs)
6698    //! author : petrbela : https://github.com/petrbela
6699
6700    var cs__months = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.
6700split('_'),
6701        cs__monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_');
6702    function cs__plural(n) {
6703        return (n > 1) && (n < 5) && (~~(n / 10) !== 1);
6704    }
6705    function cs__translate(number, withoutSuffix, key, isFuture) {
6706        var result = number + ' ';
6707        switch (key) {
6708            case 's':  // a few seconds / in a few seconds / a few seconds ago
6709                return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami';
6710            case 'm':  // a minute / in a minute / a minute ago
6711                return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou');
6712            case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago
6713                if (withoutSuffix || isFuture) {
6714                    return result + (cs__plural(number) ? 'minuty' : 'minut');
6715                } else {
6716                    return result + 'minutami';
6717                }
6718                break;
6719            case 'h':  // an hour / in an hour / an hour ago
6720                return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');
6721            case 'hh': // 9 hours / in 9 hours / 9 hours ago
6722                if (withoutSuffix || isFuture) {
6723                    return result + (cs__plural(number) ? 'hodiny' : 'hodin');
6724                } else {
6725                    return result + 'hodinami';
6726                }
6727                break;
6728            case 'd':  // a day / in a day / a day ago
6729                return (withoutSuffix || isFuture) ? 'den' : 'dnem';
6730            case 'dd': // 9 days / in 9 days / 9 days ago
6731                if (withoutSuffix || isFuture) {
6732                    return result + (cs__plural(number) ? 'dny' : 'dní');
6733                } else {
6734                    return result + 'dny';
6735                }
6736                break;
6737            case 'M':  // a month / in a month / a month ago
6738                return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem';
6739            case 'MM': // 9 months / in 9 months / 9 months ago
6740                if (withoutSuffix || isFuture) {
6741                    return result + (cs__plural(number) ? 'měsíce' : 'měsíců');
6742                } else {
6743                    return result + 'měsíci';
6744                }
6745                break;
6746            case 'y':  // a year / in a year / a year ago
6747                return (withoutSuffix || isFuture) ? 'rok' : 'rokem';
6748            case 'yy': // 9 years / in 9 years / 9 years ago
6749                if (withoutSuffix || isFuture) {
6750                    return result + (cs__plural(number) ? 'roky' : 'let');
6751                } else {
6752                    return result + 'lety';
6753                }
6754                break;
6755        }
6756    }
6757
6758    var cs = _moment__default.defineLocale('cs', {
6759        months : cs__months,
6760        monthsShort : cs__monthsShort,
6761        monthsParse : (function (months, monthsShort) {
6762            var i, _monthsParse = [];
6763            for (i = 0; i < 12; i++) {
6764                // use custom parser to solve problem with July (červenec)
6765                _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');
6766            }
6767            return _monthsParse;
6768        }(cs__months, cs__monthsShort)),
6769        weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'),
6770        weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'),
6771        weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'),
6772        longDateFormat : {
6773            LT: 'H:mm',
6774            LTS : 'H:mm:ss',
6775            L : 'DD.MM.YYYY',
6776            LL : 'D. MMMM YYYY',
6777            LLL : 'D. MMMM YYYY H:mm',
6778            LLLL : 'dddd D. MMMM YYYY H:mm'
6779        },
6780        calendar : {
6781            sameDay: '[dnes v] LT',
6782            nextDay: '[zítra v] LT',
6783            nextWeek: function () {
6784                switch (this.day()) {
6785                    case 0:
6786                        return '[v neděli v] LT';
6787                    case 1:
6788                    case 2:
6789                        return '[v] dddd [v] LT';
6790                    case 3:
6791                        return '[ve středu v] LT';
6792                    case 4:
6793                        return '[ve čtvrtek v] LT';
6794                    case 5:
6795                        return '[v pátek v] LT';
6796                    case 6:
6797                        return '[v sobotu v] LT';
6798                }
6799            },
6800            lastDay: '[včera v] LT',
6801            lastWeek: function () {
6802                switch (this.day()) {
6803                    case 0:
6804                        return '[minulou neděli v] LT';
6805                    case 1:
6806                    case 2:
6807                        return '[minulé] dddd [v] LT';
6808                    case 3:
6809                        return '[minulou středu v] LT';
6810                    case 4:
6811                    case 5:
6812                        return '[minulý] dddd [v] LT';
6813                    case 6:
6814                        return '[minulou sobotu v] LT';
6815                }
6816            },
6817            sameElse: 'L'
6818        },
6819        relativeTime : {
6820            future : 'za %s',
6821            past : 'před %s',
6822            s : cs__translate,
6823            m : cs__translate,
6824            mm : cs__translate,
6825            h : cs__translate,
6826            hh : cs__translate,
6827            d : cs__translate,
6828            dd : cs__translate,
6829            M : cs__translate,
6830            MM : cs__translate,
6831            y : cs__translate,
6832            yy : cs__translate
6833        },
6834        ordinalParse : /\d{1,2}\./,
6835        ordinal : '%d.',
6836        week : {
6837            dow : 1, // Monday is the first day of the week.
6838            doy : 4  // The week that contains Jan 4th is the first week of the year.
6839        }
6840    });
6841
6842    //! moment.js locale configuration
6843    //! locale : chuvash (cv)
6844    //! author : Anatoly Mironov : https://github.com/mirontoli
6845
6846    var cv = _moment__default.defineLocale('cv', {
6847        months : 'кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав'.split('_'),
6848        monthsShort : 'кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш'.split('_'),
6849        weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун'.split('_'),
6850        weekdaysShort : 'выр_тун_ытл_юн_кӗҫ_эрн_шӑм'.split('_'),
6851        weekdaysMin : 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'),
6852        longDateFormat : {
6853            LT : 'HH:mm',
6854            LTS : 'HH:mm:ss',
6855            L : 'DD-MM-YYYY',
6856            LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]',
6857            LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm',
6858            LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm'
6859        },
6860        calendar : {
6861            sameDay: '[Паян] LT [сехетре]',
6862            nextDay: '[Ыран] LT [сехетре]',
6863            lastDay: '[Ӗнер] LT [сехетре]',
6864            nextWeek: '[Ҫитес] dddd LT [сехетре]',
6865            lastWeek: '[Иртнӗ] dddd LT [сехетре]',
6866            sameElse: 'L'
6867        },
6868        relativeTime : {
6869            future : function (output) {
6870                var affix = /сехет$/i.exec(output) ? 'рен' : /ҫул$/i.exec(output) ? 'тан' : 'ран';
6871                return output + affix;
6872            },
6873            past : '%s каялла',
6874            s : 'пӗр-ик ҫеккунт',
6875            m : 'пӗр минут',
6876            mm : '%d минут',
6877            h : 'пӗр сехет',
6878            hh : '%d сехет',
6879            d : 'пӗр кун',
6880            dd : '%d кун',
6881            M : 'пӗр уйӑх',
6882            MM : '%d уйӑх',
6883            y : 'пӗр ҫул',
6884            yy : '%d ҫул'
6885        },
6886        ordinalParse: /\d{1,2}-мӗш/,
6887        ordinal : '%d-мӗш',
6888        week : {
6889            dow : 1, // Monday is the first day of the week.
6890            doy : 7  // The week that contains Jan 1st is the first week of the year.
6891        }
6892    });
6893
6894    //! moment.js locale configuration
6895    //! locale : Welsh (cy)
6896    //! author : Robert Allen
6897
6898    var cy = _moment__default.defineLocale('cy', {
6899        months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'),
6900        monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'),
6901        weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'),
6902        weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'),
6903        weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'),
6904        // time formats are the same as en-gb
6905        longDateFormat: {
6906            LT: 'HH:mm',
6907            LTS : 'HH:mm:ss',
6908            L: 'DD/MM/YYYY',
6909            LL: 'D MMMM YYYY',
6910            LLL: 'D MMMM YYYY HH:mm',
6911            LLLL: 'dddd, D MMMM YYYY HH:mm'
6912        },
6913        calendar: {
6914            sameDay: '[Heddiw am] LT',
6915            nextDay: '[Yfory am] LT',
6916            nextWeek: 'dddd [am] LT',
6917            lastDay: '[Ddoe am] LT',
6918            lastWeek: 'dddd [diwethaf am] LT',
6919            sameElse: 'L'
6920        },
6921        relativeTime: {
6922            future: 'mewn %s',
6923            past: '%s yn ôl',
6924            s: 'ychydig eiliadau',
6925            m: 'munud',
6926            mm: '%d munud',
6927            h: 'awr',
6928            hh: '%d awr',
6929            d: 'diwrnod',
6930            dd: '%d diwrnod',
6931            M: 'mis',
6932            MM: '%d mis',
6933            y: 'blwyddyn',
6934            yy: '%d flynedd'
6935        },
6936        ordinalParse: /\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,
6937        // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh
6938        ordinal: function (number) {
6939            var b = number,
6940                output = '',
6941                lookup = [
6942                    '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed
6943                    'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed
6944                ];
6945            if (b > 20) {
6946                if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) {
6947                    output = 'fed'; // not 30ain, 70ain or 90ain
6948                } else {
6949                    output = 'ain';
6950                }
6951            } else if (b > 0) {
6952                output = lookup[b];
6953            }
6954            return number + output;
6955        },
6956        week : {
6957            dow : 1, // Monday is the first day of the week.
6958            doy : 4  // The week that contains Jan 4th is the first week of the year.
6959        }
6960    });
6961
6962    //! moment.js locale configuration
6963    //! locale : danish (da)
6964    //! author : Ulrik Nielsen : https://github.com/mrbase
6965
6966    var da = _moment__default.defineLocale('da', {
6967        months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'),
6968        monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),
6969        weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),
6970        weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'),
6971        weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),
6972        longDateFormat : {
6973            LT : 'HH:mm',
6974            LTS : 'HH:mm:ss',
6975            L : 'DD/MM/YYYY',
6976            LL : 'D. MMMM YYYY',
6977            LLL : 'D. MMMM YYYY HH:mm',
6978            LLLL : 'dddd [d.] D. MMMM YYYY HH:mm'
6979        },
6980        calendar : {
6981            sameDay : '[I dag kl.] LT',
6982            nextDay : '[I morgen kl.] LT',
6983            nextWeek : 'dddd [kl.] LT',
6984            lastDay : '[I går kl.] LT',
6985            lastWeek : '[sidste] dddd [kl] LT',
6986            sameElse : 'L'
6987        },
6988        relativeTime : {
6989            future : 'om %s',
6990            past : '%s siden',
6991            s : 'få sekunder',
6992            m : 'et minut',
6993            mm : '%d minutter',
6994            h : 'en time',
6995            hh : '%d timer',
6996            d : 'en dag',
6997            dd : '%d dage',
6998            M : 'en måned',
6999            MM : '%d måneder',
7000            y : 'et år',
7001            yy : '%d år'
7002        },
7003        ordinalParse: /\d{1,2}\./,
7004        ordinal : '%d.',
7005        week : {
7006            dow : 1, // Monday is the first day of the week.
7007            doy : 4  // The week that contains Jan 4th is the first week of the year.
7008        }
7009    });
7010
7011    //! moment.js locale configuration
7012    //! locale : austrian german (de-at)
7013    //! author : lluchs : https://github.com/lluchs
7014    //! author: Menelion Elensúle: https://github.com/Oire
7015    //! author : Martin Groller : https://github.com/MadMG
7016
7017    function de_at__processRelativeTime(number, withoutSuffix, key, isFuture) {
7018        var format = {
7019            'm': ['eine Minute', 'einer Minute'],
7020            'h': ['eine Stunde', 'einer Stunde'],
7021            'd': ['ein Tag', 'einem Tag'],
7022            'dd': [number + ' Tage', number + ' Tagen'],
7023            'M': ['ein Monat', 'einem Monat'],
7024            'MM': [number + ' Monate', number + ' Monaten'],
7025            'y': ['ein Jahr', 'einem Jahr'],
7026            'yy': [number + ' Jahre', number + ' Jahren']
7027        };
7028        return withoutSuffix ? format[key][0] : format[key][1];
7029    }
7030
7031    var de_at = _moment__default.defineLocale('de-at', {
7032        months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),
7033        monthsShort : 'Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),
7034        weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),
7035        weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),
7036        weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
7037        longDateFormat : {
7038            LT: 'HH:mm',
7039            LTS: 'HH:mm:ss',
7040            L : 'DD.MM.YYYY',
7041            LL : 'D. MMMM YYYY',
7042            LLL : 'D. MMMM YYYY HH:mm',
7043            LLLL : 'dddd, D. MMMM YYYY HH:mm'
7044        },
7045        calendar : {
7046            sameDay: '[Heute um] LT [Uhr]',
7047            sameElse: 'L',
7048            nextDay: '[Morgen um] LT [Uhr]',
7049            nextWeek: 'dddd [um] LT [Uhr]',
7050            lastDay: '[Gestern um] LT [Uhr]',
7051            lastWeek: '[letzten] dddd [um] LT [Uhr]'
7052        },
7053        relativeTime : {
7054            future : 'in %s',
7055            past : 'vor %s',
7056            s : 'ein paar Sekunden',
7057            m : de_at__processRelativeTime,
7058            mm : '%d Minuten',
7059            h : de_at__processRelativeTime,
7060            hh : '%d Stunden',
7061            d : de_at__processRelativeTime,
7062            dd : de_at__processRelativeTime,
7063            M : de_at__processRelativeTime,
7064            MM : de_at__processRelativeTime,
7065            y : de_at__processRelativeTime,
7066            yy : de_at__processRelativeTime
7067        },
7068        ordinalParse: /\d{1,2}\./,
7069        ordinal : '%d.',
7070        week : {
7071            dow : 1, // Monday is the first day of the week.
7072            doy : 4  // The week that contains Jan 4th is the first week of the year.
7073        }
7074    });
7075
7076    //! moment.js locale configuration
7077    //! locale : german (de)
7078    //! author : lluchs : https://github.com/lluchs
7079    //! author: Menelion Elensúle: https://github.com/Oire
7080
7081    function de__processRelativeTime(number, withoutSuffix, key, isFuture) {
7082        var format = {
7083            'm': ['eine Minute', 'einer Minute'],
7084            'h': ['eine Stunde', 'einer Stunde'],
7085            'd': ['ein Tag', 'einem Tag'],
7086            'dd': [number + ' Tage', number + ' Tagen'],
7087            'M': ['ein Monat', 'einem Monat'],
7088            'MM': [number + ' Monate', number + ' Monaten'],
7089            'y': ['ein Jahr', 'einem Jahr'],
7090            'yy': [number + ' Jahre', number + ' Jahren']
7091        };
7092        return withoutSuffix ? format[key][0] : format[key][1];
7093    }
7094
7095    var de = _moment__default.defineLocale('de', {
7096        months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),
7097        monthsShort : 'Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),
7098        weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),
7099        weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),
7100        weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
7101        longDateFormat : {
7102            LT: 'HH:mm',
7103            LTS: 'HH:mm:ss',
7104            L : 'DD.MM.YYYY',
7105            LL : 'D. MMMM YYYY',
7106            LLL : 'D. MMMM YYYY HH:mm',
7107            LLLL : 'dddd, D. MMMM YYYY HH:mm'
7108        },
7109        calendar : {
7110            sameDay: '[Heute um] LT [Uhr]',
7111            sameElse: 'L',
7112            nextDay: '[Morgen um] LT [Uhr]',
7113            nextWeek: 'dddd [um] LT [Uhr]',
7114            lastDay: '[Gestern um] LT [Uhr]',
7115            lastWeek: '[letzten] dddd [um] LT [Uhr]'
7116        },
7117        relativeTime : {
7118            future : 'in %s',
7119            past : 'vor %s',
7120            s : 'ein paar Sekunden',
7121            m : de__processRelativeTime,
7122            mm : '%d Minuten',
7123            h : de__processRelativeTime,
7124            hh : '%d Stunden',
7125            d : de__processRelativeTime,
7126            dd : de__processRelativeTime,
7127            M : de__processRelativeTime,
7128            MM : de__processRelativeTime,
7129            y : de__processRelativeTime,
7130            yy : de__processRelativeTime
7131        },
7132        ordinalParse: /\d{1,2}\./,
7133        ordinal : '%d.',
7134        week : {
7135            dow : 1, // Monday is the first day of the week.
7136            doy : 4  // The week that contains Jan 4th is the first week of the year.
7137        }
7138    });
7139
7140    //! moment.js locale configuration
7141    //! locale : modern greek (el)
7142    //! author : Aggelos Karalias : https://github.com/mehiel
7143
7144    var el = _moment__default.defineLocale('el', {
7145        monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'),
7146        monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'),
7147        months : function (momentToFormat, format) {
7148            if (/D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM'
7149                return this._monthsGenitiveEl[momentToFormat.month()];
7150            } else {
7151                return this._monthsNominativeEl[momentToFormat.month()];
7152            }
7153        },
7154        monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'),
7155        weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'),
7156        weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'),
7157        weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'),
7158        meridiem : function (hours, minutes, isLower) {
7159            if (hours > 11) {
7160                return isLower ? 'μμ' : 'ΜΜ';
7161            } else {
7162                return isLower ? 'πμ' : 'ΠΜ';
7163            }
7164        },
7165        isPM : function (input) {
7166            return ((input + '').toLowerCase()[0] === 'μ');
7167        },
7168        meridiemParse : /[ΠΜ]\.?Μ?\.?/i,
7169        longDateFormat : {
7170            LT : 'h:mm A',
7171            LTS : 'h:mm:ss A',
7172            L : 'DD/MM/YYYY',
7173            LL : 'D MMMM YYYY',
7174            LLL : 'D MMMM YYYY h:mm A',
7175            LLLL : 'dddd, D MMMM YYYY h:mm A'
7176        },
7177        calendarEl : {
7178            sameDay : '[Σήμερα {}] LT',
7179            nextDay : '[Αύριο {}] LT',
7180            nextWeek : 'dddd [{}] LT',
7181            lastDay : '[Χθες {}] LT',
7182            lastWeek : function () {
7183                switch (this.day()) {
7184                    case 6:
7185                        return '[το προηγούμενο] dddd [{}] LT';
7186                    default:
7187                        return '[την προηγούμενη] dddd [{}] LT';
7188                }
7189            },
7190            sameElse : 'L'
7191        },
7192        calendar : function (key, mom) {
7193            var output = this._calendarEl[key],
7194                hours = mom && mom.hours();
7195            if (typeof output === 'function') {
7196                output = output.apply(mom);
7197            }
7198            return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις'));
7199        },
7200        relativeTime : {
7201            future : 'σε %s',
7202            past : '%s πριν',
7203            s : 'λίγα δευτερόλεπτα',
7204            m : 'ένα λεπτό',
7205            mm : '%d λεπτά',
7206            h : 'μία ώρα',
7207            hh : '%d ώρες',
7208            d : 'μία μέρα',
7209            dd : '%d μέρες',
7210            M : 'ένας μήνας',
7211            MM : '%d μήνες',
7212            y : 'ένας χρόνος',
7213            yy : '%d χρόνια'
7214        },
7215        ordinalParse: /\d{1,2}η/,
7216        ordinal: '%dη',
7217        week : {
7218            dow : 1, // Monday is the first day of the week.
7219            doy : 4  // The week that contains Jan 4st is the first week of the year.
7220        }
7221    });
7222
7223    //! moment.js locale configuration
7224    //! locale : australian english (en-au)
7225
7226    var en_au = _moment__default.defineLocale('en-au', {
7227        months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
7228        monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
7229        weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
7230        weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
7231        weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
7232        longDateFormat : {
7233            LT : 'h:mm A',
7234            LTS : 'h:mm:ss A',
7235            L : 'DD/MM/YYYY',
7236            LL : 'D MMMM YYYY',
7237            LLL : 'D MMMM YYYY h:mm A',
7238            LLLL : 'dddd, D MMMM YYYY h:mm A'
7239        },
7240        calendar : {
7241            sameDay : '[Today at] LT',
7242            nextDay : '[Tomorrow at] LT',
7243            nextWeek : 'dddd [at] LT',
7244            lastDay : '[Yesterday at] LT',
7245            lastWeek : '[Last] dddd [at] LT',
7246            sameElse : 'L'
7247        },
7248        relativeTime : {
7249            future : 'in %s',
7250            past : '%s ago',
7251            s : 'a few seconds',
7252            m : 'a minute',
7253            mm : '%d minutes',
7254            h : 'an hour',
7255            hh : '%d hours',
7256            d : 'a day',
7257            dd : '%d days',
7258            M : 'a month',
7259            MM : '%d months',
7260            y : 'a year',
7261            yy : '%d years'
7262        },
7263        ordinalParse: /\d{1,2}(st|nd|rd|th)/,
7264        ordinal : function (number) {
7265            var b = number % 10,
7266                output = (~~(number % 100 / 10) === 1) ? 'th' :
7267                    (b === 1) ? 'st' :
7268                        (b === 2) ? 'nd' :
7269                            (b === 3) ? 'rd' : 'th';
7270            return number + output;
7271        },
7272        week : {
7273            dow : 1, // Monday is the first day of the week.
7274            doy : 4  // The week that contains Jan 4th is the first week of the year.
7275        }
7276    });
7277
7278    //! moment.js locale configuration
7279    //! locale : canadian english (en-ca)
7280    //! author : Jonathan Abourbih : https://github.com/jonbca
7281
7282    var en_ca = _moment__default.defineLocale('en-ca', {
7283        months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
7284        monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
7285        weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
7286        weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
7287        weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
7288        longDateFormat : {
7289            LT : 'h:mm A',
7290            LTS : 'h:mm:ss A',
7291            L : 'YYYY-MM-DD',
7292            LL : 'D MMMM, YYYY',
7293            LLL : 'D MMMM, YYYY h:mm A',
7294            LLLL : 'dddd, D MMMM, YYYY h:mm A'
7295        },
7296        calendar : {
7297            sameDay : '[Today at] LT',
7298            nextDay : '[Tomorrow at] LT',
7299            nextWeek : 'dddd [at] LT',
7300            lastDay : '[Yesterday at] LT',
7301            lastWeek : '[Last] dddd [at] LT',
7302            sameElse : 'L'
7303        },
7304        relativeTime : {
7305            future : 'in %s',
7306            past : '%s ago',
7307            s : 'a few seconds',
7308            m : 'a minute',
7309            mm : '%d minutes',
7310            h : 'an hour',
7311            hh : '%d hours',
7312            d : 'a day',
7313            dd : '%d days',
7314            M : 'a month',
7315            MM : '%d months',
7316            y : 'a year',
7317            yy : '%d years'
7318        },
7319        ordinalParse: /\d{1,2}(st|nd|rd|th)/,
7320        ordinal : function (number) {
7321            var b = number % 10,
7322                output = (~~(number % 100 / 10) === 1) ? 'th' :
7323                    (b === 1) ? 'st' :
7324                        (b === 2) ? 'nd' :
7325                            (b === 3) ? 'rd' : 'th';
7326            return number + output;
7327        }
7328    });
7329
7330    //! moment.js locale configuration
7331    //! locale : great britain english (en-gb)
7332    //! author : Chris Gedrim : https://github.com/chrisgedrim
7333
7334    var en_gb = _moment__default.defineLocale('en-gb', {
7335        months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
7336        monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
7337        weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
7338        weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
7339        weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
7340        longDateFormat : {
7341            LT : 'HH:mm',
7342            LTS : 'HH:mm:ss',
7343            L : 'DD/MM/YYYY',
7344            LL : 'D MMMM YYYY',
7345            LLL : 'D MMMM YYYY HH:mm',
7346            LLLL : 'dddd, D MMMM YYYY HH:mm'
7347        },
7348        calendar : {
7349            sameDay : '[Today at] LT',
7350            nextDay : '[Tomorrow at] LT',
7351            nextWeek : 'dddd [at] LT',
7352            lastDay : '[Yesterday at] LT',
7353            lastWeek : '[Last] dddd [at] LT',
7354            sameElse : 'L'
7355        },
7356        relativeTime : {
7357            future : 'in %s',
7358            past : '%s ago',
7359            s : 'a few seconds',
7360            m : 'a minute',
7361            mm : '%d minutes',
7362            h : 'an hour',
7363            hh : '%d hours',
7364            d : 'a day',
7365            dd : '%d days',
7366            M : 'a month',
7367            MM : '%d months',
7368            y : 'a year',
7369            yy : '%d years'
7370        },
7371        ordinalParse: /\d{1,2}(st|nd|rd|th)/,
7372        ordinal : function (number) {
7373            var b = number % 10,
7374                output = (~~(number % 100 / 10) === 1) ? 'th' :
7375                    (b === 1) ? 'st' :
7376                        (b === 2) ? 'nd' :
7377                            (b === 3) ? 'rd' : 'th';
7378            return number + output;
7379        },
7380        week : {
7381            dow : 1, // Monday is the first day of the week.
7382            doy : 4  // The week that contains Jan 4th is the first week of the year.
7383        }
7384    });
7385
7386    //! moment.js locale configuration
7387    //! locale : esperanto (eo)
7388    //! author : Colin Dean : https://github.com/colindean
7389    //! komento: Mi estas malcerta se mi korekte traktis akuzativojn en tiu traduko.
7390    //!          Se ne, bonvolu korekti kaj avizi min por ke mi povas lerni!
7391
7392    var eo = _moment__default.defineLocale('eo', {
7393        months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aÅ­gusto_septembro_oktobro_novembro_decembro'.split('_'),
7394        monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aÅ­g_sep_okt_nov_dec'.split('_'),
7395        weekdays : 'Dimanĉo_Lundo_Mardo_Merkredo_Ĵaŭdo_Vendredo_Sabato'.split('_'),
7396        weekdaysShort : 'Dim_Lun_Mard_Merk_Ä´aÅ­_Ven_Sab'.split('_'),
7397        weekdaysMin : 'Di_Lu_Ma_Me_Ä´a_Ve_Sa'.split('_'),
7398        longDateFormat : {
7399            LT : 'HH:mm',
7400            LTS : 'HH:mm:ss',
7401            L : 'YYYY-MM-DD',
7402            LL : 'D[-an de] MMMM, YYYY',
7403            LLL : 'D[-an de] MMMM, YYYY HH:mm',
7404            LLLL : 'dddd, [la] D[-an de] MMMM, YYYY HH:mm'
7405        },
7406        meridiemParse: /[ap]\.t\.m/i,
7407        isPM: function (input) {
7408            return input.charAt(0).toLowerCase() === 'p';
7409        },
7410        meridiem : function (hours, minutes, isLower) {
7411            if (hours > 11) {
7412                return isLower ? 'p.t.m.' : 'P.T.M.';
7413            } else {
7414                return isLower ? 'a.t.m.' : 'A.T.M.';
7415            }
7416        },
7417        calendar : {
7418            sameDay : '[HodiaÅ­ je] LT',
7419            nextDay : '[MorgaÅ­ je] LT',
7420            nextWeek : 'dddd [je] LT',
7421            lastDay : '[HieraÅ­ je] LT',
7422            lastWeek : '[pasinta] dddd [je] LT',
7423            sameElse : 'L'
7424        },
7425        relativeTime : {
7426            future : 'je %s',
7427            past : 'antaÅ­ %s',
7428            s : 'sekundoj',
7429            m : 'minuto',
7430            mm : '%d minutoj',
7431            h : 'horo',
7432            hh : '%d horoj',
7433            d : 'tago',//ne 'diurno', ĉar estas uzita por proksimumo
7434            dd : '%d tagoj',
7435            M : 'monato',
7436            MM : '%d monatoj',
7437            y : 'jaro',
7438            yy : '%d jaroj'
7439        },
7440        ordinalParse: /\d{1,2}a/,
7441        ordinal : '%da',
7442        week : {
7443            dow : 1, // Monday is the first day of the week.
7444            doy : 7  // The week that contains Jan 1st is the first week of the year.
7445        }
7446    });
7447
7448    //! moment.js locale configuration
7449    //! locale : spanish (es)
7450    //! author : Julio Napurí : https://github.com/julionc
7451
7452    var monthsShortDot = 'Ene._Feb._Mar._Abr._May._Jun._Jul._Ago._Sep._Oct._Nov._Dic.'.split('_'),
7453        es__monthsShort = 'Ene_Feb_Mar_Abr_May_Jun_Jul_Ago_Sep_Oct_Nov_Dic'.split('_');
7454
7455    var es = _moment__default.defineLocale('es', {
7456        months : 'Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre'.split('_'),
7457        monthsShort : function (m, format) {
7458            if (/-MMM-/.test(format)) {
7459                return es__monthsShort[m.month()];
7460            } else {
7461                return monthsShortDot[m.month()];
7462            }
7463        },
7464        weekdays : 'Domingo_Lunes_Martes_Miércoles_Jueves_Viernes_Sábado'.split('_'),
7465        weekdaysShort : 'Dom._Lun._Mar._Mié._Jue._Vie._Sáb.'.split('_'),
7466        weekdaysMin : 'Do_Lu_Ma_Mi_Ju_Vi_Sá'.split('_'),
7467        longDateFormat : {
7468            LT : 'H:mm',
7469            LTS : 'H:mm:ss',
7470            L : 'DD/MM/YYYY',
7471            LL : 'D [de] MMMM [de] YYYY',
7472            LLL : 'D [de] MMMM [de] YYYY H:mm',
7473            LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'
7474        },
7475        calendar : {
7476            sameDay : function () {
7477                return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
7478            },
7479            nextDay : function () {
7480                return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
7481            },
7482            nextWeek : function () {
7483                return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
7484            },
7485            lastDay : function () {
7486                return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
7487            },
7488            lastWeek : function () {
7489                return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
7490            },
7491            sameElse : 'L'
7492        },
7493        relativeTime : {
7494            future : 'en %s',
7495            past : 'hace %s',
7496            s : 'unos segundos',
7497            m : 'un minuto',
7498            mm : '%d minutos',
7499            h : 'una hora',
7500            hh : '%d horas',
7501            d : 'un día',
7502            dd : '%d días',
7503            M : 'un mes',
7504            MM : '%d meses',
7505            y : 'un año',
7506            yy : '%d años'
7507        },
7508        ordinalParse : /\d{1,2}º/,
7509        ordinal : '%dº',
7510        week : {
7511            dow : 1, // Monday is the first day of the week.
7512            doy : 4  // The week that contains Jan 4th is the first week of the year.
7513        }
7514    });
7515
7516    //! moment.js locale configuration
7517    //! locale : estonian (et)
7518    //! author : Henry Kehlmann : https://github.com/madhenry
7519    //! improvements : Illimar Tambek : https://github.com/ragulka
7520
7521    function et__processRelativeTime(number, withoutSuffix, key, isFuture) {
7522        var format = {
7523            's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'],
7524            'm' : ['ühe minuti', 'üks minut'],
7525            'mm': [number + ' minuti', number + ' minutit'],
7526            'h' : ['ühe tunni', 'tund aega', 'üks tund'],
7527            'hh': [number + ' tunni', number + ' tundi'],
7528            'd' : ['ühe päeva', 'üks päev'],
7529            'M' : ['kuu aja', 'kuu aega', 'üks kuu'],
7530            'MM': [number + ' kuu', number + ' kuud'],
7531            'y' : ['ühe aasta', 'aasta', 'üks aasta'],
7532            'yy': [number + ' aasta', number + ' aastat']
7533        };
7534        if (withoutSuffix) {
7535            return format[key][2] ? format[key][2] : format[key][1];
7536        }
7537        return isFuture ? format[key][0] : format[key][1];
7538    }
7539
7540    var et = _moment__default.defineLocale('et', {
7541        months        : 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split('_'),
7542        monthsShort   : 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split('_'),
7543        weekdays      : 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split('_'),
7544        weekdaysShort : 'P_E_T_K_N_R_L'.split('_'),
7545        weekdaysMin   : 'P_E_T_K_N_R_L'.split('_'),
7546        longDateFormat : {
7547            LT   : 'H:mm',
7548            LTS : 'H:mm:ss',
7549            L    : 'DD.MM.YYYY',
7550            LL   : 'D. MMMM YYYY',
7551            LLL  : 'D. MMMM YYYY H:mm',
7552            LLLL : 'dddd, D. MMMM YYYY H:mm'
7553        },
7554        calendar : {
7555            sameDay  : '[Täna,] LT',
7556            nextDay  : '[Homme,] LT',
7557            nextWeek : '[Järgmine] dddd LT',
7558            lastDay  : '[Eile,] LT',
7559            lastWeek : '[Eelmine] dddd LT',
7560            sameElse : 'L'
7561        },
7562        relativeTime : {
7563            future : '%s pärast',
7564            past   : '%s tagasi',
7565            s      : et__processRelativeTime,
7566            m      : et__processRelativeTime,
7567            mm     : et__processRelativeTime,
7568            h      : et__processRelativeTime,
7569            hh     : et__processRelativeTime,
7570            d      : et__processRelativeTime,
7571            dd     : '%d päeva',
7572            M      : et__processRelativeTime,
7573            MM     : et__processRelativeTime,
7574            y      : et__processRelativeTime,
7575            yy     : et__processRelativeTime
7576        },
7577        ordinalParse: /\d{1,2}\./,
7578        ordinal : '%d.',
7579        week : {
7580            dow : 1, // Monday is the first day of the week.
7581            doy : 4  // The week that contains Jan 4th is the first week of the year.
7582        }
7583    });
7584
7585    //! moment.js locale configuration
7586    //! locale : euskara (eu)
7587    //! author : Eneko Illarramendi : https://github.com/eillarra
7588
7589    var eu = _moment__default.defineLocale('eu', {
7590        months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'),
7591        monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'),
7592        weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'),
7593        weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'),
7594        weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'),
7595        longDateFormat : {
7596            LT : 'HH:mm',
7597            LTS : 'HH:mm:ss',
7598            L : 'YYYY-MM-DD',
7599            LL : 'YYYY[ko] MMMM[ren] D[a]',
7600            LLL : 'YYYY[ko] MMMM[ren] D[a] HH:mm',
7601            LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm',
7602            l : 'YYYY-M-D',
7603            ll : 'YYYY[ko] MMM D[a]',
7604            lll : 'YYYY[ko] MMM D[a] HH:mm',
7605            llll : 'ddd, YYYY[ko] MMM D[a] HH:mm'
7606        },
7607        calendar : {
7608            sameDay : '[gaur] LT[etan]',
7609            nextDay : '[bihar] LT[etan]',
7610            nextWeek : 'dddd LT[etan]',
7611            lastDay : '[atzo] LT[etan]',
7612            lastWeek : '[aurreko] dddd LT[etan]',
7613            sameElse : 'L'
7614        },
7615        relativeTime : {
7616            future : '%s barru',
7617            past : 'duela %s',
7618            s : 'segundo batzuk',
7619            m : 'minutu bat',
7620            mm : '%d minutu',
7621            h : 'ordu bat',
7622            hh : '%d ordu',
7623            d : 'egun bat',
7624            dd : '%d egun',
7625            M : 'hilabete bat',
7626            MM : '%d hilabete',
7627            y : 'urte bat',
7628            yy : '%d urte'
7629        },
7630        ordinalParse: /\d{1,2}\./,
7631        ordinal : '%d.',
7632        week : {
7633            dow : 1, // Monday is the first day of the week.
7634            doy : 7  // The week that contains Jan 1st is the first week of the year.
7635        }
7636    });
7637
7638    //! moment.js locale configuration
7639    //! locale : Persian (fa)
7640    //! author : Ebrahim Byagowi : https://github.com/ebraminio
7641
7642    var fa__symbolMap = {
7643        '1': 'Û±',
7644        '2': 'Û²',
7645        '3': 'Û³',
7646        '4': 'Û´',
7647        '5': 'Ûµ',
7648        '6': 'Û¶',
7649        '7': 'Û·',
7650        '8': 'Û¸',
7651        '9': 'Û¹',
7652        '0': 'Û°'
7653    }, fa__numberMap = {
7654        'Û±': '1',
7655        'Û²': '2',
7656        'Û³': '3',
7657        'Û´': '4',
7658        'Ûµ': '5',
7659        'Û¶': '6',
7660        'Û·': '7',
7661        'Û¸': '8',
7662        'Û¹': '9',
7663        'Û°': '0'
7664    };
7665
7666    var fa = _moment__default.defineLocale('fa', {
7667        months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),
7668        monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),
7669        weekdays : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'),
7670        weekdaysShort : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'),
7671        weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'),
7672        longDateFormat : {
7673            LT : 'HH:mm',
7674            LTS : 'HH:mm:ss',
7675            L : 'DD/MM/YYYY',
7676            LL : 'D MMMM YYYY',
7677            LLL : 'D MMMM YYYY HH:mm',
7678            LLLL : 'dddd, D MMMM YYYY HH:mm'
7679        },
7680        meridiemParse: /قبل از ظهر|بعد از ظهر/,
7681        isPM: function (input) {
7682            return /بعد از ظهر/.test(input);
7683        },
7684        meridiem : function (hour, minute, isLower) {
7685            if (hour < 12) {
7686                return 'قبل از ظهر';
7687            } else {
7688                return 'بعد از ظهر';
7689            }
7690        },
7691        calendar : {
7692            sameDay : '[امروز ساعت] LT',
7693            nextDay : '[فردا ساعت] LT',
7694            nextWeek : 'dddd [ساعت] LT',
7695            lastDay : '[دیروز ساعت] LT',
7696            lastWeek : 'dddd [پیش] [ساعت] LT',
7697            sameElse : 'L'
7698        },
7699        relativeTime : {
7700            future : 'در %s',
7701            past : '%s پیش',
7702            s : 'چندین ثانیه',
7703            m : 'یک دقیقه',
7704            mm : '%d دقیقه',
7705            h : 'یک ساعت',
7706            hh : '%d ساعت',
7707            d : 'یک روز',
7708            dd : '%d روز',
7709            M : 'یک ماه',
7710            MM : '%d ماه',
7711            y : 'یک سال',
7712            yy : '%d سال'
7713        },
7714        preparse: function (string) {
7715            return string.replace(/[Û°-Û¹]/g, function (match) {
7716                return fa__numberMap[match];
7717            }).replace(/،/g, ',');
7718        },
7719        postformat: function (string) {
7720            return string.replace(/\d/g, function (match) {
7721                return fa__symbolMap[match];
7722            }).replace(/,/g, '،');
7723        },
7724        ordinalParse: /\d{1,2}م/,
7725        ordinal : '%dم',
7726        week : {
7727            dow : 6, // Saturday is the first day of the week.
7728            doy : 12 // The week that contains Jan 1st is the first week of the year.
7729        }
7730    });
7731
7732    //! moment.js locale configuration
7733    //! locale : finnish (fi)
7734    //! author : Tarmo Aidantausta : https://github.com/bleadof
7735
7736    var numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' '),
7737        numbersFuture = [
7738            'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden',
7739            numbersPast[7], numbersPast[8], numbersPast[9]
7740        ];
7741    function fi__translate(number, withoutSuffix, key, isFuture) {
7742        var result = '';
7743        switch (key) {
7744            case 's':
7745                return isFuture ? 'muutaman sekunnin' : 'muutama sekunti';
7746            case 'm':
7747                return isFuture ? 'minuutin' : 'minuutti';
7748            case 'mm':
7749                result = isFuture ? 'minuutin' : 'minuuttia';
7750                break;
7751            case 'h':
7752                return isFuture ? 'tunnin' : 'tunti';
7753            case 'hh':
7754                result = isFuture ? 'tunnin' : 'tuntia';
7755                break;
7756            case 'd':
7757                return isFuture ? 'päivän' : 'päivä';
7758            case 'dd':
7759                result = isFuture ? 'päivän' : 'päivää';
7760                break;
7761            case 'M':
7762                return isFuture ? 'kuukauden' : 'kuukausi';
7763            case 'MM':
7764                result = isFuture ? 'kuukauden' : 'kuukautta';
7765                break;
7766            case 'y':
7767                return isFuture ? 'vuoden' : 'vuosi';
7768            case 'yy':
7769                result = isFuture ? 'vuoden' : 'vuotta';
7770                break;
7771        }
7772        result = verbalNumber(number, isFuture) + ' ' + result;
7773        return result;
7774    }
7775    function verbalNumber(number, isFuture) {
7776        return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number;
7777    }
7778
7779    var fi = _moment__default.defineLocale('fi', {
7780        months : 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split('_'),
7781        monthsShort : 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split('_'),
7782        weekdays : 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split('_'),
7783        weekdaysShort : 'su_ma_ti_ke_to_pe_la'.split('_'),
7784        weekdaysMin : 'su_ma_ti_ke_to_pe_la'.split('_'),
7785        longDateFormat : {
7786            LT : 'HH.mm',
7787            LTS : 'HH.mm.ss',
7788            L : 'DD.MM.YYYY',
7789            LL : 'Do MMMM[ta] YYYY',
7790            LLL : 'Do MMMM[ta] YYYY, [klo] HH.mm',
7791            LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm',
7792            l : 'D.M.YYYY',
7793            ll : 'Do MMM YYYY',
7794            lll : 'Do MMM YYYY, [klo] HH.mm',
7795            llll : 'ddd, Do MMM YYYY, [klo] HH.mm'
7796        },
7797        calendar : {
7798            sameDay : '[tänään] [klo] LT',
7799            nextDay : '[huomenna] [klo] LT',
7800            nextWeek : 'dddd [klo] LT',
7801            lastDay : '[eilen] [klo] LT',
7802            lastWeek : '[viime] dddd[na] [klo] LT',
7803            sameElse : 'L'
7804        },
7805        relativeTime : {
7806            future : '%s päästä',
7807            past : '%s sitten',
7808            s : fi__translate,
7809            m : fi__translate,
7810            mm : fi__translate,
7811            h : fi__translate,
7812            hh : fi__translate,
7813            d : fi__translate,
7814            dd : fi__translate,
7815            M : fi__translate,
7816            MM : fi__translate,
7817            y : fi__translate,
7818            yy : fi__translate
7819        },
7820        ordinalParse: /\d{1,2}\./,
7821        ordinal : '%d.',
7822        week : {
7823            dow : 1, // Monday is the first day of the week.
7824            doy : 4  // The week that contains Jan 4th is the first week of the year.
7825        }
7826    });
7827
7828    //! moment.js locale configuration
7829    //! locale : faroese (fo)
7830    //! author : Ragnar Johannesen : https://github.com/ragnar123
7831
7832    var fo = _moment__default.defineLocale('fo', {
7833        months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'),
7834        monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),
7835        weekdays : 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split('_'),
7836        weekdaysShort : 'sun_mán_týs_mik_hós_frí_ley'.split('_'),
7837        weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'),
7838        longDateFormat : {
7839            LT : 'HH:mm',
7840            LTS : 'HH:mm:ss',
7841            L : 'DD/MM/YYYY',
7842            LL : 'D MMMM YYYY',
7843            LLL : 'D MMMM YYYY HH:mm',
7844            LLLL : 'dddd D. MMMM, YYYY HH:mm'
7845        },
7846        calendar : {
7847            sameDay : '[Í dag kl.] LT',
7848            nextDay : '[Í morgin kl.] LT',
7849            nextWeek : 'dddd [kl.] LT',
7850            lastDay : '[Í gjár kl.] LT',
7851            lastWeek : '[síðstu] dddd [kl] LT',
7852            sameElse : 'L'
7853        },
7854        relativeTime : {
7855            future : 'um %s',
7856            past : '%s síðani',
7857            s : 'fá sekund',
7858            m : 'ein minutt',
7859            mm : '%d minuttir',
7860            h : 'ein tími',
7861            hh : '%d tímar',
7862            d : 'ein dagur',
7863            dd : '%d dagar',
7864            M : 'ein mánaði',
7865            MM : '%d mánaðir',
7866            y : 'eitt ár',
7867            yy : '%d ár'
7868        },
7869        ordinalParse: /\d{1,2}\./,
7870        ordinal : '%d.',
7871        week : {
7872            dow : 1, // Monday is the first day of the week.
7873            doy : 4  // The week that contains Jan 4th is the first week of the year.
7874        }
7875    });
7876
7877    //! moment.js locale configuration
7878    //! locale : canadian french (fr-ca)
7879    //! author : Jonathan Abourbih : https://github.com/jonbca
7880
7881    var fr_ca = _moment__default.defineLocale('fr-ca', {
7882        months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),
7883        monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),
7884        weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),
7885        weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),
7886        weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),
7887        longDateFormat : {
7888            LT : 'HH:mm',
7889            LTS : 'HH:mm:ss',
7890            L : 'YYYY-MM-DD',
7891            LL : 'D MMMM YYYY',
7892            LLL : 'D MMMM YYYY HH:mm',
7893            LLLL : 'dddd D MMMM YYYY HH:mm'
7894        },
7895        calendar : {
7896            sameDay: '[Aujourd\'hui à] LT',
7897            nextDay: '[Demain à] LT',
7898            nextWeek: 'dddd [à] LT',
7899            lastDay: '[Hier à] LT',
7900            lastWeek: 'dddd [dernier à] LT',
7901            sameElse: 'L'
7902        },
7903        relativeTime : {
7904            future : 'dans %s',
7905            past : 'il y a %s',
7906            s : 'quelques secondes',
7907            m : 'une minute',
7908            mm : '%d minutes',
7909            h : 'une heure',
7910            hh : '%d heures',
7911            d : 'un jour',
7912            dd : '%d jours',
7913            M : 'un mois',
7914            MM : '%d mois',
7915            y : 'un an',
7916            yy : '%d ans'
7917        },
7918        ordinalParse: /\d{1,2}(er|e)/,
7919        ordinal : function (number) {
7920            return number + (number === 1 ? 'er' : 'e');
7921        }
7922    });
7923
7924    //! moment.js locale configuration
7925    //! locale : french (fr)
7926    //! author : John Fischer : https://github.com/jfroffice
7927
7928    var fr = _moment__default.defineLocale('fr', {
7929        months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),
7930        monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),
7931        weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),
7932        weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),
7933        weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),
7934        longDateFormat : {
7935            LT : 'HH:mm',
7936            LTS : 'HH:mm:ss',
7937            L : 'DD/MM/YYYY',
7938            LL : 'D MMMM YYYY',
7939            LLL : 'D MMMM YYYY HH:mm',
7940            LLLL : 'dddd D MMMM YYYY HH:mm'
7941        },
7942        calendar : {
7943            sameDay: '[Aujourd\'hui à] LT',
7944            nextDay: '[Demain à] LT',
7945            nextWeek: 'dddd [à] LT',
7946            lastDay: '[Hier à] LT',
7947            lastWeek: 'dddd [dernier à] LT',
7948            sameElse: 'L'
7949        },
7950        relativeTime : {
7951            future : 'dans %s',
7952            past : 'il y a %s',
7953            s : 'quelques secondes',
7954            m : 'une minute',
7955            mm : '%d minutes',
7956            h : 'une heure',
7957            hh : '%d heures',
7958            d : 'un jour',
7959            dd : '%d jours',
7960            M : 'un mois',
7961            MM : '%d mois',
7962            y : 'un an',
7963            yy : '%d ans'
7964        },
7965        ordinalParse: /\d{1,2}(er|)/,
7966        ordinal : function (number) {
7967            return number + (number === 1 ? 'er' : '');
7968        },
7969        week : {
7970            dow : 1, // Monday is the first day of the week.
7971            doy : 4  // The week that contains Jan 4th is the first week of the year.
7972        }
7973    });
7974
7975    //! moment.js locale configuration
7976    //! locale : frisian (fy)
7977    //! author : Robin van der Vliet : https://github.com/robin0van0der0v
7978
7979    var fy__monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split('_'),
7980        fy__monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_');
7981
7982    var fy = _moment__default.defineLocale('fy', {
7983        months : 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split('_'),
7984        monthsShort : function (m, format) {
7985            if (/-MMM-/.test(format)) {
7986                return fy__monthsShortWithoutDots[m.month()];
7987            } else {
7988                return fy__monthsShortWithDots[m.month()];
7989            }
7990        },
7991        weekdays : 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split('_'),
7992        weekdaysShort : 'si._mo._ti._wo._to._fr._so.'.split('_'),
7993        weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'),
7994        longDateFormat : {
7995            LT : 'HH:mm',
7996            LTS : 'HH:mm:ss',
7997            L : 'DD-MM-YYYY',
7998            LL : 'D MMMM YYYY',
7999            LLL : 'D MMMM YYYY HH:mm',
8000            LLLL : 'dddd D MMMM YYYY HH:mm'
8001        },
8002        calendar : {
8003            sameDay: '[hjoed om] LT',
8004            nextDay: '[moarn om] LT',
8005            nextWeek: 'dddd [om] LT',
8006            lastDay: '[juster om] LT',
8007            lastWeek: '[ôfrûne] dddd [om] LT',
8008            sameElse: 'L'
8009        },
8010        relativeTime : {
8011            future : 'oer %s',
8012            past : '%s lyn',
8013            s : 'in pear sekonden',
8014            m : 'ien minút',
8015            mm : '%d minuten',
8016            h : 'ien oere',
8017            hh : '%d oeren',
8018            d : 'ien dei',
8019            dd : '%d dagen',
8020            M : 'ien moanne',
8021            MM : '%d moannen',
8022            y : 'ien jier',
8023            yy : '%d jierren'
8024        },
8025        ordinalParse: /\d{1,2}(ste|de)/,
8026        ordinal : function (number) {
8027            return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');
8028        },
8029        week : {
8030            dow : 1, // Monday is the first day of the week.
8031            doy : 4  // The week that contains Jan 4th is the first week of the year.
8032        }
8033    });
8034
8035    //! moment.js locale configuration
8036    //! locale : galician (gl)
8037    //! author : Juan G. Hurtado : https://github.com/juanghurtado
8038
8039    var gl = _moment__default.defineLocale('gl', {
8040        months : 'Xaneiro_Febreiro_Marzo_Abril_Maio_Xuño_Xullo_Agosto_Setembro_Outubro_Novembro_Decembro'.split('_'),
8041        monthsShort : 'Xan._Feb._Mar._Abr._Mai._Xuñ._Xul._Ago._Set._Out._Nov._Dec.'.split('_'),
8042        weekdays : 'Domingo_Luns_Martes_Mércores_Xoves_Venres_Sábado'.split('_'),
8043        weekdaysShort : 'Dom._Lun._Mar._Mér._Xov._Ven._Sáb.'.split('_'),
8044        weekdaysMin : 'Do_Lu_Ma_Mé_Xo_Ve_Sá'.split('_'),
8045        longDateFormat : {
8046            LT : 'H:mm',
8047            LTS : 'H:mm:ss',
8048            L : 'DD/MM/YYYY',
8049            LL : 'D MMMM YYYY',
8050            LLL : 'D MMMM YYYY H:mm',
8051            LLLL : 'dddd D MMMM YYYY H:mm'
8052        },
8053        calendar : {
8054            sameDay : function () {
8055                return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';
8056            },
8057            nextDay : function () {
8058                return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';
8059            },
8060            nextWeek : function () {
8061                return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';
8062            },
8063            lastDay : function () {
8064                return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT';
8065            },
8066            lastWeek : function () {
8067                return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';
8068            },
8069            sameElse : 'L'
8070        },
8071        relativeTime : {
8072            future : function (str) {
8073                if (str === 'uns segundos') {
8074                    return 'nuns segundos';
8075                }
8076                return 'en ' + str;
8077            },
8078            past : 'hai %s',
8079            s : 'uns segundos',
8080            m : 'un minuto',
8081            mm : '%d minutos',
8082            h : 'unha hora',
8083            hh : '%d horas',
8084            d : 'un día',
8085            dd : '%d días',
8086            M : 'un mes',
8087            MM : '%d meses',
8088            y : 'un ano',
8089            yy : '%d anos'
8090        },
8091        ordinalParse : /\d{1,2}º/,
8092        ordinal : '%dº',
8093        week : {
8094            dow : 1, // Monday is the first day of the week.
8095            doy : 7  // The week that contains Jan 1st is the first week of the year.
8096        }
8097    });
8098
8099    //! moment.js locale configuration
8100    //! locale : Hebrew (he)
8101    //! author : Tomer Cohen : https://github.com/tomer
8102    //! author : Moshe Simantov : https://github.com/DevelopmentIL
8103    //! author : Tal Ater : https://github.com/TalAter
8104
8105    var he = _moment__default.defineLocale('he', {
8106        months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'),
8107        monthsShort : 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split('_'),
8108        weekdays : 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'),
8109        weekdaysShort : 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'),
8110        weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'),
8111        longDateFormat : {
8112            LT : 'HH:mm',
8113            LTS : 'HH:mm:ss',
8114            L : 'DD/MM/YYYY',
8115            LL : 'D [ב]MMMM YYYY',
8116            LLL : 'D [ב]MMMM YYYY HH:mm',
8117            LLLL : 'dddd, D [ב]MMMM YYYY HH:mm',
8118            l : 'D/M/YYYY',
8119            ll : 'D MMM YYYY',
8120            lll : 'D MMM YYYY HH:mm',
8121            llll : 'ddd, D MMM YYYY HH:mm'
8122        },
8123        calendar : {
8124            sameDay : '[היום ב־]LT',
8125            nextDay : '[מחר ב־]LT',
8126            nextWeek : 'dddd [בשעה] LT',
8127            lastDay : '[אתמול ב־]LT',
8128            lastWeek : '[ביום] dddd [האחרון בשעה] LT',
8129            sameElse : 'L'
8130        },
8131        relativeTime : {
8132            future : 'בעוד %s',
8133            past : 'לפני %s',
8134            s : 'מספר שניות',
8135            m : 'דקה',
8136            mm : '%d דקות',
8137            h : 'שעה',
8138            hh : function (number) {
8139                if (number === 2) {
8140                    return 'שעתיים';
8141                }
8142                return number + ' שעות';
8143            },
8144            d : 'יום',
8145            dd : function (number) {
8146                if (number === 2) {
8147                    return 'יומיים';
8148                }
8149                return number + ' ימים';
8150            },
8151            M : 'חודש',
8152            MM : function (number) {
8153                if (number === 2) {
8154                    return 'חודשיים';
8155                }
8156                return number + ' חודשים';
8157            },
8158            y : 'שנה',
8159            yy : function (number) {
8160                if (number === 2) {
8161                    return 'שנתיים';
8162                } else if (number % 10 === 0 && number !== 10) {
8163                    return number + ' שנה';
8164                }
8165                return number + ' שנים';
8166            }
8167        }
8168    });
8169
8170    //! moment.js locale configuration
8171    //! locale : hindi (hi)
8172    //! author : Mayank Singhal : https://github.com/mayanksinghal
8173
8174    var hi__symbolMap = {
8175            '1': '१',
8176            '2': '२',
8177            '3': '३',
8178            '4': '४',
8179            '5': '५',
8180            '6': '६',
8181            '7': '७',
8182            '8': '८',
8183            '9': '९',
8184            '0': '०'
8185        },
8186        hi__numberMap = {
8187            '१': '1',
8188            '२': '2',
8189            '३': '3',
8190            '४': '4',
8191            '५': '5',
8192            '६': '6',
8193            '७': '7',
8194            '८': '8',
8195            '९': '9',
8196            '०': '0'
8197        };
8198
8199    var hi = _moment__default.defineLocale('hi', {
8200        months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split('_'),
8201        monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split('_'),
8202        weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),
8203        weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'),
8204        weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),
8205        longDateFormat : {
8206            LT : 'A h:mm बजे',
8207            LTS : 'A h:mm:ss बजे',
8208            L : 'DD/MM/YYYY',
8209            LL : 'D MMMM YYYY',
8210            LLL : 'D MMMM YYYY, A h:mm बजे',
8211            LLLL : 'dddd, D MMMM YYYY, A h:mm बजे'
8212        },
8213        calendar : {
8214            sameDay : '[आज] LT',
8215            nextDay : '[कल] LT',
8216            nextWeek : 'dddd, LT',
8217            lastDay : '[कल] LT',
8218            lastWeek : '[पिछले] dddd, LT',
8219            sameElse : 'L'
8220        },
8221        relativeTime : {
8222            future : '%s में',
8223            past : '%s पहले',
8224            s : 'कुछ ही क्षण',
8225            m : 'एक मिनट',
8226            mm : '%d मिनट',
8227            h : 'एक घंटा',
8228            hh : '%d घंटे',
8229            d : 'एक दिन',
8230            dd : '%d दिन',
8231            M : 'एक महीने',
8232            MM : '%d महीने',
8233            y : 'एक वर्ष',
8234            yy : '%d वर्ष'
8235        },
8236        preparse: function (string) {
8237            return string.replace(/[१२३४५६७८९०]/g, function (match) {
8238                return hi__numberMap[match];
8239            });
8240        },
8241        postformat: function (string) {
8242            return string.replace(/\d/g, function (match) {
8243                return hi__symbolMap[match];
8244            });
8245        },
8246        // Hindi notation for meridiems are quite fuzzy in practice. While there exists
8247        // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi.
8248        meridiemParse: /रात|सुबह|दोपहर|शाम/,
8249        meridiemHour : function (hour, meridiem) {
8250            if (hour === 12) {
8251                hour = 0;
8252            }
8253            if (meridiem === 'रात') {
8254                return hour < 4 ? hour : hour + 12;
8255            } else if (meridiem === 'सुबह') {
8256                return hour;
8257            } else if (meridiem === 'दोपहर') {
8258                return hour >= 10 ? hour : hour + 12;
8259            } else if (meridiem === 'शाम') {
8260                return hour + 12;
8261            }
8262        },
8263        meridiem : function (hour, minute, isLower) {
8264            if (hour < 4) {
8265                return 'रात';
8266            } else if (hour < 10) {
8267                return 'सुबह';
8268            } else if (hour < 17) {
8269                return 'दोपहर';
8270            } else if (hour < 20) {
8271                return 'शाम';
8272            } else {
8273                return 'रात';
8274            }
8275        },
8276        week : {
8277            dow : 0, // Sunday is the first day of the week.
8278            doy : 6  // The week that contains Jan 1st is the first week of the year.
8279        }
8280    });
8281
8282    //! moment.js locale configuration
8283    //! locale : hrvatski (hr)
8284    //! author : Bojan Marković : https://github.com/bmarkovic
8285
8286    function hr__translate(number, withoutSuffix, key) {
8287        var result = number + ' ';
8288        switch (key) {
8289            case 'm':
8290                return withoutSuffix ? 'jedna minuta' : 'jedne minute';
8291            case 'mm':
8292                if (number === 1) {
8293                    result += 'minuta';
8294                } else if (number === 2 || number === 3 || number === 4) {
8295                    result += 'minute';
8296                } else {
8297                    result += 'minuta';
8298                }
8299                return result;
8300            case 'h':
8301                return withoutSuffix ? 'jedan sat' : 'jednog sata';
8302            case 'hh':
8303                if (number === 1) {
8304                    result += 'sat';
8305                } else if (number === 2 || number === 3 || number === 4) {
8306                    result += 'sata';
8307                } else {
8308                    result += 'sati';
8309                }
8310                return result;
8311            case 'dd':
8312                if (number === 1) {
8313                    result += 'dan';
8314                } else {
8315                    result += 'dana';
8316                }
8317                return result;
8318            case 'MM':
8319                if (number === 1) {
8320                    result += 'mjesec';
8321                } else if (number === 2 || number === 3 || number === 4) {
8322                    result += 'mjeseca';
8323                } else {
8324                    result += 'mjeseci';
8325                }
8326                return result;
8327            case 'yy':
8328                if (number === 1) {
8329                    result += 'godina';
8330                } else if (number === 2 || number === 3 || number === 4) {
8331                    result += 'godine';
8332                } else {
8333                    result += 'godina';
8334                }
8335                return result;
8336        }
8337    }
8338
8339    var hr = _moment__default.defineLocale('hr', {
8340        months : 'siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split('_'),
8341        monthsShort : 'sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split('_'),
8342        weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),
8343        weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),
8344        weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),
8345        longDateFormat : {
8346            LT : 'H:mm',
8347            LTS : 'H:mm:ss',
8348            L : 'DD. MM. YYYY',
8349            LL : 'D. MMMM YYYY',
8350            LLL : 'D. MMMM YYYY H:mm',
8351            LLLL : 'dddd, D. MMMM YYYY H:mm'
8352        },
8353        calendar : {
8354            sameDay  : '[danas u] LT',
8355            nextDay  : '[sutra u] LT',
8356            nextWeek : function () {
8357                switch (this.day()) {
8358                    case 0:
8359                        return '[u] [nedjelju] [u] LT';
8360                    case 3:
8361                        return '[u] [srijedu] [u] LT';
8362                    case 6:
8363                        return '[u] [subotu] [u] LT';
8364                    case 1:
8365                    case 2:
8366                    case 4:
8367                    case 5:
8368                        return '[u] dddd [u] LT';
8369                }
8370            },
8371            lastDay  : '[jučer u] LT',
8372            lastWeek : function () {
8373                switch (this.day()) {
8374                    case 0:
8375                    case 3:
8376                        return '[prošlu] dddd [u] LT';
8377                    case 6:
8378                        return '[prošle] [subote] [u] LT';
8379                    case 1:
8380                    case 2:
8381                    case 4:
8382                    case 5:
8383                        return '[prošli] dddd [u] LT';
8384                }
8385            },
8386            sameElse : 'L'
8387        },
8388        relativeTime : {
8389            future : 'za %s',
8390            past   : 'prije %s',
8391            s      : 'par sekundi',
8392            m      : hr__translate,
8393            mm     : hr__translate,
8394            h      : hr__translate,
8395            hh     : hr__translate,
8396            d      : 'dan',
8397            dd     : hr__translate,
8398            M      : 'mjesec',
8399            MM     : hr__translate,
8400            y      : 'godinu',
8401            yy     : hr__translate
8402        },
8403        ordinalParse: /\d{1,2}\./,
8404        ordinal : '%d.',
8405        week : {
8406            dow : 1, // Monday is the first day of the week.
8407            doy : 7  // The week that contains Jan 1st is the first week of the year.
8408        }
8409    });
8410
8411    //! moment.js locale configuration
8412    //! locale : hungarian (hu)
8413    //! author : Adam Brunner : https://github.com/adambrunner
8414
8415    var weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' ');
8416    function hu__translate(number, withoutSuffix, key, isFuture) {
8417        var num = number,
8418            suffix;
8419        switch (key) {
8420            case 's':
8421                return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce';
8422            case 'm':
8423                return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce');
8424            case 'mm':
8425                return num + (isFuture || withoutSuffix ? ' perc' : ' perce');
8426            case 'h':
8427                return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája');
8428            case 'hh':
8429                return num + (isFuture || withoutSuffix ? ' óra' : ' órája');
8430            case 'd':
8431                return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja');
8432            case 'dd':
8433                return num + (isFuture || withoutSuffix ? ' nap' : ' napja');
8434            case 'M':
8435                return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');
8436            case 'MM':
8437                return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');
8438            case 'y':
8439                return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve');
8440            case 'yy':
8441                return num + (isFuture || withoutSuffix ? ' év' : ' éve');
8442        }
8443        return '';
8444    }
8445    function week(isFuture) {
8446        return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]';
8447    }
8448
8449    var hu = _moment__default.defineLocale('hu', {
8450        months : 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'),
8451        monthsShort : 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'),
8452        weekdays : 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'),
8453        weekdaysShort : 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'),
8454        weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'),
8455        longDateFormat : {
8456            LT : 'H:mm',
8457            LTS : 'H:mm:ss',
8458            L : 'YYYY.MM.DD.',
8459            LL : 'YYYY. MMMM D.',
8460            LLL : 'YYYY. MMMM D. H:mm',
8461            LLLL : 'YYYY. MMMM D., dddd H:mm'
8462        },
8463        meridiemParse: /de|du/i,
8464        isPM: function (input) {
8465            return input.charAt(1).toLowerCase() === 'u';
8466        },
8467        meridiem : function (hours, minutes, isLower) {
8468            if (hours < 12) {
8469                return isLower === true ? 'de' : 'DE';
8470            } else {
8471                return isLower === true ? 'du' : 'DU';
8472            }
8473        },
8474        calendar : {
8475            sameDay : '[ma] LT[-kor]',
8476            nextDay : '[holnap] LT[-kor]',
8477            nextWeek : function () {
8478                return week.call(this, true);
8479            },
8480            lastDay : '[tegnap] LT[-kor]',
8481            lastWeek : function () {
8482                return week.call(this, false);
8483            },
8484            sameElse : 'L'
8485        },
8486        relativeTime : {
8487            future : '%s múlva',
8488            past : '%s',
8489            s : hu__translate,
8490            m : hu__translate,
8491            mm : hu__translate,
8492            h : hu__translate,
8493            hh : hu__translate,
8494            d : hu__translate,
8495            dd : hu__translate,
8496            M : hu__translate,
8497            MM : hu__translate,
8498            y : hu__translate,
8499            yy : hu__translate
8500        },
8501        ordinalParse: /\d{1,2}\./,
8502        ordinal : '%d.',
8503        week : {
8504            dow : 1, // Monday is the first day of the week.
8505            doy : 7  // The week that contains Jan 1st is the first week of the year.
8506        }
8507    });
8508
8509    //! moment.js locale configuration
8510    //! locale : Armenian (hy-am)
8511    //! author : Armendarabyan : https://github.com/armendarabyan
8512
8513    function hy_am__monthsCaseReplace(m, format) {
8514        var months = {
8515                'nominative': 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_'),
8516                'accusative': 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_')
8517            },
8518            nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ?
8519                'accusative' :
8520                'nominative';
8521        return months[nounCase][m.month()];
8522    }
8523    function hy_am__monthsShortCaseReplace(m, format) {
8524        var monthsShort = 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_');
8525        return monthsShort[m.month()];
8526    }
8527    function hy_am__weekdaysCaseReplace(m, format) {
8528        var weekdays = 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_');
8529        return weekdays[m.day()];
8530    }
8531
8532    var hy_am = _moment__default.defineLocale('hy-am', {
8533        months : hy_am__monthsCaseReplace,
8534        monthsShort : hy_am__monthsShortCaseReplace,
8535        weekdays : hy_am__weekdaysCaseReplace,
8536        weekdaysShort : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),
8537        weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),
8538        longDateFormat : {
8539            LT : 'HH:mm',
8540            LTS : 'HH:mm:ss',
8541            L : 'DD.MM.YYYY',
8542            LL : 'D MMMM YYYY Õ©.',
8543            LLL : 'D MMMM YYYY Õ©., HH:mm',
8544            LLLL : 'dddd, D MMMM YYYY Õ©., HH:mm'
8545        },
8546        calendar : {
8547            sameDay: '[այսօր] LT',
8548            nextDay: '[Õ¾Õ¡Õ²Õ¨] LT',
8549            lastDay: '[երեկ] LT',
8550            nextWeek: function () {
8551                return 'dddd [օրը ժամը] LT';
8552            },
8553            lastWeek: function () {
8554                return '[անցած] dddd [օրը ժամը] LT';
8555            },
8556            sameElse: 'L'
8557        },
8558        relativeTime : {
8559            future : '%s Õ°Õ¥Õ¿Õ¸',
8560            past : '%s Õ¡Õ¼Õ¡Õ»',
8561            s : 'մի քանի վայրկյան',
8562            m : 'րոպե',
8563            mm : '%d րոպե',
8564            h : 'ÕªÕ¡Õ´',
8565            hh : '%d ÕªÕ¡Õ´',
8566            d : 'օր',
8567            dd : '%d օր',
8568            M : 'Õ¡Õ´Õ«Õ½',
8569            MM : '%d Õ¡Õ´Õ«Õ½',
8570            y : 'տարի',
8571            yy : '%d տարի'
8572        },
8573        meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/,
8574        isPM: function (input) {
8575            return /^(ցերեկվա|երեկոյան)$/.test(input);
8576        },
8577        meridiem : function (hour) {
8578            if (hour < 4) {
8579                return 'գիշերվա';
8580            } else if (hour < 12) {
8581                return 'Õ¡Õ¼Õ¡Õ¾Õ¸Õ¿Õ¾Õ¡';
8582            } else if (hour < 17) {
8583                return 'ցերեկվա';
8584            } else {
8585                return 'երեկոյան';
8586            }
8587        },
8588        ordinalParse: /\d{1,2}|\d{1,2}-(ին|րդ)/,
8589        ordinal: function (number, period) {
8590            switch (period) {
8591                case 'DDD':
8592                case 'w':
8593                case 'W':
8594                case 'DDDo':
8595                    if (number === 1) {
8596                        return number + '-Õ«Õ¶';
8597                    }
8598                    return number + '-րդ';
8599                default:
8600                    return number;
8601            }
8602        },
8603        week : {
8604            dow : 1, // Monday is the first day of the week.
8605            doy : 7  // The week that contains Jan 1st is the first week of the year.
8606        }
8607    });
8608
8609    //! moment.js locale configuration
8610    //! locale : Bahasa Indonesia (id)
8611    //! author : Mohammad Satrio Utomo : https://github.com/tyok
8612    //! reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan
8613
8614    var id = _moment__default.defineLocale('id', {
8615        months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'),
8616        monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des'.split('_'),
8617        weekdays : 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'),
8618        weekdaysShort : 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'),
8619        weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'),
8620        longDateFormat : {
8621            LT : 'HH.mm',
8622            LTS : 'HH.mm.ss',
8623            L : 'DD/MM/YYYY',
8624            LL : 'D MMMM YYYY',
8625            LLL : 'D MMMM YYYY [pukul] HH.mm',
8626            LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
8627        },
8628        meridiemParse: /pagi|siang|sore|malam/,
8629        meridiemHour : function (hour, meridiem) {
8630            if (hour === 12) {
8631                hour = 0;
8632            }
8633            if (meridiem === 'pagi') {
8634                return hour;
8635            } else if (meridiem === 'siang') {
8636                return hour >= 11 ? hour : hour + 12;
8637            } else if (meridiem === 'sore' || meridiem === 'malam') {
8638                return hour + 12;
8639            }
8640        },
8641        meridiem : function (hours, minutes, isLower) {
8642            if (hours < 11) {
8643                return 'pagi';
8644            } else if (hours < 15) {
8645                return 'siang';
8646            } else if (hours < 19) {
8647                return 'sore';
8648            } else {
8649                return 'malam';
8650            }
8651        },
8652        calendar : {
8653            sameDay : '[Hari ini pukul] LT',
8654            nextDay : '[Besok pukul] LT',
8655            nextWeek : 'dddd [pukul] LT',
8656            lastDay : '[Kemarin pukul] LT',
8657            lastWeek : 'dddd [lalu pukul] LT',
8658            sameElse : 'L'
8659        },
8660        relativeTime : {
8661            future : 'dalam %s',
8662            past : '%s yang lalu',
8663            s : 'beberapa detik',
8664            m : 'semenit',
8665            mm : '%d menit',
8666            h : 'sejam',
8667            hh : '%d jam',
8668            d : 'sehari',
8669            dd : '%d hari',
8670            M : 'sebulan',
8671            MM : '%d bulan',
8672            y : 'setahun',
8673            yy : '%d tahun'
8674        },
8675        week : {
8676            dow : 1, // Monday is the first day of the week.
8677            doy : 7  // The week that contains Jan 1st is the first week of the year.
8678        }
8679    });
8680
8681    //! moment.js locale configuration
8682    //! locale : icelandic (is)
8683    //! author : Hinrik Örn Sigurðsson : https://github.com/hinrik
8684
8685    function is__plural(n) {
8686        if (n % 100 === 11) {
8687            return true;
8688        } else if (n % 10 === 1) {
8689            return false;
8690        }
8691        return true;
8692    }
8693    function is__translate(number, withoutSuffix, key, isFuture) {
8694        var result = number + ' ';
8695        switch (key) {
8696            case 's':
8697                return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum';
8698            case 'm':
8699                return withoutSuffix ? 'mínúta' : 'mínútu';
8700            case 'mm':
8701                if (is__plural(number)) {
8702                    return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum');
8703                } else if (withoutSuffix) {
8704                    return result + 'mínúta';
8705                }
8706                return result + 'mínútu';
8707            case 'hh':
8708                if (is__plural(number)) {
8709                    return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum');
8710                }
8711                return result + 'klukkustund';
8712            case 'd':
8713                if (withoutSuffix) {
8714                    return 'dagur';
8715                }
8716                return isFuture ? 'dag' : 'degi';
8717            case 'dd':
8718                if (is__plural(number)) {
8719                    if (withoutSuffix) {
8720                        return result + 'dagar';
8721                    }
8722                    return result + (isFuture ? 'daga' : 'dögum');
8723                } else if (withoutSuffix) {
8724                    return result + 'dagur';
8725                }
8726                return result + (isFuture ? 'dag' : 'degi');
8727            case 'M':
8728                if (withoutSuffix) {
8729                    return 'mánuður';
8730                }
8731                return isFuture ? 'mánuð' : 'mánuði';
8732            case 'MM':
8733                if (is__plural(number)) {
8734                    if (withoutSuffix) {
8735                        return result + 'mánuðir';
8736                    }
8737                    return result + (isFuture ? 'mánuði' : 'mánuðum');
8738                } else if (withoutSuffix) {
8739                    return result + 'mánuður';
8740                }
8741                return result + (isFuture ? 'mánuð' : 'mánuði');
8742            case 'y':
8743                return withoutSuffix || isFuture ? 'ár' : 'ári';
8744            case 'yy':
8745                if (is__plural(number)) {
8746                    return result + (withoutSuffix || isFuture ? 'ár' : 'árum');
8747                }
8748                return result + (withoutSuffix || isFuture ? 'ár' : 'ári');
8749        }
8750    }
8751
8752    var is = _moment__default.defineLocale('is', {
8753        months : 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split('_'),
8754        monthsShort : 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'),
8755        weekdays : 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split('_'),
8756        weekdaysShort : 'sun_mán_þri_mið_fim_fös_lau'.split('_'),
8757        weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'),
8758        longDateFormat : {
8759            LT : 'H:mm',
8760            LTS : 'H:mm:ss',
8761            L : 'DD/MM/YYYY',
8762            LL : 'D. MMMM YYYY',
8763            LLL : 'D. MMMM YYYY [kl.] H:mm',
8764            LLLL : 'dddd, D. MMMM YYYY [kl.] H:mm'
8765        },
8766        calendar : {
8767            sameDay : '[í dag kl.] LT',
8768            nextDay : '[á morgun kl.] LT',
8769            nextWeek : 'dddd [kl.] LT',
8770            lastDay : '[í gær kl.] LT',
8771            lastWeek : '[síðasta] dddd [kl.] LT',
8772            sameElse : 'L'
8773        },
8774        relativeTime : {
8775            future : 'eftir %s',
8776            past : 'fyrir %s síðan',
8777            s : is__translate,
8778            m : is__translate,
8779            mm : is__translate,
8780            h : 'klukkustund',
8781            hh : is__translate,
8782            d : is__translate,
8783            dd : is__translate,
8784            M : is__translate,
8785            MM : is__translate,
8786            y : is__translate,
8787            yy : is__translate
8788        },
8789        ordinalParse: /\d{1,2}\./,
8790        ordinal : '%d.',
8791        week : {
8792            dow : 1, // Monday is the first day of the week.
8793            doy : 4  // The week that contains Jan 4th is the first week of the year.
8794        }
8795    });
8796
8797    //! moment.js locale configuration
8798    //! locale : italian (it)
8799    //! author : Lorenzo : https://github.com/aliem
8800    //! author: Mattia Larentis: https://github.com/nostalgiaz
8801
8802    var it = _moment__default.defineLocale('it', {
8803        months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'),
8804        monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'),
8805        weekdays : 'Domenica_Lunedì_Martedì_Mercoledì_Giovedì_Venerdì_Sabato'.split('_'),
8806        weekdaysShort : 'Dom_Lun_Mar_Mer_Gio_Ven_Sab'.split('_'),
8807        weekdaysMin : 'D_L_Ma_Me_G_V_S'.split('_'),
8808        longDateFormat : {
8809            LT : 'HH:mm',
8810            LTS : 'HH:mm:ss',
8811            L : 'DD/MM/YYYY',
8812            LL : 'D MMMM YYYY',
8813            LLL : 'D MMMM YYYY HH:mm',
8814            LLLL : 'dddd, D MMMM YYYY HH:mm'
8815        },
8816        calendar : {
8817            sameDay: '[Oggi alle] LT',
8818            nextDay: '[Domani alle] LT',
8819            nextWeek: 'dddd [alle] LT',
8820            lastDay: '[Ieri alle] LT',
8821            lastWeek: function () {
8822                switch (this.day()) {
8823                    case 0:
8824                        return '[la scorsa] dddd [alle] LT';
8825                    default:
8826                        return '[lo scorso] dddd [alle] LT';
8827                }
8828            },
8829            sameElse: 'L'
8830        },
8831        relativeTime : {
8832            future : function (s) {
8833                return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s;
8834            },
8835            past : '%s fa',
8836            s : 'alcuni secondi',
8837            m : 'un minuto',
8838            mm : '%d minuti',
8839            h : 'un\'ora',
8840            hh : '%d ore',
8841            d : 'un giorno',
8842            dd : '%d giorni',
8843            M : 'un mese',
8844            MM : '%d mesi',
8845            y : 'un anno',
8846            yy : '%d anni'
8847        },
8848        ordinalParse : /\d{1,2}º/,
8849        ordinal: '%dº',
8850        week : {
8851            dow : 1, // Monday is the first day of the week.
8852            doy : 4  // The week that contains Jan 4th is the first week of the year.
8853        }
8854    });
8855
8856    //! moment.js locale configuration
8857    //! locale : japanese (ja)
8858    //! author : LI Long : https://github.com/baryon
8859
8860    var ja = _moment__default.defineLocale('ja', {
8861        months : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
8862        monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
8863        weekdays : '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'),
8864        weekdaysShort : '日_月_火_水_木_金_土'.split('_'),
8865        weekdaysMin : '日_月_火_水_木_金_土'.split('_'),
8866        longDateFormat : {
8867            LT : 'Ah時m分',
8868            LTS : 'Ah時m分s秒',
8869            L : 'YYYY/MM/DD',
8870            LL : 'YYYY年M月D日',
8871            LLL : 'YYYY年M月D日Ah時m分',
8872            LLLL : 'YYYY年M月D日Ah時m分 dddd'
8873        },
8874        meridiemParse: /午前|午後/i,
8875        isPM : function (input) {
8876            return input === '午後';
8877        },
8878        meridiem : function (hour, minute, isLower) {
8879            if (hour < 12) {
8880                return '午前';
8881            } else {
8882                return '午後';
8883            }
8884        },
8885        calendar : {
8886            sameDay : '[今日] LT',
8887            nextDay : '[明日] LT',
8888            nextWeek : '[来週]dddd LT',
8889            lastDay : '[昨日] LT',
8890            lastWeek : '[前週]dddd LT',
8891            sameElse : 'L'
8892        },
8893        relativeTime : {
8894            future : '%s後',
8895            past : '%s前',
8896            s : '数秒',
8897            m : '1分',
8898            mm : '%d分',
8899            h : '1時間',
8900            hh : '%d時間',
8901            d : '1日',
8902            dd : '%d日',
8903            M : '1ヶ月',
8904            MM : '%dヶ月',
8905            y : '1å¹´',
8906            yy : '%då¹´'
8907        }
8908    });
8909
8910    //! moment.js locale configuration
8911    //! locale : Boso Jowo (jv)
8912    //! author : Rony Lantip : https://github.com/lantip
8913    //! reference: http://jv.wikipedia.org/wiki/Basa_Jawa
8914
8915    var jv = _moment__default.defineLocale('jv', {
8916        months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember'.split('_'),
8917        monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des'.split('_'),
8918        weekdays : 'Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu'.split('_'),
8919        weekdaysShort : 'Min_Sen_Sel_Reb_Kem_Jem_Sep'.split('_'),
8920        weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'),
8921        longDateFormat : {
8922            LT : 'HH.mm',
8923            LTS : 'HH.mm.ss',
8924            L : 'DD/MM/YYYY',
8925            LL : 'D MMMM YYYY',
8926            LLL : 'D MMMM YYYY [pukul] HH.mm',
8927            LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
8928        },
8929        meridiemParse: /enjing|siyang|sonten|ndalu/,
8930        meridiemHour : function (hour, meridiem) {
8931            if (hour === 12) {
8932                hour = 0;
8933            }
8934            if (meridiem === 'enjing') {
8935                return hour;
8936            } else if (meridiem === 'siyang') {
8937                return hour >= 11 ? hour : hour + 12;
8938            } else if (meridiem === 'sonten' || meridiem === 'ndalu') {
8939                return hour + 12;
8940            }
8941        },
8942        meridiem : function (hours, minutes, isLower) {
8943            if (hours < 11) {
8944                return 'enjing';
8945            } else if (hours < 15) {
8946                return 'siyang';
8947            } else if (hours < 19) {
8948                return 'sonten';
8949            } else {
8950                return 'ndalu';
8951            }
8952        },
8953        calendar : {
8954            sameDay : '[Dinten puniko pukul] LT',
8955            nextDay : '[Mbenjang pukul] LT',
8956            nextWeek : 'dddd [pukul] LT',
8957            lastDay : '[Kala wingi pukul] LT',
8958            lastWeek : 'dddd [kepengker pukul] LT',
8959            sameElse : 'L'
8960        },
8961        relativeTime : {
8962            future : 'wonten ing %s',
8963            past : '%s ingkang kepengker',
8964            s : 'sawetawis detik',
8965            m : 'setunggal menit',
8966            mm : '%d menit',
8967            h : 'setunggal jam',
8968            hh : '%d jam',
8969            d : 'sedinten',
8970            dd : '%d dinten',
8971            M : 'sewulan',
8972            MM : '%d wulan',
8973            y : 'setaun',
8974            yy : '%d taun'
8975        },
8976        week : {
8977            dow : 1, // Monday is the first day of the week.
8978            doy : 7  // The week that contains Jan 1st is the first week of the year.
8979        }
8980    });
8981
8982    //! moment.js locale configuration
8983    //! locale : Georgian (ka)
8984    //! author : Irakli Janiashvili : https://github.com/irakli-janiashvili
8985
8986    function ka__monthsCaseReplace(m, format) {
8987        var months = {
8988                'nominative': 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'),
8989                'accusative': 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_')
8990            },
8991            nounCase = (/D[oD] *MMMM?/).test(format) ?
8992                'accusative' :
8993                'nominative';
8994        return months[nounCase][m.month()];
8995    }
8996    function ka__weekdaysCaseReplace(m, format) {
8997        var weekdays = {
8998                'nominative': 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'),
8999                'accusative': 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_')
9000            },
9001            nounCase = (/(წინა|შემდეგ)/).test(format) ?
9002                'accusative' :
9003                'nominative';
9004        return weekdays[nounCase][m.day()];
9005    }
9006
9007    var ka = _moment__default.defineLocale('ka', {
9008        months : ka__monthsCaseReplace,
9009        monthsShort : 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'),
9010        weekdays : ka__weekdaysCaseReplace,
9011        weekdaysShort : 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'),
9012        weekdaysMin : 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'),
9013        longDateFormat : {
9014            LT : 'h:mm A',
9015            LTS : 'h:mm:ss A',
9016            L : 'DD/MM/YYYY',
9017            LL : 'D MMMM YYYY',
9018            LLL : 'D MMMM YYYY h:mm A',
9019            LLLL : 'dddd, D MMMM YYYY h:mm A'
9020        },
9021        calendar : {
9022            sameDay : '[დღეს] LT[-ზე]',
9023            nextDay : '[ხვალ] LT[-ზე]',
9024            lastDay : '[გუშინ] LT[-ზე]',
9025            nextWeek : '[შემდეგ] dddd LT[-ზე]',
9026            lastWeek : '[წინა] dddd LT-ზე',
9027            sameElse : 'L'
9028        },
9029        relativeTime : {
9030            future : function (s) {
9031                return (/(წამი|წუთი|საათი|წელი)/).test(s) ?
9032                    s.replace(/ი$/, 'ში') :
9033                s + 'ში';
9034            },
9035            past : function (s) {
9036                if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) {
9037                    return s.replace(/(ი|ე)$/, 'ის წინ');
9038                }
9039                if ((/წელი/).test(s)) {
9040                    return s.replace(/წელი$/, 'წლის წინ');
9041                }
9042            },
9043            s : 'რამდენიმე წამი',
9044            m : 'წუთი',
9045            mm : '%d წუთი',
9046            h : 'საათი',
9047            hh : '%d საათი',
9048            d : 'დღე',
9049            dd : '%d დღე',
9050            M : 'თვე',
9051            MM : '%d თვე',
9052            y : 'წელი',
9053            yy : '%d წელი'
9054        },
9055        ordinalParse: /0|1-ლი|მე-\d{1,2}|\d{1,2}-ე/,
9056        ordinal : function (number) {
9057            if (number === 0) {
9058                return number;
9059            }
9060            if (number === 1) {
9061                return number + '-ლი';
9062            }
9063            if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) {
9064                return 'მე-' + number;
9065            }
9066            return number + '-ე';
9067        },
9068        week : {
9069            dow : 1,
9070            doy : 7
9071        }
9072    });
9073
9074    //! moment.js locale configuration
9075    //! locale : khmer (km)
9076    //! author : Kruy Vanna : https://github.com/kruyvanna
9077
9078    var km = _moment__default.defineLocale('km', {
9079        months: 'មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),
9080        monthsShort: 'មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),
9081        weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),
9082        weekdaysShort: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),
9083        weekdaysMin: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),
9084        longDateFormat: {
9085            LT: 'HH:mm',
9086            LTS : 'HH:mm:ss',
9087            L: 'DD/MM/YYYY',
9088            LL: 'D MMMM YYYY',
9089            LLL: 'D MMMM YYYY HH:mm',
9090            LLLL: 'dddd, D MMMM YYYY HH:mm'
9091        },
9092        calendar: {
9093            sameDay: '[ថ្ងៃនៈ ម៉ោង] LT',
9094            nextDay: '[ស្អែក ម៉ោង] LT',
9095            nextWeek: 'dddd [ម៉ោង] LT',
9096            lastDay: '[ម្សិលមិញ ម៉ោង] LT',
9097            lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT',
9098            sameElse: 'L'
9099        },
9100        relativeTime: {
9101            future: '%sទៀត',
9102            past: '%sមុន',
9103            s: 'ប៉ុន្មានវិនាទី',
9104            m: 'មួយនាទី',
9105            mm: '%d នាទី',
9106            h: 'មួយម៉ោង',
9107            hh: '%d ម៉ោង',
9108            d: 'មួយថ្ងៃ',
9109            dd: '%d ថ្ងៃ',
9110            M: 'មួយខែ',
9111            MM: '%d ខែ',
9112            y: 'មួយឆ្នាំ',
9113            yy: '%d ឆ្នាំ'
9114        },
9115        week: {
9116            dow: 1, // Monday is the first day of the week.
9117            doy: 4 // The week that contains Jan 4th is the first week of the year.
9118        }
9119    });
9120
9121    //! moment.js locale configuration
9122    //! locale : korean (ko)
9123    //!
9124    //! authors
9125    //!
9126    //! - Kyungwook, Park : https://github.com/kyungw00k
9127    //! - Jeeeyul Lee <[email protected]>
9128
9129    var ko = _moment__default.defineLocale('ko', {
9130        months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),
9131        monthsShort : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),
9132        weekdays : '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'),
9133        weekdaysShort : '일_월_화_수_목_금_토'.split('_'),
9134        weekdaysMin : '일_월_화_수_목_금_토'.split('_'),
9135        longDateFormat : {
9136            LT : 'A h시 m분',
9137            LTS : 'A h시 m분 s초',
9138            L : 'YYYY.MM.DD',
9139            LL : 'YYYY년 MMMM D일',
9140            LLL : 'YYYY년 MMMM D일 A h시 m분',
9141            LLLL : 'YYYY년 MMMM D일 dddd A h시 m분'
9142        },
9143        calendar : {
9144            sameDay : '오늘 LT',
9145            nextDay : '내일 LT',
9146            nextWeek : 'dddd LT',
9147            lastDay : '어제 LT',
9148            lastWeek : '지난주 dddd LT',
9149            sameElse : 'L'
9150        },
9151        relativeTime : {
9152            future : '%s 후',
9153            past : '%s 전',
9154            s : '몇초',
9155            ss : '%d초',
9156            m : '일분',
9157            mm : '%d분',
9158            h : '한시간',
9159            hh : '%d시간',
9160            d : '하루',
9161            dd : '%d일',
9162            M : '한달',
9163            MM : '%d달',
9164            y : '일년',
9165            yy : '%d년'
9166        },
9167        ordinalParse : /\d{1,2}일/,
9168        ordinal : '%d일',
9169        meridiemParse : /오전|오후/,
9170        isPM : function (token) {
9171            return token === '오후';
9172        },
9173        meridiem : function (hour, minute, isUpper) {
9174            return hour < 12 ? '오전' : '오후';
9175        }
9176    });
9177
9178    //! moment.js locale configuration
9179    //! locale : Luxembourgish (lb)
9180    //! author : mweimerskirch : https://github.com/mweimerskirch, David Raison : https://github.com/kwisatz
9181
9182    function lb__processRelativeTime(number, withoutSuffix, key, isFuture) {
9183        var format = {
9184            'm': ['eng Minutt', 'enger Minutt'],
9185            'h': ['eng Stonn', 'enger Stonn'],
9186            'd': ['een Dag', 'engem Dag'],
9187            'M': ['ee Mount', 'engem Mount'],
9188            'y': ['ee Joer', 'engem Joer']
9189        };
9190        return withoutSuffix ? format[key][0] : format[key][1];
9191    }
9192    function processFutureTime(string) {
9193        var number = string.substr(0, string.indexOf(' '));
9194        if (eifelerRegelAppliesToNumber(number)) {
9195            return 'a ' + string;
9196        }
9197        return 'an ' + string;
9198    }
9199    function processPastTime(string) {
9200        var number = string.substr(0, string.indexOf(' '));
9201        if (eifelerRegelAppliesToNumber(number)) {
9202            return 'viru ' + string;
9203        }
9204        return 'virun ' + string;
9205    }
9206    /**
9207     * Returns true if the word before the given number loses the '-n' ending.
9208     * e.g. 'an 10 Deeg' but 'a 5 Deeg'
9209     *
9210     * @param number {integer}
9211     * @returns {boolean}
9212     */
9213    function eifelerRegelAppliesToNumber(number) {
9214        number = parseInt(number, 10);
9215        if (isNaN(number)) {
9216            return false;
9217        }
9218        if (number < 0) {
9219            // Negative Number --> always true
9220            return true;
9221        } else if (number < 10) {
9222            // Only 1 digit
9223            if (4 <= number && number <= 7) {
9224                return true;
9225            }
9226            return false;
9227        } else if (number < 100) {
9228            // 2 digits
9229            var lastDigit = number % 10, firstDigit = number / 10;
9230            if (lastDigit === 0) {
9231                return eifelerRegelAppliesToNumber(firstDigit);
9232            }
9233            return eifelerRegelAppliesToNumber(lastDigit);
9234        } else if (number < 10000) {
9235            // 3 or 4 digits --> recursively check first digit
9236            while (number >= 10) {
9237                number = number / 10;
9238            }
9239            return eifelerRegelAppliesToNumber(number);
9240        } else {
9241            // Anything larger than 4 digits: recursively check first n-3 digits
9242            number = number / 1000;
9243            return eifelerRegelAppliesToNumber(number);
9244        }
9245    }
9246
9247    var lb = _moment__default.defineLocale('lb', {
9248        months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),
9249        monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),
9250        weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split('_'),
9251        weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'),
9252        weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'),
9253        longDateFormat: {
9254            LT: 'H:mm [Auer]',
9255            LTS: 'H:mm:ss [Auer]',
9256            L: 'DD.MM.YYYY',
9257            LL: 'D. MMMM YYYY',
9258            LLL: 'D. MMMM YYYY H:mm [Auer]',
9259            LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]'
9260        },
9261        calendar: {
9262            sameDay: '[Haut um] LT',
9263            sameElse: 'L',
9264            nextDay: '[Muer um] LT',
9265            nextWeek: 'dddd [um] LT',
9266            lastDay: '[Gëschter um] LT',
9267            lastWeek: function () {
9268                // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday) due to phonological rule
9269                switch (this.day()) {
9270                    case 2:
9271                    case 4:
9272                        return '[Leschten] dddd [um] LT';
9273                    default:
9274                        return '[Leschte] dddd [um] LT';
9275                }
9276            }
9277        },
9278        relativeTime : {
9279            future : processFutureTime,
9280            past : processPastTime,
9281            s : 'e puer Sekonnen',
9282            m : lb__processRelativeTime,
9283            mm : '%d Minutten',
9284            h : lb__processRelativeTime,
9285            hh : '%d Stonnen',
9286            d : lb__processRelativeTime,
9287            dd : '%d Deeg',
9288            M : lb__processRelativeTime,
9289            MM : '%d Méint',
9290            y : lb__processRelativeTime,
9291            yy : '%d Joer'
9292        },
9293        ordinalParse: /\d{1,2}\./,
9294        ordinal: '%d.',
9295        week: {
9296            dow: 1, // Monday is the first day of the week.
9297            doy: 4  // The week that contains Jan 4th is the first week of the year.
9298        }
9299    });
9300
9301    //! moment.js locale configuration
9302    //! locale : Lithuanian (lt)
9303    //! author : Mindaugas Mozūras : https://github.com/mmozuras
9304
9305    var lt__units = {
9306            'm' : 'minutė_minutės_minutę',
9307            'mm': 'minutės_minučių_minutes',
9308            'h' : 'valanda_valandos_valandą',
9309            'hh': 'valandos_valandų_valandas',
9310            'd' : 'diena_dienos_dieną',
9311            'dd': 'dienos_dienų_dienas',
9312            'M' : 'mėnuo_mėnesio_mėnesį',
9313            'MM': 'mėnesiai_mėnesių_mėnesius',
9314            'y' : 'metai_metų_metus',
9315            'yy': 'metai_metų_metus'
9316        },
9317        weekDays = 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split('_');
9318    function translateSeconds(number, withoutSuffix, key, isFuture) {
9319        if (withoutSuffix) {
9320            return 'kelios sekundės';
9321        } else {
9322            return isFuture ? 'kelių sekundžių' : 'kelias sekundes';
9323        }
9324    }
9325    function lt__monthsCaseReplace(m, format) {
9326        var months = {
9327                'nominative': 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split('_'),
9328                'accusative': 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_')
9329            },
9330            nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ?
9331                'accusative' :
9332                'nominative';
9333        return months[nounCase][m.month()];
9334    }
9335    function translateSingular(number, withoutSuffix, key, isFuture) {
9336        return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]);
9337    }
9338    function special(number) {
9339        return number % 10 === 0 || (number > 10 && number < 20);
9340    }
9341    function forms(key) {
9342        return lt__units[key].split('_');
9343    }
9344    function lt__translate(number, withoutSuffix, key, isFuture) {
9345        var result = number + ' ';
9346        if (number === 1) {
9347            return result + translateSingular(number, withoutSuffix, key[0], isFuture);
9348        } else if (withoutSuffix) {
9349            return result + (special(number) ? forms(key)[1] : forms(key)[0]);
9350        } else {
9351            if (isFuture) {
9352                return result + forms(key)[1];
9353            } else {
9354                return result + (special(number) ? forms(key)[1] : forms(key)[2]);
9355            }
9356        }
9357    }
9358    function relativeWeekDay(moment, format) {
9359        var nominative = format.indexOf('dddd HH:mm') === -1,
9360            weekDay = weekDays[moment.day()];
9361        return nominative ? weekDay : weekDay.substring(0, weekDay.length - 2) + 'į';
9362    }
9363
9364    var lt = _moment__default.defineLocale('lt', {
9365        months : lt__monthsCaseReplace,
9366        monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'),
9367        weekdays : relativeWeekDay,
9368        weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'),
9369        weekdaysMin : 'S_P_A_T_K_Pn_Å '.split('_'),
9370        longDateFormat : {
9371            LT : 'HH:mm',
9372            LTS : 'HH:mm:ss',
9373            L : 'YYYY-MM-DD',
9374            LL : 'YYYY [m.] MMMM D [d.]',
9375            LLL : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',
9376            LLLL : 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]',
9377            l : 'YYYY-MM-DD',
9378            ll : 'YYYY [m.] MMMM D [d.]',
9379            lll : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',
9380            llll : 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]'
9381        },
9382        calendar : {
9383            sameDay : '[Å iandien] LT',
9384            nextDay : '[Rytoj] LT',
9385            nextWeek : 'dddd LT',
9386            lastDay : '[Vakar] LT',
9387            lastWeek : '[Praėjusį] dddd LT',
9388            sameElse : 'L'
9389        },
9390        relativeTime : {
9391            future : 'po %s',
9392            past : 'prieš %s',
9393            s : translateSeconds,
9394            m : translateSingular,
9395            mm : lt__translate,
9396            h : translateSingular,
9397            hh : lt__translate,
9398            d : translateSingular,
9399            dd : lt__translate,
9400            M : translateSingular,
9401            MM : lt__translate,
9402            y : translateSingular,
9403            yy : lt__translate
9404        },
9405        ordinalParse: /\d{1,2}-oji/,
9406        ordinal : function (number) {
9407            return number + '-oji';
9408        },
9409        week : {
9410            dow : 1, // Monday is the first day of the week.
9411            doy : 4  // The week that contains Jan 4th is the first week of the year.
9412        }
9413    });
9414
9415    //! moment.js locale configuration
9416    //! locale : latvian (lv)
9417    //! author : Kristaps Karlsons : https://github.com/skakri
9418    //! author : Jānis Elmeris : https://github.com/JanisE
9419
9420    var lv__units = {
9421        'm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),
9422        'mm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),
9423        'h': 'stundas_stundām_stunda_stundas'.split('_'),
9424        'hh': 'stundas_stundām_stunda_stundas'.split('_'),
9425        'd': 'dienas_dienām_diena_dienas'.split('_'),
9426        'dd': 'dienas_dienām_diena_dienas'.split('_'),
9427        'M': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),
9428        'MM': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),
9429        'y': 'gada_gadiem_gads_gadi'.split('_'),
9430        'yy': 'gada_gadiem_gads_gadi'.split('_')
9431    };
9432    /**
9433     * @param withoutSuffix boolean true = a length of time; false = before/after a period of time.
9434     */
9435    function lv__format(forms, number, withoutSuffix) {
9436        if (withoutSuffix) {
9437            // E.g. "21 minūte", "3 minūtes".
9438            return number % 10 === 1 && number !== 11 ? forms[2] : forms[3];
9439        } else {
9440            // E.g. "21 minūtes" as in "pēc 21 minūtes".
9441            // E.g. "3 minūtēm" as in "pēc 3 minūtēm".
9442            return number % 10 === 1 && number !== 11 ? forms[0] : forms[1];
9443        }
9444    }
9445    function lv__relativeTimeWithPlural(number, withoutSuffix, key) {
9446        return number + ' ' + lv__format(lv__units[key], number, withoutSuffix);
9447    }
9448    function relativeTimeWithSingular(number, withoutSuffix, key) {
9449        return lv__format(lv__units[key], number, withoutSuffix);
9450    }
9451    function relativeSeconds(number, withoutSuffix) {
9452        return withoutSuffix ? 'dažas sekundes' : 'dažām sekundēm';
9453    }
9454
9455    var lv = _moment__default.defineLocale('lv', {
9456        months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'),
9457        monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'),
9458        weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'),
9459        weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'),
9460        weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'),
9461        longDateFormat : {
9462            LT : 'HH:mm',
9463            LTS : 'HH:mm:ss',
9464            L : 'DD.MM.YYYY.',
9465            LL : 'YYYY. [gada] D. MMMM',
9466            LLL : 'YYYY. [gada] D. MMMM, HH:mm',
9467            LLLL : 'YYYY. [gada] D. MMMM, dddd, HH:mm'
9468        },
9469        calendar : {
9470            sameDay : '[Å odien pulksten] LT',
9471            nextDay : '[Rīt pulksten] LT',
9472            nextWeek : 'dddd [pulksten] LT',
9473            lastDay : '[Vakar pulksten] LT',
9474            lastWeek : '[Pagājušā] dddd [pulksten] LT',
9475            sameElse : 'L'
9476        },
9477        relativeTime : {
9478            future : 'pēc %s',
9479            past : 'pirms %s',
9480            s : relativeSeconds,
9481            m : relativeTimeWithSingular,
9482            mm : lv__relativeTimeWithPlural,
9483            h : relativeTimeWithSingular,
9484            hh : lv__relativeTimeWithPlural,
9485            d : relativeTimeWithSingular,
9486            dd : lv__relativeTimeWithPlural,
9487            M : relativeTimeWithSingular,
9488            MM : lv__relativeTimeWithPlural,
9489            y : relativeTimeWithSingular,
9490            yy : lv__relativeTimeWithPlural
9491        },
9492        ordinalParse: /\d{1,2}\./,
9493        ordinal : '%d.',
9494        week : {
9495            dow : 1, // Monday is the first day of the week.
9496            doy : 4  // The week that contains Jan 4th is the first week of the year.
9497        }
9498    });
9499
9500    //! moment.js locale configuration
9501    //! locale : Montenegrin (me)
9502    //! author : Miodrag Nikač <[email protected]> : https://github.com/miodragnikac
9503
9504    var me__translator = {
9505        words: { //Different grammatical cases
9506            m: ['jedan minut', 'jednog minuta'],
9507            mm: ['minut', 'minuta', 'minuta'],
9508            h: ['jedan sat', 'jednog sata'],
9509            hh: ['sat', 'sata', 'sati'],
9510            dd: ['dan', 'dana', 'dana'],
9511            MM: ['mjesec', 'mjeseca', 'mjeseci'],
9512            yy: ['godina', 'godine', 'godina']
9513        },
9514        correctGrammaticalCase: function (number, wordKey) {
9515            return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);
9516        },
9517        translate: function (number, withoutSuffix, key) {
9518            var wordKey = me__translator.words[key];
9519            if (key.length === 1) {
9520                return withoutSuffix ? wordKey[0] : wordKey[1];
9521            } else {
9522                return number + ' ' + me__translator.correctGrammaticalCase(number, wordKey);
9523            }
9524        }
9525    };
9526
9527    var me = _moment__default.defineLocale('me', {
9528        months: ['januar', 'februar', 'mart', 'april', 'maj', 'jun', 'jul', 'avgust', 'septembar', 'oktobar', 'novembar', 'decembar'],
9529        monthsShort: ['jan.', 'feb.', 'mar.', 'apr.', 'maj', 'jun', 'jul', 'avg.', 'sep.', 'okt.', 'nov.', 'dec.'],
9530        weekdays: ['nedjelja', 'ponedjeljak', 'utorak', 'srijeda', 'četvrtak', 'petak', 'subota'],
9531        weekdaysShort: ['ned.', 'pon.', 'uto.', 'sri.', 'čet.', 'pet.', 'sub.'],
9532        weekdaysMin: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'],
9533        longDateFormat: {
9534            LT: 'H:mm',
9535            LTS : 'H:mm:ss',
9536            L: 'DD. MM. YYYY',
9537            LL: 'D. MMMM YYYY',
9538            LLL: 'D. MMMM YYYY H:mm',
9539            LLLL: 'dddd, D. MMMM YYYY H:mm'
9540        },
9541        calendar: {
9542            sameDay: '[danas u] LT',
9543            nextDay: '[sjutra u] LT',
9544
9545            nextWeek: function () {
9546                switch (this.day()) {
9547                    case 0:
9548                        return '[u] [nedjelju] [u] LT';
9549                    case 3:
9550                        return '[u] [srijedu] [u] LT';
9551                    case 6:
9552                        return '[u] [subotu] [u] LT';
9553                    case 1:
9554                    case 2:
9555                    case 4:
9556                    case 5:
9557                        return '[u] dddd [u] LT';
9558                }
9559            },
9560            lastDay  : '[juče u] LT',
9561            lastWeek : function () {
9562                var lastWeekDays = [
9563                    '[prošle] [nedjelje] [u] LT',
9564                    '[prošlog] [ponedjeljka] [u] LT',
9565                    '[prošlog] [utorka] [u] LT',
9566                    '[prošle] [srijede] [u] LT',
9567                    '[prošlog] [četvrtka] [u] LT',
9568                    '[prošlog] [petka] [u] LT',
9569                    '[prošle] [subote] [u] LT'
9570                ];
9571                return lastWeekDays[this.day()];
9572            },
9573            sameElse : 'L'
9574        },
9575        relativeTime : {
9576            future : 'za %s',
9577            past   : 'prije %s',
9578            s      : 'nekoliko sekundi',
9579            m      : me__translator.translate,
9580            mm     : me__translator.translate,
9581            h      : me__translator.translate,
9582            hh     : me__translator.translate,
9583            d      : 'dan',
9584            dd     : me__translator.translate,
9585            M      : 'mjesec',
9586            MM     : me__translator.translate,
9587            y      : 'godinu',
9588            yy     : me__translator.translate
9589        },
9590        ordinalParse: /\d{1,2}\./,
9591        ordinal : '%d.',
vendor: 5,269 bytes, lines 9592-9705
9592        week : {
9593            dow : 1, // Monday is the first day of the week.
9594            doy : 7  // The week that contains Jan 1st is the first week of the year.
9595        }
9596    });
9597
9598    //! moment.js locale configuration
9599    //! locale : macedonian (mk)
9600    //! author : Borislav Mickov : https://github.com/B0k0
9601
9602    var mk = _moment__default.defineLocale('mk', {
9603        months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'),
9604        monthsShort : 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'),
9605        weekdays : 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split('_'),
9606        weekdaysShort : 'нед_пон_вто_сре_чет_пет_саб'.split('_'),
9607        weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'),
9608        longDateFormat : {
9609            LT : 'H:mm',
9610            LTS : 'H:mm:ss',
9611            L : 'D.MM.YYYY',
9612            LL : 'D MMMM YYYY',
9613            LLL : 'D MMMM YYYY H:mm',
9614            LLLL : 'dddd, D MMMM YYYY H:mm'
9615        },
9616        calendar : {
9617            sameDay : '[Денес во] LT',
9618            nextDay : '[Утре во] LT',
9619            nextWeek : 'dddd [во] LT',
9620            lastDay : '[Вчера во] LT',
9621            lastWeek : function () {
9622                switch (this.day()) {
9623                    case 0:
9624                    case 3:
9625                    case 6:
9626                        return '[Во изминатата] dddd [во] LT';
9627                    case 1:
9628                    case 2:
9629                    case 4:
9630                    case 5:
9631                        return '[Во изминатиот] dddd [во] LT';
9632                }
9633            },
9634            sameElse : 'L'
9635        },
9636        relativeTime : {
9637            future : 'после %s',
9638            past : 'пред %s',
9639            s : 'неколку секунди',
9640            m : 'минута',
9641            mm : '%d минути',
9642            h : 'час',
9643            hh : '%d часа',
9644            d : 'ден',
9645            dd : '%d дена',
9646            M : 'месец',
9647            MM : '%d месеци',
9648            y : 'година',
9649            yy : '%d години'
9650        },
9651        ordinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/,
9652        ordinal : function (number) {
9653            var lastDigit = number % 10,
9654                last2Digits = number % 100;
9655            if (number === 0) {
9656                return number + '-ев';
9657            } else if (last2Digits === 0) {
9658                return number + '-ен';
9659            } else if (last2Digits > 10 && last2Digits < 20) {
9660                return number + '-ти';
9661            } else if (lastDigit === 1) {
9662                return number + '-ви';
9663            } else if (lastDigit === 2) {
9664                return number + '-ри';
9665            } else if (lastDigit === 7 || lastDigit === 8) {
9666                return number + '-ми';
9667            } else {
9668                return number + '-ти';
9669            }
9670        },
9671        week : {
9672            dow : 1, // Monday is the first day of the week.
9673            doy : 7  // The week that contains Jan 1st is the first week of the year.
9674        }
9675    });
9676
9677    //! moment.js locale configuration
9678    //! locale : malayalam (ml)
9679    //! author : Floyd Pink : https://github.com/floydpink
9680
9681    var ml = _moment__default.defineLocale('ml', {
9682        months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'),
9683        monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split('_'),
9684        weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split('_'),
9685        weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'),
9686        weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'),
9687        longDateFormat : {
9688            LT : 'A h:mm -നു',
9689            LTS : 'A h:mm:ss -നു',
9690            L : 'DD/MM/YYYY',
9691            LL : 'D MMMM YYYY',
9692            LLL : 'D MMMM YYYY, A h:mm -നു',
9693            LLLL : 'dddd, D MMMM YYYY, A h:mm -നു'
9694        },
9695        calendar : {
9696            sameDay : '[ഇന്ന്] LT',
9697            nextDay : '[നാളെ] LT',
9698            nextWeek : 'dddd, LT',
9699            lastDay : '[ഇന്നലെ] LT',
9700            lastWeek : '[കഴിഞ്ഞ] dddd, LT',
9701            sameElse : 'L'
9702        },
9703        relativeTime : {
9704            future : '%s കഴിഞ്ഞ്',
9705            past : '%s മുൻപ്',
9706            s : 'അൽപ നിമിഷങ്ങൾ',
9707            m : 'ഒരു മിനിറ്റ്',
9708            mm : '%d മിനിറ്റ്',
9709            h : 'ഒരു മണിക്കൂർ',
9710            hh : '%d മണിക്കൂർ',
9711            d : 'ഒരു ദിവസം',
9712            dd : '%d ദിവസം',
9713            M : 'ഒരു മാസം',
9714            MM : '%d മാസം',
9715            y : 'ഒരു വർഷം',
9716            yy : '%d വർഷം'
9717        },
9718        meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i,
9719        isPM : function (input) {
9720            return /^(ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി)$/.test(input);
9721        },
9722        meridiem : function (hour, minute, isLower) {
9723            if (hour < 4) {
9724                return 'രാത്രി';
9725            } else if (hour < 12) {
9726                return 'രാവിലെ';
9727            } else if (hour < 17) {
9728                return 'ഉച്ച കഴിഞ്ഞ്';
9729            } else if (hour < 20) {
9730                return 'വൈകുന്നേരം';
9731            } else {
9732                return 'രാത്രി';
9733            }
9734        }
9735    });
9736
9737    //! moment.js locale configuration
9738    //! locale : Marathi (mr)
9739    //! author : Harshad Kale : https://github.com/kalehv
9740
9741    var mr__symbolMap = {
9742            '1': '१',
9743            '2': '२',
9744            '3': '३',
9745            '4': '४',
9746            '5': '५',
9747            '6': '६',
9748            '7': '७',
9749            '8': '८',
9750            '9': '९',
9751            '0': '०'
9752        },
9753        mr__numberMap = {
9754            '१': '1',
9755            '२': '2',
9756            '३': '3',
9757            '४': '4',
9758            '५': '5',
9759            '६': '6',
9760            '७': '7',
9761            '८': '8',
9762            '९': '9',
9763            '०': '0'
9764        };
9765
9766    var mr = _moment__default.defineLocale('mr', {
9767        months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'),
9768        monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'),
9769        weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),
9770        weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'),
9771        weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),
9772        longDateFormat : {
9773            LT : 'A h:mm वाजता',
9774            LTS : 'A h:mm:ss वाजता',
9775            L : 'DD/MM/YYYY',
9776            LL : 'D MMMM YYYY',
9777            LLL : 'D MMMM YYYY, A h:mm वाजता',
9778            LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता'
9779        },
9780        calendar : {
9781            sameDay : '[आज] LT',
9782            nextDay : '[उद्या] LT',
9783            nextWeek : 'dddd, LT',
9784            lastDay : '[काल] LT',
9785            lastWeek: '[मागील] dddd, LT',
9786            sameElse : 'L'
9787        },
9788        relativeTime : {
9789            future : '%s नंतर',
9790            past : '%s पूर्वी',
9791            s : 'सेकंद',
9792            m: 'एक मिनिट',
9793            mm: '%d मिनिटे',
9794            h : 'एक तास',
9795            hh : '%d तास',
9796            d : 'एक दिवस',
9797            dd : '%d दिवस',
9798            M : 'एक महिना',
9799            MM : '%d महिने',
9800            y : 'एक वर्ष',
9801            yy : '%d वर्षे'
9802        },
9803        preparse: function (string) {
9804            return string.replace(/[१२३४५६७८९०]/g, function (match) {
9805                return mr__numberMap[match];
9806            });
9807        },
9808        postformat: function (string) {
9809            return string.replace(/\d/g, function (match) {
9810                return mr__symbolMap[match];
9811            });
9812        },
9813        meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/,
9814        meridiemHour : function (hour, meridiem) {
9815            if (hour === 12) {
9816                hour = 0;
9817            }
9818            if (meridiem === 'रात्री') {
9819                return hour < 4 ? hour : hour + 12;
9820            } else if (meridiem === 'सकाळी') {
9821                return hour;
9822            } else if (meridiem === 'दुपारी') {
9823                return hour >= 10 ? hour : hour + 12;
9824            } else if (meridiem === 'सायंकाळी') {
9825                return hour + 12;
9826            }
9827        },
9828        meridiem: function (hour, minute, isLower) {
9829            if (hour < 4) {
9830                return 'रात्री';
9831            } else if (hour < 10) {
9832                return 'सकाळी';
9833            } else if (hour < 17) {
9834                return 'दुपारी';
9835            } else if (hour < 20) {
9836                return 'सायंकाळी';
9837            } else {
9838                return 'रात्री';
9839            }
9840        },
9841        week : {
9842            dow : 0, // Sunday is the first day of the week.
9843            doy : 6  // The week that contains Jan 1st is the first week of the year.
9844        }
9845    });
9846
9847    //! moment.js locale configuration
9848    //! locale : Bahasa Malaysia (ms-MY)
9849    //! author : Weldan Jamili : https://github.com/weldan
9850
9851    var ms_my = _moment__default.defineLocale('ms-my', {
9852        months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),
9853        monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),
9854        weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),
9855        weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),
9856        weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),
9857        longDateFormat : {
9858            LT : 'HH.mm',
9859            LTS : 'HH.mm.ss',
9860            L : 'DD/MM/YYYY',
9861            LL : 'D MMMM YYYY',
9862            LLL : 'D MMMM YYYY [pukul] HH.mm',
9863            LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
9864        },
9865        meridiemParse: /pagi|tengahari|petang|malam/,
9866        meridiemHour: function (hour, meridiem) {
9867            if (hour === 12) {
9868                hour = 0;
9869            }
9870            if (meridiem === 'pagi') {
9871                return hour;
9872            } else if (meridiem === 'tengahari') {
9873                return hour >= 11 ? hour : hour + 12;
9874            } else if (meridiem === 'petang' || meridiem === 'malam') {
9875                return hour + 12;
9876            }
9877        },
9878        meridiem : function (hours, minutes, isLower) {
9879            if (hours < 11) {
9880                return 'pagi';
9881            } else if (hours < 15) {
9882                return 'tengahari';
9883            } else if (hours < 19) {
9884                return 'petang';
9885            } else {
9886                return 'malam';
9887            }
9888        },
9889        calendar : {
9890            sameDay : '[Hari ini pukul] LT',
9891            nextDay : '[Esok pukul] LT',
9892            nextWeek : 'dddd [pukul] LT',
9893            lastDay : '[Kelmarin pukul] LT',
9894            lastWeek : 'dddd [lepas pukul] LT',
9895            sameElse : 'L'
9896        },
9897        relativeTime : {
9898            future : 'dalam %s',
9899            past : '%s yang lepas',
9900            s : 'beberapa saat',
9901            m : 'seminit',
9902            mm : '%d minit',
9903            h : 'sejam',
9904            hh : '%d jam',
9905            d : 'sehari',
9906            dd : '%d hari',
9907            M : 'sebulan',
9908            MM : '%d bulan',
9909            y : 'setahun',
9910            yy : '%d tahun'
9911        },
9912        week : {
9913            dow : 1, // Monday is the first day of the week.
9914            doy : 7  // The week that contains Jan 1st is the first week of the year.
9915        }
9916    });
9917
9918    //! moment.js locale configuration
9919    //! locale : Bahasa Malaysia (ms-MY)
9920    //! author : Weldan Jamili : https://github.com/weldan
9921
9922    var locale_ms = _moment__default.defineLocale('ms', {
9923        months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),
9924        monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),
9925        weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),
9926        weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),
9927        weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),
9928        longDateFormat : {
9929            LT : 'HH.mm',
9930            LTS : 'HH.mm.ss',
9931            L : 'DD/MM/YYYY',
9932            LL : 'D MMMM YYYY',
9933            LLL : 'D MMMM YYYY [pukul] HH.mm',
9934            LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
9935        },
9936        meridiemParse: /pagi|tengahari|petang|malam/,
9937        meridiemHour: function (hour, meridiem) {
9938            if (hour === 12) {
9939                hour = 0;
9940            }
9941            if (meridiem === 'pagi') {
9942                return hour;
9943            } else if (meridiem === 'tengahari') {
9944                return hour >= 11 ? hour : hour + 12;
9945            } else if (meridiem === 'petang' || meridiem === 'malam') {
9946                return hour + 12;
9947            }
9948        },
9949        meridiem : function (hours, minutes, isLower) {
9950            if (hours < 11) {
9951                return 'pagi';
9952            } else if (hours < 15) {
9953                return 'tengahari';
9954            } else if (hours < 19) {
9955                return 'petang';
9956            } else {
9957                return 'malam';
9958            }
9959        },
9960        calendar : {
9961            sameDay : '[Hari ini pukul] LT',
9962            nextDay : '[Esok pukul] LT',
9963            nextWeek : 'dddd [pukul] LT',
9964            lastDay : '[Kelmarin pukul] LT',
9965            lastWeek : 'dddd [lepas pukul] LT',
9966            sameElse : 'L'
9967        },
9968        relativeTime : {
9969            future : 'dalam %s',
9970            past : '%s yang lepas',
9971            s : 'beberapa saat',
9972            m : 'seminit',
9973            mm : '%d minit',
9974            h : 'sejam',
9975            hh : '%d jam',
9976            d : 'sehari',
9977            dd : '%d hari',
9978            M : 'sebulan',
9979            MM : '%d bulan',
9980            y : 'setahun',
9981            yy : '%d tahun'
9982        },
9983        week : {
9984            dow : 1, // Monday is the first day of the week.
9985            doy : 7  // The week that contains Jan 1st is the first week of the year.
9986        }
9987    });
9988
9989    //! moment.js locale configuration
9990    //! locale : Burmese (my)
9991    //! author : Squar team, mysquar.com
9992
9993    var my__symbolMap = {
9994        '1': '၁',
9995        '2': '၂',
9996        '3': '၃',
9997        '4': '၄',
9998        '5': '၅',
9999        '6': '၆',
10000        '7': '၇',
10001        '8': '၈',
10002        '9': '၉',
10003        '0': '၀'
10004    }, my__numberMap = {
10005        '၁': '1',
10006        '၂': '2',
10007        '၃': '3',
10008        '၄': '4',
10009        '၅': '5',
10010        '၆': '6',
10011        '၇': '7',
10012        '၈': '8',
10013        '၉': '9',
10014        '၀': '0'
10015    };
10016
10017    var my = _moment__default.defineLocale('my', {
10018        months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split('_'),
10019        monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'),
10020        weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split('_'),
10021        weekdaysShort: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),
10022        weekdaysMin: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),
10023
10024        longDateFormat: {
10025            LT: 'HH:mm',
10026            LTS: 'HH:mm:ss',
10027            L: 'DD/MM/YYYY',
10028            LL: 'D MMMM YYYY',
10029            LLL: 'D MMMM YYYY HH:mm',
10030            LLLL: 'dddd D MMMM YYYY HH:mm'
10031        },
10032        calendar: {
10033            sameDay: '[ယနေ.] LT [မှာ]',
10034            nextDay: '[မနက်ဖြန်] LT [မှာ]',
10035            nextWeek: 'dddd LT [မှာ]',
10036            lastDay: '[မနေ.က] LT [မှာ]',
10037            lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]',
10038            sameElse: 'L'
10039        },
10040        relativeTime: {
10041            future: 'လာမည့် %s မှာ',
10042            past: 'လွန်ခဲ့သော %s က',
10043            s: 'စက္ကန်.အနည်းငယ်',
10044            m: 'တစ်မိနစ်',
10045            mm: '%d မိနစ်',
10046            h: 'တစ်နာရီ',
10047            hh: '%d နာရီ',
10048            d: 'တစ်ရက်',
10049            dd: '%d ရက်',
10050            M: 'တစ်လ',
10051            MM: '%d လ',
10052            y: 'တစ်နှစ်',
10053            yy: '%d နှစ်'
10054        },
10055        preparse: function (string) {
10056            return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) {
10057                return my__numberMap[match];
10058            });
10059        },
10060        postformat: function (string) {
10061            return string.replace(/\d/g, function (match) {
10062                return my__symbolMap[match];
10063            });
10064        },
10065        week: {
10066            dow: 1, // Monday is the first day of the week.
10067            doy: 4 // The week that contains Jan 1st is the first week of the year.
10068        }
10069    });
10070
10071    //! moment.js locale configuration
10072    //! locale : norwegian bokmål (nb)
10073    //! authors : Espen Hovlandsdal : https://github.com/rexxars
10074    //!           Sigurd Gartmann : https://github.com/sigurdga
10075
10076    var nb = _moment__default.defineLocale('nb', {
10077        months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),
10078        monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),
10079        weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),
10080        weekdaysShort : 'søn_man_tirs_ons_tors_fre_lør'.split('_'),
10081        weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),
10082        longDateFormat : {
10083            LT : 'H.mm',
10084            LTS : 'H.mm.ss',
10085            L : 'DD.MM.YYYY',
10086            LL : 'D. MMMM YYYY',
10087            LLL : 'D. MMMM YYYY [kl.] H.mm',
10088            LLLL : 'dddd D. MMMM YYYY [kl.] H.mm'
10089        },
10090        calendar : {
10091            sameDay: '[i dag kl.] LT',
10092            nextDay: '[i morgen kl.] LT',
10093            nextWeek: 'dddd [kl.] LT',
10094            lastDay: '[i går kl.] LT',
10095            lastWeek: '[forrige] dddd [kl.] LT',
10096            sameElse: 'L'
10097        },
10098        relativeTime : {
10099            future : 'om %s',
10100            past : 'for %s siden',
10101            s : 'noen sekunder',
10102            m : 'ett minutt',
10103            mm : '%d minutter',
10104            h : 'en time',
10105            hh : '%d timer',
10106            d : 'en dag',
10107            dd : '%d dager',
10108            M : 'en måned',
10109            MM : '%d måneder',
10110            y : 'ett år',
10111            yy : '%d år'
10112        },
10113        ordinalParse: /\d{1,2}\./,
10114        ordinal : '%d.',
10115        week : {
10116            dow : 1, // Monday is the first day of the week.
10117            doy : 4  // The week that contains Jan 4th is the first week of the year.
10118        }
10119    });
10120
10121    //! moment.js locale configuration
10122    //! locale : nepali/nepalese
10123    //! author : suvash : https://github.com/suvash
10124
10125    var ne__symbolMap = {
10126            '1': '१',
10127            '2': '२',
10128            '3': '३',
10129            '4': '४',
10130            '5': '५',
10131            '6': '६',
10132            '7': '७',
10133            '8': '८',
10134            '9': '९',
10135            '0': '०'
10136        },
10137        ne__numberMap = {
10138            '१': '1',
10139            '२': '2',
10140            '३': '3',
10141            '४': '4',
10142            '५': '5',
10143            '६': '6',
10144            '७': '7',
10145            '८': '8',
10146            '९': '9',
10147            '०': '0'
10148        };
10149
10150    var ne = _moment__default.defineLocale('ne', {
10151        months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split('_'),
10152        monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split('_'),
10153        weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split('_'),
10154        weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'),
10155        weekdaysMin : 'आइ._सो._मङ्_बु._बि._शु._श.'.split('_'),
10156        longDateFormat : {
10157            LT : 'Aको h:mm बजे',
10158            LTS : 'Aको h:mm:ss बजे',
10159            L : 'DD/MM/YYYY',
10160            LL : 'D MMMM YYYY',
10161            LLL : 'D MMMM YYYY, Aको h:mm बजे',
10162            LLLL : 'dddd, D MMMM YYYY, Aको h:mm बजे'
10163        },
10164        preparse: function (string) {
10165            return string.replace(/[१२३४५६७८९०]/g, function (match) {
10166                return ne__numberMap[match];
10167            });
10168        },
10169        postformat: function (string) {
10170            return string.replace(/\d/g, function (match) {
10171                return ne__symbolMap[match];
10172            });
10173        },
10174        meridiemParse: /राती|बिहान|दिउँसो|बेलुका|साँझ|राती/,
10175        meridiemHour : function (hour, meridiem) {
10176            if (hour === 12) {
10177                hour = 0;
10178            }
10179            if (meridiem === 'राती') {
10180                return hour < 3 ? hour : hour + 12;
10181            } else if (meridiem === 'बिहान') {
10182                return hour;
10183            } else if (meridiem === 'दिउँसो') {
10184                return hour >= 10 ? hour : hour + 12;
10185            } else if (meridiem === 'बेलुका' || meridiem === 'साँझ') {
10186                return hour + 12;
10187            }
10188        },
10189        meridiem : function (hour, minute, isLower) {
10190            if (hour < 3) {
10191                return 'राती';
10192            } else if (hour < 10) {
10193                return 'बिहान';
10194            } else if (hour < 15) {
10195                return 'दिउँसो';
10196            } else if (hour < 18) {
10197                return 'बेलुका';
10198            } else if (hour < 20) {
10199                return 'साँझ';
10200            } else {
10201                return 'राती';
10202            }
10203        },
10204        calendar : {
10205            sameDay : '[आज] LT',
10206            nextDay : '[भोली] LT',
10207            nextWeek : '[आउँदो] dddd[,] LT',
10208            lastDay : '[हिजो] LT',
10209            lastWeek : '[गएको] dddd[,] LT',
10210            sameElse : 'L'
10211        },
10212        relativeTime : {
10213            future : '%sमा',
10214            past : '%s अगाडी',
10215            s : 'केही समय',
10216            m : 'एक मिनेट',
10217            mm : '%d मिनेट',
10218            h : 'एक घण्टा',
10219            hh : '%d घण्टा',
10220            d : 'एक दिन',
10221            dd : '%d दिन',
10222            M : 'एक महिना',
10223            MM : '%d महिना',
10224            y : 'एक बर्ष',
10225            yy : '%d बर्ष'
10226        },
10227        week : {
10228            dow : 1, // Monday is the first day of the week.
10229            doy : 7  // The week that contains Jan 1st is the first week of the year.
10230        }
10231    });
10232
10233    //! moment.js locale configuration
10234    //! locale : dutch (nl)
10235    //! author : Joris Röling : https://github.com/jjupiter
10236
10237    var nl__monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'),
10238        nl__monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');
10239
10240    var nl = _moment__default.defineLocale('nl', {
10241        months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),
10242        monthsShort : function (m, format) {
10243            if (/-MMM-/.test(format)) {
10244                return nl__monthsShortWithoutDots[m.month()];
10245            } else {
10246                return nl__monthsShortWithDots[m.month()];
10247            }
10248        },
10249        weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),
10250        weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),
10251        weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),
10252        longDateFormat : {
10253            LT : 'HH:mm',
10254            LTS : 'HH:mm:ss',
10255            L : 'DD-MM-YYYY',
10256            LL : 'D MMMM YYYY',
10257            LLL : 'D MMMM YYYY HH:mm',
10258            LLLL : 'dddd D MMMM YYYY HH:mm'
10259        },
10260        calendar : {
10261            sameDay: '[vandaag om] LT',
10262            nextDay: '[morgen om] LT',
10263            nextWeek: 'dddd [om] LT',
10264            lastDay: '[gisteren om] LT',
10265            lastWeek: '[afgelopen] dddd [om] LT',
10266            sameElse: 'L'
10267        },
10268        relativeTime : {
10269            future : 'over %s',
10270            past : '%s geleden',
10271            s : 'een paar seconden',
10272            m : 'één minuut',
10273            mm : '%d minuten',
10274            h : 'één uur',
10275            hh : '%d uur',
10276            d : 'één dag',
10277            dd : '%d dagen',
10278            M : 'één maand',
10279            MM : '%d maanden',
10280            y : 'één jaar',
10281            yy : '%d jaar'
10282        },
10283        ordinalParse: /\d{1,2}(ste|de)/,
10284        ordinal : function (number) {
10285            return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');
10286        },
10287        week : {
10288            dow : 1, // Monday is the first day of the week.
10289            doy : 4  // The week that contains Jan 4th is the first week of the year.
10290        }
10291    });
10292
10293    //! moment.js locale configuration
10294    //! locale : norwegian nynorsk (nn)
10295    //! author : https://github.com/mechuwind
10296
10297    var nn = _moment__default.defineLocale('nn', {
10298        months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),
10299        monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),
10300        weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'),
10301        weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'),
10302        weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'),
10303        longDateFormat : {
10304            LT : 'HH:mm',
10305            LTS : 'HH:mm:ss',
10306            L : 'DD.MM.YYYY',
10307            LL : 'D MMMM YYYY',
10308            LLL : 'D MMMM YYYY HH:mm',
10309            LLLL : 'dddd D MMMM YYYY HH:mm'
10310        },
10311        calendar : {
10312            sameDay: '[I dag klokka] LT',
10313            nextDay: '[I morgon klokka] LT',
10314            nextWeek: 'dddd [klokka] LT',
10315            lastDay: '[I går klokka] LT',
10316            lastWeek: '[Føregåande] dddd [klokka] LT',
10317            sameElse: 'L'
10318        },
10319        relativeTime : {
10320            future : 'om %s',
10321            past : 'for %s sidan',
10322            s : 'nokre sekund',
10323            m : 'eit minutt',
10324            mm : '%d minutt',
10325            h : 'ein time',
10326            hh : '%d timar',
10327            d : 'ein dag',
10328            dd : '%d dagar',
10329            M : 'ein månad',
10330            MM : '%d månader',
10331            y : 'eit år',
10332            yy : '%d år'
10333        },
10334        ordinalParse: /\d{1,2}\./,
10335        ordinal : '%d.',
10336        week : {
10337            dow : 1, // Monday is the first day of the week.
10338            doy : 4  // The week that contains Jan 4th is the first week of the year.
10339        }
10340    });
10341
10342    //! moment.js locale configuration
10343    //! locale : polish (pl)
10344    //! author : Rafal Hirsz : https://github.com/evoL
10345
10346    var monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_'),
10347        monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_');
10348    function pl__plural(n) {
10349        return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1);
10350    }
10351    function pl__translate(number, withoutSuffix, key) {
10352        var result = number + ' ';
10353        switch (key) {
10354            case 'm':
10355                return withoutSuffix ? 'minuta' : 'minutę';
10356            case 'mm':
10357                return result + (pl__plural(number) ? 'minuty' : 'minut');
10358            case 'h':
10359                return withoutSuffix  ? 'godzina'  : 'godzinę';
10360            case 'hh':
10361                return result + (pl__plural(number) ? 'godziny' : 'godzin');
10362            case 'MM':
10363                return result + (pl__plural(number) ? 'miesiące' : 'miesięcy');
10364            case 'yy':
10365                return result + (pl__plural(number) ? 'lata' : 'lat');
10366        }
10367    }
10368
10369    var pl = _moment__default.defineLocale('pl', {
10370        months : function (momentToFormat, format) {
10371            if (format === '') {
10372                // Hack: if format empty we know this is used to generate
10373                // RegExp by moment. Give then back both valid forms of months
10374                // in RegExp ready format.
10375                return '(' + monthsSubjective[momentToFormat.month()] + '|' + monthsNominative[momentToFormat.month()] + ')';
10376            } else if (/D MMMM/.test(format)) {
10377                return monthsSubjective[momentToFormat.month()];
10378            } else {
10379                return monthsNominative[momentToFormat.month()];
10380            }
10381        },
10382        monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'),
10383        weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'),
10384        weekdaysShort : 'nie_pon_wt_śr_czw_pt_sb'.split('_'),
10385        weekdaysMin : 'N_Pn_Wt_Śr_Cz_Pt_So'.split('_'),
10386        longDateFormat : {
10387            LT : 'HH:mm',
10388            LTS : 'HH:mm:ss',
10389            L : 'DD.MM.YYYY',
10390            LL : 'D MMMM YYYY',
10391            LLL : 'D MMMM YYYY HH:mm',
10392            LLLL : 'dddd, D MMMM YYYY HH:mm'
10393        },
10394        calendar : {
10395            sameDay: '[Dziś o] LT',
10396            nextDay: '[Jutro o] LT',
10397            nextWeek: '[W] dddd [o] LT',
10398            lastDay: '[Wczoraj o] LT',
10399            lastWeek: function () {
10400                switch (this.day()) {
10401                    case 0:
10402                        return '[W zeszłą niedzielę o] LT';
10403                    case 3:
10404                        return '[W zeszłą środę o] LT';
10405                    case 6:
10406                        return '[W zeszłą sobotę o] LT';
10407                    default:
10408                        return '[W zeszły] dddd [o] LT';
10409                }
10410            },
10411            sameElse: 'L'
10412        },
10413        relativeTime : {
10414            future : 'za %s',
10415            past : '%s temu',
10416            s : 'kilka sekund',
10417            m : pl__translate,
10418            mm : pl__translate,
10419            h : pl__translate,
10420            hh : pl__translate,
10421            d : '1 dzień',
10422            dd : '%d dni',
10423            M : 'miesiąc',
10424            MM : pl__translate,
10425            y : 'rok',
10426            yy : pl__translate
10427        },
10428        ordinalParse: /\d{1,2}\./,
10429        ordinal : '%d.',
10430        week : {
10431            dow : 1, // Monday is the first day of the week.
10432            doy : 4  // The week that contains Jan 4th is the first week of the year.
10433        }
10434    });
10435
10436    //! moment.js locale configuration
10437    //! locale : brazilian portuguese (pt-br)
10438    //! author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira
10439
10440    var pt_br = _moment__default.defineLocale('pt-br', {
10441        months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),
10442        monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),
10443        weekdays : 'Domingo_Segunda-Feira_Terça-Feira_Quarta-Feira_Quinta-Feira_Sexta-Feira_Sábado'.split('_'),
10444        weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),
10445        weekdaysMin : 'Dom_2ª_3ª_4ª_5ª_6ª_Sáb'.split('_'),
10446        longDateFormat : {
10447            LT : 'HH:mm',
10448            LTS : 'HH:mm:ss',
10449            L : 'DD/MM/YYYY',
10450            LL : 'D [de] MMMM [de] YYYY',
10451            LLL : 'D [de] MMMM [de] YYYY [às] HH:mm',
10452            LLLL : 'dddd, D [de] MMMM [de] YYYY [às] HH:mm'
10453        },
10454        calendar : {
10455            sameDay: '[Hoje às] LT',
10456            nextDay: '[Amanhã às] LT',
10457            nextWeek: 'dddd [às] LT',
10458            lastDay: '[Ontem às] LT',
10459            lastWeek: function () {
10460                return (this.day() === 0 || this.day() === 6) ?
10461                    '[Último] dddd [às] LT' : // Saturday + Sunday
10462                    '[Última] dddd [às] LT'; // Monday - Friday
10463            },
10464            sameElse: 'L'
10465        },
10466        relativeTime : {
10467            future : 'em %s',
10468            past : '%s atrás',
10469            s : 'poucos segundos',
10470            m : 'um minuto',
10471            mm : '%d minutos',
10472            h : 'uma hora',
10473            hh : '%d horas',
10474            d : 'um dia',
10475            dd : '%d dias',
10476            M : 'um mês',
10477            MM : '%d meses',
10478            y : 'um ano',
10479            yy : '%d anos'
10480        },
10481        ordinalParse: /\d{1,2}º/,
10482        ordinal : '%dº'
10483    });
10484
10485    //! moment.js locale configuration
10486    //! locale : portuguese (pt)
10487    //! author : Jefferson : https://github.com/jalex79
10488
10489    var pt = _moment__default.defineLocale('pt', {
10490        months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),
10491        monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),
10492        weekdays : 'Domingo_Segunda-Feira_Terça-Feira_Quarta-Feira_Quinta-Feira_Sexta-Feira_Sábado'.split('_'),
10493        weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),
10494        weekdaysMin : 'Dom_2ª_3ª_4ª_5ª_6ª_Sáb'.split('_'),
10495        longDateFormat : {
10496            LT : 'HH:mm',
10497            LTS : 'HH:mm:ss',
10498            L : 'DD/MM/YYYY',
10499            LL : 'D [de] MMMM [de] YYYY',
10500            LLL : 'D [de] MMMM [de] YYYY HH:mm',
10501            LLLL : 'dddd, D [de] MMMM [de] YYYY HH:mm'
10502        },
10503        calendar : {
10504            sameDay: '[Hoje às] LT',
10505            nextDay: '[Amanhã às] LT',
10506            nextWeek: 'dddd [às] LT',
10507            lastDay: '[Ontem às] LT',
10508            lastWeek: function () {
10509                return (this.day() === 0 || this.day() === 6) ?
10510                    '[Último] dddd [às] LT' : // Saturday + Sunday
10511                    '[Última] dddd [às] LT'; // Monday - Friday
10512            },
10513            sameElse: 'L'
10514        },
10515        relativeTime : {
10516            future : 'em %s',
10517            past : 'há %s',
10518            s : 'segundos',
10519            m : 'um minuto',
10520            mm : '%d minutos',
10521            h : 'uma hora',
10522            hh : '%d horas',
10523            d : 'um dia',
10524            dd : '%d dias',
10525            M : 'um mês',
10526            MM : '%d meses',
10527            y : 'um ano',
10528            yy : '%d anos'
10529        },
10530        ordinalParse: /\d{1,2}º/,
10531        ordinal : '%dº',
10532        week : {
10533            dow : 1, // Monday is the first day of the week.
10534            doy : 4  // The week that contains Jan 4th is the first week of the year.
10535        }
10536    });
10537
10538    //! moment.js locale configuration
10539    //! locale : romanian (ro)
10540    //! author : Vlad Gurdiga : https://github.com/gurdiga
10541    //! author : Valentin Agachi : https://github.com/avaly
10542
10543    function ro__relativeTimeWithPlural(number, withoutSuffix, key) {
10544        var format = {
10545                'mm': 'minute',
10546                'hh': 'ore',
10547                'dd': 'zile',
10548                'MM': 'luni',
10549                'yy': 'ani'
10550            },
10551            separator = ' ';
10552        if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) {
10553            separator = ' de ';
10554        }
10555        return number + separator + format[key];
10556    }
10557
10558    var ro = _moment__default.defineLocale('ro', {
10559        months : 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split('_'),
10560        monthsShort : 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split('_'),
10561        weekdays : 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'),
10562        weekdaysShort : 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'),
10563        weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'),
10564        longDateFormat : {
10565            LT : 'H:mm',
10566            LTS : 'H:mm:ss',
10567            L : 'DD.MM.YYYY',
10568            LL : 'D MMMM YYYY',
10569            LLL : 'D MMMM YYYY H:mm',
10570            LLLL : 'dddd, D MMMM YYYY H:mm'
10571        },
10572        calendar : {
10573            sameDay: '[azi la] LT',
10574            nextDay: '[mâine la] LT',
10575            nextWeek: 'dddd [la] LT',
10576            lastDay: '[ieri la] LT',
10577            lastWeek: '[fosta] dddd [la] LT',
10578            sameElse: 'L'
10579        },
10580        relativeTime : {
10581            future : 'peste %s',
10582            past : '%s în urmă',
10583            s : 'câteva secunde',
10584            m : 'un minut',
10585            mm : ro__relativeTimeWithPlural,
10586            h : 'o oră',
10587            hh : ro__relativeTimeWithPlural,
10588            d : 'o zi',
10589            dd : ro__relativeTimeWithPlural,
10590            M : 'o lună',
10591            MM : ro__relativeTimeWithPlural,
10592            y : 'un an',
10593            yy : ro__relativeTimeWithPlural
10594        },
10595        week : {
10596            dow : 1, // Monday is the first day of the week.
10597            doy : 7  // The week that contains Jan 1st is the first week of the year.
10598        }
10599    });
10600
10601    //! moment.js locale configuration
10602    //! locale : russian (ru)
10603    //! author : Viktorminator : https://github.com/Viktorminator
10604    //! Author : Menelion Elensúle : https://github.com/Oire
10605
10606    function ru__plural(word, num) {
10607        var forms = word.split('_');
10608        return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);
10609    }
10610    function ru__relativeTimeWithPlural(number, withoutSuffix, key) {
10611        var format = {
10612            'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут',
10613            'hh': 'час_часа_часов',
10614            'dd': 'день_дня_дней',
10615            'MM': 'месяц_месяца_месяцев',
10616            'yy': 'год_года_лет'
10617        };
10618        if (key === 'm') {
10619            return withoutSuffix ? 'минута' : 'минуту';
10620        }
10621        else {
10622            return number + ' ' + ru__plural(format[key], +number);
10623        }
10624    }
10625    function ru__monthsCaseReplace(m, format) {
10626        var months = {
10627                'nominative': 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),
10628                'accusative': 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_')
10629            },
10630            nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ?
10631                'accusative' :
10632                'nominative';
10633        return months[nounCase][m.month()];
10634    }
10635    function ru__monthsShortCaseReplace(m, format) {
10636        var monthsShort = {
10637                'nominative': 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'),
10638                'accusative': 'янв_фев_мар_апр_мая_июня_июля_авг_сен_окт_ноя_дек'.split('_')
10639            },
10640            nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ?
10641                'accusative' :
10642                'nominative';
10643        return monthsShort[nounCase][m.month()];
10644    }
10645    function ru__weekdaysCaseReplace(m, format) {
10646        var weekdays = {
10647                'nominative': 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'),
10648                'accusative': 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_')
10649            },
10650            nounCase = (/\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\] ?dddd/).test(format) ?
10651                'accusative' :
10652                'nominative';
10653        return weekdays[nounCase][m.day()];
10654    }
10655
10656    var ru = _moment__default.defineLocale('ru', {
10657        months : ru__monthsCaseReplace,
10658        monthsShort : ru__monthsShortCaseReplace,
10659        weekdays : ru__weekdaysCaseReplace,
10660        weekdaysShort : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),
10661        weekdaysMin : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),
10662        monthsParse : [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[й|я]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i],
10663        longDateFormat : {
10664            LT : 'HH:mm',
10665            LTS : 'HH:mm:ss',
10666            L : 'DD.MM.YYYY',
10667            LL : 'D MMMM YYYY г.',
10668            LLL : 'D MMMM YYYY г., HH:mm',
10669            LLLL : 'dddd, D MMMM YYYY г., HH:mm'
10670        },
10671        calendar : {
10672            sameDay: '[Сегодня в] LT',
10673            nextDay: '[Завтра в] LT',
10674            lastDay: '[Вчера в] LT',
10675            nextWeek: function () {
10676                return this.day() === 2 ? '[Во] dddd [в] LT' : '[В] dddd [в] LT';
10677            },
10678            lastWeek: function (now) {
10679                if (now.week() !== this.week()) {
10680                    switch (this.day()) {
10681                        case 0:
10682                            return '[В прошлое] dddd [в] LT';
10683                        case 1:
10684                        case 2:
10685                        case 4:
10686                            return '[В прошлый] dddd [в] LT';
10687                        case 3:
10688                        case 5:
10689                        case 6:
10690                            return '[В прошлую] dddd [в] LT';
10691                    }
10692                } else {
10693                    if (this.day() === 2) {
10694                        return '[Во] dddd [в] LT';
10695                    } else {
10696                        return '[В] dddd [в] LT';
10697                    }
10698                }
10699            },
10700            sameElse: 'L'
10701        },
10702        relativeTime : {
10703            future : 'через %s',
10704            past : '%s назад',
10705            s : 'несколько секунд',
10706            m : ru__relativeTimeWithPlural,
10707            mm : ru__relativeTimeWithPlural,
10708            h : 'час',
10709            hh : ru__relativeTimeWithPlural,
10710            d : 'день',
10711            dd : ru__relativeTimeWithPlural,
10712            M : 'месяц',
10713            MM : ru__relativeTimeWithPlural,
10714            y : 'год',
10715            yy : ru__relativeTimeWithPlural
10716        },
10717        meridiemParse: /ночи|утра|дня|вечера/i,
10718        isPM : function (input) {
10719            return /^(дня|вечера)$/.test(input);
10720        },
10721        meridiem : function (hour, minute, isLower) {
10722            if (hour < 4) {
10723                return 'ночи';
10724            } else if (hour < 12) {
10725                return 'утра';
10726            } else if (hour < 17) {
10727                return 'дня';
10728            } else {
10729                return 'вечера';
10730            }
10731        },
10732        ordinalParse: /\d{1,2}-(й|го|я)/,
10733        ordinal: function (number, period) {
10734            switch (period) {
10735                case 'M':
10736                case 'd':
10737                case 'DDD':
10738                    return number + '-й';
10739                case 'D':
10740                    return number + '-го';
10741                case 'w':
10742                case 'W':
10743                    return number + '-я';
10744                default:
10745                    return number;
10746            }
10747        },
10748        week : {
10749            dow : 1, // Monday is the first day of the week.
10750            doy : 7  // The week that contains Jan 1st is the first week of the year.
10751        }
10752    });
10753
10754    //! moment.js locale configuration
10755    //! locale : Sinhalese (si)
10756    //! author : Sampath Sitinamaluwa : https://github.com/sampathsris
10757
10758    var si = _moment__default.defineLocale('si', {
10759        months : 'ජනවාරි_පෙබරවාරි_මාර්තු_අප්‍රේල්_මැයි_ජූනි_ජූලි_අගෝස්තු_සැප්තැම්බර්_ඔක්තෝබර්_නොවැම්බර්_දෙසැම්බර්'.split('_'),
10760        monthsShort : 'ජන_පෙබ_මාර්_අප්_මැයි_ජූනි_ජූලි_අගෝ_සැප්_ඔක්_නොවැ_දෙසැ'.split('_'),
10761        weekdays : 'ඉරිදා_සඳුදා_අඟහරුවාදා_බදාදා_බ්‍රහස්පතින්දා_සිකුරාදා_සෙනසුරාදා'.split('_'),
10762        weekdaysShort : 'ඉරි_සඳු_අඟ_බදා_බ්‍රහ_සිකු_සෙන'.split('_'),
10763        weekdaysMin : 'ඉ_ස_අ_බ_බ්‍ර_සි_සෙ'.
10763split('_'),
10764        longDateFormat : {
10765            LT : 'a h:mm',
10766            LTS : 'a h:mm:ss',
10767            L : 'YYYY/MM/DD',
10768            LL : 'YYYY MMMM D',
10769            LLL : 'YYYY MMMM D, a h:mm',
10770            LLLL : 'YYYY MMMM D [වැනි] dddd, a h:mm:ss'
10771        },
10772        calendar : {
10773            sameDay : '[අද] LT[ට]',
10774            nextDay : '[හෙට] LT[ට]',
10775            nextWeek : 'dddd LT[à¶§]',
10776            lastDay : '[ඊයේ] LT[ට]',
10777            lastWeek : '[පසුගිය] dddd LT[ට]',
10778            sameElse : 'L'
10779        },
10780        relativeTime : {
10781            future : '%sකින්',
10782            past : '%sකට පෙර',
10783            s : 'තත්පර කිහිපය',
10784            m : 'මිනිත්තුව',
10785            mm : 'මිනිත්තු %d',
10786            h : 'පැය',
10787            hh : 'පැය %d',
10788            d : 'දිනය',
10789            dd : 'දින %d',
10790            M : 'මාසය',
10791            MM : 'මාස %d',
10792            y : 'වසර',
10793            yy : 'වසර %d'
10794        },
10795        ordinalParse: /\d{1,2} වැනි/,
10796        ordinal : function (number) {
10797            return number + ' වැනි';
10798        },
10799        meridiem : function (hours, minutes, isLower) {
10800            if (hours > 11) {
10801                return isLower ? 'ප.ව.' : 'පස් වරු';
10802            } else {
10803                return isLower ? 'පෙ.ව.' : 'පෙර වරු';
10804            }
10805        }
10806    });
10807
10808    //! moment.js locale configuration
10809    //! locale : slovak (sk)
10810    //! author : Martin Minka : https://github.com/k2s
10811    //! based on work of petrbela : https://github.com/petrbela
10812
10813    var sk__months = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_'),
10814        sk__monthsShort = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_');
10815    function sk__plural(n) {
10816        return (n > 1) && (n < 5);
10817    }
10818    function sk__translate(number, withoutSuffix, key, isFuture) {
10819        var result = number + ' ';
10820        switch (key) {
10821            case 's':  // a few seconds / in a few seconds / a few seconds ago
10822                return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami';
10823            case 'm':  // a minute / in a minute / a minute ago
10824                return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou');
10825            case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago
10826                if (withoutSuffix || isFuture) {
10827                    return result + (sk__plural(number) ? 'minúty' : 'minút');
10828                } else {
10829                    return result + 'minútami';
10830                }
10831                break;
10832            case 'h':  // an hour / in an hour / an hour ago
10833                return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');
10834            case 'hh': // 9 hours / in 9 hours / 9 hours ago
10835                if (withoutSuffix || isFuture) {
10836                    return result + (sk__plural(number) ? 'hodiny' : 'hodín');
10837                } else {
10838                    return result + 'hodinami';
10839                }
10840                break;
10841            case 'd':  // a day / in a day / a day ago
10842                return (withoutSuffix || isFuture) ? 'deň' : 'dňom';
10843            case 'dd': // 9 days / in 9 days / 9 days ago
10844                if (withoutSuffix || isFuture) {
10845                    return result + (sk__plural(number) ? 'dni' : 'dní');
10846                } else {
10847                    return result + 'dňami';
10848                }
10849                break;
10850            case 'M':  // a month / in a month / a month ago
10851                return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom';
10852            case 'MM': // 9 months / in 9 months / 9 months ago
10853                if (withoutSuffix || isFuture) {
10854                    return result + (sk__plural(number) ? 'mesiace' : 'mesiacov');
10855                } else {
10856                    return result + 'mesiacmi';
10857                }
10858                break;
10859            case 'y':  // a year / in a year / a year ago
10860                return (withoutSuffix || isFuture) ? 'rok' : 'rokom';
10861            case 'yy': // 9 years / in 9 years / 9 years ago
10862                if (withoutSuffix || isFuture) {
10863                    return result + (sk__plural(number) ? 'roky' : 'rokov');
10864                } else {
10865                    return result + 'rokmi';
10866                }
10867                break;
10868        }
10869    }
10870
10871    var sk = _moment__default.defineLocale('sk', {
10872        months : sk__months,
10873        monthsShort : sk__monthsShort,
10874        monthsParse : (function (months, monthsShort) {
10875            var i, _monthsParse = [];
10876            for (i = 0; i < 12; i++) {
10877                // use custom parser to solve problem with July (červenec)
10878                _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');
10879            }
10880            return _monthsParse;
10881        }(sk__months, sk__monthsShort)),
10882        weekdays : 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'),
10883        weekdaysShort : 'ne_po_ut_st_št_pi_so'.split('_'),
10884        weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'),
10885        longDateFormat : {
10886            LT: 'H:mm',
10887            LTS : 'H:mm:ss',
10888            L : 'DD.MM.YYYY',
10889            LL : 'D. MMMM YYYY',
10890            LLL : 'D. MMMM YYYY H:mm',
10891            LLLL : 'dddd D. MMMM YYYY H:mm'
10892        },
10893        calendar : {
10894            sameDay: '[dnes o] LT',
10895            nextDay: '[zajtra o] LT',
10896            nextWeek: function () {
10897                switch (this.day()) {
10898                    case 0:
10899                        return '[v nedeľu o] LT';
10900                    case 1:
10901                    case 2:
10902                        return '[v] dddd [o] LT';
10903                    case 3:
10904                        return '[v stredu o] LT';
10905                    case 4:
10906                        return '[vo štvrtok o] LT';
10907                    case 5:
10908                        return '[v piatok o] LT';
10909                    case 6:
10910                        return '[v sobotu o] LT';
10911                }
10912            },
10913            lastDay: '[včera o] LT',
10914            lastWeek: function () {
10915                switch (this.day()) {
10916                    case 0:
10917                        return '[minulú nedeľu o] LT';
10918                    case 1:
10919                    case 2:
10920                        return '[minulý] dddd [o] LT';
10921                    case 3:
10922                        return '[minulú stredu o] LT';
10923                    case 4:
10924                    case 5:
10925                        return '[minulý] dddd [o] LT';
10926                    case 6:
10927                        return '[minulú sobotu o] LT';
10928                }
10929            },
10930            sameElse: 'L'
10931        },
10932        relativeTime : {
10933            future : 'za %s',
10934            past : 'pred %s',
10935            s : sk__translate,
10936            m : sk__translate,
10937            mm : sk__translate,
10938            h : sk__translate,
10939            hh : sk__translate,
10940            d : sk__translate,
10941            dd : sk__translate,
10942            M : sk__translate,
10943            MM : sk__translate,
10944            y : sk__translate,
10945            yy : sk__translate
10946        },
10947        ordinalParse: /\d{1,2}\./,
10948        ordinal : '%d.',
10949        week : {
10950            dow : 1, // Monday is the first day of the week.
10951            doy : 4  // The week that contains Jan 4th is the first week of the year.
10952        }
10953    });
10954
10955    //! moment.js locale configuration
10956    //! locale : slovenian (sl)
10957    //! author : Robert Sedovšek : https://github.com/sedovsek
10958
10959    function sl__processRelativeTime(number, withoutSuffix, key, isFuture) {
10960        var result = number + ' ';
10961        switch (key) {
10962            case 's':
10963                return withoutSuffix || isFuture ? 'nekaj sekund' : 'nekaj sekundami';
10964            case 'm':
10965                return withoutSuffix ? 'ena minuta' : 'eno minuto';
10966            case 'mm':
10967                if (number === 1) {
10968                    result += withoutSuffix ? 'minuta' : 'minuto';
10969                } else if (number === 2) {
10970                    result += withoutSuffix || isFuture ? 'minuti' : 'minutama';
10971                } else if (number < 5) {
10972                    result += withoutSuffix || isFuture ? 'minute' : 'minutami';
10973                } else {
10974                    result += withoutSuffix || isFuture ? 'minut' : 'minutami';
10975                }
10976                return result;
10977            case 'h':
10978                return withoutSuffix ? 'ena ura' : 'eno uro';
10979            case 'hh':
10980                if (number === 1) {
10981                    result += withoutSuffix ? 'ura' : 'uro';
10982                } else if (number === 2) {
10983                    result += withoutSuffix || isFuture ? 'uri' : 'urama';
10984                } else if (number < 5) {
10985                    result += withoutSuffix || isFuture ? 'ure' : 'urami';
10986                } else {
10987                    result += withoutSuffix || isFuture ? 'ur' : 'urami';
10988                }
10989                return result;
10990            case 'd':
10991                return withoutSuffix || isFuture ? 'en dan' : 'enim dnem';
10992            case 'dd':
10993                if (number === 1) {
10994                    result += withoutSuffix || isFuture ? 'dan' : 'dnem';
10995                } else if (number === 2) {
10996                    result += withoutSuffix || isFuture ? 'dni' : 'dnevoma';
10997                } else {
10998                    result += withoutSuffix || isFuture ? 'dni' : 'dnevi';
10999                }
11000                return result;
11001            case 'M':
11002                return withoutSuffix || isFuture ? 'en mesec' : 'enim mesecem';
11003            case 'MM':
11004                if (number === 1) {
11005                    result += withoutSuffix || isFuture ? 'mesec' : 'mesecem';
11006                } else if (number === 2) {
11007                    result += withoutSuffix || isFuture ? 'meseca' : 'mesecema';
11008                } else if (number < 5) {
11009                    result += withoutSuffix || isFuture ? 'mesece' : 'meseci';
11010                } else {
11011                    result += withoutSuffix || isFuture ? 'mesecev' : 'meseci';
11012                }
11013                return result;
11014            case 'y':
11015                return withoutSuffix || isFuture ? 'eno leto' : 'enim letom';
11016            case 'yy':
11017                if (number === 1) {
11018                    result += withoutSuffix || isFuture ? 'leto' : 'letom';
11019                } else if (number === 2) {
11020                    result += withoutSuffix || isFuture ? 'leti' : 'letoma';
11021                } else if (number < 5) {
11022                    result += withoutSuffix || isFuture ? 'leta' : 'leti';
11023                } else {
11024                    result += withoutSuffix || isFuture ? 'let' : 'leti';
11025                }
11026                return result;
11027        }
11028    }
11029
11030    var sl = _moment__default.defineLocale('sl', {
11031        months : 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split('_'),
11032        monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'),
11033        weekdays : 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'),
11034        weekdaysShort : 'ned._pon._tor._sre._čet._pet._sob.'.split('_'),
11035        weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'),
11036        longDateFormat : {
11037            LT : 'H:mm',
11038            LTS : 'H:mm:ss',
11039            L : 'DD. MM. YYYY',
11040            LL : 'D. MMMM YYYY',
11041            LLL : 'D. MMMM YYYY H:mm',
11042            LLLL : 'dddd, D. MMMM YYYY H:mm'
11043        },
11044        calendar : {
11045            sameDay  : '[danes ob] LT',
11046            nextDay  : '[jutri ob] LT',
11047
11048            nextWeek : function () {
11049                switch (this.day()) {
11050                    case 0:
11051                        return '[v] [nedeljo] [ob] LT';
11052                    case 3:
11053                        return '[v] [sredo] [ob] LT';
11054                    case 6:
11055                        return '[v] [soboto] [ob] LT';
11056                    case 1:
11057                    case 2:
11058                    case 4:
11059                    case 5:
11060                        return '[v] dddd [ob] LT';
11061                }
11062            },
11063            lastDay  : '[včeraj ob] LT',
11064            lastWeek : function () {
11065                switch (this.day()) {
11066                    case 0:
11067                        return '[prejšnjo] [nedeljo] [ob] LT';
11068                    case 3:
11069                        return '[prejšnjo] [sredo] [ob] LT';
11070                    case 6:
11071                        return '[prejšnjo] [soboto] [ob] LT';
11072                    case 1:
11073                    case 2:
11074                    case 4:
11075                    case 5:
11076                        return '[prejšnji] dddd [ob] LT';
11077                }
11078            },
11079            sameElse : 'L'
11080        },
11081        relativeTime : {
11082            future : 'čez %s',
11083            past   : 'pred %s',
11084            s      : sl__processRelativeTime,
11085            m      : sl__processRelativeTime,
11086            mm     : sl__processRelativeTime,
11087            h      : sl__processRelativeTime,
11088            hh     : sl__processRelativeTime,
11089            d      : sl__processRelativeTime,
11090            dd     : sl__processRelativeTime,
11091            M      : sl__processRelativeTime,
11092            MM     : sl__processRelativeTime,
11093            y      : sl__processRelativeTime,
11094            yy     : sl__processRelativeTime
11095        },
11096        ordinalParse: /\d{1,2}\./,
11097        ordinal : '%d.',
11098        week : {
11099            dow : 1, // Monday is the first day of the week.
11100            doy : 7  // The week that contains Jan 1st is the first week of the year.
11101        }
11102    });
11103
11104    //! moment.js locale configuration
11105    //! locale : Albanian (sq)
11106    //! author : Flakërim Ismani : https://github.com/flakerimi
11107    //! author: Menelion Elensúle: https://github.com/Oire (tests)
11108    //! author : Oerd Cukalla : https://github.com/oerd (fixes)
11109
11110    var sq = _moment__default.defineLocale('sq', {
11111        months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'),
11112        monthsShort : 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'),
11113        weekdays : 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split('_'),
11114        weekdaysShort : 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'),
11115        weekdaysMin : 'D_H_Ma_Më_E_P_Sh'.split('_'),
11116        meridiemParse: /PD|MD/,
11117        isPM: function (input) {
11118            return input.charAt(0) === 'M';
11119        },
11120        meridiem : function (hours, minutes, isLower) {
11121            return hours < 12 ? 'PD' : 'MD';
11122        },
11123        longDateFormat : {
11124            LT : 'HH:mm',
11125            LTS : 'HH:mm:ss',
11126            L : 'DD/MM/YYYY',
11127            LL : 'D MMMM YYYY',
11128            LLL : 'D MMMM YYYY HH:mm',
11129            LLLL : 'dddd, D MMMM YYYY HH:mm'
11130        },
11131        calendar : {
11132            sameDay : '[Sot në] LT',
11133            nextDay : '[Nesër në] LT',
11134            nextWeek : 'dddd [në] LT',
11135            lastDay : '[Dje në] LT',
11136            lastWeek : 'dddd [e kaluar në] LT',
11137            sameElse : 'L'
11138        },
11139        relativeTime : {
11140            future : 'në %s',
11141            past : '%s më parë',
11142            s : 'disa sekonda',
11143            m : 'një minutë',
11144            mm : '%d minuta',
11145            h : 'një orë',
11146            hh : '%d orë',
11147            d : 'një ditë',
11148            dd : '%d ditë',
11149            M : 'një muaj',
11150            MM : '%d muaj',
11151            y : 'një vit',
11152            yy : '%d vite'
11153        },
11154        ordinalParse: /\d{1,2}\./,
11155        ordinal : '%d.',
11156        week : {
11157            dow : 1, // Monday is the first day of the week.
11158            doy : 4  // The week that contains Jan 4th is the first week of the year.
11159        }
11160    });
11161
11162    //! moment.js locale configuration
11163    //! locale : Serbian-cyrillic (sr-cyrl)
11164    //! author : Milan Janačković<[email protected]> : https://github.com/milan-j
11165
11166    var sr_cyrl__translator = {
11167        words: { //Different grammatical cases
11168            m: ['један минут', 'једне минуте'],
11169            mm: ['минут', 'минуте', 'минута'],
11170            h: ['један сат', 'једног сата'],
11171            hh: ['сат', 'сата', 'сати'],
11172            dd: ['дан', 'дана', 'дана'],
11173            MM: ['месец', 'месеца', 'месеци'],
11174            yy: ['година', 'године', 'година']
11175        },
11176        correctGrammaticalCase: function (number, wordKey) {
11177            return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);
11178        },
11179        translate: function (number, withoutSuffix, key) {
11180            var wordKey = sr_cyrl__translator.words[key];
11181            if (key.length === 1) {
11182                return withoutSuffix ? wordKey[0] : wordKey[1];
11183            } else {
11184                return number + ' ' + sr_cyrl__translator.correctGrammaticalCase(number, wordKey);
11185            }
11186        }
11187    };
11188
11189    var sr_cyrl = _moment__default.defineLocale('sr-cyrl', {
11190        months: ['јануар', 'фебруар', 'март', 'април', 'мај', 'јун', 'јул', 'август', 'септембар', 'октобар', 'новембар', 'децембар'],
11191        monthsShort: ['јан.', 'феб.', 'мар.', 'апр.', 'мај', 'јун', 'јул', 'авг.', 'сеп.', 'окт.', 'нов.', 'дец.'],
11192        weekdays: ['недеља', 'понедељак', 'уторак', 'среда', 'четвртак', 'петак', 'субота'],
11193        weekdaysShort: ['нед.', 'пон.', 'уто.', 'сре.', 'чет.', 'пет.', 'суб.'],
11194        weekdaysMin: ['не', 'по', 'ут', 'ср', 'че', 'пе', 'су'],
11195        longDateFormat: {
11196            LT: 'H:mm',
11197            LTS : 'H:mm:ss',
11198            L: 'DD. MM. YYYY',
11199            LL: 'D. MMMM YYYY',
11200            LLL: 'D. MMMM YYYY H:mm',
11201            LLLL: 'dddd, D. MMMM YYYY H:mm'
11202        },
11203        calendar: {
11204            sameDay: '[данас у] LT',
11205            nextDay: '[сутра у] LT',
11206            nextWeek: function () {
11207                switch (this.day()) {
11208                    case 0:
11209                        return '[у] [недељу] [у] LT';
11210                    case 3:
11211                        return '[у] [среду] [у] LT';
11212                    case 6:
11213                        return '[у] [суботу] [у] LT';
11214                    case 1:
11215                    case 2:
11216                    case 4:
11217                    case 5:
11218                        return '[у] dddd [у] LT';
11219                }
11220            },
11221            lastDay  : '[јуче у] LT',
11222            lastWeek : function () {
11223                var lastWeekDays = [
11224                    '[прошле] [недеље] [у] LT',
11225                    '[прошлог] [понедељка] [у] LT',
11226                    '[прошлог] [уторка] [у] LT',
11227                    '[прошле] [среде] [у] LT',
11228                    '[прошлог] [четвртка] [у] LT',
11229                    '[прошлог] [петка] [у] LT',
11230                    '[прошле] [суботе] [у] LT'
11231                ];
11232                return lastWeekDays[this.day()];
11233            },
11234            sameElse : 'L'
11235        },
11236        relativeTime : {
11237            future : 'за %s',
11238            past   : 'пре %s',
11239            s      : 'неколико секунди',
11240            m      : sr_cyrl__translator.translate,
11241            mm     : sr_cyrl__translator.translate,
11242            h      : sr_cyrl__translator.translate,
11243            hh     : sr_cyrl__translator.translate,
11244            d      : 'дан',
11245            dd     : sr_cyrl__translator.translate,
11246            M      : 'месец',
11247            MM     : sr_cyrl__translator.translate,
11248            y      : 'годину',
11249            yy     : sr_cyrl__translator.translate
11250        },
11251        ordinalParse: /\d{1,2}\./,
11252        ordinal : '%d.',
11253        week : {
11254            dow : 1, // Monday is the first day of the week.
11255            doy : 7  // The week that contains Jan 1st is the first week of the year.
11256        }
11257    });
11258
11259    //! moment.js locale configuration
11260    //! locale : Serbian-latin (sr)
11261    //! author : Milan Janačković<[email protected]> : https://github.com/milan-j
11262
11263    var sr__translator = {
11264        words: { //Different grammatical cases
11265            m: ['jedan minut', 'jedne minute'],
11266            mm: ['minut', 'minute', 'minuta'],
11267            h: ['jedan sat', 'jednog sata'],
11268            hh: ['sat', 'sata', 'sati'],
11269            dd: ['dan', 'dana', 'dana'],
11270            MM: ['mesec', 'meseca', 'meseci'],
11271            yy: ['godina', 'godine', 'godina']
11272        },
11273        correctGrammaticalCase: function (number, wordKey) {
11274            return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);
11275        },
11276        translate: function (number, withoutSuffix, key) {
11277            var wordKey = sr__translator.words[key];
11278            if (key.length === 1) {
11279                return withoutSuffix ? wordKey[0] : wordKey[1];
11280            } else {
11281                return number + ' ' + sr__translator.correctGrammaticalCase(number, wordKey);
11282            }
11283        }
11284    };
11285
11286    var sr = _moment__default.defineLocale('sr', {
11287        months: ['januar', 'februar', 'mart', 'april', 'maj', 'jun', 'jul', 'avgust', 'septembar', 'oktobar', 'novembar', 'decembar'],
11288        monthsShort: ['jan.', 'feb.', 'mar.', 'apr.', 'maj', 'jun', 'jul', 'avg.', 'sep.', 'okt.', 'nov.', 'dec.'],
11289        weekdays: ['nedelja', 'ponedeljak', 'utorak', 'sreda', 'četvrtak', 'petak', 'subota'],
11290        weekdaysShort: ['ned.', 'pon.', 'uto.', 'sre.', 'čet.', 'pet.', 'sub.'],
11291        weekdaysMin: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'],
11292        longDateFormat: {
11293            LT: 'H:mm',
11294            LTS : 'H:mm:ss',
11295            L: 'DD. MM. YYYY',
11296            LL: 'D. MMMM YYYY',
11297            LLL: 'D. MMMM YYYY H:mm',
11298            LLLL: 'dddd, D. MMMM YYYY H:mm'
11299        },
11300        calendar: {
11301            sameDay: '[danas u] LT',
11302            nextDay: '[sutra u] LT',
11303            nextWeek: function () {
11304                switch (this.day()) {
11305                    case 0:
11306                        return '[u] [nedelju] [u] LT';
11307                    case 3:
11308                        return '[u] [sredu] [u] LT';
11309                    case 6:
11310                        return '[u] [subotu] [u] LT';
11311                    case 1:
11312                    case 2:
11313                    case 4:
11314                    case 5:
11315                        return '[u] dddd [u] LT';
11316                }
11317            },
11318            lastDay  : '[juče u] LT',
11319            lastWeek : function () {
11320                var lastWeekDays = [
11321                    '[prošle] [nedelje] [u] LT',
11322                    '[prošlog] [ponedeljka] [u] LT',
11323                    '[prošlog] [utorka] [u] LT',
11324                    '[prošle] [srede] [u] LT',
11325                    '[prošlog] [četvrtka] [u] LT',
11326                    '[prošlog] [petka] [u] LT',
11327                    '[prošle] [subote] [u] LT'
11328                ];
11329                return lastWeekDays[this.day()];
11330            },
11331            sameElse : 'L'
11332        },
11333        relativeTime : {
11334            future : 'za %s',
11335            past   : 'pre %s',
11336            s      : 'nekoliko sekundi',
11337            m      : sr__translator.translate,
11338            mm     : sr__translator.translate,
11339            h      : sr__translator.translate,
11340            hh     : sr__translator.translate,
11341            d      : 'dan',
11342            dd     : sr__translator.translate,
11343            M      : 'mesec',
11344            MM     : sr__translator.translate,
11345            y      : 'godinu',
11346            yy     : sr__translator.translate
11347        },
11348        ordinalParse: /\d{1,2}\./,
11349        ordinal : '%d.',
11350        week : {
11351            dow : 1, // Monday is the first day of the week.
11352            doy : 7  // The week that contains Jan 1st is the first week of the year.
11353        }
11354    });
11355
11356    //! moment.js locale configuration
11357    //! locale : swedish (sv)
11358    //! author : Jens Alm : https://github.com/ulmus
11359
11360    var sv = _moment__default.defineLocale('sv', {
11361        months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'),
11362        monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),
11363        weekdays : 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'),
11364        weekdaysShort : 'sön_mån_tis_ons_tor_fre_lör'.split('_'),
11365        weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'),
11366        longDateFormat : {
11367            LT : 'HH:mm',
11368            LTS : 'HH:mm:ss',
11369            L : 'YYYY-MM-DD',
11370            LL : 'D MMMM YYYY',
11371            LLL : 'D MMMM YYYY HH:mm',
11372            LLLL : 'dddd D MMMM YYYY HH:mm'
11373        },
11374        calendar : {
11375            sameDay: '[Idag] LT',
11376            nextDay: '[Imorgon] LT',
11377            lastDay: '[Igår] LT',
11378            nextWeek: '[PÃ¥] dddd LT',
11379            lastWeek: '[I] dddd[s] LT',
11380            sameElse: 'L'
11381        },
11382        relativeTime : {
11383            future : 'om %s',
11384            past : 'för %s sedan',
11385            s : 'några sekunder',
11386            m : 'en minut',
11387            mm : '%d minuter',
11388            h : 'en timme',
11389            hh : '%d timmar',
11390            d : 'en dag',
11391            dd : '%d dagar',
11392            M : 'en månad',
11393            MM : '%d månader',
11394            y : 'ett år',
11395            yy : '%d år'
11396        },
11397        ordinalParse: /\d{1,2}(e|a)/,
11398        ordinal : function (number) {
11399            var b = number % 10,
11400                output = (~~(number % 100 / 10) === 1) ? 'e' :
11401                    (b === 1) ? 'a' :
11402                        (b === 2) ? 'a' :
11403                            (b === 3) ? 'e' : 'e';
11404            return number + output;
11405        },
11406        week : {
11407            dow : 1, // Monday is the first day of the week.
11408            doy : 4  // The week that contains Jan 4th is the first week of the year.
11409        }
11410    });
11411
11412    //! moment.js locale configuration
11413    //! locale : tamil (ta)
11414    //! author : Arjunkumar Krishnamoorthy : https://github.com/tk120404
11415
11416    var ta = _moment__default.defineLocale('ta', {
11417        months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),
11418        monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),
11419        weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split('_'),
11420        weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split('_'),
11421        weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'),
11422        longDateFormat : {
11423            LT : 'HH:mm',
11424            LTS : 'HH:mm:ss',
11425            L : 'DD/MM/YYYY',
11426            LL : 'D MMMM YYYY',
11427            LLL : 'D MMMM YYYY, HH:mm',
11428            LLLL : 'dddd, D MMMM YYYY, HH:mm'
11429        },
11430        calendar : {
11431            sameDay : '[இன்று] LT',
11432            nextDay : '[நாளை] LT',
11433            nextWeek : 'dddd, LT',
11434            lastDay : '[நேற்று] LT',
11435            lastWeek : '[கடந்த வாரம்] dddd, LT',
11436            sameElse : 'L'
11437        },
11438        relativeTime : {
11439            future : '%s இல்',
11440            past : '%s முன்',
11441            s : 'ஒரு சில விநாடிகள்',
11442            m : 'ஒரு நிமிடம்',
11443            mm : '%d நிமிடங்கள்',
11444            h : 'ஒரு மணி நேரம்',
11445            hh : '%d மணி நேரம்',
11446            d : 'ஒரு நாள்',
11447            dd : '%d நாட்கள்',
11448            M : 'ஒரு மாதம்',
11449            MM : '%d மாதங்கள்',
11450            y : 'ஒரு வருடம்',
11451            yy : '%d ஆண்டுகள்'
11452        },
11453        ordinalParse: /\d{1,2}வது/,
11454        ordinal : function (number) {
11455            return number + 'வது';
11456        },
11457        // refer http://ta.wikipedia.org/s/1er1
11458        meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/,
11459        meridiem : function (hour, minute, isLower) {
11460            if (hour < 2) {
11461                return ' யாமம்';
11462            } else if (hour < 6) {
11463                return ' வைகறை';  // வைகறை
11464            } else if (hour < 10) {
11465                return ' காலை'; // காலை
11466            } else if (hour < 14) {
11467                return ' நண்பகல்'; // நண்பகல்
11468            } else if (hour < 18) {
11469                return ' எற்பாடு'; // எற்பாடு
11470            } else if (hour < 22) {
11471                return ' மாலை'; // மாலை
11472            } else {
11473                return ' யாமம்';
11474            }
11475        },
11476        meridiemHour : function (hour, meridiem) {
11477            if (hour === 12) {
11478                hour = 0;
11479            }
11480            if (meridiem === 'யாமம்') {
11481                return hour < 2 ? hour : hour + 12;
11482            } else if (meridiem === 'வைகறை' || meridiem === 'காலை') {
11483                return hour;
11484            } else if (meridiem === 'நண்பகல்') {
11485                return hour >= 10 ? hour : hour + 12;
11486            } else {
11487                return hour + 12;
11488            }
11489        },
11490        week : {
11491            dow : 0, // Sunday is the first day of the week.
11492            doy : 6  // The week that contains Jan 1st is the first week of the year.
11493        }
11494    });
11495
11496    //! moment.js locale configuration
11497    //! locale : thai (th)
11498    //! author : Kridsada Thanabulpong : https://github.com/sirn
11499
11500    var th = _moment__default.defineLocale('th', {
11501        months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'),
11502        monthsShort : 'มกรา_กุมภา_มีนา_เมษา_พฤษภา_มิถุนา_กรกฎา_สิงหา_กันยา_ตุลา_พฤศจิกา_ธันวา'.split('_'),
11503        weekdays : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'),
11504        weekdaysShort : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference
11505        weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'),
11506        longDateFormat : {
11507            LT : 'H นาฬิกา m นาที',
11508            LTS : 'H นาฬิกา m นาที s วินาที',
11509            L : 'YYYY/MM/DD',
11510            LL : 'D MMMM YYYY',
11511            LLL : 'D MMMM YYYY เวลา H นาฬิกา m นาที',
11512            LLLL : 'วันddddที่ D MMMM YYYY เวลา H นาฬิกา m นาที'
11513        },
11514        meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/,
11515        isPM: function (input) {
11516            return input === 'หลังเที่ยง';
11517        },
11518        meridiem : function (hour, minute, isLower) {
11519            if (hour < 12) {
11520                return 'ก่อนเที่ยง';
11521            } else {
11522                return 'หลังเที่ยง';
11523            }
11524        },
11525        calendar : {
11526            sameDay : '[วันนี้ เวลา] LT',
11527            nextDay : '[พรุ่งนี้ เวลา] LT',
11528            nextWeek : 'dddd[หน้า เวลา] LT',
11529            lastDay : '[เมื่อวานนี้ เวลา] LT',
11530            lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT',
11531            sameElse : 'L'
11532        },
11533        relativeTime : {
11534            future : 'อีก %s',
11535            past : '%sที่แล้ว',
11536            s : 'ไม่กี่วินาที',
11537            m : '1 นาที',
11538            mm : '%d นาที',
11539            h : '1 ชั่วโมง',
11540            hh : '%d ชั่วโมง',
11541            d : '1 วัน',
11542            dd : '%d วัน',
11543            M : '1 เดือน',
11544            MM : '%d เดือน',
11545            y : '1 ปี',
11546            yy : '%d ปี'
11547        }
11548    });
11549
11550    //! moment.js locale configuration
11551    //! locale : Tagalog/Filipino (tl-ph)
11552    //! author : Dan Hagman
11553
11554    var tl_ph = _moment__default.defineLocale('tl-ph', {
11555        months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'),
11556        monthsShort : 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'),
11557        weekdays : 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split('_'),
11558        weekdaysShort : 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'),
11559        weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'),
11560        longDateFormat : {
11561            LT : 'HH:mm',
11562            LTS : 'HH:mm:ss',
11563            L : 'MM/D/YYYY',
11564            LL : 'MMMM D, YYYY',
11565            LLL : 'MMMM D, YYYY HH:mm',
11566            LLLL : 'dddd, MMMM DD, YYYY HH:mm'
11567        },
11568        calendar : {
11569            sameDay: '[Ngayon sa] LT',
11570            nextDay: '[Bukas sa] LT',
11571            nextWeek: 'dddd [sa] LT',
11572            lastDay: '[Kahapon sa] LT',
11573            lastWeek: 'dddd [huling linggo] LT',
11574            sameElse: 'L'
11575        },
11576        relativeTime : {
11577            future : 'sa loob ng %s',
11578            past : '%s ang nakalipas',
11579            s : 'ilang segundo',
11580            m : 'isang minuto',
11581            mm : '%d minuto',
11582            h : 'isang oras',
11583            hh : '%d oras',
11584            d : 'isang araw',
11585            dd : '%d araw',
11586            M : 'isang buwan',
11587            MM : '%d buwan',
11588            y : 'isang taon',
11589            yy : '%d taon'
11590        },
11591        ordinalParse: /\d{1,2}/,
11592        ordinal : function (number) {
11593            return number;
11594        },
11595        week : {
11596            dow : 1, // Monday is the first day of the week.
11597            doy : 4  // The week that contains Jan 4th is the first week of the year.
11598        }
11599    });
11600
11601    //! moment.js locale configuration
11602    //! locale : turkish (tr)
11603    //! authors : Erhan Gundogan : https://github.com/erhangundogan,
11604    //!           Burak Yiğit Kaya: https://github.com/BYK
11605
11606    var tr__suffixes = {
11607        1: '\'inci',
11608        5: '\'inci',
11609        8: '\'inci',
11610        70: '\'inci',
11611        80: '\'inci',
11612        2: '\'nci',
11613        7: '\'nci',
11614        20: '\'nci',
11615        50: '\'nci',
11616        3: '\'üncü',
11617        4: '\'üncü',
11618        100: '\'üncü',
11619        6: '\'ncı',
11620        9: '\'uncu',
11621        10: '\'uncu',
11622        30: '\'uncu',
11623        60: '\'ıncı',
11624        90: '\'ıncı'
11625    };
11626
11627    var tr = _moment__default.defineLocale('tr', {
11628        months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'),
11629        monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'),
11630        weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'),
11631        weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'),
11632        weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),
11633        longDateFormat : {
11634            LT : 'HH:mm',
11635            LTS : 'HH:mm:ss',
11636            L : 'DD.MM.YYYY',
11637            LL : 'D MMMM YYYY',
11638            LLL : 'D MMMM YYYY HH:mm',
11639            LLLL : 'dddd, D MMMM YYYY HH:mm'
11640        },
11641        calendar : {
11642            sameDay : '[bugün saat] LT',
11643            nextDay : '[yarın saat] LT',
11644            nextWeek : '[haftaya] dddd [saat] LT',
11645            lastDay : '[dün] LT',
11646            lastWeek : '[geçen hafta] dddd [saat] LT',
11647            sameElse : 'L'
11648        },
11649        relativeTime : {
11650            future : '%s sonra',
11651            past : '%s önce',
11652            s : 'birkaç saniye',
11653            m : 'bir dakika',
11654            mm : '%d dakika',
11655            h : 'bir saat',
11656            hh : '%d saat',
11657            d : 'bir gün',
11658            dd : '%d gün',
11659            M : 'bir ay',
11660            MM : '%d ay',
11661            y : 'bir yıl',
11662            yy : '%d yıl'
11663        },
11664        ordinalParse: /\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/,
11665        ordinal : function (number) {
11666            if (number === 0) {  // special case for zero
11667                return number + '\'ıncı';
11668            }
11669            var a = number % 10,
11670                b = number % 100 - a,
11671                c = number >= 100 ? 100 : null;
11672            return number + (tr__suffixes[a] || tr__suffixes[b] || tr__suffixes[c]);
11673        },
11674        week : {
11675            dow : 1, // Monday is the first day of the week.
11676            doy : 7  // The week that contains Jan 1st is the first week of the year.
11677        }
11678    });
11679
11680    //! moment.js locale configuration
11681    //! locale : talossan (tzl)
11682    //! author : Robin van der Vliet : https://github.com/robin0van0der0v with the help of Iustì Canun
11683
11684
11685    var tzl = _moment__default.defineLocale('tzl', {
11686        months : 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split('_'),
11687        monthsShort : 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'),
11688        weekdays : 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'),
11689        weekdaysShort : 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'),
11690        weekdaysMin : 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'),
11691        longDateFormat : {
11692            LT : 'HH.mm',
11693            LTS : 'LT.ss',
11694            L : 'DD.MM.YYYY',
11695            LL : 'D. MMMM [dallas] YYYY',
11696            LLL : 'D. MMMM [dallas] YYYY LT',
11697            LLLL : 'dddd, [li] D. MMMM [dallas] YYYY LT'
11698        },
11699        meridiem : function (hours, minutes, isLower) {
11700            if (hours > 11) {
11701                return isLower ? 'd\'o' : 'D\'O';
11702            } else {
11703                return isLower ? 'd\'a' : 'D\'A';
11704            }
11705        },
11706        calendar : {
11707            sameDay : '[oxhi à] LT',
11708            nextDay : '[demà à] LT',
11709            nextWeek : 'dddd [à] LT',
11710            lastDay : '[ieiri à] LT',
11711            lastWeek : '[sür el] dddd [lasteu à] LT',
11712            sameElse : 'L'
11713        },
11714        relativeTime : {
11715            future : 'osprei %s',
11716            past : 'ja%s',
11717            s : tzl__processRelativeTime,
11718            m : tzl__processRelativeTime,
11719            mm : tzl__processRelativeTime,
11720            h : tzl__processRelativeTime,
11721            hh : tzl__processRelativeTime,
11722            d : tzl__processRelativeTime,
11723            dd : tzl__processRelativeTime,
11724            M : tzl__processRelativeTime,
11725            MM : tzl__processRelativeTime,
11726            y : tzl__processRelativeTime,
11727            yy : tzl__processRelativeTime
11728        },
11729        ordinalParse: /\d{1,2}\./,
11730        ordinal : '%d.',
11731        week : {
11732            dow : 1, // Monday is the first day of the week.
11733            doy : 4  // The week that contains Jan 4th is the first week of the year.
11734        }
11735    });
11736
11737    function tzl__processRelativeTime(number, withoutSuffix, key, isFuture) {
11738        var format = {
11739            's': ['viensas secunds', '\'iensas secunds'],
11740            'm': ['\'n míut', '\'iens míut'],
11741            'mm': [number + ' míuts', ' ' + number + ' míuts'],
11742            'h': ['\'n þora', '\'iensa þora'],
11743            'hh': [number + ' þoras', ' ' + number + ' þoras'],
11744            'd': ['\'n ziua', '\'iensa ziua'],
11745            'dd': [number + ' ziuas', ' ' + number + ' ziuas'],
11746            'M': ['\'n mes', '\'iens mes'],
11747            'MM': [number + ' mesen', ' ' + number + ' mesen'],
11748            'y': ['\'n ar', '\'iens ar'],
11749            'yy': [number + ' ars', ' ' + number + ' ars']
11750        };
11751        return isFuture ? format[key][0] : (withoutSuffix ? format[key][0] : format[key][1].trim());
11752    }
11753
11754    //! moment.js locale configuration
11755    //! locale : Morocco Central Atlas Tamaziɣt in Latin (tzm-latn)
11756    //! author : Abdel Said : https://github.com/abdelsaid
11757
11758    var tzm_latn = _moment__default.defineLocale('tzm-latn', {
11759        months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),
11760        monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),
11761        weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),
11762        weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),
11763        weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),
11764        longDateFormat : {
11765            LT : 'HH:mm',
11766            LTS : 'HH:mm:ss',
11767            L : 'DD/MM/YYYY',
11768            LL : 'D MMMM YYYY',
11769            LLL : 'D MMMM YYYY HH:mm',
11770            LLLL : 'dddd D MMMM YYYY HH:mm'
11771        },
11772        calendar : {
11773            sameDay: '[asdkh g] LT',
11774            nextDay: '[aska g] LT',
11775            nextWeek: 'dddd [g] LT',
11776            lastDay: '[assant g] LT',
11777            lastWeek: 'dddd [g] LT',
11778            sameElse: 'L'
11779        },
11780        relativeTime : {
11781            future : 'dadkh s yan %s',
11782            past : 'yan %s',
11783            s : 'imik',
11784            m : 'minuḍ',
11785            mm : '%d minuḍ',
11786            h : 'saɛa',
11787            hh : '%d tassaɛin',
11788            d : 'ass',
11789            dd : '%d ossan',
11790            M : 'ayowr',
11791            MM : '%d iyyirn',
11792            y : 'asgas',
11793            yy : '%d isgasn'
11794        },
11795        week : {
11796            dow : 6, // Saturday is the first day of the week.
11797            doy : 12  // The week that contains Jan 1st is the first week of the year.
11798        }
11799    });
11800
11801    //! moment.js locale configuration
11802    //! locale : Morocco Central Atlas Tamaziɣt (tzm)
11803    //! author : Abdel Said : https://github.com/abdelsaid
11804
11805    var tzm = _moment__default.defineLocale('tzm', {
11806        months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),
11807        monthsShort : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),
11808        weekdays : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),
11809        weekdaysShort : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),
11810        weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),
11811        longDateFormat : {
11812            LT : 'HH:mm',
11813            LTS: 'HH:mm:ss',
11814            L : 'DD/MM/YYYY',
11815            LL : 'D MMMM YYYY',
11816            LLL : 'D MMMM YYYY HH:mm',
11817            LLLL : 'dddd D MMMM YYYY HH:mm'
11818        },
11819        calendar : {
11820            sameDay: '[ⴰⵙⴷⵅ ⴴ] LT',
11821            nextDay: '[ⴰⵙⴽⴰ ⴴ] LT',
11822            nextWeek: 'dddd [â´´] LT',
11823            lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT',
11824            lastWeek: 'dddd [â´´] LT',
11825            sameElse: 'L'
11826        },
11827        relativeTime : {
11828            future : 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s',
11829            past : 'ⵢⴰⵏ %s',
11830            s : 'ⵉⵎⵉⴽ',
11831            m : 'ⵎⵉⵏⵓⴺ',
11832            mm : '%d ⵎⵉⵏⵓⴺ',
11833            h : 'ⵙⴰⵄⴰ',
11834            hh : '%d ⵜⴰⵙⵙⴰⵄⵉⵏ',
11835            d : 'ⴰⵙⵙ',
11836            dd : '%d oⵙⵙⴰⵏ',
11837            M : 'ⴰⵢoⵓⵔ',
11838            MM : '%d ⵉⵢⵢⵉⵔⵏ',
11839            y : 'ⴰⵙⴳⴰⵙ',
11840            yy : '%d ⵉⵙⴳⴰⵙⵏ'
11841        },
11842        week : {
11843            dow : 6, // Saturday is the first day of the week.
11844            doy : 12  // The week that contains Jan 1st is the first week of the year.
11845        }
11846    });
11847
11848    //! moment.js locale configuration
11849    //! locale : ukrainian (uk)
11850    //! author : zemlanin : https://github.com/zemlanin
11851    //! Author : Menelion Elensúle : https://github.com/Oire
11852
11853    function uk__plural(word, num) {
11854        var forms = word.split('_');
11855        return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);
11856    }
11857    function uk__relativeTimeWithPlural(number, withoutSuffix, key) {
11858        var format = {
11859            'mm': 'хвилина_хвилини_хвилин',
11860            'hh': 'година_години_годин',
11861            'dd': 'день_дні_днів',
11862            'MM': 'місяць_місяці_місяців',
11863            'yy': 'рік_роки_років'
11864        };
11865        if (key === 'm') {
11866            return withoutSuffix ? 'хвилина' : 'хвилину';
11867        }
11868        else if (key === 'h') {
11869            return withoutSuffix ? 'година' : 'годину';
11870        }
11871        else {
11872            return number + ' ' + uk__plural(format[key], +number);
11873        }
11874    }
11875    function uk__monthsCaseReplace(m, format) {
11876        var months = {
11877                'nominative': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_'),
11878                'accusative': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_')
11879            },
11880            nounCase = (/D[oD]? *MMMM?/).test(format) ?
11881                'accusative' :
11882                'nominative';
11883        return months[nounCase][m.month()];
11884    }
11885    function uk__weekdaysCaseReplace(m, format) {
11886        var weekdays = {
11887                'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'),
11888                'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'),
11889                'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_')
11890            },
11891            nounCase = (/(\[[ВвУу]\]) ?dddd/).test(format) ?
11892                'accusative' :
11893                ((/\[?(?:минулої|наступної)? ?\] ?dddd/).test(format) ?
11894                    'genitive' :
11895                    'nominative');
11896        return weekdays[nounCase][m.day()];
11897    }
11898    function processHoursFunction(str) {
11899        return function () {
11900            return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';
11901        };
11902    }
11903
11904    var uk = _moment__default.defineLocale('uk', {
11905        months : uk__monthsCaseReplace,
11906        monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'),
11907        weekdays : uk__weekdaysCaseReplace,
11908        weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
11909        weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
11910        longDateFormat : {
11911            LT : 'HH:mm',
11912            LTS : 'HH:mm:ss',
11913            L : 'DD.MM.YYYY',
11914            LL : 'D MMMM YYYY р.',
11915            LLL : 'D MMMM YYYY р., HH:mm',
11916            LLLL : 'dddd, D MMMM YYYY р., HH:mm'
11917        },
11918        calendar : {
11919            sameDay: processHoursFunction('[Сьогодні '),
11920            nextDay: processHoursFunction('[Завтра '),
11921            lastDay: processHoursFunction('[Вчора '),
11922            nextWeek: processHoursFunction('[У] dddd ['),
11923            lastWeek: function () {
11924                switch (this.day()) {
11925                    case 0:
11926                    case 3:
11927                    case 5:
11928                    case 6:
11929                        return processHoursFunction('[Минулої] dddd [').call(this);
11930                    case 1:
11931                    case 2:
11932                    case 4:
11933                        return processHoursFunction('[Минулого] dddd [').call(this);
11934                }
11935            },
11936            sameElse: 'L'
11937        },
11938        relativeTime : {
11939            future : 'за %s',
11940            past : '%s тому',
11941            s : 'декілька секунд',
11942            m : uk__relativeTimeWithPlural,
11943            mm : uk__relativeTimeWithPlural,
11944            h : 'годину',
11945            hh : uk__relativeTimeWithPlural,
11946            d : 'день',
11947            dd : uk__relativeTimeWithPlural,
11948            M : 'місяць',
11949            MM : uk__relativeTimeWithPlural,
11950            y : 'рік',
11951            yy : uk__relativeTimeWithPlural
11952        },
11953        // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason
11954        meridiemParse: /ночі|ранку|дня|вечора/,
11955        isPM: function (input) {
11956            return /^(дня|вечора)$/.test(input);
11957        },
11958        meridiem : function (hour, minute, isLower) {
11959            if (hour < 4) {
11960                return 'ночі';
11961            } else if (hour < 12) {
11962                return 'ранку';
11963            } else if (hour < 17) {
11964                return 'дня';
11965            } else {
11966                return 'вечора';
11967            }
11968        },
11969        ordinalParse: /\d{1,2}-(й|го)/,
11970        ordinal: function (number, period) {
11971            switch (period) {
11972                case 'M':
11973                case 'd':
11974                case 'DDD':
11975                case 'w':
11976                case 'W':
11977                    return number + '-й';
11978                case 'D':
11979                    return number + '-го';
11980                default:
11981                    return number;
11982            }
11983        },
11984        week : {
11985            dow : 1, // Monday is the first day of the week.
11986            doy : 7  // The week that contains Jan 1st is the first week of the year.
11987        }
11988    });
11989
11990    //! moment.js locale configuration
11991    //! locale : uzbek (uz)
11992    //! author : Sardor Muminov : https://github.com/muminoff
11993
11994    var uz = _moment__default.defineLocale('uz', {
11995        months : 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),
11996        monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'),
11997        weekdays : 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'),
11998        weekdaysShort : 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'),
11999        weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'),
12000        longDateFormat : {
12001            LT : 'HH:mm',
12002            LTS : 'HH:mm:ss',
12003            L : 'DD/MM/YYYY',
12004            LL : 'D MMMM YYYY',
12005            LLL : 'D MMMM YYYY HH:mm',
12006            LLLL : 'D MMMM YYYY, dddd HH:mm'
12007        },
12008        calendar : {
12009            sameDay : '[Бугун соат] LT [да]',
12010            nextDay : '[Эртага] LT [да]',
12011            nextWeek : 'dddd [куни соат] LT [да]',
12012            lastDay : '[Кеча соат] LT [да]',
12013            lastWeek : '[Утган] dddd [куни соат] LT [да]',
12014            sameElse : 'L'
12015        },
12016        relativeTime : {
12017            future : 'Якин %s ичида',
12018            past : 'Бир неча %s олдин',
12019            s : 'фурсат',
12020            m : 'бир дакика',
12021            mm : '%d дакика',
12022            h : 'бир соат',
12023            hh : '%d соат',
12024            d : 'бир кун',
12025            dd : '%d кун',
12026            M : 'бир ой',
12027            MM : '%d ой',
12028            y : 'бир йил',
12029            yy : '%d йил'
12030        },
12031        week : {
12032            dow : 1, // Monday is the first day of the week.
12033            doy : 7  // The week that contains Jan 4th is the first week of the year.
12034        }
12035    });
12036
12037    //! moment.js locale configuration
12038    //! locale : vietnamese (vi)
12039    //! author : Bang Nguyen : https://github.com/bangnk
12040
12041    var vi = _moment__default.defineLocale('vi', {
12042        months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'),
12043        monthsShort : 'Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12'.split('_'),
12044        weekdays : 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split('_'),
12045        weekdaysShort : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),
12046        weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),
12047        longDateFormat : {
12048            LT : 'HH:mm',
12049            LTS : 'HH:mm:ss',
12050            L : 'DD/MM/YYYY',
12051            LL : 'D MMMM [năm] YYYY',
12052            LLL : 'D MMMM [năm] YYYY HH:mm',
12053            LLLL : 'dddd, D MMMM [năm] YYYY HH:mm',
12054            l : 'DD/M/YYYY',
12055            ll : 'D MMM YYYY',
12056            lll : 'D MMM YYYY HH:mm',
12057            llll : 'ddd, D MMM YYYY HH:mm'
12058        },
12059        calendar : {
12060            sameDay: '[Hôm nay lúc] LT',
12061            nextDay: '[Ngày mai lúc] LT',
12062            nextWeek: 'dddd [tuần tới lúc] LT',
12063            lastDay: '[Hôm qua lúc] LT',
12064            lastWeek: 'dddd [tuần rồi lúc] LT',
12065            sameElse: 'L'
12066        },
12067        relativeTime : {
12068            future : '%s tới',
12069            past : '%s trước',
12070            s : 'vài giây',
12071            m : 'một phút',
12072            mm : '%d phút',
12073            h : 'một giờ',
12074            hh : '%d giờ',
12075            d : 'một ngày',
12076            dd : '%d ngày',
12077            M : 'một tháng',
12078            MM : '%d tháng',
12079            y : 'một năm',
12080            yy : '%d năm'
12081        },
12082        ordinalParse: /\d{1,2}/,
12083        ordinal : function (number) {
12084            return number;
12085        },
12086        week : {
12087            dow : 1, // Monday is the first day of the week.
12088            doy : 4  // The week that contains Jan 4th is the first week of the year.
12089        }
12090    });
12091
12092    //! moment.js locale configuration
12093    //! locale : chinese (zh-cn)
12094    //! author : suupic : https://github.com/suupic
12095    //! author : Zeno Zeng : https://github.com/zenozeng
12096
12097    var zh_cn = _moment__default.defineLocale('zh-cn', {
12098        months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),
12099        monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
12100        weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),
12101        weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'),
12102        weekdaysMin : '日_一_二_三_四_五_六'.split('_'),
12103        longDateFormat : {
12104            LT : 'Ah点mm分',
12105            LTS : 'Ah点m分s秒',
12106            L : 'YYYY-MM-DD',
12107            LL : 'YYYY年MMMD日',
12108            LLL : 'YYYY年MMMD日Ah点mm分',
12109            LLLL : 'YYYY年MMMD日ddddAh点mm分',
12110            l : 'YYYY-MM-DD',
12111            ll : 'YYYY年MMMD日',
12112            lll : 'YYYY年MMMD日Ah点mm分',
12113            llll : 'YYYY年MMMD日ddddAh点mm分'
12114        },
12115        meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
12116        meridiemHour: function (hour, meridiem) {
12117            if (hour === 12) {
12118                hour = 0;
12119            }
12120            if (meridiem === '凌晨' || meridiem === '早上' ||
12121                meridiem === '上午') {
12122                return hour;
12123            } else if (meridiem === '下午' || meridiem === '晚上') {
12124                return hour + 12;
12125            } else {
12126                // '中午'
12127                return hour >= 11 ? hour : hour + 12;
12128            }
12129        },
12130        meridiem : function (hour, minute, isLower) {
12131            var hm = hour * 100 + minute;
12132            if (hm < 600) {
12133                return '凌晨';
12134            } else if (hm < 900) {
12135                return '早上';
12136            } else if (hm < 1130) {
12137                return '上午';
12138            } else if (hm < 1230) {
12139                return '中午';
12140            } else if (hm < 1800) {
12141                return '下午';
12142            } else {
12143                return '晚上';
12144            }
12145        },
12146        calendar : {
12147            sameDay : function () {
12148                return this.minutes() === 0 ? '[今天]Ah[点整]' : '[今天]LT';
12149            },
12150            nextDay : function () {
12151                return this.minutes() === 0 ? '[明天]Ah[点整]' : '[明天]LT';
12152            },
12153            lastDay : function () {
12154                return this.minutes() === 0 ? '[昨天]Ah[点整]' : '[昨天]LT';
12155            },
12156            nextWeek : function () {
12157                var startOfWeek, prefix;
12158                startOfWeek = _moment__default().startOf('week');
12159                prefix = this.unix() - startOfWeek.unix() >= 7 * 24 * 3600 ? '[下]' : '[本]';
12160                return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm';
12161            },
12162            lastWeek : function () {
12163                var startOfWeek, prefix;
12164                startOfWeek = _moment__default().startOf('week');
12165                prefix = this.unix() < startOfWeek.unix()  ? '[上]' : '[本]';
12166                return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm';
12167            },
12168            sameElse : 'LL'
12169        },
12170        ordinalParse: /\d{1,2}(日|月|周)/,
12171        ordinal : function (number, period) {
12172            switch (period) {
12173                case 'd':
12174                case 'D':
12175                case 'DDD':
12176                    return number + '日';
12177                case 'M':
12178                    return number + '月';
12179                case 'w':
12180                case 'W':
12181                    return number + '周';
12182                default:
12183                    return number;
12184            }
12185        },
12186        relativeTime : {
12187            future : '%s内',
12188            past : '%s前',
12189            s : '几秒',
12190            m : '1 分钟',
12191            mm : '%d 分钟',
12192            h : '1 小时',
12193            hh : '%d 小时',
12194            d : '1 天',
12195            dd : '%d 天',
12196            M : '1 个月',
12197            MM : '%d 个月',
12198            y : '1 å¹´',
12199            yy : '%d å¹´'
12200        },
12201        week : {
12202            // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效
12203            dow : 1, // Monday is the first day of the week.
12204            doy : 4  // The week that contains Jan 4th is the first week of the year.
12205        }
12206    });
12207
12208    //! moment.js locale configuration
12209    //! locale : traditional chinese (zh-tw)
12210    //! author : Ben : https://github.com/ben-lin
12211
12212    var zh_tw = _moment__default.defineLocale('zh-tw', {
12213        months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),
12214        monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
12215        weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),
12216        weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),
12217        weekdaysMin : '日_一_二_三_四_五_六'.split('_'),
12218        longDateFormat : {
12219            LT : 'Ah點mm分',
12220            LTS : 'Ah點m分s秒',
12221            L : 'YYYY年MMMD日',
12222            LL : 'YYYY年MMMD日',
12223            LLL : 'YYYY年MMMD日Ah點mm分',
12224            LLLL : 'YYYY年MMMD日ddddAh點mm分',
12225            l : 'YYYY年MMMD日',
12226            ll : 'YYYY年MMMD日',
12227            lll : 'YYYY年MMMD日Ah點mm分',
12228            llll : 'YYYY年MMMD日ddddAh點mm分'
12229        },
12230        meridiemParse: /早上|上午|中午|下午|晚上/,
12231        meridiemHour : function (hour, meridiem) {
12232            if (hour === 12) {
12233                hour = 0;
12234            }
12235            if (meridiem === '早上' || meridiem === '上午') {
12236                return hour;
12237            } else if (meridiem === '中午') {
12238                return hour >= 11 ? hour : hour + 12;
12239            } else if (meridiem === '下午' || meridiem === '晚上') {
12240                return hour + 12;
12241            }
12242        },
12243        meridiem : function (hour, minute, isLower) {
12244            var hm = hour * 100 + minute;
12245            if (hm < 900) {
12246                return '早上';
12247            } else if (hm < 1130) {
12248                return '上午';
12249            } else if (hm < 1230) {
12250                return '中午';
12251            } else if (hm < 1800) {
12252                return '下午';
12253            } else {
12254                return '晚上';
12255            }
12256        },
12257        calendar : {
12258            sameDay : '[今天]LT',
12259            nextDay : '[明天]LT',
12260            nextWeek : '[下]ddddLT',
12261            lastDay : '[昨天]LT',
12262            lastWeek : '[上]ddddLT',
12263            sameElse : 'L'
12264        },
12265        ordinalParse: /\d{1,2}(日|月|週)/,
12266        ordinal : function (number, period) {
12267            switch (period) {
12268                case 'd' :
12269                case 'D' :
12270                case 'DDD' :
12271                    return number + '日';
12272                case 'M' :
12273                    return number + '月';
12274                case 'w' :
12275                case 'W' :
12276                    return number + '週';
12277                default :
12278                    return number;
12279            }
12280        },
12281        relativeTime : {
12282            future : '%s內',
12283            past : '%s前',
12284            s : '幾秒',
12285            m : '一分鐘',
12286            mm : '%d分鐘',
12287            h : '一小時',
12288            hh : '%d小時',
12289            d : '一天',
12290            dd : '%d天',
12291            M : '一個月',
12292            MM : '%d個月',
12293            y : '一年',
12294            yy : '%då¹´'
12295        }
12296    });
12297
12298    var moment_with_locales = _moment__default;
12299    moment_with_locales.locale('en');
12300
12301    return moment_with_locales;
12302
12303}));
12304/*! version : 4.17.37
12305 =========================================================
12306 bootstrap-datetimejs
12307 https://github.com/Eonasdan/bootstrap-datetimepicker
12308 Copyright (c) 2015 Jonathan Peterson
12309 =========================================================
12310 */
12311!function(a){"use strict";if("function"==typeof define&&define.amd)define(["jquery","moment"],a);else if("object"==typeof exports)a(require("jquery"),require("moment"));else{if("undefined"==typeof jQuery)throw"bootstrap-datetimepicker requires jQuery to be loaded first";if("undefined"==typeof moment)throw"bootstrap-datetimepicker requires Moment.js to be loaded first";a(jQuery,moment)}}(function(a,b){"use strict";if(!b)throw new Error("bootstrap-datetimepicker requires Moment.js to be loaded first");var c=function(c,d){var e,f,g,h,i,j,k,l={},m=!0,n=!1,o=!1,p=0,q=[{clsName:"days",navFnc:"M",navStep:1},{clsName:"months",navFnc:"y",navStep:1},{clsName:"years",navFnc:"y",navStep:10},{clsName:"decades",navFnc:"y",navStep:100}],r=["days","months","years","decades"],s=["top","bottom","auto"],t=["left","right","auto"],u=["default","to
12311p","bottom"],v={up:38,38:"up",down:40,40:"down",left:37,37:"left",right:39,39:"right",tab:9,9:"tab",escape:27,27:"escape",enter:13,13:"enter",pageUp:33,33:"pageUp",pageDown:34,34:"pageDown",shift:16,16:"shift",control:17,17:"control",space:32,32:"space",t:84,84:"t","delete":46,46:"delete"},w={},x=function(a){var c,e,f,g,h,i=!1;return void 0!==b.tz&&void 0!==d.timeZone&&null!==d.timeZone&&""!==d.timeZone&&(i=!0),void 0===a||null===a?c=i?b().tz(d.timeZone).startOf("d"):b().startOf("d"):i?(e=b().tz(d.timeZone).utcOffset(),f=b(a,j,d.useStrict).utcOffset(),f!==e?(g=b().tz(d.timeZone).format("Z"),h=b(a,j,d.useStrict).format("YYYY-MM-DD[T]HH:mm:ss")+g,c=b(h,j,d.useStrict).tz(d.timeZone)):c=b(a,j,d.useStrict).tz(d.timeZone)):c=b(a,j,d.useStrict),c},y=function(a){if("string"!=typeof a||a.length>1)throw new TypeError("isEnabled expects a single character string parameter");switch(a){case"y":return-1!==i.indexOf("Y");case"M":return-1!==i.indexOf("M");case"d":return-1!==i.toLowerCase().indexOf("d");case"h":case"H":return-1!==i.toLowerCase().indexOf("h");case"m":return-1!==i.indexOf("m");case"s":return-1!==i.indexOf("s");default:return!1}},z=function(){return y("h")||y("m")||y("s")},A=function(){return y("y")||y("M")||y("d")},B=function(){var b=a("<thead>").append(a("<tr>").append(a("<th>").addClass("prev").attr("data-action","previous").append(a("<span>").addClass(d.icons.previous))).append(a("<th>").addClass("picker-switch").attr("data-action","pickerSwitch").attr("colspan",d.calendarWeeks?"6":"5")).append(a("<th>").addClass("next").attr("data-action","next").append(a("<span>").addClass(d.icons.next)))),c=a("<tbody>").append(a("<tr>").append(a("<td>").attr("colspan",d.calendarWeeks?"8":"7")));return[a("<div>").addClass("datepicker-days").append(a("<table>").addClass("table-condensed").append(b).append(a("<tbody>"))),a("<div>").addClass("datepicker-months").append(a("<table>").addClass("table-condensed").append(b.clone()).append(c.clone())),a("<div>").addClass("datepicker-years").append(a("<table>").addClass("table-condensed").append(b.clone()).append(c.clone())),a("<div>").addClass("datepicker-decades").append(a("<table>").addClass("table-condensed").append(b.clone()).append(c.clone()))]},C=function(){var b=a("<tr>"),c=a("<tr>"),e=a("<tr>");return y("h")&&(b.append(a("<td>").append(a("<a>").attr({href:"#",tabindex:"-1",title:d.tooltips.incrementHour}).addClass("btn").attr("data-action","incrementHours").append(a("<span>").addClass(d.icons.up)))),c.append(a("<td>").append(a("<span>").addClass("timepicker-hour").attr({"data-time-component":"hours",title:d.tooltips.pickHour}).attr("data-action","showHours"))),e.append(a("<td>").append(a("<a>").attr({href:"#",tabindex:"-1",title:d.tooltips.decrementHour}).addClass("btn").attr("data-action","decrementHours").append(a("<span>").addClass(d.icons.down))))),y("m")&&(y("h")&&(b.append(a("<td>").addClass("separator")),c.append(a("<td>").addClass("separator").html(":")),e.append(a("<td>").addClass("separator"))),b.append(a("<td>").append(a("<a>").attr({href:"#",tabindex:"-1",title:d.tooltips.incrementMinute}).addClass("btn").attr("data-action","incrementMinutes").append(a("<span>").addClass(d.icons.up)))),c.append(a("<td>").append(a("<span>").addClass("timepicker-minute").attr({"data-time-component":"minutes",title:d.tooltips.pickMinute}).attr("data-action","showMinutes"))),e.append(a("<td>").append(a("<a>").attr({href:"#",tabindex:"-1",title:d.tooltips.decrementMinute}).addClass("btn").attr("data-action","decrementMinutes").append(a("<span>").addClass(d.icons.down))))),y("s")&&(y("m")&&(b.append(a("<td>").addClass("separator")),c.append(a("<td>").addClass("separator").html(":")),e.append(a("<td>").addClass("separator"))),b.append(a("<td>").append(a("<a>").attr({href:"#",tabindex:"-1",title:d.tooltips.incrementSecond}).addClass("btn").attr("data-action","incrementSeconds").append(a("<span>").addClass(d.icons.up)))),c.append(a("<td>").append(a("<span>").addClass("timepicker-second").attr({"data-time-component":"seconds",title:d.tooltips.pickSecond}).attr("data-action","showSeconds"))),e.append(a("<td>").append(a("<a>").attr({href:"#",tabindex:"-1",title:d.tooltips.decrementSecond}).addClass("btn").attr("data-action","decrementSeconds").append(a("<span>").addClass(d.icons.down))))),h||(b.append(a("<td>").addClass("separator")),c.append(a("<td>").append(a("<button>").addClass("btn btn-primary").attr({"data-action":"togglePeriod",tabindex:"-1",title:d.tooltips.togglePeriod}))),e.append(a("<td>").addClass("separator"))),a("<div>").addClass("timepicker-picker").append(a("<table>").addClass("table-condensed").append([b,c,e]))},D=function(){var b=a("<div>").addClass("timepicker-hours").append(a("<table>").addClass("table-condensed")),c=a("<div>").addClass("timepicker-minutes").append(a("<table>").addClass("table-condensed")),d=a("<div>").addClass("timepicker-seconds").append(a("<table>").addClass("table-condensed")),e=[C()];return y("h")&&e.push(b),y("m")&&e.push(c),y("s")&&e.push(d),e},E=function(){var b=[];return d.showTodayButton&&b.push(a("<td>").append(a("<a>").attr({"data-action":"today",title:d.tooltips.today}).append(a("<span>").addClass(d.icons.today)))),!d.sideBySide&&A()&&z()&&b.push(a("<td>").append(a("<a>").attr({"data-action":"togglePicker",title:d.tooltips.selectTime}).append(a("<span>").addClass(d.icons.time)))),d.showClear&&b.push(a("<td>").append(a("<a>").attr({"data-action":"clear",title:d.tooltips.clear}).append(a("<span>").addClass(d.icons.clear)))),d.showClose&&b.push(a("<td>").append(a("<a>").attr({"data-action":"close",title:d.tooltips.close}).append(a("<span>").addClass(d.icons.close)))),a("<table>").addClass("table-condensed").append(a("<tbody>").append(a("<tr>").append(b)))},F=function(){var b=a("<div>").addClass("bootstrap-datetimepicker-widget dropdown-menu"),c=a("<div>").addClass("datepicker").append(B()),e=a("<div>").addClass("timepicker").append(D()),f=a("<ul>").addClass("list-unstyled"),g=a("<li>").addClass("picker-switch"+(d.collapse?" accordion-toggle":"")).append(E());return d.inline&&b.removeClass("dropdown-menu"),h&&b.addClass("usetwentyfour"),y("s")&&!h&&b.addClass("wider"),d.sideBySide&&A()&&z()?(b.addClass("timepicker-sbs"),"top"===d.toolbarPlacement&&b.append(g),b.append(a("<div>").addClass("row").append(c.addClass("col-md-6")).append(e.addClass("col-md-6"))),"bottom"===d.toolbarPlacement&&b.append(g),b):("top"===d.toolbarPlacement&&f.append(g),A()&&f.append(a("<li>
12311").addClass(d.collapse&&z()?"collapse in":"").append(c)),"default"===d.toolbarPlacement&&f.append(g),z()&&f.append(a("<li>").addClass(d.collapse&&A()?"collapse":"").append(e)),"bottom"===d.toolbarPlacement&&f.append(g),b.append(f))},G=function(){var b,e={};return b=c.is("input")||d.inline?c.data():c.find("input").data(),b.dateOptions&&b.dateOptions instanceof Object&&(e=a.extend(!0,e,b.dateOptions)),a.each(d,function(a){var c="date"+a.charAt(0).toUpperCase()+a.slice(1);void 0!==b[c]&&(e[a]=b[c])}),e},H=function(){var b,e=(n||c).position(),f=(n||c).offset(),g=d.widgetPositioning.vertical,h=d.widgetPositioning.horizontal;if(d.widgetParent)b=d.widgetParent.append(o);else if(c.is("input"))b=c.after(o).parent();else{if(d.inline)return void(b=c.append(o));b=c,c.children().first().after(o)}if("auto"===g&&(g=f.top+1.5*o.height()>=a(window).height()+a(window).scrollTop()&&o.height()+c.outerHeight()<f.top?"top":"bottom"),"auto"===h&&(h=b.width()<f.left+o.outerWidth()/2&&f.left+o.outerWidth()>a(window).width()?"right":"left"),"top"===g?o.addClass("top").removeClass("bottom"):o.addClass("bottom").removeClass("top"),"right"===h?o.addClass("pull-right"):o.removeClass("pull-right"),"relative"!==b.css("position")&&(b=b.parents().filter(function(){return"relative"===a(this).css("position")}).first()),0===b.length)throw new Error("datetimepicker component should be placed within a relative positioned container");o.css({top:"top"===g?"auto":e.top+c.outerHeight(),bottom:"top"===g?e.top+c.outerHeight():"auto",left:"left"===h?b===c?0:e.left:"auto",right:"left"===h?"auto":b.outerWidth()-c.outerWidth()-(b===c?0:e.left)})},I=function(a){"dp.change"===a.type&&(a.date&&a.date.isSame(a.oldDate)||!a.date&&!a.oldDate)||c.trigger(a)},J=function(a){"y"===a&&(a="YYYY"),I({type:"dp.update",change:a,viewDate:f.clone()})},K=function(a){o&&(a&&(k=Math.max(p,Math.min(3,k+a))),o.find(".datepicker > div").hide().filter(".datepicker-"+q[k].clsName).show())},L=function(){var b=a("<tr>"),c=f.clone().startOf("w").startOf("d");for(d.calendarWeeks===!0&&b.append(a("<th>").addClass("cw").text("#"));c.isBefore(f.clone().endOf("w"));)b.append(a("<th>").addClass("dow").text(c.format("dd"))),c.add(1,"d");o.find(".datepicker-days thead").append(b)},M=function(a){return d.disabledDates[a.format("YYYY-MM-DD")]===!0},N=function(a){return d.enabledDates[a.format("YYYY-MM-DD")]===!0},O=function(a){return d.disabledHours[a.format("H")]===!0},P=function(a){return d.enabledHours[a.format("H")]===!0},Q=function(b,c){if(!b.isValid())return!1;if(d.disabledDates&&"d"===c&&M(b))return!1;if(d.enabledDates&&"d"===c&&!N(b))return!1;if(d.minDate&&b.isBefore(d.minDate,c))return!1;if(d.maxDate&&b.isAfter(d.maxDate,c))return!1;if(d.daysOfWeekDisabled&&"d"===c&&-1!==d.daysOfWeekDisabled.indexOf(b.day()))return!1;if(d.disabledHours&&("h"===c||"m"===c||"s"===c)&&O(b))return!1;if(d.enabledHours&&("h"===c||"m"===c||"s"===c)&&!P(b))return!1;if(d.disabledTimeIntervals&&("h"===c||"m"===c||"s"===c)){var e=!1;if(a.each(d.disabledTimeIntervals,function(){return b.isBetween(this[0],this[1])?(e=!0,!1):void 0}),e)return!1}return!0},R=function(){for(var b=[],c=f.clone().startOf("y").startOf("d");c.isSame(f,"y");)b.push(a("<span>").attr("data-action","selectMonth").addClass("month").text(c.format("MMM"))),c.add(1,"M");o.find(".datepicker-months td").empty().append(b)},S=function(){var b=o.find(".datepicker-months"),c=b.find("th"),g=b.find("tbody").find("span");c.eq(0).find("span").attr("title",d.tooltips.prevYear),c.eq(1).attr("title",d.tooltips.selectYear),c.eq(2).find("span").attr("title",d.tooltips.nextYear),b.find(".disabled").removeClass("disabled"),Q(f.clone().subtract(1,"y"),"y")||c.eq(0).addClass("disabled"),c.eq(1).text(f.year()),Q(f.clone().add(1,"y"),"y")||c.eq(2).addClass("disabled"),g.removeClass("active"),e.isSame(f,"y")&&!m&&g.eq(e.month()).addClass("active"),g.each(function(b){Q(f.clone().month(b),"M")||a(this).addClass("disabled")})},T=function(){var a=o.find(".datepicker-years"),b=a.find("th"),c=f.clone().subtract(5,"y"),g=f.clone().add(6,"y"),h="";for(b.eq(0).find("span").attr("title",d.tooltips.prevDecade),b.eq(1).attr("title",d.tooltips.selectDecade),b.eq(2).find("span").attr("title",d.tooltips.nextDecade),a.find(".disabled").removeClass("disabled"),d.minDate&&d.minDate.isAfter(c,"y")&&b.eq(0).addClass("disabled"),b.eq(1).text(c.year()+"-"+g.year()),d.maxDate&&d.maxDate.isBefore(g,"y")&&b.eq(2).addClass("disabled");!c.isAfter(g,"y");)h+='<span data-action="selectYear" class="year'+(c.isSame(e,"y")&&!m?" active":"")+(Q(c,"y")?"":" disabled")+'">'+c.year()+"</span>",c.add(1,"y");a.find("td").html(h)},U=function(){var a=o.find(".datepicker-decades"),c=a.find("th"),g=b({y:f.year()-f.year()%100-1}),h=g.clone().add(100,"y"),i=g.clone(),j="";for(c.eq(0).find("span").attr("title",d.tooltips.prevCentury),c.eq(2).find("span").attr("title",d.tooltips.nextCentury),a.find(".disabled").removeClass("disabled"),(g.isSame(b({y:1900}
12311))||d.minDate&&d.minDate.isAfter(g,"y"))&&c.eq(0).addClass("disabled"),c.eq(1).text(g.year()+"-"+h.year()),(g.isSame(b({y:2e3}))||d.maxDate&&d.maxDate.isBefore(h,"y"))&&c.eq(2).addClass("disabled");!g.isAfter(h,"y");)j+='<span data-action="selectDecade" class="decade'+(g.isSame(e,"y")?" active":"")+(Q(g,"y")?"":" disabled")+'" data-selection="'+(g.year()+6)+'">'+(g.year()+1)+" - "+(g.year()+12)+"</span>",g.add(12,"y");j+="<span></span><span></span><span></span>",a.find("td").html(j),c.eq(1).text(i.year()+1+"-"+g.year())},V=function(){var b,c,g,h,i=o.find(".datepicker-days"),j=i.find("th"),k=[];if(A()){for(j.eq(0).find("span").attr("title",d.tooltips.prevMonth),j.eq(1).attr("title",d.tooltips.selectMonth),j.eq(2).find("span").attr("title",d.tooltips.nextMonth),i.find(".disabled").removeClass("disabled"),j.eq(1).text(f.format(d.dayViewHeaderFormat)),Q(f.clone().subtract(1,"M"),"M")||j.eq(0).addClass("disabled"),Q(f.clone().add(1,"M"),"M")||j.eq(2).addClass("disabled"),b=f.clone().startOf("M").startOf("w").startOf("d"),h=0;42>h;h++)0===b.weekday()&&(c=a("<tr>"),d.calendarWeeks&&c.append('<td class="cw">'+b.week()+"</td>"),k.push(c)),g="",b.isBefore(f,"M")&&(g+=" old"),b.isAfter(f,"M")&&(g+=" new"),b.isSame(e,"d")&&!m&&(g+=" active"),Q(b,"d")||(g+=" disabled"),b.isSame(x(),"d")&&(g+=" today"),(0===b.day()||6===b.day())&&(g+=" weekend"),c.append('<td data-action="selectDay" data-day="'+b.format("L")+'" class="day'+g+'">'+b.date()+"</td>"),b.add(1,"d");i.find("tbody").empty().append(k),S(),T(),U()}},W=function(){var b=o.find(".timepicker-hours table"),c=f.clone().startOf("d"),d=[],e=a("<tr>");for(f.hour()>11&&!h&&c.hour(12);c.isSame(f,"d")&&(h||f.hour()<12&&c.hour()<12||f.hour()>11);)c.hour()%4===0&&(e=a("<tr>"),d.push(e)),e.append('<td data-action="selectHour" class="hour'+(Q(c,"h")?"":" disabled")+'">'+c.format(h?"HH":"hh")+"</td>"),c.add(1,"h");b.empty().append(d)},X=function(){for(var b=o.find(".timepicker-minutes table"),c=f.clone().startOf("h"),e=[],g=a("<tr>"),h=1===d.stepping?5:d.stepping;f.isSame(c,"h");)c.minute()%(4*h)===0&&(g=a("<tr>"),e.push(g)),g.append('<td data-action="selectMinute" class="minute'+(Q(c,"m")?"":" disabled")+'">'+c.format("mm")+"</td>"),c.add(h,"m");b.empty().append(e)},Y=function(){for(var b=o.find(".timepicker-seconds table"),c=f.clone().startOf("m"),d=[],e=a("<tr>");f.isSame(c,"m");)c.second()%20===0&&(e=a("<tr>"),d.push(e)),e.append('<td data-action="selectSecond" class="second'+(Q(c,"s")?"":" disabled")+'">'+c.format("ss")+"</td>"),c.add(5,"s");b.empty().append(d)},Z=function(){var a,b,c=o.find(".timepicker span[data-time-component]");h||(a=o.find(".timepicker [data-action=togglePeriod]"),b=e.clone().add(e.hours()>=12?-12:12,"h"),a.text(e.format("A")),Q(b,"h")?a.removeClass("disabled"):a.addClass("disabled")),c.filter("[data-time-component=hours]").text(e.format(h?"HH":"hh")),c.filter("[data-time-component=minutes]").text(e.format("mm")),c.filter("[data-time-component=seconds]").text(e.format("ss")),W(),X(),Y()},$=function(){o&&(V(),Z())},_=function(a){var b=m?null:e;return a?(a=a.clone().locale(d.locale),1!==d.stepping&&a.minutes(Math.round(a.minutes()/d.stepping)*d.stepping%60).seconds(0),void(Q(a)?(e=a,f=e.clone(),g.val(e.format(i)),c.data("date",e.format(i)),m=!1,$(),I({type:"dp.change",date:e.clone(),oldDate:b})):(d.keepInvalid||g.val(m?"":e.format(i)),I({type:"dp.error",date:a})))):(m=!0,g.val(""),c.data("date",""),I({type:"dp.change",date:!1,oldDate:b}),void $())},aa=function(){var b=!1;return o?(o.find(".collapse").each(function(){var c=a(this).data("collapse");return c&&c.transitioning?(b=!0,!1):!0}),b?l:(n&&n.hasClass("btn")&&n.toggleClass("active"),o.hide(),a(window).off("resize",H),o.off("click","[data-action]"),o.off("mousedown",!1),o.remove(),o=!1,I({type:"dp.hide",date:e.clone()}),g.blur(),l)):l},ba=function(){_(null)},ca={next:function(){var a=q[k].navFnc;f.add(q[k].navStep,a),V(),J(a)},previous:function(){var a=q[k].navFnc;f.subtract(q[k].navStep,a),V(),J(a)},pickerSwitch:function(){K(1)},selectMonth:function(b){var c=a(b.target).closest("tbody").find("span").index(a(b.target));
12311f.month(c),k===p?(_(e.clone().year(f.year()).month(f.month())),d.inline||aa()):(K(-1),V()),J("M")},selectYear:function(b){var c=parseInt(a(b.target).text(),10)||0;f.year(c),k===p?(_(e.clone().year(f.year())),d.inline||aa()):(K(-1),V()),J("YYYY")},selectDecade:function(b){var c=parseInt(a(b.target).data("selection"),10)||0;f.year(c),k===p?(_(e.clone().year(f.year())),d.inline||aa()):(K(-1),V()),J("YYYY")},selectDay:function(b){var c=f.clone();a(b.target).is(".old")&&c.subtract(1,"M"),a(b.target).is(".new")&&c.add(1,"M"),_(c.date(parseInt(a(b.target).text(),10))),z()||d.keepOpen||d.inline||aa()},incrementHours:function(){var a=e.clone().add(1,"h");Q(a,"h")&&_(a)},incrementMinutes:function(){var a=e.clone().add(d.stepping,"m");Q(a,"m")&&_(a)},incrementSeconds:function(){var a=e.clone().add(1,"s");Q(a,"s")&&_(a)},decrementHours:function(){var a=e.clone().subtract(1,"h");Q(a,"h")&&_(a)},decrementMinutes:function(){var a=e.clone().subtract(d.stepping,"m");Q(a,"m")&&_(a)},decrementSeconds:function(){var a=e.clone().subtract(1,"s");Q(a,"s")&&_(a)},togglePeriod:function(){_(e.clone().add(e.hours()>=12?-12:12,"h"))},togglePicker:function(b){var c,e=a(b.target),f=e.closest("ul"),g=f.find(".in"),h=f.find(".collapse:not(.in)");if(g&&g.length){if(c=g.data("collapse"),c&&c.transitioning)return;g.collapse?(g.collapse("hide"),h.collapse("show")):(g.removeClass("in"),h.addClass("in")),e.is("span")?e.toggleClass(d.icons.time+" "+d.icons.date):e.find("span").toggleClass(d.icons.time+" "+d.icons.date)}},showPicker:function(){o.find(".timepicker > div:not(.timepicker-picker)").hide(),o.find(".timepicker .timepicker-picker").show()},showHours:function(){o.find(".timepicker .timepicker-picker").hide(),o.find(".timepicker .timepicker-hours").show()},showMinutes:function(){o.find(".timepicker .timepicker-picker").hide(),o.find(".timepicker .timepicker-minutes").show()},showSeconds:function(){o.find(".timepicker .timepicker-picker").hide(),o.find(".timepicker .timepicker-seconds").show()},selectHour:function(b){var c=parseInt(a(b.target).text(),10);h||(e.hours()>=12?12!==c&&(c+=12):12===c&&(c=0)),_(e.clone().hours(c)),ca.showPicker.call(l)},selectMinute:function(b){_(e.clone().minutes(parseInt(a(b.target).text(),10))),ca.showPicker.call(l)},selectSecond:function(b){_(e.clone().seconds(parseInt(a(b.target).text(),10))),ca.showPicker.call(l)},clear:ba,today:function(){var a=x();Q(a,"d")&&_(a)},close:aa},da=function(b){return a(b.currentTarget).is(".disabled")?!1:(ca[a(b.currentTarget).data("action")].apply(l,arguments),!1)},ea=function(){var b,c={year:function(a){return a.month(0).date(1).hours(0).seconds(0).minutes(0)},month:function(a){return a.date(1).hours(0).seconds(0).minutes(0)},day:function(a){return a.hours(0).seconds(0).minutes(0)},hour:function(a){return a.seconds(0).minutes(0)},minute:function(a){return a.seconds(0)}};return g.prop("disabled")||!d.ignoreReadonly&&g.prop("readonly")||o?l:(void 0!==g.val()&&0!==g.val().trim().length?_(ga(g.val().trim())):d.useCurrent&&m&&(g.is("input")&&0===g.val().trim().length||d.inline)&&(b=x(),"string"==typeof d.useCurrent&&(b=c[d.useCurrent](b)),_(b)),o=F(),L(),R(),o.find(".timepicker-hours").hide(),o.find(".timepicker-minutes").hide(),o.find(".timepicker-seconds").hide(),$(),K(),a(window).on("resize",H),o.on("click","[data-action]",da),o.on("mousedown",!1),n&&n.hasClass("btn")&&n.toggleClass("active"),o.show(),H(),d.focusOnShow&&!g.is(":focus")&&g.focus(),I({type:"dp.show"}),l)},fa=function(){return o?aa():ea()},ga=function(a){return a=void 0===d.parseInputDate?b.isMoment(a)||a instanceof Date?b(a):x(a):d.parseInputDate(a),a.locale(d.locale),a},ha=function(a){var b,c,e,f,g=null,h=[],i={},j=a.which,k="p";w[j]=k;for(b in w)w.hasOwnProperty(b)&&w[b]===k&&(h.push(b),parseInt(b,10)!==j&&(i[b]=!0));for(b in d.keyBinds)if(d.keyBinds.hasOwnProperty(b)&&"function"==typeof d.keyBinds[b]&&(e=b.split(" "),e.length===h.length&&v[j]===e[e.length-1])){for(f=!0,c=e.length-2;c>=0;c--)if(!(v[e[c]]in i)){f=!1;break}if(f){g=d.keyBinds[b];break}}g&&(g.call(l,o),a.stopPropagation(),a.preventDefault())},ia=function(a){w[a.which]="r",a.stopPropagation(),a.preventDefault()},ja=function(b){var c=a(b.target).val().trim(),d=c?ga(c):null;return _(d),b.stopImmediatePropagation(),!1},ka=function(){g.on({change:ja,blur:d.debug?"":aa,keydown:ha,keyup:ia,focus:d.allowInputToggle?ea:""}
12311),c.is("input")?g.on({focus:ea}):n&&(n.on("click",fa),n.on("mousedown",!1))},la=function(){g.off({change:ja,blur:blur,keydown:ha,keyup:ia,focus:d.allowInputToggle?aa:""}),c.is("input")?g.off({focus:ea}):n&&(n.off("click",fa),n.off("mousedown",!1))},ma=function(b){var c={};return a.each(b,function(){var a=ga(this);a.isValid()&&(c[a.format("YYYY-MM-DD")]=!0)}),Object.keys(c).length?c:!1},na=function(b){var c={};return a.each(b,function(){c[this]=!0}),Object.keys(c).length?c:!1},oa=function(){var a=d.format||"L LT";i=a.replace(/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,function(a){var b=e.localeData().longDateFormat(a)||a;return b.replace(/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,function(a){return e.localeData().longDateFormat(a)||a})}),j=d.extraFormats?d.extraFormats.slice():[],j.indexOf(a)<0&&j.indexOf(i)<0&&j.push(i),h=i.toLowerCase().indexOf("a")<1&&i.replace(/\[.*?\]/g,"").indexOf("h")<1,y("y")&&(p=2),y("M")&&(p=1),y("d")&&(p=0),k=Math.max(p,k),m||_(e)};if(l.destroy=function(){aa(),la(),c.removeData("DateTimePicker"),c.removeData("date")},l.toggle=fa,l.show=ea,l.hide=aa,l.disable=function(){return aa(),n&&n.hasClass("btn")&&n.addClass("disabled"),g.prop("disabled",!0),l},l.enable=function(){return n&&n.hasClass("btn")&&n.removeClass("disabled"),g.prop("disabled",!1),l},l.ignoreReadonly=function(a){if(0===arguments.length)return d.ignoreReadonly;if("boolean"!=typeof a)throw new TypeError("ignoreReadonly () expects a boolean parameter");return d.ignoreReadonly=a,l},l.options=function(b){if(0===arguments.length)return a.extend(!0,{},d);if(!(b instanceof Object))throw new TypeError("options() options parameter should be an object");return a.extend(!0,d,b),a.each(d,function(a,b){if(void 0===l[a])throw new TypeError("option "+a+" is not recognized!");l[a](b)}),l},l.date=function(a){if(0===arguments.length)return m?null:e.clone();if(!(null===a||"string"==typeof a||b.isMoment(a)||a instanceof Date))throw new TypeError("date() parameter must be one of [null, string, moment or Date]");return _(null===a?null:ga(a)),l},l.format=function(a){if(0===arguments.length)return d.format;if("string"!=typeof a&&("boolean"!=typeof a||a!==!1))throw new TypeError("format() expects a sting or boolean:false parameter "+a);return d.format=a,i&&oa(),l},l.timeZone=function(a){return 0===arguments.length?d.timeZone:(d.timeZone=a,l)},l.dayViewHeaderFormat=function(a){if(0===arguments.length)return d.dayViewHeaderFormat;if("string"!=typeof a)throw new TypeError("dayViewHeaderFormat() expects a string parameter");return d.dayViewHeaderFormat=a,l},l.extraFormats=function(a){if(0===arguments.length)return d.extraFormats;if(a!==!1&&!(a instanceof Array))throw new TypeError("extraFormats() expects an array or false parameter");return d.extraFormats=a,j&&oa(),l},l.disabledDates=function(b){if(0===arguments.length)return d.disabledDates?a.extend({},d.disabledDates):d.disabledDates;if(!b)return d.disabledDates=!1,$(),l;if(!(b instanceof Array))throw new TypeError("disabledDates() expects an array parameter");return d.disabledDates=ma(b),d.enabledDates=!1,$(),l},l.enabledDates=function(b){if(0===arguments.length)return d.enabledDates?a.extend({},d.enabledDates):d.enabledDates;if(!b)return d.enabledDates=!1,$(),l;if(!(b instanceof Array))throw new TypeError("enabledDates() expects an array parameter");return d.enabledDates=ma(b),d.disabledDates=!1,$(),l},l.daysOfWeekDisabled=function(a){if(0===arguments.length)return d.daysOfWeekDisabled.splice(0);if("boolean"==typeof a&&!a)return d.daysOfWeekDisabled=!1,$(),l;if(!(a instanceof Array))throw new TypeError("daysOfWeekDisabled() expects an array parameter");if(d.daysOfWeekDisabled=a.reduce(function(a,b){return b=parseInt(b,10),b>6||0>b||isNaN(b)?a:(-1===a.indexOf(b)&&a.push(b),a)},[]).sort(),d.useCurrent&&!d.keepInvalid){for(var b=0;!Q(e,"d");){if(e.add(1,"d"),7===b)throw"Tried 7 times to find a valid date";b++}_(e)}return $(),l},l.maxDate=function(a){if(0===arguments.length)return d.maxDate?d.maxDate.clone():d.maxDate;if("boolean"==typeof a&&a===!1)return d.maxDate=!1,$(),l;"string"==typeof a&&("now"===a||"moment"===a)&&(a=x());var b=ga(a);if(!b.isValid())throw new TypeError("maxDate() Could not parse date parameter: "+a);if(d.minDate&&b.isBefore(d.minDate))throw new TypeError("maxDate() date parameter is before options.minDate: "+b.format(i));return d.maxDate=b,d.useCurrent&&!d.keepInvalid&&e.isAfter(a)&&_(d.maxDate),f.isAfter(b)&&(f=b.clone().subtract(d.stepping,"m")),$(),l}
vendor: 9,458 bytes, lines 12311-12312
12311,l.minDate=function(a){if(0===arguments.length)return d.minDate?d.minDate.clone():d.minDate;if("boolean"==typeof a&&a===!1)return d.minDate=!1,$(),l;"string"==typeof a&&("now"===a||"moment"===a)&&(a=x());var b=ga(a);if(!b.isValid())throw new TypeError("minDate() Could not parse date parameter: "+a);if(d.maxDate&&b.isAfter(d.maxDate))throw new TypeError("minDate() date parameter is after options.maxDate: "+b.format(i));return d.minDate=b,d.useCurrent&&!d.keepInvalid&&e.isBefore(a)&&_(d.minDate),f.isBefore(b)&&(f=b.clone().add(d.stepping,"m")),$(),l},l.defaultDate=function(a){if(0===arguments.length)return d.defaultDate?d.defaultDate.clone():d.defaultDate;if(!a)return d.defaultDate=!1,l;"string"==typeof a&&("now"===a||"moment"===a)&&(a=x());var b=ga(a);if(!b.isValid())throw new TypeError("defaultDate() Could not parse date parameter: "+a);if(!Q(b))throw new TypeError("defaultDate() date passed is invalid according to component setup validations");return d.defaultDate=b,(d.defaultDate&&d.inline||""===g.val().trim())&&_(d.defaultDate),l},l.locale=function(a){if(0===arguments.length)return d.locale;if(!b.localeData(a))throw new TypeError("locale() locale "+a+" is not loaded from moment locales!");return d.locale=a,e.locale(d.locale),f.locale(d.locale),i&&oa(),o&&(aa(),ea()),l},l.stepping=function(a){return 0===arguments.length?d.stepping:(a=parseInt(a,10),(isNaN(a)||1>a)&&(a=1),d.stepping=a,l)},l.useCurrent=function(a){var b=["year","month","day","hour","minute"];if(0===arguments.length)return d.useCurrent;if("boolean"!=typeof a&&"string"!=typeof a)throw new TypeError("useCurrent() expects a boolean or string parameter");if("string"==typeof a&&-1===b.indexOf(a.toLowerCase()))throw new TypeError("useCurrent() expects a string parameter of "+b.join(", "));return d.useCurrent=a,l},l.collapse=function(a){if(0===arguments.length)return d.collapse;if("boolean"!=typeof a)throw new TypeError("collapse() expects a boolean parameter");return d.collapse===a?l:(d.collapse=a,o&&(aa(),ea()),l)},l.icons=function(b){if(0===arguments.length)return a.extend({},d.icons);if(!(b instanceof Object))throw new TypeError("icons() expects parameter to be an Object");return a.extend(d.icons,b),o&&(aa(),ea()),l},l.tooltips=function(b){if(0===arguments.length)return a.extend({},d.tooltips);if(!(b instanceof Object))throw new TypeError("tooltips() expects parameter to be an Object");return a.extend(d.tooltips,b),o&&(aa(),ea()),l},l.useStrict=function(a){if(0===arguments.length)return d.useStrict;if("boolean"!=typeof a)throw new TypeError("useStrict() expects a boolean parameter");return d.useStrict=a,l},l.sideBySide=function(a){if(0===arguments.length)return d.sideBySide;if("boolean"!=typeof a)throw new TypeError("sideBySide() expects a boolean parameter");return d.sideBySide=a,o&&(aa(),ea()),l},l.viewMode=function(a){if(0===arguments.length)return d.viewMode;if("string"!=typeof a)throw new TypeError("viewMode() expects a string parameter");if(-1===r.indexOf(a))throw new TypeError("viewMode() parameter must be one of ("+r.join(", ")+") value");return d.viewMode=a,k=Math.max(r.indexOf(a),p),K(),l},l.toolbarPlacement=function(a){if(0===arguments.length)return d.toolbarPlacement;if("string"!=typeof a)throw new TypeError("toolbarPlacement() expects a string parameter");if(-1===u.indexOf(a))throw new TypeError("toolbarPlacement() parameter must be one of ("+u.join(", ")+") value");return d.toolbarPlacement=a,o&&(aa(),ea()),l},l.widgetPositioning=function(b){if(0===arguments.length)return a.extend({},d.widgetPositioning);if("[object Object]"!=={}.toString.call(b))throw new TypeError("widgetPositioning() expects an object variable");if(b.horizontal){if("string"!=typeof b.horizontal)throw new TypeError("widgetPositioning() horizontal variable must be a string");if(b.horizontal=b.horizontal.toLowerCase(),-1===t.indexOf(b.horizontal))throw new TypeError("widgetPositioning() expects horizontal parameter to be one of ("+t.join(", ")+")");d.widgetPositioning.horizontal=b.horizontal}if(b.vertical){if("string"!=typeof b.vertical)throw new TypeError("widgetPositioning() vertical variable must be a string");if(b.vertical=b.vertical.toLowerCase(),-1===s.indexOf(b.vertical))throw new TypeError("widgetPositioning() expects vertical parameter to be one of ("+s.join(", ")+")");d.widgetPositioning.vertical=b.vertical}return $(),l},l.calendarWeeks=function(a){if(0===arguments.length)return d.calendarWeeks;if("boolean"!=typeof a)throw new TypeError("calendarWeeks() expects parameter to be a boolean value");return d.calendarWeeks=a,$(),l},l.showTodayButton=function(a){if(0===arguments.length)return d.showTodayButton;if("boolean"!=typeof a)throw new TypeError("showTodayButton() expects a boolean parameter");return d.showTodayButton=a,o&&(aa(),ea()),l},l.showClear=function(a){if(0===arguments.length)return d.showClear;if("boolean"!=typeof a)throw new TypeError("showClear() expects a boolean parameter");return d.showClear=a,o&&(aa(),ea()),l},l.widgetParent=function(b){if(0===arguments.length)return d.widgetParent;if("string"==typeof b&&(b=a(b)),null!==b&&"string"!=typeof b&&!(b instanceof a))throw new TypeError("widgetParent() expects a string or a jQuery object parameter");return d.widgetParent=b,o&&(aa(),ea()),l},l.keepOpen=function(a){if(0===arguments.length)return d.keepOpen;if("boolean"!=typeof a)throw new TypeError("keepOpen() expects a boolean parameter");return d.keepOpen=a,l},l.focusOnShow=function(a){if(0===arguments.length)return d.focusOnShow;if("boolean"!=typeof a)throw new TypeError("focusOnShow() expects a boolean parameter");return d.focusOnShow=a,l},l.inline=function(a){if(0===arguments.length)return d.inline;if("boolean"!=typeof a)throw new TypeError("inline() expects a boolean parameter");return d.inline=a,l},l.clear=function(){return ba(),l},l.keyBinds=function(a){return d.keyBinds=a,l},l.getMoment=function(a){return x(a)},l.debug=function(a){if("boolean"!=typeof a)throw new TypeError("debug() expects a boolean parameter");return d.debug=a,l},l.allowInputToggle=function(a){if(0===arguments.length)return d.allowInputToggle;if("boolean"!=typeof a)throw new TypeError("allowInputToggle() expects a boolean parameter");return d.allowInputToggle=a,l},l.showClose=function(a){if(0===arguments.length)return d.showClose;if("boolean"!=typeof a)throw new TypeError("showClose() expects a boolean parameter");return d.showClose=a,l},l.keepInvalid=function(a){if(0===arguments.length)return d.keepInvalid;if("boolean"!=typeof a)throw new TypeError("keepInvalid() expects a boolean parameter");return d.keepInvalid=a,l},l.datepickerInput=function(a){if(0===arguments.length)return d.datepickerInput;if("string"!=typeof a)throw new TypeError("datepickerInput() expects a string parameter");return d.datepickerInput=a,l},l.parseInputDate=function(a){if(0===arguments.length)return d.parseInputDate;
12312        if("function"!=typeof a)throw new TypeError("parseInputDate() sholud be as function");return d.parseInputDate=a,l},l.disabledTimeIntervals=function(b){if(0===arguments.length)return d.disabledTimeIntervals?a.extend({},d.disabledTimeIntervals):d.disabledTimeIntervals;if(!b)return d.disabledTimeIntervals=!1,$(),l;if(!(b instanceof Array))throw new TypeError("disabledTimeIntervals() expects an array parameter");return d.disabledTimeIntervals=b,$(),l},l.disabledHours=function(b){if(0===arguments.length)return d.disabledHours?a.extend({},d.disabledHours):d.disabledHours;if(!b)return d.disabledHours=!1,$(),l;if(!(b instanceof Array))throw new TypeError("disabledHours() expects an array parameter");if(d.disabledHours=na(b),d.enabledHours=!1,d.useCurrent&&!d.keepInvalid){for(var c=0;!Q(e,"h");){if(e.add(1,"h"),24===c)throw"Tried 24 times to find a valid date";c++}_(e)}return $(),l},l.enabledHours=function(b){if(0===arguments.length)return d.enabledHours?a.extend({},d.enabledHours):d.enabledHours;if(!b)return d.enabledHours=!1,$(),l;if(!(b instanceof Array))throw new TypeError("enabledHours() expects an array parameter");if(d.enabledHours=na(b),d.disabledHours=!1,d.useCurrent&&!d.keepInvalid){for(var c=0;!Q(e,"h");){if(e.add(1,"h"),24===c)throw"Tried 24 times to find a valid date";c++}_(e)}return $(),l},l.viewDate=function(a){if(0===arguments.length)return f.clone();if(!a)return f=e.clone(),l;if(!("string"==typeof a||b.isMoment(a)||a instanceof Date))throw new TypeError("viewDate() parameter must be one of [string, moment or Date]");return f=ga(a),J(),l},c.is("input"))g=c;else if(g=c.find(d.datepickerInput),0===g.size())g=c.find("input");else if(!g.is("input"))throw new Error('CSS class "'+d.datepickerInput+'" cannot be applied to non input element');if(c.hasClass("input-group")&&(n=0===c.find(".datepickerbutton").size()?c.find(".input-group-addon"):c.find(".datepickerbutton")),!d.inline&&!g.is("input"))throw new Error("Could not initialize DateTimePicker without an input element");return e=x(),f=e.clone(),a.extend(!0,d,G()),l.options(d),oa(),ka(),g.prop("disabled")&&l.disable(),g.is("input")&&0!==g.val().trim().length?_(ga(g.val().trim())):d.defaultDate&&void 0===g.attr("placeholder")&&_(d.defaultDate),d.inline&&ea(),l};a.fn.datetimepicker=function(b){return this.each(function(){var d=a(this);d.data("DateTimePicker")||(b=a.extend(!0,{},a.fn.datetimepicker.defaults,b),d.data("DateTimePicker",c(d,b)))})},a.fn.datetimepicker.defaults={timeZone:"Etc/UTC",format:!1,dayViewHeaderFormat:"MMMM YYYY",extraFormats:!1,stepping:1,minDate:!1,maxDate:!1,useCurrent:!0,
12312collapse:!0,locale:b.locale(),defaultDate:!1,disabledDates:!1,enabledDates:!1,icons:{time:"glyphicon glyphicon-time",date:"glyphicon glyphicon-calendar",up:"glyphicon glyphicon-chevron-up",down:"glyphicon glyphicon-chevron-down",previous:"glyphicon glyphicon-chevron-left",next:"glyphicon glyphicon-chevron-right",today:"glyphicon glyphicon-screenshot",clear:"glyphicon glyphicon-trash",close:"glyphicon glyphicon-remove"},tooltips:{today:"Go to today",clear:"Clear selection",close:"Close the picker",selectMonth:"Select Month",prevMonth:"Previous Month",nextMonth:"Next Month",selectYear:"Select Year",prevYear:"Previous Year",nextYear:"Next Year",selectDecade:"Select Decade",prevDecade:"Previous Decade",nextDecade:"Next Decade",prevCentury:"Previous Century",nextCentury:"Next Century",pickHour:"Pick Hour",incrementHour:"Increment Hour",decrementHour:"Decrement Hour",pickMinute:"Pick Minute",incrementMinute:"Increment Minute",decrementMinute:"Decrement Minute",pickSecond:"Pick Second",incrementSecond:"Increment Second",decrementSecond:"Decrement Second",togglePeriod:"Toggle Period",selectTime:"Select Time"},useStrict:!1,sideBySide:!1,daysOfWeekDisabled:!1,calendarWeeks:!1,viewMode:"days",toolbarPlacement:"default",showTodayButton:!1,showClear:!1,showClose:!1,widgetPositioning:{horizontal:"auto",vertical:"auto"},widgetParent:null,ignoreReadonly:!1,keepOpen:!1,focusOnShow:!0,inline:!1,keepInvalid:!1,datepickerInput:".datepickerinput",keyBinds:{up:function(a){if(a){var b=this.date()||this.getMoment();a.find(".datepicker").is(":visible")?this.date(b.clone().subtract(7,"d")):this.date(b.clone().add(this.stepping(),"m"))}},down:function(a){if(!a)return void this.show();var b=this.date()||this.getMoment();a.find(".datepicker").is(":visible")?this.date(b.clone().add(7,"d")):this.date(b.clone().subtract(this.stepping(),"m"))},"control up":function(a){if(a){var b=this.date()||this.getMoment();a.find(".datepicker").is(":visible")?this.date(b.clone().subtract(1,"y")):this.date(b.clone().add(1,"h"))}},"control down":function(a){if(a){var b=this.date()||this.getMoment();a.find(".datepicker").is(":visible")?this.date(b.clone().add(1,"y")):this.date(b.clone().subtract(1,"h"))}},left:function(a){if(a){var b=this.date()||this.getMoment();a.find(".datepicker").is(":visible")&&this.date(b.clone().subtract(1,"d"))}},right:function(a){if(a){var b=this.date()||this.getMoment();a.find(".datepicker").is(":visible")&&this.date(b.clone().add(1,"d"))}},pageUp:function(a){if(a){var b=this.date()||this.getMoment();a.find(".datepicker").is(":visible")&&this.date(b.clone().subtract(1,"M"))}},pageDown:function(a){if(a){var b=this.date()||this.getMoment();a.find(".datepicker").is(":visible")&&this.date(b.clone().add(1,"M"))}},enter:function(){this.hide()},escape:function(){this.hide()},"control space":function(a){a.find(".timepicker").is(":visible")&&a.find('.btn[data-action="togglePeriod"]').click()},t:function(){this.date(this.getMoment())},"delete":function(){this.clear()}},debug:!1,allowInputToggle:!1,disabledTimeIntervals:!1,disabledHours:!1,enabledHours:!1,viewDate:!1}});
12313/*!
12314 * Jasny Bootstrap v3.1.3 (http://jasny.github.io/bootstrap)
12315 * Copyright 2012-2014 Arnold Daniels
12316 * Licensed under Apache-2.0 (https://github.com/jasny/bootstrap/blob/master/LICENSE)
12317 */
12318
12319if (typeof jQuery === 'undefined') { throw new Error('Jasny Bootstrap\'s JavaScript requires jQuery') }
12320
12321/* ========================================================================
12322 * Bootstrap: transition.js v3.1.3
12323 * http://getbootstrap.com/javascript/#transitions
12324 * ========================================================================
12325 * Copyright 2011-2014 Twitter, Inc.
12326 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
12327 * ======================================================================== */
12328
12329
12330+function ($) {
12331  'use strict';
12332
12333  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
12334  // ============================================================
12335
12336  function transitionEnd() {
12337    var el = document.createElement('bootstrap')
12338
12339    var transEndEventNames = {
12340      WebkitTransition : 'webkitTransitionEnd',
12341      MozTransition    : 'transitionend',
12342      OTransition      : 'oTransitionEnd otransitionend',
12343      transition       : 'transitionend'
12344    }
12345
12346    for (var name in transEndEventNames) {
12347      if (el.style[name] !== undefined) {
12348        return { end: transEndEventNames[name] }
12349      }
12350    }
12351
12352    return false // explicit for ie8 (  ._.)
12353  }
12354
12355  if ($.support.transition !== undefined) return  // Prevent conflict with Twitter Bootstrap
12356
12357  // http://blog.alexmaccaw.com/css-transitions
12358  $.fn.emulateTransitionEnd = function (duration) {
12359    var called = false, $el = this
12360    $(this).one($.support.transition.end, function () { called = true })
12361    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
12362    setTimeout(callback, duration)
12363    return this
12364  }
12365
12366  $(function () {
12367    $.support.transition = transitionEnd()
12368  })
12369
12370}(window.jQuery);
12371
12372/* ========================================================================
12373 * Bootstrap: offcanvas.js v3.1.3
12374 * http://jasny.github.io/bootstrap/javascript/#offcanvas
12375 * ========================================================================
12376 * Copyright 2013-2014 Arnold Daniels
12377 *
12378 * Licensed under the Apache License, Version 2.0 (the "License")
12379 * you may not use this file except in compliance with the License.
12380 * You may obtain a copy of the License at
12381 *
12382 * http://www.apache.org/licenses/LICENSE-2.0
12383 *
12384 * Unless required by applicable law or agreed to in writing, software
12385 * distributed under the License is distributed on an "AS IS" BASIS,
12386 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12387 * See the License for the specific language governing permissions and
12388 * limitations under the License.
12389 * ======================================================================== */
12390
12391+function ($) { "use strict";
12392
12393  // OFFCANVAS PUBLIC CLASS DEFINITION
12394  // =================================
12395
12396  var OffCanvas = function (element, options) {
12397    this.$element = $(element)
12398    this.options  = $.extend({}, OffCanvas.DEFAULTS, options)
12399    this.state    = null
12400    this.placement = null
12401    
12402    if (this.options.recalc) {
12403      this.calcClone()
12404      $(window).on('resize', $.proxy(this.recalc, this))
12405    }
12406    
12407    if (this.options.autohide)
12408      $(document).on('click', $.proxy(this.autohide, this))
12409
12410    if (this.options.toggle) this.toggle()
12411    
12412    if (this.options.disablescrolling) {
12413        this.options.disableScrolling = this.options.disablescrolling
12414        delete this.options.disablescrolling
12415    }
12416  }
12417
12418  OffCanvas.DEFAULTS = {
12419    toggle: true,
12420    placement: 'auto',
12421    autohide: true,
12422    recalc: true,
12423    disableScrolling: true
12424  }
12425
12426  OffCanvas.prototype.offset = function () {
12427    switch (this.placement) {
12428      case 'left':
12429      case 'right':  return this.$element.outerWidth()
12430      case 'top':
12431      case 'bottom': return this.$element.outerHeight()
12432    }
12433  }
12434  
12435  OffCanvas.prototype.calcPlacement = function () {
12436    if (this.options.placement !== 'auto') {
12437        this.placement = this.options.placement
12438        return
12439    }
12440    
12441    if (!this.$element.hasClass('in')) {
12442      this.$element.css('visiblity', 'hidden !important').addClass('in')
12443    } 
12444    
12445    var horizontal = $(window).width() / this.$element.width()
12446    var vertical = $(window).height() / this.$element.height()
12447        
12448    var element = this.$element
12449    function ab(a, b) {
12450      if (element.css(b) === 'auto') return a
12451      if (element.css(a) === 'auto') return b
12452      
12453      var size_a = parseInt(element.css(a), 10)
12454      var size_b = parseInt(element.css(b), 10)
12455  
12456      return size_a > size_b ? b : a
12457    }
12458    
12459    this.placement = horizontal >= vertical ? ab('left', 'right') : ab('top', 'bottom')
12460      
12461    if (this.$element.css('visibility') === 'hidden !important') {
12462      this.$element.removeClass('in').css('visiblity', '')
12463    }
12464  }
12465  
12466  OffCanvas.prototype.opposite = function (placement) {
12467    switch (placement) {
12468      case 'top':    return 'bottom'
12469      case 'left':   return 'right'
12470      case 'bottom': return 'top'
12471      case 'right':  return 'left'
12472    }
12473  }
12474  
12475  OffCanvas.prototype.getCanvasElements = function() {
12476    // Return a set containing the canvas plus all fixed elements
12477    var canvas = this.options.canvas ? $(this.options.canvas) : this.$element
12478    
12479    var fixed_elements = canvas.find('*').filter(function() {
12480      return $(this).css('position') === 'fixed'
12481    }).not(this.options.exclude)
12482    
12483    return canvas.add(fixed_elements)
12484  }
12485  
12486  OffCanvas.prototype.slide = function (elements, offset, callback) {
12487    // Use jQuery animation if CSS transitions aren't supported
12488    if (!$.support.transition) {
12489      var anim = {}
12490      anim[this.placement] = "+=" + offset
12491      return elements.animate(anim, 350, callback)
12492    }
12493
12494    var placement = this.placement
12495    var opposite = this.opposite(placement)
12496    
12497    elements.each(function() {
12498      if ($(this).css(placement) !== 'auto')
12499        $(this).css(placement, (parseInt($(this).css(placement), 10) || 0) + offset)
12500      
12501      if ($(this).css(opposite) !== 'auto')
12502        $(this).css(opposite, (parseInt($(this).css(opposite), 10) || 0) - offset)
12503    })
12504    
12505    this.$element
12506      .one($.support.transition.end, callback)
12507      .emulateTransitionEnd(350)
12508  }
12509
12510  OffCanvas.prototype.disableScrolling = function() {
12511    var bodyWidth = $('body').width()
12512    var prop = 'padding-' + this.opposite(this.placement)
12513
12514    if ($('body').data('offcanvas-style') === undefined) {
12515      $('body').data('offcanvas-style', $('body').attr('style') || '')
12516    }
12517      
12518    $('body').css('overflow', 'hidden')
12519
12520    if ($('body').width() > bodyWidth) {
12521      var padding = parseInt($('body').css(prop), 10) + $('body').width() - bodyWidth
12522      
12523      setTimeout(function() {
12524        $('body').css(prop, padding)
12525      }, 1)
12526    }
12527  }
12528
12529  OffCanvas.prototype.show = function () {
12530    if (this.state) return
12531    
12532    var startEvent = $.Event('show.bs.offcanvas')
12533    this.$element.trigger(startEvent)
12534    if (startEvent.isDefaultPrevented()) return
12535
12536    this.state = 'slide-in'
12537    this.calcPlacement();
12538    
12539    var elements = this.getCanvasElements()
12540    var placement = this.placement
12541    var opposite = this.opposite(placement)
12542    var offset = this.offset()
12543
12544    if (elements.index(this.$element) !== -1) {
12545      $(this.$element).data('offcanvas-style', $(this.$element).attr('style') || '')
12546      this.$element.css(placement, -1 * offset)
12547      this.$element.css(placement); // Workaround: Need to get the CSS property for it to be applied before the next line of code
12548    }
12549
12550    elements.addClass('canvas-sliding').each(function() {
12551      if ($(this).data('offcanvas-style') === undefined) $(this).data('offcanvas-style', $(this).attr('style') || '')
12552      if ($(this).css('position') === 'static') $(this).css('position', 'relative')
12553      if (($(this).css(placement) === 'auto' || $(this).css(placement) === '0px') &&
12554          ($(this).css(opposite) === 'auto' || $(this).css(opposite) === '0px')) {
12555        $(this).css(placement, 0)
12556      }
12557    })
12558    
12559    if (this.options.disableScrolling) this.disableScrolling()
12560    
12561    var complete = function () {
12562      if (this.state != 'slide-in') return
12563      
12564      this.state = 'slid'
12565
12566      elements.removeClass('canvas-sliding').addClass('canvas-slid')
12567      this.$element.trigger('shown.bs.offcanvas')
12568    }
12569
12570    setTimeout($.proxy(function() {
12571      this.$element.addClass('in')
12572      this.slide(elements, offset, $.proxy(complete, this))
12573    }, this), 1)
12574  }
12575
12576  OffCanvas.prototype.hide = function (fast) {
12577    if (this.state !== 'slid') return
12578
12579    var startEvent = $.Event('hide.bs.offcanvas')
12580    this.$element.trigger(startEvent)
12581    if (startEvent.isDefaultPrevented()) return
12582
12583    this.state = 'slide-out'
12584
12585    var elements = $('.canvas-slid')
12586    var placement = this.placement
12587    var offset = -1 * this.offset()
12588
12589    var complete = function () {
12590      if (this.state != 'slide-out') return
12591      
12592      this.state = null
12593      this.placement = null
12594      
12595      this.$element.removeClass('in')
12596      
12597      elements.removeClass('canvas-sliding')
12598      elements.add(this.$element).add('body').each(function() {
12599        $(this).attr('style', $(this).data('offcanvas-style')).removeData('offcanvas-style')
12600      })
12601
12602      this.$element.trigger('hidden.bs.offcanvas')
12603    }
12604
12605    elements.removeClass('canvas-slid').addClass('canvas-sliding')
12606    
12607    setTimeout($.proxy(function() {
12608      this.slide(elements, offset, $.proxy(complete, this))
12609    }, this), 1)
12610  }
12611
12612  OffCanvas.prototype.toggle = function () {
12613    if (this.state === 'slide-in' || this.state === 'slide-out') return
12614    this[this.state === 'slid' ? 'hide' : 'show']()
12615  }
12616
12617  OffCanvas.prototype.calcClone = function() {
12618    this.$calcClone = this.$element.clone()
12619      .html('')
12620      .addClass('offcanvas-clone').removeClass('in')
12621      .appendTo($('body'))
12622  }
12623
12624  OffCanvas.prototype.recalc = function () {
12625    if (this.$calcClone.css('display') === 'none' || (this.state !== 'slid' && this.state !== 'slide-in')) return
12626    
12627    this.state = null
12628    this.placement = null
12629    var elements = this.getCanvasElements()
12630    
12631    this.$element.removeClass('in')
12632    
12633    elements.removeClass('canvas-slid')
12634    elements.add(this.$element).add('body').each(function() {
12635      $(this).attr('style', $(this).data('offcanvas-style')).removeData('offcanvas-style')
12636    })
12637  }
12638  
12639  OffCanvas.prototype.autohide = function (e) {
12640    if ($(e.target).closest(this.$element).length === 0) this.hide()
12641  }
12642
12643  // OFFCANVAS PLUGIN DEFINITION
12644  // ==========================
12645
12646  var old = $.fn.offcanvas
12647
12648  $.fn.offcanvas = function (option) {
12649    return this.each(function () {
12650      var $this   = $(this)
12651      var data    = $this.data('bs.offcanvas')
12652      var options = $.extend({}, OffCanvas.DEFAULTS, $this.data(), typeof option === 'object' && option)
12653
12654      if (!data) $this.data('bs.offcanvas', (data = new OffCanvas(this, options)))
12655      if (typeof option === 'string') data[option]()
12656    })
12657  }
12658
12659  $.fn.offcanvas.Constructor = OffCanvas
12660
12661
12662  // OFFCANVAS NO CONFLICT
12663  // ====================
12664
12665  $.fn.offcanvas.noConflict = function () {
12666    $.fn.offcanvas = old
12667    return this
12668  }
12669
12670
12671  // OFFCANVAS DATA-API
12672  // =================
12673
12674  $(document).on('click.bs.offcanvas.data-api', '[data-toggle=offcanvas]', function (e) {
12675    var $this   = $(this), href
12676    var target  = $this.attr('data-target')
12677        || e.preventDefault()
12678        || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
12679    var $canvas = $(target)
12680    var data    = $canvas.data('bs.offcanvas')
12681    var option  = data ? 'toggle' : $this.data()
12682
12683    e.stopPropagation()
12684
12685    if (data) data.toggle()
12686      else $canvas.offcanvas(option)
12687  })
12688
12689}(window.jQuery);
12690
12691/* ============================================================
12692 * Bootstrap: rowlink.js v3.1.3
12693 * http://jasny.github.io/bootstrap/javascript/#rowlink
12694 * ============================================================
12695 * Copyright 2012-2014 Arnold Daniels
12696 *
12697 * Licensed under the Apache License, Version 2.0 (the "License");
12698 * you may not use this file except in compliance with the License.
12699 * You may obtain a copy of the License at
12700 *
12701 * http://www.apache.org/licenses/LICENSE-2.0
12702 *
12703 * Unless required by applicable law or agreed to in writing, software
12704 * distributed under the License is distributed on an "AS IS" BASIS,
12705 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12706 * See the License for the specific language governing permissions and
12707 * limitations under the License.
12708 * ============================================================ */
12709
12710+function ($) { "use strict";
12711
12712  var Rowlink = function (element, options) {
12713    this.$element = $(element)
12714    this.options = $.extend({}, Rowlink.DEFAULTS, options)
12715    
12716    this.$element.on('click.bs.rowlink', 'td:not(.rowlink-skip)', $.proxy(this.click, this))
12717  }
12718
12719  Rowlink.DEFAULTS = {
12720    target: "a"
12721  }
12722
12723  Rowlink.prototype.click = function(e) {
12724    var target = $(e.currentTarget).closest('tr').find(this.options.target)[0]
12725    if ($(e.target)[0] === target) return
12726    
12727    e.preventDefault();
12728    
12729    if (target.click) {
12730      target.click()
12731    } else if (document.createEvent) {
12732      var evt = document.createEvent("MouseEvents"); 
12733      evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); 
12734      target.dispatchEvent(evt);
12735    }
12736  }
12737
12738  
12739  // ROWLINK PLUGIN DEFINITION
12740  // ===========================
12741
12742  var old = $.fn.rowlink
12743
12744  $.fn.rowlink = function (options) {
12745    return this.each(function () {
12746      var $this = $(this)
12747      var data = $this.data('bs.rowlink')
12748      if (!data) $this.data('bs.rowlink', (data = new Rowlink(this, options)))
12749    })
12750  }
12751
12752  $.fn.rowlink.Constructor = Rowlink
12753
12754
12755  // ROWLINK NO CONFLICT
12756  // ====================
12757
12758  $.fn.rowlink.noConflict = function () {
12759    $.fn.rowlink = old
12760    return this
12761  }
12762
12763
12764  // ROWLINK DATA-API
12765  // ==================
12766
12767  $(document).on('click.bs.rowlink.data-api', '[data-link="row"]', function (e) {
12768    if ($(e.target).closest('.rowlink-skip').length !== 0) return
12769    
12770    var $this = $(this)
12771    if ($this.data('bs.rowlink')) return
12772    $this.rowlink($this.data())
12773    $(e.target).trigger('click.bs.rowlink')
12774  })
12775  
12776}(window.jQuery);
12777
12778/* ===========================================================
12779 * Bootstrap: inputmask.js v3.1.0
12780 * http://jasny.github.io/bootstrap/javascript/#inputmask
12781 * 
12782 * Based on Masked Input plugin by Josh Bush (digitalbush.com)
12783 * ===========================================================
12784 * Copyright 2012-2014 Arnold Daniels
12785 *
12786 * Licensed under the Apache License, Version 2.0 (the "License")
12787 * you may not use this file except in compliance with the License.
12788 * You may obtain a copy of the License at
12789 *
12790 * http://www.apache.org/licenses/LICENSE-2.0
12791 *
12792 * Unless required by applicable law or agreed to in writing, software
12793 * distributed under the License is distributed on an "AS IS" BASIS,
12794 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12795 * See the License for the specific language governing permissions and
12796 * limitations under the License.
12797 * ========================================================== */
12798
12799+function ($) { "use strict";
12800
12801  var isIphone = (window.orientation !== undefined)
12802  var isAndroid = navigator.userAgent.toLowerCase().indexOf("android") > -1
12803  var isIE = window.navigator.appName == 'Microsoft Internet Explorer'
12804
12805  // INPUTMASK PUBLIC CLASS DEFINITION
12806  // =================================
12807
12808  var Inputmask = function (element, options) {
12809    if (isAndroid) return // No support because caret positioning doesn't work on Android
12810    
12811    this.$element = $(element)
12812    this.options = $.extend({}, Inputmask.DEFAULTS, options)
12813    this.mask = String(this.options.mask)
12814    
12815    this.init()
12816    this.listen()
12817        
12818    this.checkVal() //Perform initial check for existing values
12819  }
12820
12821  Inputmask.DEFAULTS = {
12822    mask: "",
12823    placeholder: "_",
12824    definitions: {
12825      '9': "[0-9]",
12826      'a': "[A-Za-z]",
12827      'w': "[A-Za-z0-9]",
12828      '*': "."
12829    }
12830  }
12831
12832  Inputmask.prototype.init = function() {
12833    var defs = this.options.definitions
12834    var len = this.mask.length
12835
12836    this.tests = [] 
12837    this.partialPosition = this.mask.length
12838    this.firstNonMaskPos = null
12839
12840    $.each(this.mask.split(""), $.proxy(function(i, c) {
12841      if (c == '?') {
12842        len--
12843        this.partialPosition = i
12844      } else if (defs[c]) {
12845        this.tests.push(new RegExp(defs[c]))
12846        if (this.firstNonMaskPos === null)
12847          this.firstNonMaskPos =  this.tests.length - 1
12848      } else {
12849        this.tests.push(null)
12850      }
12851    }, this))
12852
12853    this.buffer = $.map(this.mask.split(""), $.proxy(function(c, i) {
12854      if (c != '?') return defs[c] ? this.options.placeholder : c
12855    }, this))
12856
12857    this.focusText = this.$element.val()
12858
12859    this.$element.data("rawMaskFn", $.proxy(function() {
12860      return $.map(this.buffer, function(c, i) {
12861        return this.tests[i] && c != this.options.placeholder ? c : null
12862      }).join('')
12863    }, this))
12864  }
12865    
12866  Inputmask.prototype.listen = function() {
12867    if (this.$element.attr("readonly")) return
12868
12869    var pasteEventName = (isIE ? 'paste' : 'input') + ".mask"
12870
12871    this.$element
12872      .on("unmask.bs.inputmask", $.proxy(this.unmask, this))
12873
12874      .on("focus.bs.inputmask", $.proxy(this.focusEvent, this))
12875      .on("blur.bs.inputmask", $.proxy(this.blurEvent, this))
12876
12877      .on("keydown.bs.inputmask", $.proxy(this.keydownEvent, this))
12878      .on("keypress.bs.inputmask", $.proxy(this.keypressEvent, this))
12879
12880      .on(pasteEventName, $.proxy(this.pasteEvent, this))
12881  }
12882
12883  //Helper Function for Caret positioning
12884  Inputmask.prototype.caret = function(begin, end) {
12885    if (this.$element.length === 0) return
12886    if (typeof begin == 'number') {
12887      end = (typeof end == 'number') ? end : begin
12888      return this.$element.each(function() {
12889        if (this.setSelectionRange) {
12890          this.setSelectionRange(begin, end)
12891        } else if (this.createTextRange) {
12892          var range = this.createTextRange()
12893          range.collapse(true)
12894          range.moveEnd('character', end)
12895          range.moveStart('character', begin)
12896          range.select()
12897        }
12898      })
12899    } else {
12900      if (this.$element[0].setSelectionRange) {
12901        begin = this.$element[0].selectionStart
12902        end = this.$element[0].selectionEnd
12903      } else if (document.selection && document.selection.createRange) {
12904        var range = document.selection.createRange()
12905        begin = 0 - range.duplicate().moveStart('character', -100000)
12906        end = begin + range.text.length
12907      }
12908      return {
12909        begin: begin, 
12910        end: end
12911      }
12912    }
12913  }
12914  
12915  Inputmask.prototype.seekNext = function(pos) {
12916    var len = this.mask.length
12917    while (++pos <= len && !this.tests[pos]);
12918
12919    return pos
12920  }
12921  
12922  Inputmask.prototype.seekPrev = function(pos) {
12923    while (--pos >= 0 && !this.tests[pos]);
12924
12925    return pos
12926  }
12927
12928  Inputmask.prototype.shiftL = function(begin,end) {
12929    var len = this.mask.length
12930
12931    if (begin < 0) return
12932
12933    for (var i = begin, j = this.seekNext(end); i < len; i++) {
12934      if (this.tests[i]) {
12935        if (j < len && this.tests[i].test(this.buffer[j])) {
12936          this.buffer[i] = this.buffer[j]
12937          this.buffer[j] = this.options.placeholder
12938        } else
12939          break
12940        j = this.seekNext(j)
12941      }
12942    }
12943    this.writeBuffer()
12944    this.caret(Math.max(this.firstNonMaskPos, begin))
12945  }
12946
12947  Inputmask.prototype.shiftR = function(pos) {
12948    var len = this.mask.length
12949
12950    for (var i = pos, c = this.options.placeholder; i < len; i++) {
12951      if (this.tests[i]) {
12952        var j = this.seekNext(i)
12953        var t = this.buffer[i]
12954        this.buffer[i] = c
12955        if (j < len && this.tests[j].test(t))
12956          c = t
12957        else
12958          break
12959      }
12960    }
12961  },
12962
12963  Inputmask.prototype.unmask = function() {
12964    this.$element
12965      .unbind(".mask")
12966      .removeData("inputmask")
12967  }
12968
12969  Inputmask.prototype.focusEvent = function() {
12970    this.focusText = this.$element.val()
12971    var len = this.mask.length 
12972    var pos = this.checkVal()
12973    this.writeBuffer()
12974
12975    var that = this
12976    var moveCaret = function() {
12977      if (pos == len)
12978        that.caret(0, pos)
12979      else
12980        that.caret(pos)
12981    }
12982
12983    moveCaret()
12984    setTimeout(moveCaret, 50)
12985  }
12986
12987  Inputmask.prototype.blurEvent = function() {
12988    this.checkVal()
12989    if (this.$element.val() !== this.focusText)
12990      this.$element.trigger('change')
12991  }
12992
12993  Inputmask.prototype.keydownEvent = function(e) {
12994    var k = e.which
12995
12996    //backspace, delete, and escape get special treatment
12997    if (k == 8 || k == 46 || (isIphone && k == 127)) {
12998      var pos = this.caret(),
12999      begin = pos.begin,
13000      end = pos.end
13001
13002      if (end - begin === 0) {
13003        begin = k != 46 ? this.seekPrev(begin) : (end = this.seekNext(begin - 1))
13004        end = k == 46 ? this.seekNext(end) : end
13005      }
13006      this.clearBuffer(begin, end)
13007      this.shiftL(begin, end - 1)
13008
13009      return false
13010    } else if (k == 27) {//escape
13011      this.$element.val(this.focusText)
13012      this.caret(0, this.checkVal())
13013      return false
13014    }
13015  }
13016
13017  Inputmask.prototype.keypressEvent = function(e) {
13018    var len = this.mask.length
13019
13020    var k = e.which,
13021    pos = this.caret()
13022
13023    if (e.ctrlKey || e.altKey || e.metaKey || k < 32)  {//Ignore
13024      return true
13025    } else if (k) {
13026      if (pos.end - pos.begin !== 0) {
13027        this.clearBuffer(pos.begin, pos.end)
13028        this.shiftL(pos.begin, pos.end - 1)
13029      }
13030
13031      var p = this.seekNext(pos.begin - 1)
13032      if (p < len) {
13033        var c = String.fromCharCode(k)
13034        if (this.tests[p].test(c)) {
13035          this.shiftR(p)
13036          this.buffer[p] = c
13037          this.writeBuffer()
13038          var next = this.seekNext(p)
13039          this.caret(next)
13040        }
13041      }
13042      return false
13043    }
13044  }
13045
13046  Inputmask.prototype.pasteEvent = function() {
13047    var that = this
13048
13049    setTimeout(function() {
13050      that.caret(that.checkVal(true))
13051    }, 0)
13052  }
13053
13054  Inputmask.prototype.clearBuffer = function(start, end) {
13055    var len = this.mask.length
13056
13057    for (var i = start; i < end && i < len; i++) {
13058      if (this.tests[i])
13059        this.buffer[i] = this.options.placeholder
13060    }
13061  }
13062
13063  Inputmask.prototype.writeBuffer = function() {
13064    return this.$element.val(this.buffer.join('')).val()
13065  }
13066
13067  Inputmask.prototype.checkVal = function(allow) {
13068    var len = this.mask.length
13069    //try to place characters where they belong
13070    var test = this.$element.val()
13071    var lastMatch = -1
13072
13073    for (var i = 0, pos = 0; i < len; i++) {
13074      if (this.tests[i]) {
13075        this.buffer[i] = this.options.placeholder
13076        while (pos++ < test.length) {
13077          var c = test.charAt(pos - 1)
13078          if (this.tests[i].test(c)) {
13079            this.buffer[i] = c
13080            lastMatch = i
13081            break
13082          }
13083        }
13084        if (pos > test.length)
13085          break
13086      } else if (this.buffer[i] == test.charAt(pos) && i != this.partialPosition) {
13087        pos++
13088        lastMatch = i
13089      }
13090    }
13091    if (!allow && lastMatch + 1 < this.partialPosition) {
13092      this.$element.val("")
13093      this.clearBuffer(0, len)
13094    } else if (allow || lastMatch + 1 >= this.partialPosition) {
13095      this.writeBuffer()
13096      if (!allow) this.$element.val(this.$element.val().substring(0, lastMatch + 1))
13097    }
13098    return (this.partialPosition ? i : this.firstNonMaskPos)
13099  }
13100
13101  
13102  // INPUTMASK PLUGIN DEFINITION
13103  // ===========================
13104
13105  var old = $.fn.inputmask
13106  
13107  $.fn.inputmask = function (options) {
13108    return this.each(function () {
13109      var $this = $(this)
13110      var data = $this.data('bs.inputmask')
13111      
13112      if (!data) $this.data('bs.inputmask', (data = new Inputmask(this, options)))
13113    })
13114  }
13115
13116  $.fn.inputmask.Constructor = Inputmask
13117
13118
13119  // INPUTMASK NO CONFLICT
13120  // ====================
13121
13122  $.fn.inputmask.noConflict = function () {
13123    $.fn.inputmask = old
13124    return this
13125  }
13126
13127
13128  // INPUTMASK DATA-API
13129  // ==================
13130
13131  $(document).on('focus.bs.inputmask.data-api', '[data-mask]', function (e) {
13132    var $this = $(this)
13133    if ($this.data('bs.inputmask')) return
13134    $this.inputmask($this.data())
13135  })
13136
13137}(window.jQuery);
13138
13139/*!
13140 * JavaScript Cookie v2.1.0
13141 * https://github.com/js-cookie/js-cookie
13142 *
13143 * Copyright 2006, 2015 Klaus Hartl & Fagner Brack
13144 * Released under the MIT license
13145 */
13146(function (factory) {
13147    if (typeof define === 'function' && define.amd) {
13148        define(factory);
13149    } else if (typeof exports === 'object') {
13150        module.exports = factory();
13151    } else {
13152        var _OldCookies = window.Cookies;
13153        var api = window.Cookies = factory();
13154        api.noConflict = function () {
13155            window.Cookies = _OldCookies;
13156            return api;
13157        };
13158    }
13159}(function () {
13160    function extend () {
13161        var i = 0;
13162        var result = {};
13163        for (; i < arguments.length; i++) {
13164            var attributes = arguments[ i ];
13165            for (var key in attributes) {
13166                result[key] = attributes[key];
13167            }
13168        }
13169        return result;
13170    }
13171
13172    function init (converter) {
13173        function api (key, value, attributes) {
13174            var result;
13175
13176            // Write
13177
13178            if (arguments.length > 1) {
13179                attributes = extend({
13180                    path: '/'
13181                }, api.defaults, attributes);
13182
13183                if (typeof attributes.expires === 'number') {
13184                    var expires = new Date();
13185                    expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5);
13186                    attributes.expires = expires;
13187                }
13188
13189                try {
13190                    result = JSON.stringify(value);
13191                    if (/^[\{\[]/.test(result)) {
13192                        value = result;
13193                    }
13194                } catch (e) {}
13195
13196                if (!converter.write) {
13197                    value = encodeURIComponent(String(value))
13198                        .replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
13199                } else {
13200                    value = converter.write(value, key);
13201                }
13202
13203                key = encodeURIComponent(String(key));
13204                key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent);
13205                key = key.replace(/[\(\)]/g, escape);
13206
13207                return (document.cookie = [
13208                    key, '=', value,
13209                    attributes.expires && '; expires=' + attributes.expires.toUTCString(), // use expires attribute, max-age is not supported by IE
13210                    attributes.path    && '; path=' + attributes.path,
13211                    attributes.domain  && '; domain=' + attributes.domain,
13212                    attributes.secure ? '; secure' : ''
13213                ].join(''));
vendor: 1,663 bytes, lines 13214-13265
13214            }
13215
13216            // Read
13217
13218            if (!key) {
13219                result = {};
13220            }
13221
13222            // To prevent the for loop in the first place assign an empty array
13223            // in case there are no cookies at all. Also prevents odd result when
13224            // calling "get()"
13225            var cookies = document.cookie ? document.cookie.split('; ') : [];
13226            var rdecode = /(%[0-9A-Z]{2})+/g;
13227            var i = 0;
13228
13229            for (; i < cookies.length; i++) {
13230                var parts = cookies[i].split('=');
13231                var name = parts[0].replace(rdecode, decodeURIComponent);
13232                var cookie = parts.slice(1).join('=');
13233
13234                if (cookie.charAt(0) === '"') {
13235                    cookie = cookie.slice(1, -1);
13236                }
13237
13238                try {
13239                    cookie = converter.read ?
13240                        converter.read(cookie, name) : converter(cookie, name) ||
13241                    cookie.replace(rdecode, decodeURIComponent);
13242
13243                    if (this.json) {
13244                        try {
13245                            cookie = JSON.parse(cookie);
13246                        } catch (e) {}
13247                    }
13248
13249                    if (key === name) {
13250                        result = cookie;
13251                        break;
13252                    }
13253
13254                    if (!key) {
13255                        result[name] = cookie;
13256                    }
13257                } catch (e) {}
13258            }
13259
13260            return result;
13261        }
13262
13263        api.get = api.set = api;
13264        api.getJSON = function () {
13265            return api.apply({
13266                json: true
13267            }, [].slice.call(arguments));
13268        };
13269        api.defaults = {};
13270
13271        api.remove = function (key, attributes) {
13272            api(key, '', extend(attributes, {
13273                expires: -1
13274            }));
13275        };
13276
13277        api.withConverter = init;
13278
13279        return api;
13280    }
13281
13282    return init(function () {});
13283}));
13284/*!
13285 * @copyright Copyright &copy; Kartik Visweswaran, Krajee.com, 2014 - 2015
13286 * @version 4.3.2
13287 *
13288 * File input styled for Bootstrap 3.0 that utilizes HTML5 File Input's advanced features including the FileReader API.
13289 *
13290 * The plugin drastically enhances the HTML file input to preview multiple files on the client before upload. In
13291 * addition it provides the ability to preview content of images, text, videos, audio, html, flash and other objects.
13292 * It also offers the ability to upload and delete files using AJAX, and add files in batches (i.e. preview, append,
13293 * or remove before upload).
13294 *
13295 * Author: Kartik Visweswaran
13296 * Copyright: 2015, Kartik Visweswaran, Krajee.com
13297 * For more JQuery plugins visit http://plugins.krajee.com
13298 * For more Yii related demos visit http://demos.krajee.com
13299 */
13300(function (factory) {
13301    "use strict";
13302    if (typeof define === 'function' && define.amd) { // jshint ignore:line
13303        // AMD. Register as an anonymous module.
13304        define(['jquery'], factory); // jshint ignore:line
13305    } else { // noinspection JSUnresolvedVariable
13306        if (typeof module === 'object' && module.exports) { // jshint ignore:line
13307            // Node/CommonJS
13308            // noinspection JSUnresolvedVariable
13309            module.exports = factory(require('jquery')); // jshint ignore:line
13310        } else {
13311            // Browser globals
13312            factory(window.jQuery);
13313        }
13314    }
13315}(function ($) {
13316    "use strict";
13317
13318    $.fn.fileinputLocales = {};
13319
13320    var NAMESPACE, objUrl, compare, isIE, isEdge, handler, previewCache, getNum, hasFileAPISupport, hasDragDropSupport,
13321        hasFileUploadSupport, addCss, STYLE_SETTING, OBJECT_PARAMS, DEFAULT_PREVIEW, defaultFileActionSettings, tMain1,
13322        tMain2, tPreview, tIcon, tClose, tCaption, tBtnDefault, tBtnLink, tBtnBrowse, tModal, tProgress, tFooter,
13323        tActions, tActionDelete, tActionUpload, tZoom, tGeneric, tHtml, tImage, tText, tVideo, tAudio, tFlash, tObject,
13324        tOther, defaultLayoutTemplates, defaultPreviewTemplates, defaultPreviewTypes, defaultPreviewSettings, FileInput,
13325        defaultFileTypeSettings, isEmpty, isArray, isSet, getElement, uniqId, htmlEncode, replaceTags, cleanMemory;
13326
13327    NAMESPACE = '.fileinput';
13328    //noinspection JSUnresolvedVariable
13329    objUrl = window.URL || window.webkitURL;
13330    compare = function (input, str, exact) {
13331        return input !== undefined && (exact ? input === str : input.match(str));
13332    };
13333    isIE = function (ver) {
13334        // check for IE versions < 11
13335        if (navigator.appName !== 'Microsoft Internet Explorer') {
13336            return false;
13337        }
13338        if (ver === 10) {
13339            return new RegExp('msie\\s' + ver, 'i').test(navigator.userAgent);
13340        }
13341        var div = document.createElement("div"), status;
13342        div.innerHTML = "<!--[if IE " + ver + "]> <i></i> <![endif]-->";
13343        status = div.getElementsByTagName("i").length;
13344        document.body.appendChild(div);
13345        div.parentNode.removeChild(div);
13346        return status;
13347    };
13348    isEdge = function () {
13349        return new RegExp('Edge\/[0-9]+', 'i').test(navigator.userAgent);
13350    };
13351    handler = function ($el, event, callback, skipNS) {
13352        var ev = skipNS ? event : event.split(' ').join(NAMESPACE + ' ') + NAMESPACE;
13353        $el.off(ev).on(ev, callback);
13354    };
13355    previewCache = {
13356        data: {},
13357        init: function (obj) {
13358            var content = obj.initialPreview, id = obj.id;
13359            if (content.length > 0 && !isArray(content)) {
13360                content = content.split(obj.initialPreviewDelimiter);
13361            }
13362            previewCache.data[id] = {
13363                content: content,
13364                config: obj.initialPreviewConfig,
13365                tags: obj.initialPreviewThumbTags,
13366                delimiter: obj.initialPreviewDelimiter,
13367                template: obj.previewGenericTemplate,
13368                msg: function (n) {
13369                    return obj._getMsgSelected(n);
13370                },
13371                initId: obj.previewInitId,
13372                footer: obj._getLayoutTemplate('footer').replace(/\{progress}/g, obj._renderThumbProgress()),
13373                isDelete: obj.initialPreviewShowDelete,
13374                caption: obj.initialCaption,
13375                actions: function (showUpload, showDelete, disabled, url, key) {
13376                    return obj._renderFileActions(showUpload, showDelete, disabled, url, key);
13377                }
13378            };
13379        },
13380        fetch: function (id) {
13381            return previewCache.data[id].content.filter(function (n) {
13382                return n !== null;
13383            });
13384        },
13385        count: function (id, all) {
13386            return !!previewCache.data[id] && !!previewCache.data[id].content ?
13387                (all ? previewCache.data[id].content.length : previewCache.fetch(id).length) : 0;
13388        },
13389        get: function (id, i, isDisabled) {
13390            var ind = 'init_' + i, data = previewCache.data[id], config = data.config[i],
13391                previewId = data.initId + '-' + ind, out, $tmp, frameClass = ' file-preview-initial';
13392            /** @namespace config.frameClass */
13393            /** @namespace config.frameAttr */
13394            isDisabled = isDisabled === undefined ? true : isDisabled;
13395            if (data.content[i] === null) {
13396                return '';
13397            }
13398            if (!isEmpty(config) && !isEmpty(config.frameClass)) {
13399                frameClass += ' ' + config.frameClass;
13400            }
13401            out = data.template
13402                .replace(/\{previewId}/g, previewId)
13403                .replace(/\{frameClass}/g, frameClass)
13404                .replace(/\{fileindex}/g, ind)
13405                .replace(/\{content}/g, data.content[i])
13406                .replace(/\{footer}/g, previewCache.footer(id, i, isDisabled));
13407            if (data.tags.length && data.tags[i]) {
13408                out = replaceTags(out, data.tags[i]);
13409            }
13410            if (!isEmpty(config) && !isEmpty(config.frameAttr)) {
13411                $tmp = $(document.createElement('div')).html(out);
13412                $tmp.find('.file-preview-initial').attr(config.frameAttr);
13413                out = $tmp.html();
13414                $tmp.remove();
13415            }
13416            return out;
13417        },
13418        add: function (id, content, config, tags, append) {
13419            var data = $.extend(true, {}, previewCache.data[id]), index;
13420            if (!isArray(content)) {
13421                content = content.split(data.delimiter);
13422            }
13423            if (append) {
13424                index = data.content.push(content) - 1;
13425                data.config[index] = config;
13426                data.tags[index] = tags;
13427            } else {
13428                index = content.length - 1;
13429                data.content = content;
13430                data.config = config;
13431                data.tags = tags;
13432            }
13433            previewCache.data[id] = data;
13434            return index;
13435        },
13436        set: function (id, content, config, tags, append) {
13437            var data = $.extend(true, {}, previewCache.data[id]), i, chk;
13438            if (!content || !content.length) {
13439                return;
13440            }
13441            if (!isArray(content)) {
13442                content = content.split(data.delimiter);
13443            }
13444            chk = content.filter(function (n) {
13445                return n !== null;
13446            });
13447            if (!chk.length) {
13448                return;
13449            }
13450            if (data.content === undefined) {
13451                data.content = [];
13452            }
13453            if (data.config === undefined) {
13454                data.config = [];
13455            }
13456            if (data.tags === undefined) {
13457                data.tags = [];
13458            }
13459            if (append) {
13460                for (i = 0; i < content.length; i++) {
13461                    if (content[i]) {
13462                        data.content.push(content[i]);
13463                    }
13464                }
13465                for (i = 0; i < config.length; i++) {
13466                    if (config[i]) {
13467                        data.config.push(config[i]);
13468                    }
13469                }
13470                for (i = 0; i < tags.length; i++) {
13471                    if (tags[i]) {
13472                        data.tags.push(tags[i]);
13473                    }
13474                }
13475            } else {
13476                data.content = content;
13477                data.config = config;
13478                data.tags = tags;
13479            }
13480            previewCache.data[id] = data;
13481        },
13482        unset: function (id, index) {
13483            var chk = previewCache.count(id);
13484            if (!chk) {
13485                return;
13486            }
13487            if (chk === 1) {
13488                previewCache.data[id].content = [];
13489                previewCache.data[id].config = [];
13490                previewCache.data[id].tags = [];
13491                return;
13492            }
13493            previewCache.data[id].content[index] = null;
13494            previewCache.data[id].config[index] = null;
13495            previewCache.data[id].tags[index] = null;
13496        },
13497        out: function (id) {
13498            var html = '', data = previewCache.data[id], caption, len = previewCache.count(id, true);
13499            if (len === 0) {
13500                return {content: '', caption: ''};
13501            }
13502            for (var i = 0; i < len; i++) {
13503                html += previewCache.get(id, i);
13504            }
13505            caption = data.msg(previewCache.count(id));
13506            return {content: html, caption: caption};
13507        },
13508        footer: function (id, i, isDisabled) {
13509            var data = previewCache.data[id];
13510            isDisabled = isDisabled === undefined ? true : isDisabled;
13511            if (data.config.length === 0 || isEmpty(data.config[i])) {
13512                return '';
13513            }
13514            var config = data.config[i],
13515                caption = isSet('caption', config) ? config.caption : '',
13516                width = isSet('width', config) ? config.width : 'auto',
13517                url = isSet('url', config) ? config.url : false,
13518                key = isSet('key', config) ? config.key : null,
13519                disabled = (url === false) && isDisabled,
13520                actions = data.isDelete ? data.actions(false, true, disabled, url, key) : '',
13521                footer = data.footer.replace(/\{actions}/g, actions);
13522            return footer.replace(/\{caption}/g, caption)
13523                .replace(/\{width}/g, width)
13524                .replace(/\{indicator}/g, '')
13525                .replace(/\{indicatorTitle}/g, '');
13526        }
13527    };
13528    getNum = function (num, def) {
13529        def = def || 0;
13530        if (typeof num === "number") {
13531            return num;
13532        }
13533        if (typeof num === "string") {
13534            num = parseFloat(num);
13535        }
13536        return isNaN(num) ? def : num;
13537    };
13538    hasFileAPISupport = function () {
13539        return !!(window.File && window.FileReader);
13540    };
13541    hasDragDropSupport = function () {
13542        var div = document.createElement('div');
13543        /** @namespace div.draggable */
13544        /** @namespace div.ondragstart */
13545        /** @namespace div.ondrop */
13546        return !isIE(9) && !isEdge() && // Fix for MS Edge drag & drop support bug
13547            (div.draggable !== undefined || (div.ondragstart !== undefined && div.ondrop !== undefined));
13548    };
13549    hasFileUploadSupport = function () {
13550        return hasFileAPISupport() && window.FormData;
13551    };
13552    addCss = function ($el, css) {
13553        $el.removeClass(css).addClass(css);
13554    };
13555    STYLE_SETTING = 'style="width:{width};height:{height};"';
13556    OBJECT_PARAMS = '      <param name="controller" value="true" />\n' +
13557        '      <param name="allowFullScreen" value="true" />\n' +
13558        '      <param name="allowScriptAccess" value="always" />\n' +
13559        '      <param name="autoPlay" value="false" />\n' +
13560        '      <param name="autoStart" value="false" />\n' +
13561        '      <param name="quality" value="high" />\n';
13562    DEFAULT_PREVIEW = '<div class="file-preview-other">\n' +
13563        '   <span class="{previewFileIconClass}">{previewFileIcon}</span>\n' +
13564        '</div>';
13565    defaultFileActionSettings = {
13566        removeIcon: '<i class="glyphicon glyphicon-trash text-danger"></i>',
13567        removeClass: 'btn btn-xs btn-default',
13568        removeTitle: 'Remove file',
13569        uploadIcon: '<i class="glyphicon glyphicon-upload text-info"></i>',
13570        uploadClass: 'btn btn-xs btn-default',
13571        uploadTitle: 'Upload file',
13572        indicatorNew: '<i class="glyphicon glyphicon-hand-down text-warning"></i>',
13573        indicatorSuccess: '<i class="glyphicon glyphicon-ok-sign text-success"></i>',
13574        indicatorError: '<i class="glyphicon glyphicon-exclamation-sign text-danger"></i>',
13575        indicatorLoading: '<i class="glyphicon glyphicon-hand-up text-muted"></i>',
13576        indicatorNewTitle: 'Not uploaded yet',
13577        indicatorSuccessTitle: 'Uploaded',
13578        indicatorErrorTitle: 'Upload Error',
13579        indicatorLoadingTitle: 'Uploading ...'
13580    };
13581    tMain1 = '{preview}\n' +
13582        '<div class="kv-upload-progress hide"></div>\n' +
13583        '<div class="input-group {class}">\n' +
13584        '   {caption}\n' +
13585        '   <div class="input-group-btn">\n' +
13586        '       {remove}\n' +
13587        '       {cancel}\n' +
13588        '       {upload}\n' +
13589        '       {browse}\n' +
13590        '   </div>\n' +
13591        '</div>';
13592    tMain2 = '{preview}\n<div class="kv-upload-progress hide"></div>\n{remove}\n{cancel}\n{upload}\n{browse}\n';
13593    tPreview = '<div class="file-preview {class}">\n' +
13594        '    {close}' +
13595        '    <div class="{dropClass}">\n' +
13596        '    <div class="file-preview-thumbnails">\n' +
13597        '    </div>\n' +
13598        '    <div class="clearfix"></div>' +
13599        '    <div class="file-preview-status text-center text-success"></div>\n' +
13600        '    <div class="kv-fileinput-error"></div>\n' +
13601        '    </div>\n' +
13602        '</div>';
13603    tClose = '<div class="close fileinput-remove">&times;</div>\n';
13604    tIcon = '<span class="glyphicon glyphicon-file kv-caption-icon"></span>';
13605    tCaption = '<div tabindex="500" class="form-control file-caption {class}">\n' +
13606        '   <div class="file-caption-name"></div>\n' +
13607        '</div>\n';
13608    //noinspection HtmlUnknownAttribute
13609    tBtnDefault = '<button type="{type}" tabindex="500" title="{title}" class="{css}" {status}>{icon}{label}</button>';
13610    tBtnLink = '<a href="{href}" tabindex="500" title="{title}" class="{css}" {status}>{icon}{label}</a>';
13611    tBtnBrowse = '<div tabindex="500" class="{css}" {status}>{icon}{label}</div>';
13612    tModal = '<div id="{id}" class="file-preview-detail-modal modal fade" tabindex="-1">\n' +
13613        '  <div class="modal-dialog modal-lg">\n' +
13614        '    <div class="modal-content">\n' +
13615        '      <div class="modal-header">\n' +
13616        '        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>\n' +
13617        '        <h3 class="modal-title">{heading} <small>{title}</small></h3>\n' +
13618        '      </div>\n' +
13619        '      <div class="modal-body">\n' +
13620        '           <pre>{body}</pre>\n' +
13621        '      </div>\n' +
13622        '    </div>\n' +
13623        '  </div>\n' +
13624        '</div>';
13625    tProgress = '<div class="progress">\n' +
13626        '    <div class="{class}" role="progressbar"' +
13627        ' aria-valuenow="{percent}" aria-valuemin="0" aria-valuemax="100" style="width:{percent}%;">\n' +
13628        '        {percent}%\n' +
13629        '     </div>\n' +
13630        '</div>';
13631    tFooter = '<div class="file-thumbnail-footer">\n' +
13632        '    <div class="file-footer-caption" title="{caption}">{caption}</div>\n' +
13633        '    {progress} {actions}\n' +
13634        '</div>';
13635    tActions = '<div class="file-actions">\n' +
13636        '    <div class="file-footer-buttons">\n' +
13637        '        {upload}{delete}{other}
13637' +
13638        '    </div>\n' +
13639        '    <div class="file-upload-indicator" title="{indicatorTitle}">{indicator}</div>\n' +
13640        '    <div class="clearfix"></div>\n' +
13641        '</div>';
13642    tActionDelete = '<button type="button" class="kv-file-remove {removeClass}" ' +
13643        'title="{removeTitle}" {dataUrl}{dataKey}>{removeIcon}</button>\n';
13644    tActionUpload = '<button type="button" class="kv-file-upload {uploadClass}" title="{uploadTitle}">' +
13645        '   {uploadIcon}\n</button>\n';
13646    tZoom = '<button type="button" class="btn btn-default btn-xs btn-block" title="{zoomTitle}: {caption}" onclick="{dialog}">\n' +
13647        '   {zoomInd}\n' +
13648        '</button>\n';
13649    tGeneric = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}">\n' +
13650        '   {content}\n' +
13651        '   {footer}\n' +
13652        '</div>\n';
13653    tHtml = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}">\n' +
13654        '    <object class="file-object" data="{data}" type="{type}" width="{width}" height="{height}">\n' +
13655        '       ' + DEFAULT_PREVIEW + '\n' +
13656        '    </object>\n' +
13657        '   {footer}\n' +
13658        '</div>';
13659    tImage = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}">\n' +
13660        '   <img src="{data}" class="file-preview-image" title="{caption}" alt="{caption}" ' + STYLE_SETTING + '>\n' +
13661        '   {footer}\n' +
13662        '</div>\n';
13663    tText = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}">\n' +
13664        '   <pre class="file-preview-text" title="{caption}" ' + STYLE_SETTING + '>{data}</pre>\n' +
13665        '   {zoom}\n' +
13666        '   {footer}\n' +
13667        '</div>';
13668    tVideo = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}"' +
13669        ' title="{caption}" ' + STYLE_SETTING + '>\n' +
13670        '   <video width="{width}" height="{height}" controls>\n' +
13671        '       <source src="{data}" type="{type}">\n' +
13672        '       ' + DEFAULT_PREVIEW + '\n' +
13673        '   </video>\n' +
13674        '   {footer}\n' +
13675        '</div>\n';
13676    tAudio = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}"' +
13677        ' title="{caption}" ' + STYLE_SETTING + '>\n' +
13678        '   <audio controls>\n' +
13679        '       <source src="' + '{data}' + '" type="{type}">\n' +
13680        '       ' + DEFAULT_PREVIEW + '\n' +
13681        '   </audio>\n' +
13682        '   {footer}\n' +
13683        '</div>';
13684    tFlash = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}"' +
13685        ' title="{caption}" ' + STYLE_SETTING + '>\n' +
13686        '   <object class="file-object" type="application/x-shockwave-flash" width="{width}" height="{height}" data="{data}">\n' +
13687        OBJECT_PARAMS + '       ' + DEFAULT_PREVIEW + '\n' +
13688        '   </object>\n' +
13689        '   {footer}\n' +
13690        '</div>\n';
13691    tObject = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}"' +
13692        ' title="{caption}" ' + STYLE_SETTING + '>\n' +
13693        '   <object class="file-object" data="{data}" type="{type}" width="{width}" height="{height}">\n' +
13694        '       <param name="movie" value="{caption}" />\n' +
13695        OBJECT_PARAMS + '         ' + DEFAULT_PREVIEW + '\n' +
13696        '   </object>\n' +
13697        '   {footer}\n' +
13698        '</div>';
13699    tOther = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}"' +
13700        ' title="{caption}" ' + STYLE_SETTING + '>\n' +
13701        '   <div class="file-preview-other-frame">\n' +
13702        '   ' + DEFAULT_PREVIEW + '\n' +
13703        '   </div>\n' +
13704        '   <div class="file-preview-other-footer">{footer}</div>\n' +
13705        '</div>';
13706    defaultLayoutTemplates = {
13707        main1: tMain1,
13708        main2: tMain2,
13709        preview: tPreview,
13710        close: tClose,
13711        zoom: tZoom,
13712        icon: tIcon,
13713        caption: tCaption,
13714        modal: tModal,
13715        progress: tProgress,
13716        footer: tFooter,
13717        actions: tActions,
13718        actionDelete: tActionDelete,
13719        actionUpload: tActionUpload,
13720        btnDefault: tBtnDefault,
13721        btnLink: tBtnLink,
13722        btnBrowse: tBtnBrowse
13723    };
13724    defaultPreviewTemplates = {
13725        generic: tGeneric,
13726        html: tHtml,
13727        image: tImage,
13728        text: tText,
13729        video: tVideo,
13730        audio: tAudio,
13731        flash: tFlash,
13732        object: tObject,
13733        other: tOther
13734    };
13735    defaultPreviewTypes = ['image', 'html', 'text', 'video', 'audio', 'flash', 'object'];
13736    defaultPreviewSettings = {
13737        image: {width: "auto", height: "160px"},
13738        html: {width: "213px", height: "160px"},
13739        text: {width: "160px", height: "136px"},
13740        video: {width: "213px", height: "160px"},
13741        audio: {width: "213px", height: "80px"},
13742        flash: {width: "213px", height: "160px"},
13743        object: {width: "160px", height: "160px"},
13744        other: {width: "160px", height: "160px"}
13745    };
13746    defaultFileTypeSettings = {
13747        image: function (vType, vName) {
13748            return compare(vType, 'image.*') || compare(vName, /\.(gif|png|jpe?g)$/i);
13749        },
13750        html: function (vType, vName) {
13751            return compare(vType, 'text/html') || compare(vName, /\.(htm|html)$/i);
13752        },
13753        text: function (vType, vName) {
13754            return compare(vType, 'text.*') || compare(vType, /\.(xml|javascript)$/i) ||
13755                compare(vName, /\.(txt|md|csv|nfo|ini|json|php|js|css)$/i);
13756        },
13757        video: function (vType, vName) {
13758            return compare(vType, 'video.*') && (compare(vType, /(ogg|mp4|mp?g|webm|3gp)$/i) ||
13759                compare(vName, /\.(og?|mp4|webm|mp?g|3gp)$/i));
13760        },
13761        audio: function (vType, vName) {
13762            return compare(vType, 'audio.*') && (compare(vType, /(ogg|mp3|mp?g|wav)$/i) ||
13763                compare(vName, /\.(og?|mp3|mp?g|wav)$/i));
13764        },
13765        flash: function (vType, vName) {
13766            return compare(vType, 'application/x-shockwave-flash', true) || compare(vName, /\.(swf)$/i);
13767        },
13768        object: function (vType, vName) {
13769            return compare(vType, 'application/pdf', true) || compare(vName, /\.(pdf)$/i);
13770        },
13771        other: function () {
13772            return true;
13773        }
13774    };
13775    isEmpty = function (value, trim) {
13776        return value === undefined || value === null || value.length === 0 || (trim && $.trim(value) === '');
13777    };
13778    isArray = function (a) {
13779        return Array.isArray(a) || Object.prototype.toString.call(a) === '[object Array]';
13780    };
13781    isSet = function (needle, haystack) {
13782        return (typeof haystack === 'object' && needle in haystack);
13783    };
13784    getElement = function (options, param, value) {
13785        return (isEmpty(options) || isEmpty(options[param])) ? value : $(options[param]);
13786    };
13787    uniqId = function () {
13788        return Math.round(new Date().getTime() + (Math.random() * 100));
13789    };
13790    htmlEncode = function (str) {
13791        return str.replace(/&/g, '&amp;')
13792            .replace(/</g, '&lt;')
13793            .replace(/>/g, '&gt;')
13794            .replace(/"/g, '&quot;')
13795            .replace(/'/g, '&apos;');
13796    };
13797    replaceTags = function (str, tags) {
13798        var out = str;
13799        if (!tags) {
13800            return out;
13801        }
13802        $.each(tags, function (key, value) {
13803            if (typeof value === "function") {
13804                value = value();
13805            }
13806            out = out.split(key).join(value);
13807        });
13808        return out;
13809    };
13810    cleanMemory = function ($thumb) {
13811        var data = $thumb.is('img') ? $thumb.attr('src') : $thumb.find('source').attr('src');
13812        /** @namespace objUrl.revokeObjectURL */
13813        objUrl.revokeObjectURL(data);
13814    };
13815    FileInput = function (element, options) {
13816        var self = this;
13817        self.$element = $(element);
13818        if (!self._validate()) {
13819            return;
13820        }
13821        self.isPreviewable = hasFileAPISupport();
13822        self.isIE9 = isIE(9);
13823        self.isIE10 = isIE(10);
13824        if (self.isPreviewable || self.isIE9) {
13825            self._init(options);
13826            self._listen();
13827        } else {
13828            self.$element.removeClass('file-loading');
13829        }
13830    };
13831
13832    FileInput.prototype = {
13833        constructor: FileInput,
13834        _init: function (options) {
13835            var self = this, $el = self.$element, t;
13836            $.each(options, function (key, value) {
13837                switch (key) {
13838                    case 'minFileCount':
13839                    case 'maxFileCount':
13840                    case 'maxFileSize':
13841                        self[key] = getNum(value);
13842                        break;
13843                    default:
13844                        self[key] = value;
13845                        break;
13846                }
13847            });
13848            if (isEmpty(self.allowedPreviewTypes)) {
13849                self.allowedPreviewTypes = defaultPreviewTypes;
13850            }
13851            self.fileInputCleared = false;
13852            self.fileBatchCompleted = true;
13853            if (!self.isPreviewable) {
13854                self.showPreview = false;
13855            }
13856            self.uploadFileAttr = !isEmpty($el.attr('name')) ? $el.attr('name') : 'file_data';
13857            self.reader = null;
13858            self.formdata = {};
13859            self.clearStack();
13860            self.uploadCount = 0;
13861            self.uploadStatus = {};
13862            self.uploadLog = [];
13863            self.uploadAsyncCount = 0;
13864            self.loadedImages = [];
13865            self.totalImagesCount = 0;
13866            self.ajaxRequests = [];
13867            self.isError = false;
13868            self.ajaxAborted = false;
13869            self.cancelling = false;
13870            t = self._getLayoutTemplate('progress');
13871            self.progressTemplate = t.replace('{class}', self.progressClass);
13872            self.progressCompleteTemplate = t.replace('{class}', self.progressCompleteClass);
13873            self.progressErrorTemplate = t.replace('{class}', self.progressErrorClass);
13874            self.dropZoneEnabled = hasDragDropSupport() && self.dropZoneEnabled;
13875            self.isDisabled = self.$element.attr('disabled') || self.$element.attr('readonly');
13876            self.isUploadable = hasFileUploadSupport() && !isEmpty(self.uploadUrl);
13877            self.slug = typeof options.slugCallback === "function" ? options.slugCallback : self._slugDefault;
13878            self.mainTemplate = self.showCaption ? self._getLayoutTemplate('main1') : self._getLayoutTemplate('main2');
13879            self.captionTemplate = self._getLayoutTemplate('caption');
13880            self.previewGenericTemplate = self._getPreviewTemplate('generic');
13881            if (self.resizeImage && (self.maxImageWidth || self.maxImageHeight)) {
13882                self.imageCanvas = document.createElement('canvas');
13883                self.imageCanvasContext = self.imageCanvas.getContext('2d');
13884            }
13885            if (isEmpty(self.$element.attr('id'))) {
13886                self.$element.attr('id', uniqId());
13887            }
13888            if (self.$container === undefined) {
13889                self.$container = self._createContainer();
13890            } else {
13891                self._refreshContainer();
13892            }
13893            self.$dropZone = self.$container.find('.file-drop-zone');
13894            self.$progress = self.$container.find('.kv-upload-progress');
13895            self.$btnUpload = self.$container.find('.fileinput-upload');
13896            self.$captionContainer = getElement(options, 'elCaptionContainer', self.$container.find('.file-caption'));
13897            self.$caption = getElement(options, 'elCaptionText', self.$container.find('.file-caption-name'));
13898            self.$previewContainer = getElement(options, 'elPreviewContainer', self.$container.find('.file-preview'));
13899            self.$preview = getElement(options, 'elPreviewImage', self.$container.find('.file-preview-thumbnails'));
13900            self.$previewStatus = getElement(options, 'elPreviewStatus', self.$container.find('.file-preview-status'));
13901            self.$errorContainer = getElement(options, 'elErrorContainer',
13902                self.$previewContainer.find('.kv-fileinput-error'));
13903            if (!isEmpty(self.msgErrorClass)) {
13904                addCss(self.$errorContainer, self.msgErrorClass);
13905            }
13906            self.$errorContainer.hide();
13907            self.fileActionSettings = $.extend(true, defaultFileActionSettings, options.fileActionSettings);
13908            self.previewInitId = "preview-" + uniqId();
13909            self.id = self.$element.attr('id');
13910            previewCache.init(self);
13911            self._initPreview(true);
13912            self._initPreviewDeletes();
13913            self.options = options;
13914            self._setFileDropZoneTitle();
13915            self.$element.removeClass('file-loading');
13916            if (self.$element.attr('disabled')) {
13917                self.disable();
13918            }
13919        },
13920        _validate: function () {
13921            var self = this, $exception;
13922            if (self.$element.attr('type') === 'file') {
13923                return true;
13924            }
13925            $exception = '<div class="help-block alert alert-warning">' +
13926                '<h4>Invalid Input Type</h4>' +
13927                'You must set an input <code>type = file</code> for <b>bootstrap-fileinput</b> plugin to initialize.' +
13928                '</div>';
13929            self.$element.after($exception);
13930            return false;
13931        },
13932        _errorsExist: function () {
13933            var self = this, $err;
13934            if (self.$errorContainer.find('li').length) {
13935                return true;
13936            }
13937            $err = $(document.createElement('div')).html(self.$errorContainer.html());
13938            $err.find('span.kv-error-close').remove();
13939            $err.find('ul').remove();
13940            return $.trim($err.text()).length ? true : false;
13941        },
13942        _errorHandler: function (evt, caption) {
13943            var self = this, err = evt.target.error;
13944            /** @namespace err.NOT_FOUND_ERR */
13945            /** @namespace err.SECURITY_ERR */
13946            /** @namespace err.NOT_READABLE_ERR */
13947            if (err.code === err.NOT_FOUND_ERR) {
13948                self._showError(self.msgFileNotFound.replace('{name}', caption));
13949            } else if (err.code === err.SECURITY_ERR) {
13950                self._showError(self.msgFileSecured.replace('{name}', caption));
13951            } else if (err.code === err.NOT_READABLE_ERR) {
13952                self._showError(self.msgFileNotReadable.replace('{name}', caption));
13953            } else if (err.code === err.ABORT_ERR) {
13954                self._showError(self.msgFilePreviewAborted.replace('{name}', caption));
13955            } else {
13956                self._showError(self.msgFilePreviewError.replace('{name}', caption));
13957            }
13958        },
13959        _addError: function (msg) {
13960            var self = this, $error = self.$errorContainer;
13961            if (msg && $error.length) {
13962                $error.html(self.errorCloseButton + msg);
13963                handler($error.find('.kv-error-close'), 'click', function () {
13964                    $error.fadeOut('slow');
13965                });
13966            }
13967        },
13968        _resetErrors: function (fade) {
13969            var self = this, $error = self.$errorContainer;
13970            self.isError = false;
13971            self.$container.removeClass('has-error');
13972            $error.html('');
13973            if (fade) {
13974                $error.fadeOut('slow');
13975            } else {
13976                $error.hide();
13977            }
13978        },
13979        _showFolderError: function (folders) {
13980            var self = this, $error = self.$errorContainer, msg;
13981            if (!folders) {
13982                return;
13983            }
13984            msg = self.msgFoldersNotAllowed.replace(/\{n}/g, folders);
13985            self._addError(msg);
13986            addCss(self.$container, 'has-error');
13987            $error.fadeIn(800);
13988            self._raise('filefoldererror', [folders, msg]);
13989        },
13990        _showUploadError: function (msg, params, event) {
13991            var self = this, $error = self.$errorContainer, ev = event || 'fileuploaderror', e = params && params.id ?
13992            '<li data-file-id="' + params.id + '">' + msg + '</li>' : '<li>' + msg + '</li>';
13993            if ($error.find('ul').length === 0) {
13994                self._addError('<ul>' + e + '</ul>');
13995            } else {
13996                $error.find('ul').append(e);
13997            }
13998            $error.fadeIn(800);
13999            self._raise(ev, [params, msg]);
14000            self.$container.removeClass('file-input-new');
14001            addCss(self.$container, 'has-error');
14002            return true;
14003        },
14004        _showError: function (msg, params, event) {
14005            var self = this, $error = self.$errorContainer, ev = event || 'fileerror';
14006            params = params || {};
14007            params.reader = self.reader;
14008            self._addError(msg);
14009            $error.fadeIn(800);
14010            self._raise(ev, [params, msg]);
14011            if (!self.isUploadable) {
14012                self._clearFileInput();
14013            }
14014            self.$container.removeClass('file-input-new');
14015            addCss(self.$container, 'has-error');
14016            self.$btnUpload.attr('disabled', true);
14017            return true;
14018        },
14019        _noFilesError: function (params) {
14020            var self = this, label = self.minFileCount > 1 ? self.filePlural : self.fileSingle,
14021                msg = self.msgFilesTooLess.replace('{n}', self.minFileCount).replace('{files}', label),
14022                $error = self.$errorContainer;
14023            self._addError(msg);
14024            self.isError = true;
14025            self._updateFileDetails(0);
14026            $error.fadeIn(800);
14027            self._raise('fileerror', [params, msg]);
14028            self._clearFileInput();
14029            addCss(self.$container, 'has-error');
14030        },
14031        _parseError: function (jqXHR, errorThrown, fileName) {
14032            /** @namespace jqXHR.responseJSON */
14033            var self = this, errMsg = $.trim(errorThrown + ''),
14034                dot = errMsg.slice(-1) === '.' ? '' : '.',
14035                text = jqXHR.responseJSON !== undefined && jqXHR.responseJSON.error !== undefined ?
14036                    jqXHR.responseJSON.error : jqXHR.responseText;
14037            if (self.cancelling && self.msgUploadAborted) {
14038                errMsg = self.msgUploadAborted;
14039            }
14040            if (self.showAjaxErrorDetails && text) {
14041                text = $.trim(text.replace(/\n\s*\n/g, '\n'));
14042                text = text.length > 0 ? '<pre>' + text + '</pre>' : '';
14043                errMsg += dot + text;
14044            } else {
14045                errMsg += dot;
14046            }
14047            self.cancelling = false;
14048            return fileName ? '<b>' + fileName + ': </b>' + errMsg : errMsg;
14049        },
14050        _parseFileType: function (file) {
14051            var self = this, isValid, vType, cat, i;
14052            for (i = 0; i < defaultPreviewTypes.length; i += 1) {
14053                cat = defaultPreviewTypes[i];
14054                isValid = isSet(cat, self.fileTypeSettings) ? self.fileTypeSettings[cat] : defaultFileTypeSettings[cat];
14055                vType = isValid(file.type, file.name) ? cat : '';
14056                if (!isEmpty(vType)) {
14057                    return vType;
14058                }
14059            }
14060            return 'other';
14061        },
14062        _parseFilePreviewIcon: function (content, fname) {
14063            var self = this, ext, icn = self.previewFileIcon;
14064            if (fname && fname.indexOf('.') > -1) {
14065                ext = fname.split('.').pop();
14066                if (self.previewFileIconSettings && self.previewFileIconSettings[ext]) {
14067                    icn = self.previewFileIconSettings[ext];
14068                }
14069                if (self.previewFileExtSettings) {
14070                    $.each(self.previewFileExtSettings, function (key, func) {
14071                        if (self.previewFileIconSettings[key] && func(ext)) {
14072                            icn = self.previewFileIconSettings[key];
14073                        }
14074                    });
14075                }
14076            }
14077            if (content.indexOf('{previewFileIcon}') > -1) {
14078                return content.replace(/\{previewFileIconClass}/g, self.previewFileIconClass).replace(
14079                    /\{previewFileIcon}/g, icn);
14080            }
14081            return content;
14082        },
14083        _raise: function (event, params) {
14084            var self = this, e = $.Event(event);
14085            if (params !== undefined) {
14086                self.$element.trigger(e, params);
14087            } else {
14088                self.$element.trigger(e);
14089            }
14090            if (e.isDefaultPrevented()) {
14091                return false;
14092            }
14093            if (!e.result) {
14094                return e.result;
14095            }
14096            switch (event) {
14097                // ignore these events
14098                case 'filebatchuploadcomplete':
14099                case 'filebatchuploadsuccess':
14100                case 'fileuploaded':
14101                case 'fileclear':
14102                case 'filecleared':
14103                case 'filereset':
14104                case 'fileerror':
14105                case 'filefoldererror':
14106                case 'fileuploaderror':
14107                case 'filebatchuploaderror':
14108                case 'filedeleteerror':
14109                case 'filecustomerror':
14110                case 'filesuccessremove':
14111                    break;
14112                // receive data response via `filecustomerror` event`
14113                default:
14114                    self.ajaxAborted = e.result;
14115                    break;
14116            }
14117            return true;
14118        },
14119        _listen: function () {
14120            var self = this, $el = self.$element, $form = $el.closest('form'), $cont = self.$container;
14121            handler($el, 'change', $.proxy(self._change, self));
14122            handler(self.$btnFile, 'click', $.proxy(self._browse, self));
14123            handler($form, 'reset', $.proxy(self.reset, self));
14124            handler($cont.find('.fileinput-remove:not([disabled])'), 'click', $.proxy(self.clear, self));
14125            handler($cont.find('.fileinput-cancel'), 'click', $.proxy(self.cancel, self));
14126            self._initDragDrop();
14127            if (!self.isUploadable) {
14128                handler($form, 'submit', $.proxy(self._submitForm, self));
14129            }
14130            handler(self.$container.find('.fileinput-upload'), 'click', $.proxy(self._uploadClick, self));
14131        },
14132        _initDragDrop: function () {
14133            var self = this, $zone = self.$dropZone;
14134            if (self.isUploadable && self.dropZoneEnabled && self.showPreview) {
14135                handler($zone, 'dragenter dragover', $.proxy(self._zoneDragEnter, self));
14136                handler($zone, 'dragleave', $.proxy(self._zoneDragLeave, self));
14137                handler($zone, 'drop', $.proxy(self._zoneDrop, self));
14138                handler($(document), 'dragenter dragover drop', self._zoneDragDropInit);
14139            }
14140        },
14141        _zoneDragDropInit: function (e) {
14142            e.stopPropagation();
14143            e.preventDefault();
14144        },
14145        _zoneDragEnter: function (e) {
14146            var self = this, hasFiles = $.inArray('Files', e.originalEvent.dataTransfer.types) > -1;
14147            self._zoneDragDropInit(e);
14148            if (self.isDisabled || !hasFiles) {
14149                e.originalEvent.dataTransfer.effectAllowed = 'none';
14150                e.originalEvent.dataTransfer.dropEffect = 'none';
14151                return;
14152            }
14153            addCss(self.$dropZone, 'file-highlighted');
14154        },
14155        _zoneDragLeave: function (e) {
14156            var self = this;
14157            self._zoneDragDropInit(e);
14158            if (self.isDisabled) {
14159                return;
14160            }
14161            self.$dropZone.removeClass('file-highlighted');
14162        },
14163        _zoneDrop: function (e) {
14164            var self = this;
14165            e.preventDefault();
14166            /** @namespace e.originalEvent.dataTransfer */
14167            if (self.isDisabled || isEmpty(e.originalEvent.dataTransfer.files)) {
14168                return;
14169            }
14170            self._change(e, 'dragdrop');
14171            self.$dropZone.removeClass('file-highlighted');
14172        },
14173        _uploadClick: function (e) {
14174            var self = this, $btn = self.$container.find('.fileinput-upload'), $form,
14175                isEnabled = !$btn.hasClass('disabled') && isEmpty($btn.attr('disabled'));
14176            if (e && e.isDefaultPrevented()) {
14177                return;
14178            }
14179            if (!self.isUploadable) {
14180                if (isEnabled && $btn.attr('type') !== 'submit') {
14181                    $form = $btn.closest('form');
14182                    // downgrade to normal form submit if possible
14183                    if ($form.length) {
14184                        $form.trigger('submit');
14185                    }
14186                    e.preventDefault();
14187                }
14188                return;
14189            }
14190            e.preventDefault();
14191            if (isEnabled) {
14192                self.upload();
14193            }
14194        },
14195        _submitForm: function () {
14196            var self = this, $el = self.$element, files = $el.get(0).files;
14197            if (files && self.minFileCount > 0 && self._getFileCount(files.length) < self.minFileCount) {
14198                self._noFilesError({});
14199                return false;
14200            }
14201            return !self._abort({});
14202        },
14203        _clearPreview: function () {
14204            var self = this, $thumbs = !self.showUploadedThumbs ? self.$preview.find('.file-preview-frame') :
14205                self.$preview.find('.file-preview-frame:not(.file-preview-success)');
14206            $thumbs.remove();
14207            if (!self.$preview.find('.file-preview-frame').length || !self.showPreview) {
14208                self._resetUpload();
14209            }
14210            self._validateDefaultPreview();
14211        },
14212        _initPreview: function (isInit) {
14213            var self = this, cap = self.initialCaption || '', out;
14214            if (!previewCache.count(self.id)) {
14215                self._clearPreview();
14216                if (isInit) {
14217                    self._setCaption(cap);
14218                } else {
14219                    self._initCaption();
14220                }
14221                return;
14222            }
14223            out = previewCache.out(self.id);
14224            cap = isInit && self.initialCaption ? self.initialCaption : out.caption;
14225            self.$preview.html(out.content);
14226            self._setCaption(cap);
14227            if (!isEmpty(out.content)) {
14228                self.$container.removeClass('file-input-new');
14229            }
14230        },
14231        _initPreviewDeletes: function () {
14232            var self = this, deleteExtraData = self.deleteExtraData || {},
14233                resetProgress = function () {
14234                    var hasFiles = self.isUploadable ? previewCache.count(self.id) : self.$element.get(0).files.length;
14235                    if (self.$preview.find('.kv-file-remove').length === 0 && !hasFiles) {
14236                        self.reset();
14237                        self.initialCaption = '';
14238                    }
14239                };
14240
14241            self.$preview.find('.kv-file-remove').each(function () {
14242                var $el = $(this), vUrl = $el.data('url') || self.deleteUrl, vKey = $el.data('key');
14243                if (isEmpty(vUrl) || vKey === undefined) {
14244                    return;
14245                }
14246                var $frame = $el.closest('.file-preview-frame'), cache = previewCache.data[self.id],
14247                    settings, params, index = $frame.data('fileindex'), config, extraData;
14248                index = parseInt(index.replace('init_', ''));
14249                config = isEmpty(cache.config) && isEmpty(cache.config[index]) ? null : cache.config[index];
14250                extraData = isEmpty(config) || isEmpty(config.extra) ? deleteExtraData : config.extra;
14251                if (typeof extraData === "function") {
14252                    extraData = extraData();
14253                }
14254                params = {id: $el.attr('id'), key: vKey, extra: extraData};
14255                settings = $.extend(true, {}, {
14256                    url: vUrl,
14257                    type: 'POST',
14258                    dataType: 'json',
14259                    data: $.extend(true, {}, {key: vKey}, extraData),
14260                    beforeSend: function (jqXHR) {
14261                        self.ajaxAborted = false;
14262                        self._raise('filepredelete', [vKey, jqXHR, extraData]);
14263                        if (self.ajaxAborted) {
14264                            jqXHR.abort();
14265                        } else {
14266                            addCss($frame, 'file-uploading');
14267                            addCss($el, 'disabled');
14268                        }
14269                    },
14270                    success: function (data, textStatus, jqXHR) {
14271                        var n, cap;
14272                        if (isEmpty(data) || isEmpty(data.error)) {
14273                            previewCache.unset(self.id, index);
14274                            n = previewCache.count(self.id);
14275                            cap = n > 0 ? self._getMsgSelected(n) : '';
14276                            self._raise('filedeleted', [vKey, jqXHR, extraData]);
14277                            self._setCaption(cap);
14278                        } else {
14279                            params.jqXHR = jqXHR;
14280                            params.response = data;
14281                            self._showError(data.error, params, 'filedeleteerror');
14282                            $frame.removeClass('file-uploading');
14283                            $el.removeClass('disabled');
14284                            resetProgress();
14285                            return;
14286                        }
14287                        $frame.removeClass('file-uploading').addClass('file-deleted');
14288                        $frame.fadeOut('slow', function () {
14289                            self._clearObjects($frame);
14290                            $frame.remove();
14291                            resetProgress();
14292                            if (!n && self.getFileStack().length === 0) {
14293                                self._setCaption('');
14294                                self.reset();
14295                            }
14296                        });
14297                    },
14298                    error: function (jqXHR, textStatus, errorThrown) {
14299                        var errMsg = self._parseError(jqXHR, errorThrown);
14300                        params.jqXHR = jqXHR;
14301                        params.response = {};
14302                        self._showError(errMsg, params, 'filedeleteerror');
14303                        $frame.removeClass('file-uploading');
14304                        resetProgress();
14305                    }
14306                }, self.ajaxDeleteSettings);
14307                handler($el, 'click', function () {
14308                    if (!self._validateMinCount()) {
14309                        return false;
14310                    }
14311                    $.ajax(settings);
14312                });
14313            });
14314        },
14315        _clearObjects: function ($el) {
14316            $el.find('video audio').each(function () {
14317                this.pause();
14318                $(this).remove();
14319            });
14320            $el.find('img object div').each(function () {
14321                $(this).remove();
14322            });
14323        },
14324        _clearFileInput: function () {
14325            var self = this, $el = self.$element, $srcFrm, $tmpFrm, $tmpEl;
14326            if (isEmpty($el.val())) {
14327                return;
14328            }
14329            // Fix for IE ver < 11, that does not clear file inputs. Requires a sequence of steps to prevent IE
14330            // crashing but still allow clearing of the file input.
14331            if (self.isIE9 || self.isIE10) {
14332                $srcFrm = $el.closest('form');
14333                $tmpFrm = $(document.createElement('form'));
14334                $tmpEl = $(document.createElement('div'));
14335                $el.before($tmpEl);
14336                if ($srcFrm.length) {
14337                    $srcFrm.after($tmpFrm);
14338                } else {
14339                    $tmpEl.after($tmpFrm);
14340                }
14341                $tmpFrm.append($el).trigger('reset');
14342                $tmpEl.before($el).remove();
14343                $tmpFrm.remove();
14344            } else { // normal input clear behavior for other sane browsers
14345                $el.val('');
14346            }
14347            self.fileInputCleared = true;
14348        },
14349        _resetUpload: function () {
14350            var self = this;
14351            self.uploadCache = {content: [], config: [], tags: [], append: true};
14352            self.uploadCount = 0;
14353            self.uploadStatus = {};
14354            self.uploadLog = [];
14355            self.uploadAsyncCount = 0;
14356            self.loadedImages = [];
14357            self.totalImagesCount = 0;
14358            self.$btnUpload.removeAttr('disabled');
14359            self._setProgress(0);
14360            addCss(self.$progress, 'hide');
14361            self._resetErrors(false);
14362            self.ajaxAborted = false;
14363            self.ajaxRequests = [];
14364            self._resetCanvas();
14365        },
14366        _resetCanvas: function () {
14367            var self = this;
14368            if (self.canvas && self.imageCanvasContext) {
14369                self.imageCanvasContext.clearRect(0, 0, self.canvas.width, self.canvas.height);
14370            }
14371        },
14372        _hasInitialPreview: function () {
14373            var self = this;
14374            return !self.overwriteInitial && previewCache.count(self.id);
14375        },
14376        _resetPreview: function () {
14377            var self = this, out, cap;
14378            if (previewCache.count(self.id)) {
14379                out = previewCache.out(self.id);
14380                self.$preview.html(out.content);
14381                cap = self.initialCaption ? self.initialCaption : out.caption;
14382                self._setCaption(cap);
14383            } else {
14384                self._clearPreview();
14385                self._initCaption();
14386            }
14387        },
14388        _clearDefaultPreview: function () {
14389            var self = this;
14390            self.$preview.find('.file-default-preview').remove();
14391        },
14392        _validateDefaultPreview: function () {
14393            var self = this;
14394            if (!self.showPreview || isEmpty(self.defaultPreviewContent)) {
14395                return;
14396            }
14397            self.$preview.html('<div class="file-default-preview">' + self.defaultPreviewContent + '</div>');
14398            self.$container.removeClass('file-input-new');
14399        },
14400        _resetPreviewThumbs: function (isAjax) {
14401            var self = this, out;
14402            if (isAjax) {
14403                self._clearPreview();
14404                self.clearStack();
14405                return;
14406            }
14407            if (self._hasInitialPreview()) {
14408                out = previewCache.out(self.id);
14409                self.$preview.html(out.content);
14410                self._setCaption(out.caption);
14411                self._initPreviewDeletes();
14412            } else {
14413                self._clearPreview();
14414            }
14415        },
14416        _getLayoutTemplate: function (t) {
14417            var self = this,
14418                template = isSet(t, self.layoutTemplates) ? self.layoutTemplates[t] : defaultLayoutTemplates[t];
14419            if (isEmpty(self.customLayoutTags)) {
14420                return template;
14421            }
14422            return replaceTags(template, self.customLayoutTags);
14423        },
14424        _getPreviewTemplate: function (t) {
14425            var self = this,
14426                template = isSet(t, self.previewTemplates) ? self.previewTemplates[t] : defaultPreviewTemplates[t];
14427            if (isEmpty(self.customPreviewTags)) {
14428                return template;
14429            }
14430            return replaceTags(template, self.customPreviewTags);
14431        },
14432        _getOutData: function (jqXHR, responseData, filesData) {
14433            var self = this;
14434            jqXHR = jqXHR || {};
14435            responseData = responseData || {};
14436            filesData = filesData || self.filestack.slice(0) || {};
14437            return {
14438                form: self.formdata,
14439                files: filesData,
14440                filenames: self.filenames,
14441                extra: self._getExtraData(),
14442                response: responseData,
14443                reader: self.reader,
14444                jqXHR: jqXHR
14445            };
14446        },
14447        _getMsgSelected: function (n) {
14448            var self = this, strFiles = n === 1 ? self.fileSingle : self.filePlural;
14449            return self.msgSelected.replace('{n}', n).replace('{files}', strFiles);
14450        },
14451        _getThumbs: function (css) {
14452            css = css || '';
14453            return this.$preview.find('.file-preview-frame:not(.file-preview-initial)' + css);
14454        },
14455        _getExtraData: function (previewId, index) {
14456            var self = this, data = self.uploadExtraData;
14457            if (typeof self.uploadExtraData === "function") {
14458                data = self.uploadExtraData(previewId, index);
14459            }
14460            return data;
14461        },
14462        _initXhr: function (xhrobj, previewId, fileCount) {
14463            var self = this;
14464            if (xhrobj.upload) {
14465                xhrobj.upload.addEventListener('progress', function (event) {
14466                    var pct = 0, position = event.loaded || event.position, total = event.total;
14467                    /** @namespace event.lengthComputable */
14468                    if (event.lengthComputable) {
14469                        pct = Math.ceil(position / total * 100);
14470                    }
14471                    if (previewId) {
14472                        self._setAsyncUploadStatus(previewId, pct, fileCount);
14473                    } else {
14474                        self._setProgress(Math.ceil(pct));
14475                    }
14476                }, false);
14477            }
14478            return xhrobj;
14479        },
14480        _ajaxSubmit: function (fnBefore, fnSuccess, fnComplete, fnError, previewId, index) {
14481            var self = this, settings;
14482            self._raise('filepreajax', [previewId, index]);
14483            self._uploadExtra(previewId, index);
14484            settings = $.extend(true, {}, {
14485                xhr: function () {
14486                    var xhrobj = $.ajaxSettings.xhr();
14487                    return self._initXhr(xhrobj, previewId, self.getFileStack().length);
14488                },
14489                url: self.uploadUrl,
14490                type: 'POST',
14491                dataType: 'json',
14492                data: self.formdata,
14493                cache: false,
14494                processData: false,
14495                contentType: false,
14496                beforeSend: fnBefore,
14497                success: fnSuccess,
14498                complete: fnComplete,
14499                error: fnError
14500            }, self.ajaxSettings);
14501            self.ajaxRequests.push($.ajax(settings));
14502        },
14503        _initUploadSuccess: function (out, $thumb, allFiles) {
14504            var self = this, append, data, index, $newThumb, content, config, tags, i;
14505            if (!self.showPreview || typeof out !== 'object' || $.isEmptyObject(out)) {
14506                return;
14507            }
14508            if (out.initialPreview !== undefined && out.initialPreview.length > 0) {
14509                self.hasInitData = true;
14510                content = out.initialPreview || [];
14511                config = out.initialPreviewConfig || [];
14512                tags = out.initialPreviewThumbTags || [];
14513                append = out.append === undefined || out.append ? true : false;
14514                self.overwriteInitial = false;
14515                if ($thumb !== undefined) {
14516                    if (!allFiles) {
14517                        index = previewCache.add(self.id, content, config[0], tags[0], append);
14518                        data = previewCache.get(self.id, index, false);
14519                        $newThumb = $(data).hide();
14520                        $thumb.after($newThumb).fadeOut('slow', function () {
14521                            $newThumb.fadeIn('slow').css('display:inline-block');
14522                            self._initPreviewDeletes();
14523                            self._clearFileInput();
14524                            $thumb.remove();
14525                        });
14526                    } else {
14527                        i = $thumb.attr('data-fileindex');
14528                        self.uploadCache.content[i] = content[0];
14529                        self.uploadCache.config[i] = config[0];
14530                        self.uploadCache.tags[i] = tags[0];
14531                        self.uploadCache.append = append;
14532                    }
14533                } else {
14534                    previewCache.set(self.id, content, config, tags, append);
14535                    self._initPreview();
14536                    self._initPreviewDeletes();
14537                }
14538            }
14539        },
14540        _initSuccessThumbs: function () {
14541            var self = this;
14542            if (!self.showPreview) {
14543                return;
14544            }
14545            self._getThumbs('.file-preview-success').each(function () {
14546                var $thumb = $(this), $remove = $thumb.find('.kv-file-remove');
14547                $remove.removeAttr('disabled');
14548                handler($remove, 'click', function () {
14549                    var out = self._raise('filesuccessremove', [$thumb.attr('id'), $thumb.data('fileindex')]);
14550                    cleanMemory($thumb);
14551                    if (out === false) {
14552                        return;
14553                    }
14554                    $thumb.fadeOut('slow', function () {
14555                        $thumb.remove();
14556                        if (!self.$preview.find('.file-preview-frame').length) {
14557                            self.reset();
14558                        }
14559                    });
14560                });
14561            });
14562        },
14563        _checkAsyncComplete: function () {
14564            var self = this, previewId, i;
14565            for (i = 0; i < self.filestack.length; i++) {
14566                if (self.filestack[i]) {
14567                    previewId = self.previewInitId + "-" + i;
14568                    if ($.inArray(previewId, self.uploadLog) === -1) {
14569                        return false;
14570                    }
14571                }
14572            }
14573            return (self.uploadAsyncCount === self.uploadLog.length);
14574        },
14575        _uploadExtra: function (previewId, index) {
14576            var self = this, data = self._getExtraData(previewId, index);
14577            if (data.length === 0) {
14578                return;
14579            }
14580            $.each(data, function (key, value) {
14581                self.formdata.append(key, value);
14582            });
14583        },
14584        _uploadSingle: function (i, files, allFiles) {
14585            var self = this, total = self.getFileStack().length, formdata = new FormData(), outData,
14586                previewId = self.previewInitId + "-" + i, $thumb, chkComplete, $btnUpload, $btnDelete,
14587                hasPostData = self.filestack.length > 0 || !$.isEmptyObject(self.uploadExtraData),
14588                fnBefore, fnSuccess, fnComplete, fnError, updateUploadLog, params = {id: previewId, index: i};
14589            self.formdata = formdata;
14590            if (self.showPreview) {
14591                $thumb = $('#' + previewId + ':not(.file-preview-initial)');
14592                $btnUpload = $thumb.find('.kv-file-upload');
14593                $btnDelete = $thumb.find('.kv-file-remove');
14594                $('#' + previewId).find('.file-thumb-progress').removeClass('hide');
14595            }
14596            if (total === 0 || !hasPostData || ($btnUpload && $btnUpload.hasClass('disabled')) || self._abort(params)) {
14597                return;
14598            }
14599            updateUploadLog = function (i, previewId) {
14600                self.updateStack(i, undefined);
14601                self.uploadLog.push(previewId);
14602                if (self._checkAsyncComplete()) {
14603                    self.fileBatchCompleted = true;
14604                }
14605            };
14606            chkComplete = function () {
14607                if (!self.fileBatchCompleted) {
14608                    return;
14609                }
14610                setTimeout(function () {
14611                    if (self.showPreview) {
14612                        previewCache.set(
14613                            self.id,
14614                            self.uploadCache.content,
14615                            self.uploadCache.config,
14616                            self.uploadCache.tags,
14617                            self.uploadCache.append
14618                        );
14619                        if (self.hasInitData) {
14620                            self._initPreview();
14621                            self._initPreviewDeletes();
14622                        }
14623                    }
14624                    self.unlock();
14625                    self._clearFileInput();
14626                    self._raise('filebatchuploadcomplete', [self.filestack, self._getExtraData()]);
14627                    self.uploadCount = 0;
14628                    self.uploadStatus = {};
14629                    self.uploadLog = [];
14630                    self._setProgress(100);
14631                }, 100);
14632            };
14633            fnBefore = function (jqXHR) {
14634                outData = self._getOutData(jqXHR);
14635                self.fileBatchCompleted = false;
14636                if (self.showPreview) {
14637                    if (!$thumb.hasClass('file-preview-success')) {
14638                        self._setThumbStatus($thumb, 'Loading');
14639                        addCss($thumb, 'file-uploading');
14640                    }
14641                    $btnUpload.attr('disabled', true);
14642                    $btnDelete.attr('disabled', true);
14643                }
14644                if (!allFiles) {
14645                    self.lock();
14646                }
14647                self._raise('filepreupload', [outData, previewId, i]);
14648                $.extend(true, params, outData);
14649                if (self._abort(params)) {
14650                    jqXHR.abort();
14651                    self._setProgressCancelled();
14652                }
14653            };
14654            fnSuccess = function (data, textStatus, jqXHR) {
14655                outData = self._getOutData(jqXHR, data);
14656                $.extend(true, params, outData);
14657                setTimeout(function () {
14658                    if (isEmpty(data) || isEmpty(data.error)) {
14659                        if (self.showPreview) {
14660                            self._setThumbStatus($thumb, 'Success');
14661                            $btnUpload.hide();
14662                            self._initUploadSuccess(data, $thumb, allFiles);
14663                        }
14664                        self._raise('fileuploaded', [outData, previewId, i]);
14665                        if (!allFiles) {
14666                            self.updateStack(i, undefined);
14667                        } else {
14668                            updateUploadLog(i, previewId);
14669                        }
14670                    } else {
14671                        self._showUploadError(data.error, params);
14672                        self._setPreviewError($thumb, i);
14673                        if (allFiles) {
14674                            updateUploadLog(i, previewId);
14675                        }
14676                    }
14677                }, 100);
14678            };
14679            fnComplete = function () {
14680                setTimeout(function () {
14681                    if (self.showPreview) {
14682                        $btnUpload.removeAttr('disabled');
14683                        $btnDelete.removeAttr('disabled');
14684                        $thumb.removeClass('file-uploading');
14685                    }
14686                    if (!allFiles) {
14687                        self.unlock(false);
14688                        self._clearFileInput();
14689                    } else {
14690                        chkComplete();
14691                    }
14692                    self._initSuccessThumbs();
14693                }, 100);
14694            };
14695            fnError = function (jqXHR, textStatus, errorThrown) {
14696                var errMsg = self._parseError(jqXHR, errorThrown, (allFiles ? files[i].name : null));
14697                setTimeout(function () {
14698                    if (allFiles) {
14699                        updateUploadLog(i, previewId);
14700                    }
14701                    self.uploadStatus[previewId] = 100;
14702                    self._setPreviewError($thumb, i);
14703                    $.extend(true, params, self._getOutData(jqXHR));
14704                    self._showUploadError(errMsg, params);
14705                }, 100);
14706            };
14707            formdata.append(self.uploadFileAttr, files[i], self.filenames[i]);
14708            formdata.append('file_id', i);
14709            self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError, previewId, i);
14710        },
14711        _uploadBatch: function () {
14712            var self = this, files = self.filestack, total = files.length, params = {}, fnBefore, fnSuccess, fnError,
14713                fnComplete, hasPostData = self.filestack.length > 0 || !$.isEmptyObject(self.uploadExtraData),
14714                setAllUploaded;
14715            self.formdata = new FormData();
14716            if (total === 0 || !hasPostData || self._abort(params)) {
14717                return;
14718            }
14719            setAllUploaded = function () {
14720                $.each(files, function (key) {
14721                    self.updateStack(key, undefined);
14722                });
14723                self._clearFileInput();
14724            };
14725            fnBefore = function (jqXHR) {
14726                self.lock();
14727                var outData = self._getOutData(jqXHR);
14728                if (self.showPreview) {
14729                    self._getThumbs().each(function () {
14730                        var $thumb = $(this), $btnUpload = $thumb.find('.kv-file-upload'),
14731                            $btnDelete = $thumb.find('.kv-file-remove');
14732                        if (!$thumb.hasClass('file-preview-success')) {
14733                            self._setThumbStatus($thumb, 'Loading');
14734                            addCss($thumb, 'file-uploading');
14735                        }
14736                        $btnUpload.attr('disabled', true);
14737                        $btnDelete.attr('disabled', true);
14738                    });
14739                }
14740                self._raise('filebatchpreupload', [outData]);
14741                if (self._abort(outData)) {
14742                    jqXHR.abort();
14743                    self._setProgressCancelled();
14744                }
14745            };
14746            fnSuccess = function (data, textStatus, jqXHR) {
14747                /** @namespace data.errorkeys */
14748                var outData = self._getOutData(jqXHR, data), $thumbs = self._getThumbs(), key = 0,
14749                    keys = isEmpty(data) || isEmpty(data.errorkeys) ? [] : data.errorkeys;
14750                if (isEmpty(data) || isEmpty(data.error)) {
14751                    self._raise('filebatchuploadsuccess', [outData]);
14752                    setAllUploaded();
14753                    if (self.showPreview) {
14754                        $thumbs.each(function () {
14755                            var $thumb = $(this), $btnUpload = $thumb.find('.kv-file-upload');
14756                            $thumb.find('.kv-file-upload').hide();
14757                            self._setThumbStatus($thumb, 'Success');
14758                            $thumb.removeClass('file-uploading');
14759                            $btnUpload.removeAttr('disabled');
14760                        });
14761                        self._initUploadSuccess(data);
14762                    } else {
14763                        self.reset();
14764                    }
14765                } else {
14766                    if (self.showPreview) {
14767                        $thumbs.each(function () {
14768                            var $thumb = $(this), $btnDelete = $thumb.find('.kv-file-remove'),
14769                                $btnUpload = $thumb.find('.kv-file-upload');
14770                            $thumb.removeClass('file-uploading');
14771                            $btnUpload.removeAttr('disabled');
14772                            $btnDelete.removeAttr('disabled');
14773                            if (keys.length === 0) {
14774                                self._setPreviewError($thumb);
14775                                return;
14776                            }
14777                            if ($.inArray(key, keys) !== -1) {
14778                                self._setPreviewError($thumb);
14779                            } else {
14780                                $thumb.find('.kv-file-upload').hide();
14781                                self._setThumbStatus($thumb, 'Success');
14782                                self.updateStack(key, undefined);
14783                            }
14784                            key++;
14785                        });
14786                        self._initUploadSuccess(data);
14787                    }
14788                    self._showUploadError(data.error, outData, 'filebatchuploaderror');
14789                }
14790            };
14791            fnComplete = function () {
14792                self._setProgress(100);
14793                self.unlock();
14794                self._initSuccessThumbs();
14795                self._clearFileInput();
14796                self._raise('filebatchuploadcomplete', [self.filestack, self._getExtraData()]);
14797            };
14798            fnError = function (jqXHR, textStatus, errorThrown) {
14799                var outData = self._getOutData(jqXHR), errMsg = self._parseError(jqXHR, errorThrown);
14800                self._showUploadError(errMsg, outData, 'filebatchuploaderror');
14801                self.uploadFileCount = total - 1;
14802                if (!self.showPreview) {
14803                    return;
14804                }
14805                self._getThumbs().each(function () {
14806                    var $thumb = $(this), key = $thumb.attr('data-fileindex');
14807                    $thumb.removeClass('file-uploading');
14808                    if (self.filestack[key] !== undefined) {
14809                        self._setPreviewError($thumb);
14810                    }
14811                });
14812                self._getThumbs().removeClass('file-uploading');
14813                self._getThumbs(' .kv-file-upload').removeAttr('disabled');
14814                self._getThumbs(' .kv-file-delete').removeAttr('disabled');
14815            };
14816            $.each(files, function (key, data) {
14817                if (!isEmpty(files[key])) {
14818                    self.formdata.append(self.uploadFileAttr, data, self.filenames[key]);
14819                }
14820            });
14821            self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError);
14822        },
14823        _uploadExtraOnly: function () {
14824            var self = this, params = {}, fnBefore, fnSuccess, fnComplete, fnError;
14825            self.formdata = new FormData();
14826            if (self._abort(params)) {
14827                return;
14828            }
14829            fnBefore = function (jqXHR) {
14830                self.lock();
14831                var outData = self._getOutData(jqXHR);
14832                self._raise('filebatchpreupload', [outData]);
14833                self._setProgress(50);
14834                params.data = outData;
14835                params.xhr = jqXHR;
14836                if (self._abort(params)) {
14837                    jqXHR.abort();
14838                    self._setProgressCancelled();
14839                }
14840            };
14841            fnSuccess = function (data, textStatus, jqXHR) {
14842                var outData = self._getOutData(jqXHR, data);
14843                if (isEmpty(data) || isEmpty(data.error)) {
14844                    self._raise('filebatchuploadsuccess', [outData]);
14845                    self._clearFileInput();
14846                    self._initUploadSuccess(data);
14847                } else {
14848                    self._showUploadError(data.error, outData, 'filebatchuploaderror');
14849                }
14850            };
14851            fnComplete = function () {
14852                self._setProgress(100);
14853                self.unlock();
14854                self._clearFileInput();
14855                self._raise('filebatchuploadcomplete', [self.filestack, self._getExtraData()]);
14856            };
14857            fnError = function (jqXHR, textStatus, errorThrown) {
14858                var outData = self._getOutData(jqXHR), errMsg = self._parseError(jqXHR, errorThrown);
14859                params.data = outData;
14860                self._showUploadError(errMsg, outData, 'filebatchuploaderror');
14861            };
14862            self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError);
14863        },
14864        _initFileActions: function () {
14865            var self = this;
14866            if (!self.showPreview) {
14867                return;
14868            }
14869            self.$preview.find('.kv-file-remove').each(function () {
14870                var $el = $(this), $frame = $el.closest('.file-preview-frame'), hasError,
14871                    id = $frame.attr('id'), ind = $frame.attr('data-fileindex'), n, cap, status;
14872                handler($el, 'click', function () {
14873                    status = self._raise('filepreremove', [id, ind]);
14874                    if (status === false || !self._validateMinCount()) {
14875                        return false;
14876                    }
14877                    hasError = $frame.hasClass('file-preview-error');
14878                    cleanMemory($frame);
14879                    $frame.fadeOut('slow', function () {
14880                        self.updateStack(ind, undefined);
14881                        self._clearObjects($frame);
14882                        $frame.remove();
14883                        if (id && hasError) {
14884                            self.$errorContainer.find('li[data-file-id="' + id + '"]').fadeOut('fast', function () {
14885                                $(this).remove();
14886                                if (!self._errorsExist()) {
14887                                    self._resetErrors();
14888                                }
14889                            });
14890                        }
14891                        var filestack = self.getFileStack(true), len = filestack.length, chk = previewCache.count(
14892                            self.id),
14893                            hasThumb = self.showPreview && self.$preview.find('.file-preview-frame').length;
14894                        self._clearFileInput();
14895                        if (len === 0 && chk === 0 && !hasThumb) {
14896                            self.reset();
14897                        } else {
14898                            n = chk + len;
14899                            cap = n > 1 ? self._getMsgSelected(n) : (filestack[0] ? self._getFileNames()[0] : '');
14900                            self._setCaption(cap);
14901                        }
14902                        self._raise('fileremoved', [id, ind]);
14903                    });
14904                });
14905            });
14906            self.$preview.find('.kv-file-upload').each(function () {
14907                var $el = $(this);
14908                handler($el, 'click', function () {
14909                    var $frame = $el.closest('.file-preview-frame'),
14910                        ind = $frame.attr('data-fileindex');
14911                    if (!$frame.hasClass('file-preview-error')) {
14912                        self._uploadSingle(ind, self.filestack, false);
14913                    }
14914                });
14915            });
14916        },
14917        _hideFileIcon: function () {
14918            if (this.overwriteInitial) {
14919                this.$captionContainer.find('.kv-caption-icon').hide();
14920            }
14921        },
14922        _showFileIcon: function () {
14923            this.$captionContainer.find('.kv-caption-icon').show();
14924        },
14925        _previewDefault: function (file, previewId, isDisabled) {
14926            if (!this.showPreview) {
14927                return;
14928            }
14929            var self = this, frameClass = '', fname = file ? file.name : '',
14930                /** @namespace objUrl.createObjectURL */
14931                data = objUrl.createObjectURL(file), ind = previewId.slice(previewId.lastIndexOf('-') + 1),
14932                config = self.previewSettings.other || defaultPreviewSettings.other,
14933                footer = self._renderFileFooter(file.name, config.width),
14934                previewOtherTemplate = self._parseFilePreviewIcon(self._getPreviewTemplate('other'), fname);
14935            if (isDisabled === true) {
14936                if (!self.isUploadable) {
14937                    footer += '<div class="file-other-error" title="' + self.fileActionSettings.indicatorErrorTitle +
14938                        '">' + self.fileActionSettings.indicatorError + '</div>';
14939                }
14940            }
14941            self._clearDefaultPreview();
14942            self.$preview.append("\n" + previewOtherTemplate
14943                    .replace(/\{previewId}/g, previewId)
14944                    .replace(/\{frameClass}/g, frameClass)
14945                    .replace(/\{fileindex}/g, ind)
14946                    .replace(/\{caption}/g, self.slug(file.name))
14947                    .replace(/\{width}/g, config.width)
14948                    .replace(/\{height}/g, config.height)
14949                    .replace(/\{type}/g, file.type)
14950                    .replace(/\{data}/g, data)
14951                    .replace(/\{footer}/g, footer));
14952            if (isDisabled === true && self.isUploadable) {
14953                self._setThumbStatus($('#' + previewId), 'Error');
14954            }
14955        },
14956        _previewFile: function (i, file, theFile, previewId, data) {
14957            if (!this.showPreview) {
14958                return;
14959            }
14960            var self = this, cat = self._parseFileType(file), fname = file ? file.name : '', caption = self.slug(fname),
14961                content, strText, types = self.allowedPreviewTypes, mimes = self.allowedPreviewMimeTypes,
14962                tmplt = self._getPreviewTemplate(cat), chkTypes = types && types.indexOf(cat) >= 0, id,
14963                config = isSet(cat, self.previewSettings) ? self.previewSettings[cat] : defaultPreviewSettings[cat],
14964                chkMimes = mimes && mimes.indexOf(file.type) !== -1,
14965                footer = self._renderFileFooter(caption, config.width), modal = '',
14966                ind = previewId.slice(previewId.lastIndexOf('-') + 1);
14967            if (chkTypes || chkMimes) {
14968                tmplt = self._parseFilePreviewIcon(tmplt, fname.split('.').pop());
14969                if (cat === 'text') {
14970                    strText = htmlEncode(theFile.target.result);
14971                    id = 'text-' + uniqId();
14972                    content = tmplt.replace(/\{zoom}/g, self._getLayoutTemplate('zoom'));
14973                    modal = self._getLayoutTemplate('modal').replace('{id}', id)
14974                        .replace(/\{title}/g, caption)
14975                        .replace(/\{body}/g, strText).replace(/\{heading}/g, self.msgZoomModalHeading);
14976                    content = content.replace(/\{previewId}
14976/g, previewId).replace(/\{caption}/g, caption)
14977                            .replace(/\{width}/g, config.width).replace(/\{height}/g, config.height)
14978                            .replace(/\{frameClass}/g, '').replace(/\{zoomInd}/g, self.zoomIndicator)
14979                            .replace(/\{footer}/g, footer).replace(/\{fileindex}/g, ind)
14980                            .replace(/\{type}/g, file.type).replace(/\{zoomTitle}/g, self.msgZoomTitle)
14981                            .replace(/\{dialog}/g, "$('#" + id + "').modal('show')")
14982                            .replace(/\{data}/g, strText) + modal;
14983                } else {
14984                    content = tmplt.replace(/\{previewId}/g, previewId).replace(/\{caption}/g, caption)
14985                        .replace(/\{frameClass}/g, '').replace(/\{type}/g, file.type).replace(/\{fileindex}/g, ind)
14986                        .replace(/\{width}/g, config.width).replace(/\{height}/g, config.height)
14987                        .replace(/\{footer}/g, footer).replace(/\{data}/g, data);
14988                }
14989                self._clearDefaultPreview();
14990                self.$preview.append("\n" + content);
14991                self._validateImage(i, previewId, caption, file.type);
14992            } else {
14993                self._previewDefault(file, previewId);
14994            }
14995        },
14996        _slugDefault: function (text) {
14997            return isEmpty(text) ? '' : String(text).replace(/[\-\[\]\/\{}:;#%=\(\)\*\+\?\\\^\$\|<>&"']/g, '_');
14998        },
14999        _readFiles: function (files) {
15000            this.reader = new FileReader();
15001            var self = this, $el = self.$element, $preview = self.$preview, reader = self.reader,
15002                $container = self.$previewContainer, $status = self.$previewStatus, msgLoading = self.msgLoading,
15003                msgProgress = self.msgProgress, previewInitId = self.previewInitId, numFiles = files.length,
15004                settings = self.fileTypeSettings, ctr = self.filestack.length, readFile,
15005                throwError = function (msg, file, previewId, index) {
15006                    var p1 = $.extend(true, {}, self._getOutData({}, {}, files), {id: previewId, index: index}),
15007                        p2 = {id: previewId, index: index, file: file, files: files};
15008                    self._previewDefault(file, previewId, true);
15009                    if (self.isUploadable) {
15010                        self.addToStack(undefined);
15011                    }
15012                    setTimeout(readFile(index + 1), 100);
15013                    self._initFileActions();
15014                    if (self.removeFromPreviewOnError) {
15015                        $('#' + previewId).remove();
15016                    }
15017                    return self.isUploadable ? self._showUploadError(msg, p1) : self._showError(msg, p2);
15018                };
15019
15020            self.loadedImages = [];
15021            self.totalImagesCount = 0;
15022
15023            $.each(files, function (key, file) {
15024                var func = self.fileTypeSettings.image || defaultFileTypeSettings.image;
15025                if (func && func(file.type)) {
15026                    self.totalImagesCount++;
15027                }
15028            });
15029
15030            readFile = function (i) {
15031                if (isEmpty($el.attr('multiple'))) {
15032                    numFiles = 1;
15033                }
15034                if (i >= numFiles) {
15035                    if (self.isUploadable && self.filestack.length > 0) {
15036                        self._raise('filebatchselected', [self.getFileStack()]);
15037                    } else {
15038                        self._raise('filebatchselected', [files]);
15039                    }
15040                    $container.removeClass('file-thumb-loading');
15041                    $status.html('');
15042                    return;
15043                }
15044                var node = ctr + i, previewId = previewInitId + "-" + node, isText, file = files[i],
15045                    caption = self.slug(file.name), fileSize = (file.size || 0) / 1000, checkFile, fileExtExpr = '',
15046                    previewData = objUrl.createObjectURL(file), fileCount = 0, j, msg, typ, chk,
15047                    fileTypes = self.allowedFileTypes, strTypes = isEmpty(fileTypes) ? '' : fileTypes.join(', '),
15048                    fileExt = self.allowedFileExtensions, strExt = isEmpty(fileExt) ? '' : fileExt.join(', ');
15049                if (!isEmpty(fileExt)) {
15050                    fileExtExpr = new RegExp('\\.(' + fileExt.join('|') + ')$', 'i');
15051                }
15052                fileSize = fileSize.toFixed(2);
15053                if (self.maxFileSize > 0 && fileSize > self.maxFileSize) {
15054                    msg = self.msgSizeTooLarge.replace('{name}', caption)
15055                        .replace('{size}', fileSize)
15056                        .replace('{maxSize}', self.maxFileSize);
15057                    self.isError = throwError(msg, file, previewId, i);
15058                    return;
15059                }
15060                if (!isEmpty(fileTypes) && isArray(fileTypes)) {
15061                    for (j = 0; j < fileTypes.length; j += 1) {
15062                        typ = fileTypes[j];
15063                        checkFile = settings[typ];
15064                        chk = (checkFile !== undefined && checkFile(file.type, caption));
15065                        fileCount += isEmpty(chk) ? 0 : chk.length;
15066                    }
15067                    if (fileCount === 0) {
15068                        msg = self.msgInvalidFileType.replace('{name}', caption).replace('{types}', strTypes);
15069                        self.isError = throwError(msg, file, previewId, i);
15070                        return;
15071                    }
15072                }
15073                if (fileCount === 0 && !isEmpty(fileExt) && isArray(fileExt) && !isEmpty(fileExtExpr)) {
15074                    chk = compare(caption, fileExtExpr);
15075                    fileCount += isEmpty(chk) ? 0 : chk.length;
15076                    if (fileCount === 0) {
15077                        msg = self.msgInvalidFileExtension.replace('{name}', caption).replace('{extensions}',
15078                            strExt);
15079                        self.isError = throwError(msg, file, previewId, i);
15080                        return;
15081                    }
15082                }
15083                if (!self.showPreview) {
15084                    self.addToStack(file);
15085                    setTimeout(readFile(i + 1), 100);
15086                    self._raise('fileloaded', [file, previewId, i, reader]);
15087                    return;
15088                }
15089                if ($preview.length > 0 && FileReader !== undefined) {
15090                    $status.html(msgLoading.replace('{index}', i + 1).replace('{files}', numFiles));
15091                    $container.addClass('file-thumb-loading');
15092                    reader.onerror = function (evt) {
15093                        self._errorHandler(evt, caption);
15094                    };
15095                    reader.onload = function (theFile) {
15096                        self._previewFile(i, file, theFile, previewId, previewData);
15097                        self._initFileActions();
15098                    };
15099                    reader.onloadend = function () {
15100                        msg = msgProgress
15101                            .replace('{index}', i + 1).replace('{files}', numFiles)
15102                            .replace('{percent}', 50).replace('{name}', caption);
15103                        setTimeout(function () {
15104                            $status.html(msg);
15105                            self._updateFileDetails(numFiles);
15106                            readFile(i + 1);
15107                        }, 100);
15108                        self._raise('fileloaded', [file, previewId, i, reader]);
15109                    };
15110                    reader.onprogress = function (data) {
15111                        if (data.lengthComputable) {
15112                            var fact = (data.loaded / data.total) * 100, progress = Math.ceil(fact);
15113                            msg = msgProgress.replace('{index}', i + 1).replace('{files}', numFiles)
15114                                .replace('{percent}', progress).replace('{name}', caption);
15115                            setTimeout(function () {
15116                                $status.html(msg);
15117                            }, 100);
15118                        }
15119                    };
15120                    isText = isSet('text', settings) ? settings.text : defaultFileTypeSettings.text;
15121                    if (isText(file.type, caption)) {
15122                        reader.readAsText(file, self.textEncoding);
15123                    } else {
15124                        reader.readAsArrayBuffer(file);
15125                    }
15126                } else {
15127                    self._previewDefault(file, previewId);
15128                    setTimeout(function () {
15129                        readFile(i + 1);
15130                        self._updateFileDetails(numFiles);
15131                    }, 100);
15132                    self._raise('fileloaded', [file, previewId, i, reader]);
15133                }
15134                self.addToStack(file);
15135            };
15136
15137            readFile(0);
15138            self._updateFileDetails(numFiles, false);
15139        },
15140        _updateFileDetails: function (numFiles) {
15141            var self = this, $el = self.$element, fileStack = self.getFileStack(),
15142                name = ($el[0].files[0] && $el[0].files[0].name) || (fileStack.length && fileStack[0].name) || '',
15143                label = self.slug(name), n = self.isUploadable ? fileStack.length : numFiles,
15144                nFiles = previewCache.count(self.id) + n, log = n > 1 ? self._getMsgSelected(nFiles) : label;
15145            if (self.isError) {
15146                self.$previewContainer.removeClass('file-thumb-loading');
15147                self.$previewStatus.html('');
15148                self.$captionContainer.find('.kv-caption-icon').hide();
15149            } else {
15150                self._showFileIcon();
15151            }
15152            self._setCaption(log, self.isError);
15153            self.$container.removeClass('file-input-new file-input-ajax-new');
15154            if (arguments.length === 1) {
15155                self._raise('fileselect', [numFiles, label]);
15156            }
15157            if (previewCache.count(self.id)) {
15158                self._initPreviewDeletes();
15159            }
15160        },
15161        _setThumbStatus: function ($thumb, status) {
15162            var self = this;
15163            if (!self.showPreview) {
15164                return;
15165            }
15166            var icon = 'indicator' + status, msg = icon + 'Title',
15167                css = 'file-preview-' + status.toLowerCase(),
15168                $indicator = $thumb.find('.file-upload-indicator'),
15169                config = self.fileActionSettings;
15170            $thumb.removeClass('file-preview-success file-preview-error file-preview-loading');
15171            if (status === 'Error') {
15172                $thumb.find('.kv-file-upload').attr('disabled', true);
15173            }
15174            $indicator.html(config[icon]);
15175            $indicator.attr('title', config[msg]);
15176            $thumb.addClass(css);
15177        },
15178        _setProgressCancelled: function () {
15179            var self = this;
15180            self._setProgress(100, self.$progress, self.msgCancelled);
15181        },
15182        _setProgress: function (p, $el, error) {
15183            var self = this, pct = Math.min(p, 100), template = pct < 100 ? self.progressTemplate :
15184                (error ? self.progressErrorTemplate : self.progressCompleteTemplate);
15185            $el = $el || self.$progress;
15186            if (!isEmpty(template)) {
15187                $el.html(template.replace(/\{percent}/g, pct));
15188                if (error) {
15189                    $el.find('[role="progressbar"]').html(error);
15190                }
15191            }
15192        },
15193        _setFileDropZoneTitle: function () {
15194            var self = this, $zone = self.$container.find('.file-drop-zone');
15195            $zone.find('.' + self.dropZoneTitleClass).remove();
15196            if (!self.isUploadable || !self.showPreview || $zone.length === 0 || self.getFileStack().length > 0 || !self.dropZoneEnabled) {
15197                return;
15198            }
15199            if ($zone.find('.file-preview-frame').length === 0 && isEmpty(self.defaultPreviewContent)) {
15200                $zone.prepend('<div class="' + self.dropZoneTitleClass + '">' + self.dropZoneTitle + '</div>');
15201            }
15202            self.$container.removeClass('file-input-new');
15203            addCss(self.$container, 'file-input-ajax-new');
15204        },
15205        _setAsyncUploadStatus: function (previewId, pct, total) {
15206            var self = this, sum = 0;
15207            self._setProgress(pct, $('#' + previewId).find('.file-thumb-progress'));
15208            self.uploadStatus[previewId] = pct;
15209            $.each(self.uploadStatus, function (key, value) {
15210                sum += value;
15211            });
15212            self._setProgress(Math.ceil(sum / total));
15213
15214        },
15215        _validateMinCount: function () {
15216            var self = this, len = self.isUploadable ? self.getFileStack().length : self.$element.get(0).files.length;
15217            if (self.validateInitialCount && self.minFileCount > 0 && self._getFileCount(
15218                    len - 1) < self.minFileCount) {
15219                self._noFilesError({});
15220                return false;
15221            }
15222            return true;
15223        },
15224        _getFileCount: function (fileCount) {
15225            var self = this, addCount = 0;
15226            if (self.validateInitialCount && !self.overwriteInitial) {
15227                addCount = previewCache.count(self.id);
15228                fileCount += addCount;
15229            }
15230            return fileCount;
15231        },
15232        _getFileName: function (file) {
15233            return file && file.name ? this.slug(file.name) : undefined;
15234        },
15235        _getFileNames: function (skipNull) {
15236            var self = this;
15237            return self.filenames.filter(function (n) {
15238                return (skipNull ? n !== undefined : n !== undefined && n !== null);
15239            });
15240        },
15241        _setPreviewError: function ($thumb, i, val) {
15242            var self = this;
15243            if (i) {
15244                self.updateStack(i, val);
15245            }
15246            if (self.removeFromPreviewOnError) {
15247                $thumb.remove();
15248            } else {
15249                self._setThumbStatus($thumb, 'Error');
15250            }
15251        },
15252        _checkDimensions: function (i, chk, $img, $thumb, fname, type, params) {
15253            var self = this, msg, dim, tag = chk === 'Small' ? 'min' : 'max', limit = self[tag + 'Image' + type],
15254                $imgEl, isValid;
15255            if (isEmpty(limit) || !$img.length) {
15256                return;
15257            }
15258            $imgEl = $img[0];
15259            dim = (type === 'Width') ? $imgEl.naturalWidth || $imgEl.width : $imgEl.naturalHeight || $imgEl.height;
15260            isValid = chk === 'Small' ? dim >= limit : dim <= limit;
15261            if (isValid) {
15262                return;
15263            }
15264            msg = self['msgImage' + type + chk].replace('{name}', fname).replace('{size}', limit);
15265            self._showUploadError(msg, params);
15266            self._setPreviewError($thumb, i, null);
15267        },
15268        _validateImage: function (i, previewId, fname, ftype) {
15269            var self = this, $preview = self.$preview, params, w1, w2,
15270                $thumb = $preview.find("#" + previewId), $img = $thumb.find('img');
15271            fname = fname || 'Untitled';
15272            if (!$img.length) {
15273                return;
15274            }
15275            handler($img, 'load', function () {
15276                w1 = $thumb.width();
15277                w2 = $preview.width();
15278                if (w1 > w2) {
15279                    $img.css('width', '100%');
15280                    $thumb.css('width', '97%');
15281                }
15282                params = {ind: i, id: previewId};
15283                self._checkDimensions(i, 'Small', $img, $thumb, fname, 'Width', params);
15284                self._checkDimensions(i, 'Small', $img, $thumb, fname, 'Height', params);
15285                if (!self.resizeImage) {
15286                    self._checkDimensions(i, 'Large', $img, $thumb, fname, 'Width', params);
15287                    self._checkDimensions(i, 'Large', $img, $thumb, fname, 'Height', params);
15288                }
15289                self._raise('fileimageloaded', [previewId]);
15290                self.loadedImages.push({ind: i, img: $img, thumb: $thumb, pid: previewId, typ: ftype});
15291                self._validateAllImages();
15292                objUrl.revokeObjectURL($img.attr('src'));
15293            });
15294        },
15295        _validateAllImages: function () {
15296            var self = this, i, config, $img, $thumb, pid, ind, params = {}, errFunc;
15297            if (self.loadedImages.length !== self.totalImagesCount) {
15298                return;
15299            }
15300            self._raise('fileimagesloaded');
15301            if (!self.resizeImage) {
15302                return;
15303            }
15304            errFunc = self.isUploadable ? self._showUploadError : self._showError;
15305            for (i = 0; i < self.loadedImages.length; i++) {
15306                config = self.loadedImages[i];
15307                $img = config.img;
15308                $thumb = config.thumb;
15309                pid = config.pid;
15310                ind = config.ind;
15311                params = {id: pid, 'index': ind};
15312                if (!self._getResizedImage($img[0], config.typ, pid, ind)) {
15313                    errFunc(self.msgImageResizeError, params, 'fileimageresizeerror');
15314                    self._setPreviewError($thumb, ind);
15315                }
15316            }
15317            self._raise('fileimagesresized');
15318        },
15319        _getResizedImage: function (image, type, pid, ind) {
15320            var self = this, width = image.naturalWidth, height = image.naturalHeight, ratio = 1,
15321                maxWidth = self.maxImageWidth || width, maxHeight = self.maxImageHeight || height,
15322                isValidImage = (width && height), chkWidth, chkHeight,
15323                canvas = self.imageCanvas, context = self.imageCanvasContext;
15324            if (!isValidImage) {
15325                return false;
15326            }
15327            if (width === maxWidth && height === maxHeight) {
15328                return true;
15329            }
15330            type = type || self.resizeDefaultImageType;
15331            chkWidth = width > maxWidth;
15332            chkHeight = height > maxHeight;
15333            if (self.resizePreference === 'width') {
15334                ratio = chkWidth ? maxWidth / width : (chkHeight ? maxHeight / height : 1);
15335            } else {
15336                ratio = chkHeight ? maxHeight / height : (chkWidth ? maxWidth / width : 1);
15337            }
15338            self._resetCanvas();
15339            width *= ratio;
15340            height *= ratio;
15341            canvas.width = width;
15342            canvas.height = height;
15343            try {
15344                context.drawImage(image, 0, 0, width, height);
15345                canvas.toBlob(function (blob) {
15346                    self._raise('fileimageresized', [pid, ind]);
15347                    self.filestack[ind] = blob;
15348                }, type, self.resizeQuality);
15349                return true;
15350            }
15351            catch (err) {
15352                return false;
15353            }
15354        },
15355        _initBrowse: function ($container) {
15356            var self = this;
15357            self.$btnFile = $container.find('.btn-file');
15358            self.$btnFile.append(self.$element);
15359        },
15360        _initCaption: function () {
15361            var self = this, cap = self.initialCaption || '';
15362            if (self.overwriteInitial || isEmpty(cap)) {
15363                self.$caption.html('');
15364                return false;
15365            }
15366            self._setCaption(cap);
15367            return true;
15368        },
15369        _setCaption: function (content, isError) {
15370            var self = this, title, out, n, cap, stack = self.getFileStack();
15371            if (!self.$caption.length) {
15372                return;
15373            }
15374            if (isError) {
15375                title = $('<div>' + self.msgValidationError + '</div>').text();
15376                n = stack.length;
15377                if (n) {
15378                    cap = n === 1 && stack[0] ? self._getFileNames()[0] : self._getMsgSelected(n);
15379                } else {
15380                    cap = self._getMsgSelected(self.msgNo);
15381                }
15382                out = '<span class="' + self.msgValidationErrorClass + '">' + self.msgValidationErrorIcon +
15383                    (isEmpty(content) ? cap : content) + '</span>';
15384            } else {
15385                if (isEmpty(content)) {
15386                    return;
15387                }
15388                title = $('<div>' + content + '</div>').text();
15389                out = self._getLayoutTemplate('icon') + title;
15390            }
15391            self.$caption.html(out);
15392            self.$caption.attr('title', title);
15393            self.$captionContainer.find('.file-caption-ellipsis').attr('title', title);
15394        },
15395        _createContainer: function () {
15396            var self = this,
15397                $container = $(document.createElement("div"))
15398                    .attr({"class": 'file-input file-input-new'})
15399                    .html(self._renderMain());
15400            self.$element.before($container);
15401            self._initBrowse($container);
15402            return $container;
15403        },
15404        _refreshContainer: function () {
15405            var self = this, $container = self.$container;
15406            $container.before(self.$element);
15407            $container.html(self._renderMain());
15408            self._initBrowse($container);
15409        },
15410        _renderMain: function () {
15411            var self = this, dropCss = (self.isUploadable && self.dropZoneEnabled) ? ' file-drop-zone' : 'file-drop-disabled',
15412                close = !self.showClose ? '' : self._getLayoutTemplate('close'),
15413                preview = !self.showPreview ? '' : self._getLayoutTemplate('preview')
15414                    .replace(/\{class}/g, self.previewClass)
15415                    .replace(/\{dropClass}/g, dropCss),
15416                css = self.isDisabled ? self.captionClass + ' file-caption-disabled' : self.captionClass,
15417                caption = self.captionTemplate.replace(/\{class}/g, css + ' kv-fileinput-caption');
15418            return self.mainTemplate.replace(/\{class}/g, self.mainClass)
15419                .replace(/\{preview}/g, preview)
15420                .replace(/\{close}/g, close)
15421                .replace(/\{caption}/g, caption)
15422                .replace(/\{upload}/g, self._renderButton('upload'))
15423                .replace(/\{remove}/g, self._renderButton('remove'))
15424                .replace(/\{cancel}/g, self._renderButton('cancel'))
15425                .replace(/\{browse}/g, self._renderButton('browse'));
15426        },
15427        _renderButton: function (type) {
15428            var self = this, tmplt = self._getLayoutTemplate('btnDefault'), css = self[type + 'Class'],
15429                title = self[type + 'Title'], icon = self[type + 'Icon'], label = self[type + 'Label'],
15430                status = self.isDisabled ? ' disabled' : '', btnType = 'button';
15431            switch (type) {
15432                case 'remove':
15433                    if (!self.showRemove) {
15434                        return '';
15435                    }
15436                    break;
15437                case 'cancel':
15438                    if (!self.showCancel) {
15439                        return '';
15440                    }
15441                    css += ' hide';
15442                    break;
15443                case 'upload':
15444                    if (!self.showUpload) {
15445                        return '';
15446                    }
15447                    if (self.isUploadable && !self.isDisabled) {
15448                        tmplt = self._getLayoutTemplate('btnLink').replace('{href}', self.uploadUrl);
15449                    } else {
15450                        btnType = 'submit';
15451                    }
15452                    break;
15453                case 'browse':
15454                    tmplt = self._getLayoutTemplate('btnBrowse');
15455                    break;
15456                default:
15457                    return '';
15458            }
15459            css += type === 'browse' ? ' btn-file' : ' fileinput-' + type + ' fileinput-' + type + '-button';
15460            if (!isEmpty(label)) {
15461                label = ' <span class="' + self.buttonLabelClass + '">' + label + '</span>';
15462            }
15463            return tmplt.replace('{type}', btnType)
15464                .replace('{css}', css)
15465                .replace('{title}', title)
15466                .replace('{status}', status)
15467                .replace('{icon}', icon)
15468                .replace('{label}', label);
15469        },
15470        _renderThumbProgress: function () {
15471            return '<div class="file-thumb-progress hide">' + this.progressTemplate.replace(/\{percent}/g,
15472                    '0') + '</div>';
15473        },
15474        _renderFileFooter: function (caption, width) {
15475            var self = this, config = self.fileActionSettings, footer, out, template = self._getLayoutTemplate(
15476                'footer');
15477            if (self.isUploadable) {
15478                footer = template.replace(/\{actions}/g, self._renderFileActions(true, true, false, false, false));
15479                out = footer.replace(/\{caption}/g, caption)
15480                    .replace(/\{width}/g, width)
15481                    .replace(/\{progress}/g, self._renderThumbProgress())
15482                    .replace(/\{indicator}/g, config.indicatorNew)
15483                    .replace(/\{indicatorTitle}/g, config.indicatorNewTitle);
15484            } else {
15485                out = template.replace(/\{actions}/g, '')
15486                    .replace(/\{caption}/g, caption)
15487                    .replace(/\{progress}/g, '')
15488                    .replace(/\{width}/g, width)
15489                    .replace(/\{indicator}/g, '')
15490                    .replace(/\{indicatorTitle}/g, '');
15491            }
15492            out = replaceTags(out, self.previewThumbTags);
15493            return out;
15494        },
15495        _renderFileActions: function (showUpload, showDelete, disabled, url, key) {
15496            if (!showUpload && !showDelete) {
15497                return '';
15498            }
15499            var self = this,
15500                vUrl = url === false ? '' : ' data-url="' + url + '"',
15501                vKey = key === false ? '' : ' data-key="' + key + '"',
15502                btnDelete = self._getLayoutTemplate('actionDelete'),
15503                btnUpload = '',
15504                template = self._getLayoutTemplate('actions'),
15505                otherButtons = self.otherActionButtons.replace(/\{dataKey}/g, vKey),
15506                config = self.fileActionSettings,
15507                removeClass = disabled ? config.removeClass + ' disabled' : config.removeClass;
15508            btnDelete = btnDelete
15509                .replace(/\{removeClass}/g, removeClass)
15510                .replace(/\{removeIcon}/g, config.removeIcon)
15511                .replace(/\{removeTitle}/g, config.removeTitle)
15512                .replace(/\{dataUrl}/g, vUrl)
15513                .replace(/\{dataKey}/g, vKey);
15514            if (showUpload) {
15515                btnUpload = self._getLayoutTemplate('actionUpload')
15516                    .replace(/\{uploadClass}/g, config.uploadClass)
15517                    .replace(/\{uploadIcon}/g, config.uploadIcon)
15518                    .replace(/\{uploadTitle}/g, config.uploadTitle);
15519            }
15520            return template
15521                .replace(/\{delete}/g, btnDelete)
15522                .replace(/\{upload}/g, btnUpload)
15523                .replace(/\{other}/g, otherButtons);
15524        },
15525        _browse: function (e) {
15526            var self = this;
15527            self._raise('filebrowse');
15528            if (e && e.isDefaultPrevented()) {
15529                return;
15530            }
15531            if (self.isError && !self.isUploadable) {
15532                self.clear();
15533            }
15534            self.$captionContainer.focus();
15535        },
15536        _change: function (e) {
15537            var self = this, $el = self.$element;
15538            if (!self.isUploadable && isEmpty($el.val()) && self.fileInputCleared) { // IE 11 fix
15539                self.fileInputCleared = false;
15540                return;
15541            }
15542            self.fileInputCleared = false;
15543            var tfiles, msg, total, isDragDrop = arguments.length >
15543 1, isAjaxUpload = self.isUploadable, i = 0, f, n, len,
15544                files = isDragDrop ? e.originalEvent.dataTransfer.files : $el.get(0).files, ctr = self.filestack.length,
15545                isSingleUpload = isEmpty($el.attr('multiple')), flagSingle = (isSingleUpload && ctr > 0), folders = 0,
15546                throwError = function (mesg, file, previewId, index) {
15547                    var p1 = $.extend(true, {}, self._getOutData({}, {}, files), {id: previewId, index: index}),
15548                        p2 = {id: previewId, index: index, file: file, files: files};
15549                    return self.isUploadable ? self._showUploadError(mesg, p1) : self._showError(mesg, p2);
15550                };
15551            self.reader = null;
15552            self._resetUpload();
15553            self._hideFileIcon();
15554            if (self.isUploadable) {
15555                self.$container.find('.file-drop-zone .' + self.dropZoneTitleClass).remove();
15556            }
15557            if (isDragDrop) {
15558                tfiles = [];
15559                while (files[i]) {
15560                    f = files[i];
15561                    if (!f.type && f.size % 4096 === 0) {
15562                        folders++;
15563                    } else {
15564                        tfiles.push(f);
15565                    }
15566                    i++;
15567                }
15568            } else {
15569                if (e.target.files === undefined) {
15570                    tfiles = e.target && e.target.value ? [
15571                        {name: e.target.value.replace(/^.+\\/, '')}
15572                    ] : [];
15573                } else {
15574                    tfiles = e.target.files;
15575                }
15576            }
15577            if (isEmpty(tfiles) || tfiles.length === 0) {
15578                if (!isAjaxUpload) {
15579                    self.clear();
15580                }
15581                self._showFolderError(folders);
15582                self._raise('fileselectnone');
15583                return;
15584            }
15585            self._resetErrors();
15586            len = tfiles.length;
15587            total = self._getFileCount(self.isUploadable ? (self.getFileStack().length + len) : len);
15588            if (self.maxFileCount > 0 && total > self.maxFileCount) {
15589                if (!self.autoReplace || len > self.maxFileCount) {
15590                    n = (self.autoReplace && len > self.maxFileCount) ? len : total;
15591                    msg = self.msgFilesTooMany.replace('{m}', self.maxFileCount).replace('{n}', n);
15592                    self.isError = throwError(msg, null, null, null);
15593                    self.$captionContainer.find('.kv-caption-icon').hide();
15594                    self._setCaption('', true);
15595                    self.$container.removeClass('file-input-new file-input-ajax-new');
15596                    return;
15597                }
15598                if (total > self.maxFileCount) {
15599                    self._resetPreviewThumbs(isAjaxUpload);
15600                }
15601            } else {
15602                if (!isAjaxUpload || flagSingle) {
15603                    self._resetPreviewThumbs(false);
15604                    if (flagSingle) {
15605                        self.clearStack();
15606                    }
15607                } else {
15608                    if (isAjaxUpload && ctr === 0 && (!previewCache.count(self.id) || self.overwriteInitial)) {
15609                        self._resetPreviewThumbs(true);
15610                    }
15611                }
15612            }
15613            if (self.isPreviewable) {
15614                self._readFiles(tfiles);
15615            } else {
15616                self._updateFileDetails(1);
15617            }
15618            self._showFolderError(folders);
15619        },
15620        _abort: function (params) {
15621            var self = this, data;
15622            if (self.ajaxAborted && typeof self.ajaxAborted === "object" && self.ajaxAborted.message !== undefined) {
15623                data = $.extend(true, {}, self._getOutData(), params);
15624                data.abortData = self.ajaxAborted.data || {};
15625                data.abortMessage = self.ajaxAborted.message;
15626                self.cancel();
15627                self._setProgress(100, self.$progress, self.msgCancelled);
15628                self._showUploadError(self.ajaxAborted.message, data, 'filecustomerror');
15629                return true;
15630            }
15631            return false;
15632        },
15633        _resetFileStack: function () {
15634            var self = this, i = 0, newstack = [], newnames = [];
15635            self._getThumbs().each(function () {
15636                var $thumb = $(this), ind = $thumb.attr('data-fileindex'),
15637                    file = self.filestack[ind];
15638                if (ind === -1) {
15639                    return;
15640                }
15641                if (file !== undefined) {
15642                    newstack[i] = file;
15643                    newnames[i] = self._getFileName(file);
15644                    $thumb.attr({
15645                        'id': self.previewInitId + '-' + i,
15646                        'data-fileindex': i
15647                    });
15648                    i++;
15649                } else {
15650                    $thumb.attr({
15651                        'id': 'uploaded-' + uniqId(),
15652                        'data-fileindex': '-1'
15653                    });
15654                }
15655            });
15656            self.filestack = newstack;
15657            self.filenames = newnames;
15658        },
15659        clearStack: function () {
15660            var self = this;
15661            self.filestack = [];
15662            self.filenames = [];
15663            return self.$element;
15664        },
15665        updateStack: function (i, file) {
15666            var self = this;
15667            self.filestack[i] = file;
15668            self.filenames[i] = self._getFileName(file);
15669            return self.$element;
15670        },
15671        addToStack: function (file) {
15672            var self = this;
15673            self.filestack.push(file);
15674            self.filenames.push(self._getFileName(file));
15675            return self.$element;
15676        },
15677        getFileStack: function (skipNull) {
15678            var self = this;
15679            return self.filestack.filter(function (n) {
15680                return (skipNull ? n !== undefined : n !== undefined && n !== null);
15681            });
15682        },
15683        lock: function () {
15684            var self = this;
15685            self._resetErrors();
15686            self.disable();
15687            if (self.showRemove) {
15688                addCss(self.$container.find('.fileinput-remove'), 'hide');
15689            }
15690            if (self.showCancel) {
15691                self.$container.find('.fileinput-cancel').removeClass('hide');
15692            }
15693            self._raise('filelock', [self.filestack, self._getExtraData()]);
15694            return self.$element;
15695        },
15696        unlock: function (reset) {
15697            var self = this;
15698            if (reset === undefined) {
15699                reset = true;
15700            }
15701            self.enable();
15702            if (self.showCancel) {
15703                addCss(self.$container.find('.fileinput-cancel'), 'hide');
15704            }
15705            if (self.showRemove) {
15706                self.$container.find('.fileinput-remove').removeClass('hide');
15707            }
15708            if (reset) {
15709                self._resetFileStack();
15710            }
15711            self._raise('fileunlock', [self.filestack, self._getExtraData()]);
15712            return self.$element;
15713        },
15714        cancel: function () {
15715            var self = this, xhr = self.ajaxRequests, len = xhr.length, i;
15716            if (len > 0) {
15717                for (i = 0; i < len; i += 1) {
15718                    self.cancelling = true;
15719                    xhr[i].abort();
15720                }
15721            }
15722            self._setProgressCancelled();
15723            self._getThumbs().each(function () {
15724                var $thumb = $(this), ind = $thumb.attr('data-fileindex');
15725                $thumb.removeClass('file-uploading');
15726                if (self.filestack[ind] !== undefined) {
15727                    $thumb.find('.kv-file-upload').removeClass('disabled').removeAttr('disabled');
15728                    $thumb.find('.kv-file-remove').removeClass('disabled').removeAttr('disabled');
15729                }
15730                self.unlock();
15731            });
15732            return self.$element;
15733        },
15734        clear: function () {
15735            var self = this, cap;
15736            self.$btnUpload.removeAttr('disabled');
15737            self._getThumbs().find('video,audio,img').each(function () {
15738                cleanMemory($(this));
15739            });
15740            self._resetUpload();
15741            self.clearStack();
15742            self._clearFileInput();
15743            self._resetErrors(true);
15744            self._raise('fileclear');
15745            if (self._hasInitialPreview()) {
15746                self._showFileIcon();
15747                self._resetPreview();
15748                self._initPreviewDeletes();
15749                self.$container.removeClass('file-input-new');
15750            } else {
15751                self._getThumbs().each(function () {
15752                    self._clearObjects($(this));
15753                });
15754                if (self.isUploadable) {
15755                    previewCache.data[self.id] = {};
15756                }
15757                self.$preview.html('');
15758                cap = (!self.overwriteInitial && self.initialCaption.length > 0) ? self.initialCaption : '';
15759                self._setCaption(cap);
15760                self.$caption.attr('title', '');
15761                addCss(self.$container, 'file-input-new');
15762                self._validateDefaultPreview();
15763            }
15764            if (self.$container.find('.file-preview-frame').length === 0) {
15765                if (!self._initCaption()) {
15766                    self.$captionContainer.find('.kv-caption-icon').hide();
15767                }
15768            }
15769            self._hideFileIcon();
15770            self._raise('filecleared');
15771            self.$captionContainer.focus();
15772            self._setFileDropZoneTitle();
15773            return self.$element;
15774        },
15775        reset: function () {
15776            var self = this;
15777            self._resetPreview();
15778            self.$container.find('.fileinput-filename').text('');
15779            self._raise('filereset');
15780            addCss(self.$container, 'file-input-new');
15781            if (self.$preview.find('.file-preview-frame').length || self.isUploadable && self.dropZoneEnabled) {
15782                self.$container.removeClass('file-input-new');
15783            }
15784            self._setFileDropZoneTitle();
15785            self.clearStack();
15786            self.formdata = {};
15787            return self.$element;
15788        },
15789        disable: function () {
15790            var self = this;
15791            self.isDisabled = true;
15792            self._raise('filedisabled');
15793            self.$element.attr('disabled', 'disabled');
15794            self.$container.find(".kv-fileinput-caption").addClass("file-caption-disabled");
15795            self.$container.find(".btn-file, .fileinput-remove, .fileinput-upload, .file-preview-frame button").attr(
15796                "disabled",
15797                true);
15798            self._initDragDrop();
15799            return self.$element;
15800        },
15801        enable: function () {
15802            var self = this;
15803            self.isDisabled = false;
15804            self._raise('fileenabled');
15805            self.$element.removeAttr('disabled');
15806            self.$container.find(".kv-fileinput-caption").removeClass("file-caption-disabled");
15807            self.$container.find(
15808                ".btn-file, .fileinput-remove, .fileinput-upload, .file-preview-frame button").removeAttr("disabled");
15809            self._initDragDrop();
15810            return self.$element;
15811        },
15812        upload: function () {
15813            var self = this, totLen = self.getFileStack().length, params = {},
15814                i, outData, len, hasExtraData = !$.isEmptyObject(self._getExtraData());
15815            if (self.minFileCount > 0 && self._getFileCount(totLen) < self.minFileCount) {
15816                self._noFilesError(params);
15817                return;
15818            }
15819            if (!self.isUploadable || self.isDisabled || (totLen === 0 && !hasExtraData)) {
15820                return;
15821            }
15822            self._resetUpload();
15823            self.$progress.removeClass('hide');
15824            self.uploadCount = 0;
15825            self.uploadStatus = {};
15826            self.uploadLog = [];
15827            self.lock();
15828            self._setProgress(2);
15829            if (totLen === 0 && hasExtraData) {
15830                self._uploadExtraOnly();
15831                return;
15832            }
15833            len = self.filestack.length;
15834            self.hasInitData = false;
15835            if (self.uploadAsync) {
15836                outData = self._getOutData();
15837                self._raise('filebatchpreupload', [outData]);
15838                self.fileBatchCompleted = false;
15839                self.uploadCache = {content: [], config: [], tags: [], append: true};
15840                self.uploadAsyncCount = self.getFileStack().length;
15841                for (i = 0; i < len; i++) {
15842                    self.uploadCache.content[i] = null;
15843                    self.uploadCache.config[i] = null;
15844                    self.uploadCache.tags[i] = null;
15845                }
15846                for (i = 0; i < len; i++) {
15847                    if (self.filestack[i] !== undefined) {
15848                        self._uploadSingle(i, self.filestack, true);
15849                    }
15850                }
15851                return;
15852            }
15853            self._uploadBatch();
15854            return self.$element;
15855        },
15856        destroy: function () {
15857            var self = this, $cont = self.$container;
15858            $cont.find('.file-drop-zone').off();
15859            self.$element.insertBefore($cont).off(NAMESPACE).removeData();
15860            $cont.off().remove();
15861            return self.$element;
15862        },
15863        refresh: function (options) {
15864            var self = this, $el = self.$element;
15865            options = options ? $.extend(true, {}, self.options, options) : self.options;
15866            self.destroy();
15867            $el.fileinput(options);
15868            if ($el.val()) {
15869                $el.trigger('change.fileinput');
15870            }
15871            return $el;
15872        }
15873    };
15874
15875    $.fn.fileinput = function (option) {
15876        if (!hasFileAPISupport() && !isIE(9)) {
15877            return;
15878        }
15879        var args = Array.apply(null, arguments), retvals = [];
15880        args.shift();
15881        this.each(function () {
15882            var self = $(this), data = self.data('fileinput'), options = typeof option === 'object' && option,
15883                lang = options.language || self.data('language') || 'en', loc = {}, opts;
15884
15885            if (!data) {
15886                if (lang !== 'en' && !isEmpty($.fn.fileinputLocales[lang])) {
15887                    loc = $.fn.fileinputLocales[lang];
15888                }
15889                opts = $.extend(true, {}, $.fn.fileinput.defaults, $.fn.fileinputLocales.en, loc, options, self.data());
15890                data = new FileInput(this, opts);
15891                self.data('fileinput', data);
15892            }
15893
15894            if (typeof option === 'string') {
15895                retvals.push(data[option].apply(data, args));
15896            }
15897        });
15898        switch (retvals.length) {
15899            case 0:
15900                return this;
15901            case 1:
15902                return retvals[0];
15903            default:
15904                return retvals;
15905        }
15906    };
15907
15908    $.fn.fileinput.defaults = {
15909        language: 'en',
15910        showCaption: true,
15911        showPreview: true,
15912        showRemove: true,
15913        showUpload: true,
15914        showCancel: true,
15915        showClose: true,
15916        showUploadedThumbs: true,
15917        autoReplace: false,
15918        mainClass: '',
15919        previewClass: '',
15920        captionClass: '',
15921        mainTemplate: null,
15922        initialCaption: '',
15923        initialPreview: [],
15924        initialPreviewDelimiter: '*$$*',
15925        initialPreviewConfig: [],
15926        initialPreviewThumbTags: [],
15927        previewThumbTags: {},
15928        initialPreviewShowDelete: true,
15929        removeFromPreviewOnError: false,
15930        deleteUrl: '',
15931        deleteExtraData: {},
15932        overwriteInitial: true,
15933        layoutTemplates: defaultLayoutTemplates,
15934        previewTemplates: defaultPreviewTemplates,
15935        allowedPreviewTypes: null,
15936        allowedPreviewMimeTypes: null,
15937        allowedFileTypes: null,
15938        allowedFileExtensions: null,
15939        defaultPreviewContent: null,
15940        customLayoutTags: {},
15941        customPreviewTags: {},
15942        previewSettings: defaultPreviewSettings,
15943        fileTypeSettings: defaultFileTypeSettings,
15944        previewFileIcon: '<i class="glyphicon glyphicon-file"></i>',
15945        previewFileIconClass: 'file-icon-4x',
15946        previewFileIconSettings: {},
15947        previewFileExtSettings: {},
15948        buttonLabelClass: 'hidden-xs',
15949        browseIcon: '<i class="glyphicon glyphicon-folder-open"></i>&nbsp;',
15950        browseClass: 'btn btn-primary',
15951        removeIcon: '<i class="glyphicon glyphicon-trash"></i>',
15952        removeClass: 'btn btn-default',
15953        cancelIcon: '<i class="glyphicon glyphicon-ban-circle"></i>',
15954        cancelClass: 'btn btn-default',
15955        uploadIcon: '<i class="glyphicon glyphicon-upload"></i>',
15956        uploadClass: 'btn btn-default',
15957        uploadUrl: null,
15958        uploadAsync: true,
15959        uploadExtraData: {},
15960        minImageWidth: null,
15961        minImageHeight: null,
15962        maxImageWidth: null,
15963        maxImageHeight: null,
15964        resizeImage: false,
15965        resizePreference: 'width',
15966        resizeQuality: 0.92,
15967        resizeDefaultImageType: 'image/jpeg',
15968        maxFileSize: 0,
15969        minFileCount: 0,
15970        maxFileCount: 0,
15971        validateInitialCount: false,
15972        msgValidationErrorClass: 'text-danger',
15973        msgValidationErrorIcon: '<i class="glyphicon glyphicon-exclamation-sign"></i> ',
15974        msgErrorClass: 'file-error-message',
15975        progressThumbClass: "progress-bar progress-bar-success progress-bar-striped active",
15976        progressClass: "progress-bar progress-bar-success progress-bar-striped active",
15977        progressCompleteClass: "progress-bar progress-bar-success",
15978        progressErrorClass: "progress-bar progress-bar-danger",
15979        previewFileType: 'image',
15980        zoomIndicator: '<i class="glyphicon glyphicon-zoom-in"></i>',
15981        elCaptionContainer: null,
15982        elCaptionText: null,
15983        elPreviewContainer: null,
15984        elPreviewImage: null,
15985        elPreviewStatus: null,
15986        elErrorContainer: null,
15987        errorCloseButton: '<span class="close kv-error-close">&times;</span>',
15988        slugCallback: null,
15989        dropZoneEnabled: true,
15990        dropZoneTitleClass: 'file-drop-zone-title',
15991        fileActionSettings: {},
15992        otherActionButtons: '',
15993        textEncoding: 'UTF-8',
15994        ajaxSettings: {},
15995        ajaxDeleteSettings: {},
15996        showAjaxErrorDetails: true
15997    };
15998
15999    $.fn.fileinputLocales.en = {
16000        fileSingle: 'file',
16001        filePlural: 'files',
16002        browseLabel: 'Browse &hellip;',
16003        removeLabel: 'Remove',
16004        removeTitle: 'Clear selected files',
16005        cancelLabel: 'Cancel',
16006        cancelTitle: 'Abort ongoing upload',
16007        uploadLabel: 'Upload',
16008        uploadTitle: 'Upload selected files',
16009        msgNo: 'No',
16010        msgCancelled: 'Cancelled',
16011        msgZoomTitle: 'View details',
16012        msgZoomModalHeading: 'Detailed Preview',
16013        msgSizeTooLarge: 'File "{name}" (<b>{size} KB</b>) exceeds maximum allowed upload size of <b>{maxSize} KB</b>.',
16014        msgFilesTooLess: 'You must select at least <b>{n}</b> {files} to upload.',
16015        msgFilesTooMany: 'Number of files selected for upload <b>({n})</b> exceeds maximum allowed limit of <b>{m}</b>.',
16016        msgFileNotFound: 'File "{name}" not found!',
16017        msgFileSecured: 'Security restrictions prevent reading the file "{name}".',
16018        msgFileNotReadable: 'File "{name}" is not readable.',
16019        msgFilePreviewAborted: 'File preview aborted for "{name}".',
16020        msgFilePreviewError: 'An error occurred while reading the file "{name}".',
16021        msgInvalidFileType: 'Invalid type for file "{name}". Only "{types}" files are supported.',
16022        msgInvalidFileExtension: 'Invalid extension for file "{name}". Only "{extensions}" files are supported.',
16023        msgUploadAborted: 'The file upload was aborted',
16024        msgValidationError: 'Validation Error',
16025        msgLoading: 'Loading file {index} of {files} &hellip;',
16026        msgProgress: 'Loading file {index} of {files} - {name} - {percent}% completed.',
16027        msgSelected: '{n} {files} selected',
16028        msgFoldersNotAllowed: 'Drag & drop files only! {n} folder(s) dropped were skipped.',
16029        msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.',
16030        msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.',
16031        msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.',
16032        msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.',
16033        msgImageResizeError: 'Could not get the image dimensions to resize.',
16034        msgImageResizeException: 'Error while resizing the image.<pre>{errors}</pre>',
16035        dropZoneTitle: 'Drag & drop files here &hellip;'
16036    };
16037
16038    $.fn.fileinput.Constructor = FileInput;
16039
16040    /**
16041     * Convert automatically file inputs with class 'file' into a bootstrap fileinput control.
16042     */
16043    $(document).ready(function () {
16044        var $input = $('input.file[type=file]');
16045        if ($input.length) {
16046            $input.fileinput();
16047        }
16048    });
16049}));
16050
16051/*!
16052 * FileInput Slovakian Translations
16053 *
16054 * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or
16055 * any HTML markup tags in the messages must not be converted or translated.
16056 *
16057 * @see http://github.com/kartik-v/bootstrap-fileinput
16058 *
16059 * NOTE: this file must be saved in UTF-8 encoding.
16060 */
16061(function ($) {
16062    "use strict";
16063
16064    $.fn.fileinputLocales['sk'] = {
16065        fileSingle: 'súbor',
16066        filePlural: 'súbory',
16067        browseLabel: 'Vybrať &hellip;',
16068        removeLabel: 'Odstrániť',
16069        removeTitle: 'Vyčistiť vybraté súbory',
16070        cancelLabel: 'Storno',
16071        cancelTitle: 'Prerušiť  nahrávanie',
16072        uploadLabel: 'Nahrať',
16073        uploadTitle: 'Nahrať vybraté súbory',
16074        msgNo: 'Nie',
16075        msgCancelled: 'Zrušené',
16076        msgZoomTitle: 'Zobraziť podrobnosti',
16077        msgZoomModalHeading: 'Detailný náhľad',
16078        msgSizeTooLarge: 'Súbor "{name}" (<b>{size} KB</b>): prekročenie - maximálna povolená veľkosť <b>{maxSize} KB</b>.',
16079        msgFilesTooLess: 'Musíte vybrať najmenej <b>{n}</b> {files} pre nahranie.',
16080        msgFilesTooMany: 'Počet vybratých súborov pre nahranie <b>({n})</b>: prekročenie - maximálny povolený limit <b>{m}</b>.',
16081        msgFileNotFound: 'Súbor "{name}" nebol nájdený!',
16082        msgFileSecured: 'Zabezpečenie súboru znemožnilo čítať súbor "{name}".',
16083        msgFileNotReadable: 'Súbor "{name}" nie je čitateľný.',
16084        msgFilePreviewAborted: 'Náhľad súboru bol prerušený pre "{name}".',
16085        msgFilePreviewError: 'Nastala chyba pri načítaní súboru "{name}".',
16086        msgInvalidFileType: 'Neplatný typ súboru "{name}". Iba "{types}" súborov sú podporované.',
16087        msgInvalidFileExtension: 'Neplatná extenzia súboru "{name}". Iba "{extensions}" súborov sú podporované.',
16088        msgUploadAborted: 'Súbor nahrávania bol prerušený',
16089        msgValidationError: 'Chyba overenia',
16090        msgLoading: 'Nahrávanie súboru {index} z {files} &hellip;',
16091        msgProgress: 'Nahrávanie súboru {index} z {files} - {name} - {percent}% dokončené.',
16092        msgSelected: '{n} {files} vybraté',
16093        msgFoldersNotAllowed: 'Tiahni a pusť iba súbory! Vynechané {n} pustené prečinok(y).',
16094        msgImageWidthSmall: 'Šírka image súboru "{name}", musí byť minimálne {size} px.',
16095        msgImageHeightSmall: 'Výška image súboru "{name}", musí byť minimálne {size} px.',
16096        msgImageWidthLarge: 'Šírka image súboru "{name}" nemôže presiahnuť {size} px.',
16097        msgImageHeightLarge: 'Výška súboru obrazu "{name}" nesmie presiahnuť {size} px.',
16098        msgImageResizeError: 'Nemožno získať rozmery obrázku zmeniť veľkosť.',
16099        msgImageResizeException: 'Chyba pri zmene veľkosti obrázka.<pre>{errors}</pre>',
16100        dropZoneTitle: 'Tiahni a pusť súbory tu &hellip;',
16101        fileActionSettings: {
16102            removeTitle: 'odstrániť súbor',
16103            uploadTitle: 'nahrať súbor',
16104            indicatorNewTitle: 'Ešte nenahral',
16105            indicatorSuccessTitle: 'nahral',
16106            indicatorErrorTitle: 'nahrať Chyba',
16107            indicatorLoadingTitle: 'nahrávanie ...'
16108        }
16109    };
16110})(window.jQuery);
16111/**
16112 * Super simple wysiwyg editor v0.8.2
16113 * http://summernote.org/
16114 *
16115 * summernote.js
16116 * Copyright 2013-2016 Alan Hong. and other contributors
16117 * summernote may be freely distributed under the MIT license./
16118 *
16119 * Date: 2016-08-08T01:21Z
16120 */
16121(function (factory) {
16122  /* global define */
16123  if (typeof define === 'function' && define.amd) {
16124    // AMD. Register as an anonymous module.
16125    define(['jquery'], factory);
16126  } else if (typeof module === 'object' && module.exports) {
16127    // Node/CommonJS
16128    module.exports = factory(require('jquery'));
16129  } else {
16130    // Browser globals
16131    factory(window.jQuery);
16132  }
16133}(function ($) {
16134  'use strict';
16135
16136  /**
16137   * @class core.func
16138   *
16139   * func utils (for high-order func's arg)
16140   *
16141   * @singleton
16142   * @alternateClassName func
16143   */
16144  var func = (function () {
16145    var eq = function (itemA) {
16146      return function (itemB) {
16147        return itemA === itemB;
16148      };
16149    };
16150
16151    var eq2 = function (itemA, itemB) {
16152      return itemA === itemB;
16153    };
16154
16155    var peq2 = function (propName) {
16156      return function (itemA, itemB) {
16157        return itemA[propName] === itemB[propName];
16158      };
16159    };
16160
16161    var ok = function () {
16162      return true;
16163    };
16164
16165    var fail = function () {
16166      return false;
16167    };
16168
16169    var not = function (f) {
16170      return function () {
16171        return !f.apply(f, arguments);
16172      };
16173    };
16174
16175    var and = function (fA, fB) {
16176      return function (item) {
16177        return fA(item) && fB(item);
16178      };
16179    };
16180
16181    var self = function (a) {
16182      return a;
16183    };
16184
16185    var invoke = function (obj, method) {
16186      return function () {
16187        return obj[method].apply(obj, arguments);
16188      };
16189    };
16190
16191    var idCounter = 0;
16192
16193    /**
16194     * generate a globally-unique id
16195     *
16196     * @param {String} [prefix]
16197     */
16198    var uniqueId = function (prefix) {
16199      var id = ++idCounter + '';
16200      return prefix ? prefix + id : id;
16201    };
16202
16203    /**
16204     * returns bnd (bounds) from rect
16205     *
16206     * - IE Compatibility Issue: http://goo.gl/sRLOAo
16207     * - Scroll Issue: http://goo.gl/sNjUc
16208     *
16209     * @param {Rect} rect
16210     * @return {Object} bounds
16211     * @return {Number} bounds.top
16212     * @return {Number} bounds.left
16213     * @return {Number} bounds.width
16214     * @return {Number} bounds.height
16215     */
16216    var rect2bnd = function (rect) {
16217      var $document = $(document);
16218      return {
16219        top: rect.top + $document.scrollTop(),
16220        left: rect.left + $document.scrollLeft(),
16221        width: rect.right - rect.left,
16222        height: rect.bottom - rect.top
16223      };
16224    };
16225
16226    /**
16227     * returns a copy of the object where the keys have become the values and the values the keys.
16228     * @param {Object} obj
16229     * @return {Object}
16230     */
16231    var invertObject = function (obj) {
16232      var inverted = {};
16233      for (var key in obj) {
16234        if (obj.hasOwnProperty(key)) {
16235          inverted[obj[key]] = key;
16236        }
16237      }
16238      return inverted;
16239    };
16240
16241    /**
16242     * @param {String} namespace
16243     * @param {String} [prefix]
16244     * @return {String}
16245     */
16246    var namespaceToCamel = function (namespace, prefix) {
16247      prefix = prefix || '';
16248      return prefix + namespace.split('.').map(function (name) {
16249        return name.substring(0, 1).toUpperCase() + name.substring(1);
16250      }).join('');
16251    };
16252
16253    /**
16254     * Returns a function, that, as long as it continues to be invoked, will not
16255     * be triggered. The function will be called after it stops being called for
16256     * N milliseconds. If `immediate` is passed, trigger the function on the
16257     * leading edge, instead of the trailing.
16258     * @param {Function} func
16259     * @param {Number} wait
16260     * @param {Boolean} immediate
16261     * @return {Function}
16262     */
16263    var debounce = function (func, wait, immediate) {
16264      var timeout;
16265      return function () {
16266        var context = this, args = arguments;
16267        var later = function () {
16268          timeout = null;
16269          if (!immediate) {
16270            func.apply(context, args);
16271          }
16272        };
16273        var callNow = immediate && !timeout;
16274        clearTimeout(timeout);
16275        timeout = setTimeout(later, wait);
16276        if (callNow) {
16277          func.apply(context, args);
16278        }
16279      };
16280    };
16281
16282    return {
16283      eq: eq,
16284      eq2: eq2,
16285      peq2: peq2,
16286      ok: ok,
16287      fail: fail,
16288      self: self,
16289      not: not,
16290      and: and,
16291      invoke: invoke,
16292      uniqueId: uniqueId,
16293      rect2bnd: rect2bnd,
16294      invertObject: invertObject,
16295      namespaceToCamel: namespaceToCamel,
16296      debounce: debounce
16297    };
16298  })();
16299
16300  /**
16301   * @class core.list
16302   *
16303   * list utils
16304   *
16305   * @singleton
16306   * @alternateClassName list
16307   */
16308  var list = (function () {
16309    /**
16310     * returns the first item of an array.
16311     *
16312     * @param {Array} array
16313     */
16314    var head = function (array) {
16315      return array[0];
16316    };
16317
16318    /**
16319     * returns the last item of an array.
16320     *
16321     * @param {Array} array
16322     */
16323    var last = function (array) {
16324      return array[array.length - 1];
16325    };
16326
16327    /**
16328     * returns everything but the last entry of the array.
16329     *
16330     * @param {Array} array
16331     */
16332    var initial = function (array) {
16333      return array.slice(0, array.length - 1);
16334    };
16335
16336    /**
16337     * returns the rest of the items in an array.
16338     *
16339     * @param {Array} array
16340     */
16341    var tail = function (array) {
16342      return array.slice(1);
16343    };
16344
16345    /**
16346     * returns item of array
16347     */
16348    var find = function (array, pred) {
16349      for (var idx = 0, len = array.length; idx < len; idx ++) {
16350        var item = array[idx];
16351        if (pred(item)) {
16352          return item;
16353        }
16354      }
16355    };
16356
16357    /**
16358     * returns true if all of the values in the array pass the predicate truth test.
16359     */
16360    var all = function (array, pred) {
16361      for (var idx = 0, len = array.length; idx < len; idx ++) {
16362        if (!pred(array[idx])) {
16363          return false;
16364        }
16365      }
16366      return true;
16367    };
16368
16369    /**
16370     * returns index of item
16371     */
16372    var indexOf = function (array, item) {
16373      return $.inArray(item, array);
16374    };
16375
16376    /**
16377     * returns true if the value is present in the list.
16378     */
16379    var contains = function (array, item) {
16380      return indexOf(array, item) !== -1;
16381    };
16382
16383    /**
16384     * get sum from a list
16385     *
16386     * @param {Array} array - array
16387     * @param {Function} fn - iterator
16388     */
16389    var sum = function (array, fn) {
16390      fn = fn || func.self;
16391      return array.reduce(function (memo, v) {
16392        return memo + fn(v);
16393      }, 0);
16394    };
16395  
16396    /**
16397     * returns a copy of the collection with array type.
16398     * @param {Collection} collection - collection eg) node.childNodes, ...
16399     */
16400    var from = function (collection) {
16401      var result = [], idx = -1, length = collection.length;
16402      while (++idx < length) {
16403        result[idx] = collection[idx];
16404      }
16405      return result;
16406    };
16407
16408    /**
16409     * returns whether list is empty or not
16410     */
16411    var isEmpty = function (array) {
16412      return !array || !array.length;
16413    };
16414  
16415    /**
16416     * cluster elements by predicate function.
16417     *
16418     * @param {Array} array - array
16419     * @param {Function} fn - predicate function for cluster rule
16420     * @param {Array[]}
16421     */
16422    var clusterBy = function (array, fn) {
16423      if (!array.length) { return []; }
16424      var aTail = tail(array);
16425      return aTail.reduce(function (memo, v) {
16426        var aLast = last(memo);
16427        if (fn(last(aLast), v)) {
16428          aLast[aLast.length] = v;
16429        } else {
16430          memo[memo.length] = [v];
16431        }
16432        return memo;
16433      }, [[head(array)]]);
16434    };
16435  
16436    /**
16437     * returns a copy of the array with all false values removed
16438     *
16439     * @param {Array} array - array
16440     * @param {Function} fn - predicate function for cluster rule
16441     */
16442    var compact = function (array) {
16443      var aResult = [];
16444      for (var idx = 0, len = array.length; idx < len; idx ++) {
16445        if (array[idx]) { aResult.push(array[idx]); }
16446      }
16447      return aResult;
16448    };
16449
16450    /**
16451     * produces a duplicate-free version of the array
16452     *
16453     * @param {Array} array
16454     */
16455    var unique = function (array) {
16456      var results = [];
16457
16458      for (var idx = 0, len = array.length; idx < len; idx ++) {
16459        if (!contains(results, array[idx])) {
16460          results.push(array[idx]);
16461        }
16462      }
16463
16464      return results;
16465    };
16466
16467    /**
16468     * returns next item.
16469     * @param {Array} array
16470     */
16471    var next = function (array, item) {
16472      var idx = indexOf(array, item);
16473      if (idx === -1) { return null; }
16474
16475      return array[idx + 1];
16476    };
16477
16478    /**
16479     * returns prev item.
16480     * @param {Array} array
16481     */
16482    var prev = function (array, item) {
16483      var idx = indexOf(array, item);
16484      if (idx === -1) { return null; }
16485
16486      return array[idx - 1];
16487    };
16488
16489    return { head: head, last: last, initial: initial, tail: tail,
16490             prev: prev, next: next, find: find, contains: contains,
16491             all: all, sum: sum, from: from, isEmpty: isEmpty,
16492             clusterBy: clusterBy, compact: compact, unique: unique };
16493  })();
16494
16495  var isSupportAmd = typeof define === 'function' && define.amd;
16496
16497  /**
16498   * returns whether font is installed or not.
16499   *
16500   * @param {String} fontName
16501   * @return {Boolean}
16502   */
16503  var isFontInstalled = function (fontName) {
16504    var testFontName = fontName === 'Comic Sans MS' ? 'Courier New' : 'Comic Sans MS';
16505    var $tester = $('<div>').css({
16506      position: 'absolute',
16507      left: '-9999px',
16508      top: '-9999px',
16509      fontSize: '200px'
16510    }).text('mmmmmmmmmwwwwwww').appendTo(document.body);
16511
16512    var originalWidth = $tester.css('fontFamily', testFontName).width();
16513    var width = $tester.css('fontFamily', fontName + ',' + testFontName).width();
16514
16515    $tester.remove();
16516
16517    return originalWidth !== width;
16518  };
16519
16520  var userAgent = navigator.userAgent;
16521  var isMSIE = /MSIE|Trident/i.test(userAgent);
16522  var browserVersion;
16523  if (isMSIE) {
16524    var matches = /MSIE (\d+[.]\d+)/.exec(userAgent);
16525    if (matches) {
16526      browserVersion = parseFloat(matches[1]);
16527    }
16528    matches = /Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(userAgent);
16529    if (matches) {
16530      browserVersion = parseFloat(matches[1]);
16531    }
16532  }
16533
16534  var isEdge = /Edge\/\d+/.test(userAgent);
16535
16536  var hasCodeMirror = !!window.CodeMirror;
16537  if (!hasCodeMirror && isSupportAmd && typeof require !== 'undefined') {
16538    if (typeof require.resolve !== 'undefined') {
16539      try {
16540        // If CodeMirror can't be resolved, `require.resolve` will throw an
16541        // exception and `hasCodeMirror` won't be set to `true`.
16542        require.resolve('codemirror');
16543        hasCodeMirror = true;
16544      } catch (e) {
16545        // Do nothing.
16546      }
16547    } else if (typeof eval('require').specified !== 'undefined') {
16548      hasCodeMirror = eval('require').specified('codemirror');
16549    }
16550  }
16551
16552  /**
16553   * @class core.agent
16554   *
16555   * Object which check platform and agent
16556   *
16557   * @singleton
16558   * @alternateClassName agent
16559   */
16560  var agent = {
16561    isMac: navigator.appVersion.indexOf('Mac') > -1,
16562    isMSIE: isMSIE,
16563    isEdge: isEdge,
16564    isFF: !isEdge && /firefox/i.test(userAgent),
16565    isPhantom: /PhantomJS/i.test(userAgent),
16566    isWebkit: !isEdge && /webkit/i.test(userAgent),
16567    isChrome: !isEdge && /chrome/i.test(userAgent),
16568    isSafari: !isEdge && /safari/i.test(userAgent),
16569    browserVersion: browserVersion,
16570    jqueryVersion: parseFloat($.fn.jquery),
16571    isSupportAmd: isSupportAmd,
16572    hasCodeMirror: hasCodeMirror,
16573    isFontInstalled: isFontInstalled,
16574    isW3CRangeSupport: !!document.createRange
16575  };
16576
16577
16578  var NBSP_CHAR = String.fromCharCode(160);
16579  var ZERO_WIDTH_NBSP_CHAR = '\ufeff';
16580
16581  /**
16582   * @class core.dom
16583   *
16584   * Dom functions
16585   *
16586   * @singleton
16587   * @alternateClassName dom
16588   */
16589  var dom = (function () {
16590    /**
16591     * @method isEditable
16592     *
16593     * returns whether node is `note-editable` or not.
16594     *
16595     * @param {Node} node
16596     * @return {Boolean}
16597     */
16598    var isEditable = function (node) {
16599      return node && $(node).hasClass('note-editable');
16600    };
16601
16602    /**
16603     * @method isControlSizing
16604     *
16605     * returns whether node is `note-control-sizing` or not.
16606     *
16607     * @param {Node} node
16608     * @return {Boolean}
16609     */
16610    var isControlSizing = function (node) {
16611      return node && $(node).hasClass('note-control-sizing');
16612    };
16613
16614    /**
16615     * @method makePredByNodeName
16616     *
16617     * returns predicate which judge whether nodeName is same
16618     *
16619     * @param {String} nodeName
16620     * @return {Function}
16621     */
16622    var makePredByNodeName = function (nodeName) {
16623      nodeName = nodeName.toUpperCase();
16624      return function (node) {
16625        return node && node.nodeName.toUpperCase() === nodeName;
16626      };
16627    };
16628
16629    /**
16630     * @method isText
16631     *
16632     *
16633     *
16634     * @param {Node} node
16635     * @return {Boolean} true if node's type is text(3)
16636     */
16637    var isText = function (node) {
16638      return node && node.nodeType === 3;
16639    };
16640
16641    /**
16642     * @method isElement
16643     *
16644     *
16645     *
16646     * @param {Node} node
16647     * @return {Boolean} true if node's type is element(1)
16648     */
16649    var isElement = function (node) {
16650      return node && node.nodeType === 1;
16651    };
16652
16653    /**
16654     * ex) br, col, embed, hr, img, input, ...
16655     * @see http://www.w3.org/html/wg/drafts/html/master/syntax.html#void-elements
16656     */
16657    var isVoid = function (node) {
16658      return node && /^BR|^IMG|^HR|^IFRAME|^BUTTON/.test(node.nodeName.toUpperCase());
16659    };
16660
16661    var isPara = function (node) {
16662      if (isEditable(node)) {
16663        return false;
16664      }
16665
16666      // Chrome(v31.0), FF(v25.0.1) use DIV for paragraph
16667      return node && /^DIV|^P|^LI|^H[1-7]/.test(node.nodeName.toUpperCase());
16668    };
16669
16670    var isHeading = function (node) {
16671      return node && /^H[1-7]/.test(node.nodeName.toUpperCase());
16672    };
16673
16674    var isPre = makePredByNodeName('PRE');
16675
16676    var isLi = makePredByNodeName('LI');
16677
16678    var isPurePara = function (node) {
16679      return isPara(node) && !isLi(node);
16680    };
16681
16682    var isTable = makePredByNodeName('TABLE');
16683
16684    var isData = makePredByNodeName('DATA');
16685
16686    var isInline = function (node) {
16687      return !isBodyContainer(node) &&
16688             !isList(node) &&
16689             !isHr(node) &&
16690             !isPara(node) &&
16691             !isTable(node) &&
16692             !isBlockquote(node) &&
16693             !isData(node);
16694    };
16695
16696    var isList = function (node) {
16697      return node && /^UL|^OL/.test(node.nodeName.toUpperCase());
16698    };
16699
16700    var isHr = makePredByNodeName('HR');
16701
16702    var isCell = function (node) {
16703      return node && /^TD|^TH/.test(node.nodeName.toUpperCase());
16704    };
16705
16706    var isBlockquote = makePredByNodeName('BLOCKQUOTE');
16707
16708    var isBodyContainer = function (node) {
16709      return isCell(node) || isBlockquote(node) || isEditable(node);
16710    };
16711
16712    var isAnchor = makePredByNodeName('A');
16713
16714    var isParaInline = function (node) {
16715      return isInline(node) && !!ancestor(node, isPara);
16716    };
16717
16718    var isBodyInline = function (node) {
16719      return isInline(node) && !ancestor(node, isPara);
16720    };
16721
16722    var isBody = makePredByNodeName('BODY');
16723
16724    /**
16725     * returns whether nodeB is closest sibling of nodeA
16726     *
16727     * @param {Node} nodeA
16728     * @param {Node} nodeB
16729     * @return {Boolean}
16730     */
16731    var isClosestSibling = function (nodeA, nodeB) {
16732      return nodeA.nextSibling === nodeB ||
16733             nodeA.previousSibling === nodeB;
16734    };
16735
16736    /**
16737     * returns array of closest siblings with node
16738     *
16739     * @param {Node} node
16740     * @param {function} [pred] - predicate function
16741     * @return {Node[]}
16742     */
16743    var withClosestSiblings = function (node, pred) {
16744      pred = pred || func.ok;
16745
16746      var siblings = [];
16747      if (node.previousSibling && pred(node.previousSibling)) {
16748        siblings.push(node.previousSibling);
16749      }
16750      siblings.push(node);
16751      if (node.nextSibling && pred(node.nextSibling)) {
16752        siblings.push(node.nextSibling);
16753      }
16754      return siblings;
16755    };
16756
16757    /**
16758     * blank HTML for cursor position
16759     * - [workaround] old IE only works with &nbsp;
16760     * - [workaround] IE11 and other browser works with bogus br
16761     */
16762    var blankHTML = agent.isMSIE && agent.browserVersion < 11 ? '&nbsp;' : '<br>';
16763
16764    /**
16765     * @method nodeLength
16766     *
16767     * returns #text's text size or element's childNodes size
16768     *
16769     * @param {Node} node
16770     */
16771    var nodeLength = function (node) {
16772      if (isText(node)) {
16773        return node.nodeValue.length;
16774      }
16775      
16776      if (node) {
16777        return node.childNodes.length;
16778      }
16779      
16780      return 0;
16781      
16782    };
16783
16784    /**
16785     * returns whether node is empty or not.
16786     *
16787     * @param {Node} node
16788     * @return {Boolean}
16789     */
16790    var isEmpty = function (node) {
16791      var len = nodeLength(node);
16792
16793      if (len === 0) {
16794        return true;
16795      } else if (!isText(node) && len === 1 && node.innerHTML === blankHTML) {
16796        // ex) <p><br></p>, <span><br></span>
16797        return true;
16798      } else if (list.all(node.childNodes, isText) && node.innerHTML === '') {
16799        // ex) <p></p>, <span></span>
16800        return true;
16801      }
16802
16803      return false;
16804    };
16805
16806    /**
16807     * padding blankHTML if node is empty (for cursor position)
16808     */
16809    var paddingBlankHTML = function (node) {
16810      if (!isVoid(node) && !nodeLength(node)) {
16811        node.innerHTML = blankHTML;
16812      }
16813    };
16814
16815    /**
16816     * find nearest ancestor predicate hit
16817     *
16818     * @param {Node} node
16819     * @param {Function} pred - predicate function
16820     */
16821    var ancestor = function (node, pred) {
16822      while (node) {
16823        if (pred(node)) { return node; }
16824        if (isEditable(node)) { break; }
16825
16826        node = node.parentNode;
16827      }
16828      return null;
16829    };
16830
16831    /**
16832     * find nearest ancestor only single child blood line and predicate hit
16833     *
16834     * @param {Node} node
16835     * @param {Function} pred - predicate function
16836     */
16837    var singleChildAncestor = function (node, pred) {
16838      node = node.parentNode;
16839
16840      while (node) {
16841        if (nodeLength(node) !== 1) { break; }
16842        if (pred(node)) { return node; }
16843        if (isEditable(node)) { break; }
16844
16845        node = node.parentNode;
16846      }
16847      return null;
16848    };
16849
16850    /**
16851     * returns new array of ancestor nodes (until predicate hit).
16852     *
16853     * @param {Node} node
16854     * @param {Function} [optional] pred - predicate function
16855     */
16856    var listAncestor = function (node, pred) {
16857      pred = pred || func.fail;
16858
16859      var ancestors = [];
16860      ancestor(node, function (el) {
16861        if (!isEditable(el)) {
16862          ancestors.push(el);
16863        }
16864
16865        return pred(el);
16866      });
16867      return ancestors;
16868    };
16869
16870    /**
16871     * find farthest ancestor predicate hit
16872     */
16873    var lastAncestor = function (node, pred) {
16874      var ancestors = listAncestor(node);
16875      return list.last(ancestors.filter(pred));
16876    };
16877
16878    /**
16879     * returns common ancestor node between two nodes.
16880     *
16881     * @param {Node} nodeA
16882     * @param {Node} nodeB
16883     */
16884    var commonAncestor = function (nodeA, nodeB) {
16885      var ancestors = listAncestor(nodeA);
16886      for (var n = nodeB; n; n = n.parentNode) {
16887        if ($.inArray(n, ancestors) > -1) { return n; }
16888      }
16889      return null; // difference document area
16890    };
16891
16892    /**
16893     * listing all previous siblings (until predicate hit).
16894     *
16895     * @param {Node} node
16896     * @param {Function} [optional] pred - predicate function
16897     */
16898    var listPrev = function (node, pred) {
16899      pred = pred || func.fail;
16900
16901      var nodes = [];
16902      while (node) {
16903        if (pred(node)) { break; }
16904        nodes.push(node);
16905        node = node.previousSibling;
16906      }
16907      return nodes;
16908    };
16909
16910    /**
16911     * listing next siblings (until predicate hit).
16912     *
16913     * @param {Node} node
16914     * @param {Function} [pred] - predicate function
16915     */
16916    var listNext = function (node, pred) {
16917      pred = pred || func.fail;
16918
16919      var nodes = [];
16920      while (node) {
16921        if (pred(node)) { break; }
16922        nodes.push(node);
16923        node = node.nextSibling;
16924      }
16925      return nodes;
16926    };
16927
16928    /**
16929     * listing descendant nodes
16930     *
16931     * @param {Node} node
16932     * @param {Function} [pred] - predicate function
16933     */
16934    var listDescendant = function (node, pred) {
16935      var descendants = [];
16936      pred = pred || func.ok;
16937
16938      // start DFS(depth first search) with node
16939      (function fnWalk(current) {
16940        if (node !== current && pred(current)) {
16941          descendants.push(current);
16942        }
16943        for (var idx = 0, len = current.childNodes.length; idx < len; idx++) {
16944          fnWalk(current.childNodes[idx]);
16945        }
16946      })(node);
16947
16948      return descendants;
16949    };
16950
16951    /**
16952     * wrap node with new tag.
16953     *
16954     * @param {Node} node
16955     * @param {Node} tagName of wrapper
16956     * @return {Node} - wrapper
16957     */
16958    var wrap = function (node, wrapperName) {
16959      var parent = node.parentNode;
16960      var wrapper = $('<' + wrapperName + '>')[0];
16961
16962      parent.insertBefore(wrapper, node);
16963      wrapper.appendChild(node);
16964
16965      return wrapper;
16966    };
16967
16968    /**
16969     * insert node after preceding
16970     *
16971     * @param {Node} node
16972     * @param {Node} preceding - predicate function
16973     */
16974    var insertAfter = function (node, preceding) {
16975      var next = preceding.nextSibling, parent = preceding.parentNode;
16976      if (next) {
16977        parent.insertBefore(node, next);
16978      } else {
16979        parent.appendChild(node);
16980      }
16981      return node;
16982    };
16983
16984    /**
16985     * append elements.
16986     *
16987     * @param {Node} node
16988     * @param {Collection} aChild
16989     */
16990    var appendChildNodes = function (node, aChild) {
16991      $.each(aChild, function (idx, child) {
16992        node.appendChild(child);
16993      });
16994      return node;
16995    };
16996
16997    /**
16998     * returns whether boundaryPoint is left edge or not.
16999     *
17000     * @param {BoundaryPoint} point
17001     * @return {Boolean}
17002     */
17003    var isLeftEdgePoint = function (point) {
17004      return point.offset === 0;
17005    };
17006
17007    /**
17008     * returns whether boundaryPoint is right edge or not.
17009     *
17010     * @param {BoundaryPoint} point
17011     * @return {Boolean}
17012     */
17013    var isRightEdgePoint = function (point) {
17014      return point.offset === nodeLength(point.node);
17015    };
17016
17017    /**
17018     * returns whether boundaryPoint is edge or not.
17019     *
17020     * @param {BoundaryPoint} point
17021     * @return {Boolean}
17022     */
17023    var isEdgePoint = function (point) {
17024      return isLeftEdgePoint(point) || isRightEdgePoint(point);
17025    };
17026
17027    /**
17028     * returns whether node is left edge of ancestor or not.
17029     *
17030     * @param {Node} node
17031     * @param {Node} ancestor
17032     * @return {Boolean}
17033     */
17034    var isLeftEdgeOf = function (node, ancestor) {
17035      while (node && node !== ancestor) {
17036        if (position(node) !== 0) {
17037          return false;
17038        }
17039        node = node.parentNode;
17040      }
17041
17042      return true;
17043    };
17044
17045    /**
17046     * returns whether node is right edge of ancestor or not.
17047     *
17048     * @param {Node} node
17049     * @param {Node} ancestor
17050     * @return {Boolean}
17051     */
17052    var isRightEdgeOf = function (node, ancestor) {
17053      if (!ancestor) {
17054        return false;
17055      }
17056      while (node && node !== ancestor) {
17057        if (position(node) !== nodeLength(node.parentNode) - 1) {
17058          return false;
17059        }
17060        node = node.parentNode;
17061      }
17062
17063      return true;
17064    };
17065
17066    /**
17067     * returns whether point is left edge of ancestor or not.
17068     * @param {BoundaryPoint} point
17069     * @param {Node} ancestor
17070     * @return {Boolean}
17071     */
17072    var isLeftEdgePointOf = function (point, ancestor) {
17073      return isLeftEdgePoint(point) && isLeftEdgeOf(point.node, ancestor);
17074    };
17075
17076    /**
17077     * returns whether point is right edge of ancestor or not.
17078     * @param {BoundaryPoint} point
17079     * @param {Node} ancestor
17080     * @return {Boolean}
17081     */
17082    var isRightEdgePointOf = function (point, ancestor) {
17083      return isRightEdgePoint(point) && isRightEdgeOf(point.node, ancestor);
17084    };
17085
17086    /**
17087     * returns offset from parent.
17088     *
17089     * @param {Node} node
17090     */
17091    var position = function (node) {
17092      var offset = 0;
17093      while ((node = node.previousSibling)) {
17094        offset += 1;
17095      }
17096      return offset;
17097    };
17098
17099    var hasChildren = function (node) {
17100      return !!(node && node.childNodes && node.childNodes.length);
17101    };
17102
17103    /**
17104     * returns previous boundaryPoint
17105     *
17106     * @param {BoundaryPoint} point
17107     * @param {Boolean} isSkipInnerOffset
17108     * @return {BoundaryPoint}
17109     */
17110    var prevPoint = function (point, isSkipInnerOffset) {
17111      var node, offset;
17112
17113      if (point.offset === 0) {
17114        if (isEditable(point.node)) {
17115          return null;
17116        }
17117
17118        node = point.node.parentNode;
17119        offset = position(point.node);
17120      } else if (hasChildren(point.node)) {
17121        node = point.node.childNodes[point.offset - 1];
17122        offset = nodeLength(node);
17123      } else {
17124        node = point.node;
17125        offset = isSkipInnerOffset ? 0 : point.offset - 1;
17126      }
17127
17128      return {
17129        node: node,
17130        offset: offset
17131      };
17132    };
17133
17134    /**
17135     * returns next boundaryPoint
17136     *
17137     * @param {BoundaryPoint} point
17138     * @param {Boolean} isSkipInnerOffset
17139     * @return {BoundaryPoint}
17140     */
17141    var nextPoint = function (point, isSkipInnerOffset) {
17142      var node, offset;
17143
17144      if (nodeLength(point.node) === point.offset) {
17145        if (isEditable(point.node)) {
17146          return null;
17147        }
17148
17149        node = point.node.parentNode;
17150        offset = position(point.node) + 1;
17151      } else if (hasChildren(point.node)) {
17152        node = point.node.childNodes[point.offset];
17153        offset = 0;
17154      } else {
17155        node = point.node;
17156        offset = isSkipInnerOffset ? nodeLength(point.node) : point.offset + 1;
17157      }
17158
17159      return {
17160        node: node,
17161        offset: offset
17162      };
17163    };
17164
17165    /**
17166     * returns whether pointA and pointB is same or not.
17167     *
17168     * @param {BoundaryPoint} pointA
17169     * @param {BoundaryPoint} pointB
17170     * @return {Boolean}
17171     */
17172    var isSamePoint = function (pointA, pointB) {
17173      return pointA.node === pointB.node && pointA.offset === pointB.offset;
17174    };
17175
17176    /**
17177     * returns whether point is visible (can set cursor) or not.
17178     *
17179     * @param {BoundaryPoint} point
17180     * @return {Boolean}
17181     */
17182    var isVisiblePoint = function (point) {
17183      if (isText(point.node) || !hasChildren(point.node) || isEmpty(point.node)) {
17184        return true;
17185      }
17186
17187      var leftNode = point.node.childNodes[point.offset - 1];
17188      var rightNode = point.node.childNodes[point.offset];
17189      if ((!leftNode || isVoid(leftNode)) && (!rightNode || isVoid(rightNode))) {
17190        return true;
17191      }
17192
17193      return false;
17194    };
17195
17196    /**
17197     * @method prevPointUtil
17198     *
17199     * @param {BoundaryPoint} point
17200     * @param {Function} pred
17201     * @return {BoundaryPoint}
17202     */
17203    var prevPointUntil = function (point, pred) {
17204      while (point) {
17205        if (pred(point)) {
17206          return point;
17207        }
17208
17209        point = prevPoint(point);
17210      }
17211
17212      return null;
17213    };
17214
17215    /**
17216     * @method nextPointUntil
17217     *
17218     * @param {BoundaryPoint} point
17219     * @param {Function} pred
17220     * @return {BoundaryPoint}
17221     */
17222    var nextPointUntil = function (point, pred) {
17223      while (point) {
17224        if (pred(point)) {
17225          return point;
17226        }
17227
17228        point = nextPoint(point);
17229      }
17230
17231      return null;
17232    };
17233
17234    /**
17235     * returns whether point has character or not.
17236     *
17237     * @param {Point} point
17238     * @return {Boolean}
17239     */
17240    var isCharPoint = function (point) {
17241      if (!isText(point.node)) {
17242        return false;
17243      }
17244
17245      var ch = point.node.nodeValue.charAt(point.offset - 1);
17246      return ch && (ch !== ' ' && ch !== NBSP_CHAR);
17247    };
17248
17249    /**
17250     * @method walkPoint
17251     *
17252     * @param {BoundaryPoint} startPoint
17253     * @param {BoundaryPoint} endPoint
17254     * @param {Function} handler
17255     * @param {Boolean} isSkipInnerOffset
17256     */
17257    var walkPoint = function (startPoint, endPoint, handler, isSkipInnerOffset) {
17258      var point = startPoint;
17259
17260      while (point) {
17261        handler(point);
17262
17263        if (isSamePoint(point, endPoint)) {
17264          break;
17265        }
17266
17267        var isSkipOffset = isSkipInnerOffset &&
17268                           startPoint.node !== point.node &&
17269                           endPoint.node !== point.node;
17270        point = nextPoint(point, isSkipOffset);
17271      }
17272    };
17273
17274    /**
17275     * @method makeOffsetPath
17276     *
17277     * return offsetPath(array of offset) from ancestor
17278     *
17279     * @param {Node} ancestor - ancestor node
17280     * @param {Node} node
17281     */
17282    var makeOffsetPath = function (ancestor, node) {
17283      var ancestors = listAncestor(node, func.eq(ancestor));
17284      return ancestors.map(position).reverse();
17285    };
17286
17287    /**
17288     * @method fromOffsetPath
17289     *
17290     * return element from offsetPath(array of offset)
17291     *
17292     * @param {Node} ancestor - ancestor node
17293     * @param {array} offsets - offsetPath
17294     */
17295    var fromOffsetPath = function (ancestor, offsets) {
17296      var current = ancestor;
17297      for (var i = 0, len = offsets.length; i < len; i++) {
17298        if (current.childNodes.length <= offsets[i]) {
17299          current = current.childNodes[current.childNodes.length - 1];
17300        } else {
17301          current = current.childNodes[offsets[i]];
17302        }
17303      }
17304      return current;
17305    };
17306
17307    /**
17308     * @method splitNode
17309     *
17310     * split element or #text
17311     *
17312     * @param {BoundaryPoint} point
17313     * @param {Object} [options]
17314     * @param {Boolean} [options.isSkipPaddingBlankHTML] - default: false
17315     * @param {Boolean} [options.isNotSplitEdgePoint] - default: false
17316     * @return {Node} right node of boundaryPoint
17317     */
17318    var splitNode = function (point, options) {
17319      var isSkipPaddingBlankHTML = options && options.isSkipPaddingBlankHTML;
17320      var isNotSplitEdgePoint = options && options.isNotSplitEdgePoint;
17321
17322      // edge case
17323      if (isEdgePoint(point) && (isText(point.node) || isNotSplitEdgePoint)) {
17324        if (isLeftEdgePoint(point)) {
17325          return point.node;
17326        } else if (isRightEdgePoint(point)) {
17327          return point.node.nextSibling;
17328        }
17329      }
17330
17331      // split #text
17332      if (isText(point.node)) {
17333        return point.node.splitText(point.offset);
17334      } else {
17335        var childNode = point.node.childNodes[point.offset];
17336        var clone = insertAfter(point.node.cloneNode(false), point.node);
17337        appendChildNodes(clone, listNext(childNode));
17338
17339        if (!isSkipPaddingBlankHTML) {
17340          paddingBlankHTML(point.node);
17341          paddingBlankHTML(clone);
17342        }
17343
17344        return clone;
17345      }
17346    };
17347
17348    /**
17349     * @method splitTree
17350     *
17351     * split tree by point
17352     *
17353     * @param {Node} root - split root
17354     * @param {BoundaryPoint} point
17355     * @param {Object} [options]
17356     * @param {Boolean} [options.isSkipPaddingBlankHTML] - default: false
17357     * @param {Boolean} [options.isNotSplitEdgePoint] - default: false
17358     * @return {Node} right node of boundaryPoint
17359     */
17360    var splitTree = function (root, point, options) {
17361      // ex) [#text, <span>, <p>]
17362      var ancestors = listAncestor(point.node, func.eq(root));
17363
17364      if (!ancestors.length) {
17365        return null;
17366      } else if (ancestors.length === 1) {
17367        return splitNode(point, options);
17368      }
17369
17370      return ancestors.reduce(function (node, parent) {
17371        if (node === point.node) {
17372          node = splitNode(point, options);
17373        }
17374
17375        return splitNode({
17376          node: parent,
17377          offset: node ? dom.position(node) : nodeLength(parent)
17378        }, options);
17379      });
17380    };
17381
17382    /**
17383     * split point
17384     *
17385     * @param {Point} point
17386     * @param {Boolean} isInline
17387     * @return {Object}
17388     */
17389    var splitPoint = function (point, isInline) {
17390      // find splitRoot, container
17391      //  - inline: splitRoot is a child of paragraph
17392      //  - block: splitRoot is a child of bodyContainer
17393      var pred = isInline ? isPara : isBodyContainer;
17394      var ancestors = listAncestor(point.node, pred);
17395      var topAncestor = list.last(ancestors) || point.node;
17396
17397      var splitRoot, container;
17398      if (pred(topAncestor)) {
17399        splitRoot = ancestors[ancestors.length - 2];
17400        container = topAncestor;
17401      } else {
17402        splitRoot = topAncestor;
17403        container = splitRoot.parentNode;
17404      }
17405
17406      // if splitRoot is exists, split with splitTree
17407      var pivot = splitRoot && splitTree(splitRoot, point, {
17408        isSkipPaddingBlankHTML: isInline,
17409        isNotSplitEdgePoint: isInline
17410      });
17411
17412      // if container is point.node, find pivot with point.offset
17413      if (!pivot && container === point.node) {
17414        pivot = point.node.childNodes[point.offset];
17415      }
17416
17417      return {
17418        rightNode: pivot,
17419        container: container
17420      };
17421    };
17422
17423    var create = function (nodeName) {
17424      return document.createElement(nodeName);
17425    };
17426
17427    var createText = function (text) {
17428      return document.createTextNode(text);
17429    };
17430
17431    /**
17432     * @method remove
17433     *
17434     * remove node, (isRemoveChild: remove child or not)
17435     *
17436     * @param {Node} node
17437     * @param {Boolean} isRemoveChild
17438     */
17439    var remove = function (node, isRemoveChild) {
17440      if (!node || !node.parentNode) { return; }
17441      if (node.removeNode) { return node.removeNode(isRemoveChild); }
17442
17443      var parent = node.parentNode;
17444      if (!isRemoveChild) {
17445        var nodes = [];
17446        var i, len;
17447        for (i = 0, len = node.childNodes.length; i < len; i++) {
17448          nodes.push(node.childNodes[i]);
17449        }
17450
17451        for (i = 0, len = nodes.length; i < len; i++) {
17452          parent.insertBefore(nodes[i], node);
17453        }
17454      }
17455
17456      parent.removeChild(node);
17457    };
17458
17459    /**
17460     * @method removeWhile
17461     *
17462     * @param {Node} node
17463     * @param {Function} pred
17464     */
17465    var removeWhile = function (node, pred) {
17466      while (node) {
17467        if (isEditable(node) || !pred(node)) {
17468          break;
17469        }
17470
17471        var parent = node.parentNode;
17472        remove(node);
17473        node = parent;
17474      }
17475    };
17476
17477    /**
17478     * @method replace
17479     *
17480     * replace node with provided nodeName
17481     *
17482     * @param {Node} node
17483     * @param {String} nodeName
17484     * @return {Node} - new node
17485     */
17486    var replace = function (node, nodeName) {
17487      if (node.nodeName.toUpperCase() === nodeName.toUpperCase()) {
17488        return node;
17489      }
17490
17491      var newNode = create(nodeName);
17492
17493      if (node.style.cssText) {
17494        newNode.style.cssText = node.style.cssText;
17495      }
17496
17497      appendChildNodes(newNode, list.from(node.childNodes));
17498      insertAfter(newNode, node);
17499      remove(node);
17500
17501      return newNode;
17502    };
17503
17504    var isTextarea = makePredByNodeName('TEXTAREA');
17505
17506    /**
17507     * @param {jQuery} $node
17508     * @param {Boolean} [stripLinebreaks] - default: false
17509     */
17510    var value = function ($node, stripLinebreaks) {
17511      var val = isTextarea($node[0]) ? $node.val() : $node.html();
17512      if (stripLinebreaks) {
17513        return val.replace(/[\n\r]/g, '');
17514      }
17515      return val;
17516    };
17517
17518    /**
17519     * @method html
17520     *
17521     * get the HTML contents of node
17522     *
17523     * @param {jQuery} $node
17524     * @param {Boolean} [isNewlineOnBlock]
17525     */
17526    var html = function ($node, isNewlineOnBlock) {
17527      var markup = value($node);
17528
17529      if (isNewlineOnBlock) {
17530        var regexTag = /<(\/?)(\b(?!!)[^>\s]*)(.*?)(\s*\/?>)/g;
17531        markup = markup.replace(regexTag, function (match, endSlash, name) {
17532          name = name.toUpperCase();
17533          var isEndOfInlineContainer = /^DIV|^TD|^TH|^P|^LI|^H[1-7]/.test(name) &&
17534                                       !!endSlash;
17535          var isBlockNode = /^BLOCKQUOTE|^TABLE|^TBODY|^TR|^HR|^UL|^OL/.test(name);
17536
17537          return match + ((isEndOfInlineContainer || isBlockNode) ? '\n' : '');
17538        });
17539        markup = $.trim(markup);
17540      }
17541
17542      return markup;
17543    };
17544
17545    var posFromPlaceholder = function (placeholder) {
17546      var $placeholder = $(placeholder);
17547      var pos = $placeholder.offset();
17548      var height = $placeholder.outerHeight(true); // include margin
17549
17550      return {
17551        left: pos.left,
17552        top: pos.top + height
17553      };
17554    };
17555
17556    var attachEvents = function ($node, events) {
17557      Object.keys(events).forEach(function (key) {
17558        $node.on(key, events[key]);
17559      });
17560    };
17561
17562    var detachEvents = function ($node, events) {
17563      Object.keys(events).forEach(function (key) {
17564        $node.off(key, events[key]);
17565      });
17566    };
17567
17568    return {
17569      /** @property {String} NBSP_CHAR */
17570      NBSP_CHAR: NBSP_CHAR,
17571      /** @property {String} ZERO_WIDTH_NBSP_CHAR */
17572      ZERO_WIDTH_NBSP_CHAR: ZERO_WIDTH_NBSP_CHAR,
17573      /** @property {String} blank */
17574      blank: blankHTML,
17575      /** @property {String} emptyPara */
17576      emptyPara: '<p>' + blankHTML + '</p>',
17577      makePredByNodeName: makePredByNodeName,
17578      isEditable: isEditable,
17579      isControlSizing: isControlSizing,
17580      isText: isText,
17581      isElement: isElement,
17582      isVoid: isVoid,
17583      isPara: isPara,
17584      isPurePara: isPurePara,
17585      isHeading: isHeading,
17586      isInline: isInline,
17587      isBlock: func.not(isInline),
17588      isBodyInline: isBodyInline,
17589      isBody: isBody,
17590      isParaInline: isParaInline,
17591      isPre: isPre,
17592      isList: isList,
17593      isTable: isTable,
17594      isData: isData,
17595      isCell: isCell,
17596      isBlockquote: isBlockquote,
17597      isBodyContainer: isBodyContainer,
17598      isAnchor: isAnchor,
17599      isDiv: makePredByNodeName('DIV'),
17600      isLi: isLi,
17601      isBR: makePredByNodeName('BR'),
17602      isSpan: makePredByNodeName('SPAN'),
17603      isB: makePredByNodeName('B'),
17604      isU: makePredByNodeName('U'),
17605      isS: makePredByNodeName('S'),
17606      isI: makePredByNodeName('I'),
17607      isImg: makePredByNodeName('IMG'),
17608      isTextarea: isTextarea,
17609      isEmpty: isEmpty,
17610      isEmptyAnchor: func.and(isAnchor, isEmpty),
17611      isClosestSibling: isClosestSibling,
17612      withClosestSiblings: withClosestSiblings,
17613      nodeLength: nodeLength,
17614      isLeftEdgePoint: isLeftEdgePoint,
17615      isRightEdgePoint: isRightEdgePoint,
17616      isEdgePoint: isEdgePoint,
17617      isLeftEdgeOf: isLeftEdgeOf,
17618      isRightEdgeOf: isRightEdgeOf,
17619      isLeftEdgePointOf: isLeftEdgePointOf,
17620      isRightEdgePointOf: isRightEdgePointOf,
17621      prevPoint: prevPoint,
17622      nextPoint: nextPoint,
17623      isSamePoint: isSamePoint,
17624      isVisiblePoint: isVisiblePoint,
17625      prevPointUntil: prevPointUntil,
17626      nextPointUntil: nextPointUntil,
17627      isCharPoint: isCharPoint,
17628      walkPoint: walkPoint,
17629      ancestor: ancestor,
17630      singleChildAncestor: singleChildAncestor,
17631      listAncestor: listAncestor,
17632      lastAncestor: lastAncestor,
17633      listNext: listNext,
17634      listPrev: listPrev,
17635      listDescendant: listDescendant,
17636      commonAncestor: commonAncestor,
17637      wrap: wrap,
17638      insertAfter: insertAfter,
17639      appendChildNodes: appendChildNodes,
17640      position: position,
17641      hasChildren: hasChildren,
17642      makeOffsetPath: makeOffsetPath,
17643      fromOffsetPath: fromOffsetPath,
17644      splitTree: splitTree,
17645      splitPoint: splitPoint,
17646      create: create,
17647      createText: createText,
17648      remove: remove,
17649      removeWhile: removeWhile,
17650      replace: replace,
17651      html: html,
17652      value: value,
17653      posFromPlaceholder: posFromPlaceholder,
17654      attachEvents: attachEvents,
17655      detachEvents: detachEvents
17656    };
17657  })();
17658
17659  /**
17660   * @param {jQuery} $note
17661   * @param {Object} options
17662   * @return {Context}
17663   */
17664  var Context = function ($note, options) {
17665    var self = this;
17666
17667    var ui = $.summernote.ui;
17668    this.memos = {};
17669    this.modules = {};
17670    this.layoutInfo = {};
17671    this.options = options;
17672
17673    /**
17674     * create layout and initialize modules and other resources
17675     */
17676    this.initialize = function () {
17677      this.layoutInfo = ui.createLayout($note, options);
17678      this._initialize();
17679      $note.hide();
17680      return this;
17681    };
17682
17683    /**
17684     * destroy modules and other resources and remove layout
17685     */
17686    this.destroy = function () {
17687      this._destroy();
17688      $note.removeData('summernote');
17689      ui.removeLayout($note, this.layoutInfo);
17690    };
17691
17692    /**
17693     * destory modules and other resources and initialize it again
17694     */
17695    this.reset = function () {
17696      var disabled = self.isDisabled();
17697      this.code(dom.emptyPara);
17698      this._destroy();
17699      this._initialize();
17700
17701      if (disabled) {
17702        self.disable();
17703      }
17704    };
17705
17706    this._initialize = function () {
17707      // add optional buttons
17708      var buttons = $.extend({}, this.options.buttons);
17709      Object.keys(buttons).forEach(function (key) {
17710        self.memo('button.' + key, buttons[key]);
17711      });
17712
17713      var modules = $.extend({}, this.options.modules, $.summernote.plugins || {});
17714
17715      // add and initialize modules
17716      Object.keys(modules).forEach(function (key) {
17717        self.module(key, modules[key], true);
17718      });
17719
17720      Object.keys(this.modules).forEach(function (key) {
17721        self.initializeModule(key);
17722      });
17723    };
17724
17725    this._destroy = function () {
17726      // destroy modules with reversed order
17727      Object.keys(this.modules).reverse().forEach(function (key) {
17728        self.removeModule(key);
17729      });
17730
17731      Object.keys(this.memos).forEach(function (key) {
17732        self.removeMemo(key);
17733      });
17734    };
17735
17736    this.code = function (html) {
17737      var isActivated = this.invoke('codeview.isActivated');
17738
17739      if (html === undefined) {
17740        this.invoke('codeview.sync');
17741        return isActivated ? this.layoutInfo.codable.val() : this.layoutInfo.editable.html();
17742      } else {
17743        if (isActivated) {
17744          this.layoutInfo.codable.val(html);
17745        } else {
17746          this.layoutInfo.editable.html(html);
17747        }
17748        $note.val(html);
17749        this.triggerEvent('change', html);
17750      }
17751    };
17752
17753    this.isDisabled = function () {
17754      return this.layoutInfo.editable.attr('contenteditable') === 'false';
17755    };
17756
17757    this.enable = function () {
17758      this.layoutInfo.editable.attr('contenteditable', true);
17759      this.invoke('toolbar.activate', true);
17760    };
17761
17762    this.disable = function () {
17763      // close codeview if codeview is opend
17764      if (this.invoke('codeview.isActivated')) {
17765        this.invoke('codeview.deactivate');
17766      }
17767      this.layoutInfo.editable.attr('contenteditable', false);
17768      this.invoke('toolbar.deactivate', true);
17769    };
17770
17771    this.triggerEvent = function () {
17772      var namespace = list.head(arguments);
17773      var args = list.tail(list.from(arguments));
17774
17775      var callback = this.options.callbacks[func.namespaceToCamel(namespace, 'on')];
17776      if (callback) {
17777        callback.apply($note[0], args);
17778      }
17779      $note.trigger('summernote.' + namespace, args);
17780    };
17781
17782    this.initializeModule = function (key) {
17783      var module = this.modules[key];
17784      module.shouldInitialize = module.shouldInitialize || func.ok;
17785      if (!module.shouldInitialize()) {
17786        return;
17787      }
17788
17789      // initialize module
17790      if (module.initialize) {
17791        module.initialize();
17792      }
17793
17794      // attach events
17795      if (module.events) {
17796        dom.attachEvents($note, module.events);
17797      }
17798    };
17799
17800    this.module = function (key, ModuleClass, withoutIntialize) {
17801      if (arguments.length === 1) {
17802        return this.modules[key];
17803      }
17804
17805      this.modules[key] = new ModuleClass(this);
17806
17807      if (!withoutIntialize) {
17808        this.initializeModule(key);
17809      }
17810    };
17811
17812    this.removeModule = function (key) {
17813      var module = this.modules[key];
17814      if (module.shouldInitialize()) {
17815        if (module.events) {
17816          dom.detachEvents($note, module.events);
17817        }
17818
17819        if (module.destroy) {
17820          module.destroy();
17821        }
17822      }
17823
17824      delete this.modules[key];
17825    };
17826
17827    this.memo = function (key, obj) {
17828      if (arguments.length === 1) {
17829        return this.memos[key];
17830      }
17831      this.memos[key] = obj;
17832    };
17833
17834    this.removeMemo = function (key) {
17835      if (this.memos[key] && this.memos[key].destroy) {
17836        this.memos[key].destroy();
17837      }
17838
17839      delete this.memos[key];
17840    };
17841
17842    this.createInvokeHandler = function (namespace, value) {
17843      return function (event) {
17844        event.preventDefault();
17845        self.invoke(namespace, value || $(event.target).closest('[data-value]').data('value'));
17846      };
17847    };
17848
17849    this.invoke = function () {
17850      var namespace = list.head(arguments);
17851      var args = list.tail(list.from(arguments));
17852
17853      var splits = namespace.split('.');
17854      var hasSeparator = splits.length > 1;
17855      var moduleName = hasSeparator && list.head(splits);
17856      var methodName = hasSeparator ? list.last(splits) : list.head(splits);
17857
17858      var module = this.modules[moduleName || 'editor'];
17859      if (!moduleName && this[methodName]) {
17860        return this[methodName].apply(this, args);
17861      } else if (module && module[methodName] && module.shouldInitialize()) {
17862        return module[methodName].apply(module, args);
17863      }
17864    };
17865
17866    return this.initialize();
17867  };
17868
17869  $.fn.extend({
17870    /**
17871     * Summernote API
17872     *
17873     * @param {Object|String}
17874     * @return {this}
17875     */
17876    summernote: function () {
17877      var type = $.type(list.head(arguments));
17878      var isExternalAPICalled = type === 'string';
17879      var hasInitOptions = type === 'object';
17880
17881      var options = hasInitOptions ? list.head(arguments) : {};
17882
17883      options = $.extend({}, $.summernote.options, options);
17884      options.langInfo = $.extend(true, {}, $.summernote.lang['en-US'], $.summernote.lang[options.lang]);
17885      options.icons = $.extend(true, {}, $.summernote.options.icons, options.icons);
17886
17887      this.each(function (idx, note) {
17888        var $note = $(note);
17889        if (!$note.data('summernote')) {
17890          var context = new Context($note, options);
17891          $note.data('summernote', context);
17892          $note.data('summernote').triggerEvent('init', context.layoutInfo);
17893        }
17894      });
17895
17896      var $note = this.first();
17897      if ($note.length) {
17898        var context = $note.data('summernote');
17899        if (isExternalAPICalled) {
17900          return context.invoke.apply(context, list.from(arguments));
17901        } else if (options.focus) {
17902          context.invoke('editor.focus');
17903        }
17904      }
17905
17906      return this;
17907    }
17908  });
17909
17910
17911  var Renderer = function (markup, children, options, callback) {
17912    this.render = function ($parent) {
17913      var $node = $(markup);
17914
17915      if (options && options.contents) {
17916        $node.html(options.contents);
17917      }
17918
17919      if (options && options.className) {
17920        $node.addClass(options.className);
17921      }
17922
17923      if (options && options.data) {
17924        $.each(options.data, function (k, v) {
17925          $node.attr('data-' + k, v);
17926        });
17927      }
17928
17929      if (options && options.click) {
17930        $node.on('click', options.click);
17931      }
17932
17933      if (children) {
17934        var $container = $node.find('.note-children-container');
17935        children.forEach(function (child) {
17936          child.render($container.length ? $container : $node);
17937        });
17938      }
17939
17940      if (callback) {
17941        callback($node, options);
17942      }
17943
17944      if (options && options.callback) {
17945        options.callback($node);
17946      }
17947
17948      if ($parent) {
17949        $parent.append($node);
17950      }
17951
17952      return $node;
17953    };
17954  };
17955
17956  var renderer = {
17957    create: function (markup, callback) {
17958      return function () {
17959        var children = $.isArray(arguments[0]) ? arguments[0] : [];
17960        var options = typeof arguments[1] === 'object' ? arguments[1] : arguments[0];
17961        if (options && options.children) {
17962          children = options.children;
17963        }
17964        return new Renderer(markup, children, options, callback);
17965      };
17966    }
17967  };
17968
17969  var editor = renderer.create('<div class="note-editor note-frame panel panel-default"/>');
17970  var toolbar = renderer.create('<div class="note-toolbar panel-heading"/>');
17971  var editingArea = renderer.create('<div class="note-editing-area"/>');
17972  var codable = renderer.create('<textarea class="note-codable"/>');
17973  var editable = renderer.create('<div class="note-editable panel-body" contentEditable="true"/>');
17974  var statusbar = renderer.create([
17975    '<div class="note-statusbar">',
17976    '  <div class="note-resizebar">',
17977    '    <div class="note-icon-bar"/>',
17978    '    <div class="note-icon-bar"/>',
17979    '    <div class="note-icon-bar"/>',
17980    '  </div>',
17981    '</div>'
17982  ].join(''));
17983
17984  var airEditor = renderer.create('<div class="note-editor"/>');
17985  var airEditable = renderer.create('<div class="note-editable" contentEditable="true"/>');
17986
17987  var buttonGroup = renderer.create('<div class="note-btn-group btn-group">');
17988  var button = renderer.create('<button type="button" class="note-btn btn btn-default btn-sm" tabindex="-1">', function ($node, options) {
17989    if (options && options.tooltip) {
17990      $node.attr({
17991        title: options.tooltip
17992      }).tooltip({
17993        container: 'body',
17994        trigger: 'hover',
17995        placement: 'bottom'
17996      });
17997    }
17998  });
17999
18000  var dropdown = renderer.create('<div class="dropdown-menu">', function ($node, options) {
18001    var markup = $.isArray(options.items) ? options.items.map(function (item) {
18002      var value = (typeof item === 'string') ? item : (item.value || '');
18003      var content = options.template ? options.template(item) : item;
18004      return '<li><a href="#" data-value="' + value + '">' + content + '</a></li>';
18005    }).join('') : options.items;
18006
18007    $node.html(markup);
18008  });
18009
18010  var dropdownCheck = renderer.create('<div class="dropdown-menu note-check">', function ($node, options) {
18011    var markup = $.isArray(options.items) ? options.items.map(function (item) {
18012      var value = (typeof item === 'string') ? item : (item.value || '');
18013      var content = options.template ? options.template(item) : item;
18014      return '<li><a href="#" data-value="' + value + '">' + icon(options.checkClassName) + ' ' + content + '</a></li>';
18015    }).join('') : options.items;
18016    $node.html(markup);
18017  });
18018
18019  var palette = renderer.create('<div class="note-color-palette"/>', function ($node, options) {
18020    var contents = [];
18021    for (var row = 0, rowSize = options.colors.length; row < rowSize; row++) {
18022      var eventName = options.eventName;
18023      var colors = options.colors[row];
18024      var buttons = [];
18025      for (var col = 0, colSize = colors.length; col < colSize; col++) {
18026        var color = colors[col];
18027        buttons.push([
18028          '<button type="button" class="note-color-btn"',
18029          'style="background-color:', color, '" ',
18030          'data-event="', eventName, '" ',
18031          'data-value="', color, '" ',
18032          'title="', color, '" ',
18033          'data-toggle="button" tabindex="-1"></button>'
18034        ].join(''));
18035      }
18036      contents.push('<div class="note-color-row">' + buttons.join('') + '</div>');
18037    }
18038    $node.html(contents.join(''));
18039
18040    $node.find('.note-color-btn').tooltip({
18041      container: 'body',
18042      trigger: 'hover',
18043      placement: 'bottom'
18044    });
18045  });
18046
18047  var dialog = renderer.create('<div class="modal" aria-hidden="false" tabindex="-1"/>', function ($node, options) {
18048    if (options.fade) {
18049      $node.addClass('fade');
18050    }
18051    $node.html([
18052      '<div class="modal-dialog">',
18053      '  <div class="modal-content">',
18054      (options.title ?
18055      '    <div class="modal-header">' +
18056      '      <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>' +
18057      '      <h4 class="modal-title">' + options.title + '</h4>' +
18058      '    </div>' : ''
18059      ),
18060      '    <div class="modal-body">' + options.body + '</div>',
18061      (options.footer ?
18062      '    <div class="modal-footer">' + options.footer + '</div>' : ''
18063      ),
18064      '  </div>',
18065      '</div>'
18066    ].join(''));
18067  });
18068
18069  var popover = renderer.create([
18070    '<div class="note-popover popover in">',
18071    '  <div class="arrow"/>',
18072    '  <div class="popover-content note-children-container"/>',
18073    '</div>'
18074  ].join(''), function ($node, options) {
18075    var direction = typeof options.direction !== 'undefined' ? options.direction : 'bottom';
18076
18077    $node.addClass(direction);
18078
18079    if (options.hideArrow) {
18080      $node.find('.arrow').hide();
18081    }
18082  });
18083
18084  var icon = function (iconClassName, tagName) {
18085    tagName = tagName || 'i';
18086    return '<' + tagName + ' class="' + iconClassName + '"/>';
18087  };
18088
18089  var ui = {
18090    editor: editor,
18091    toolbar: toolbar,
18092    editingArea: editingArea,
18093    codable: codable,
18094    editable: editable,
18095    statusbar: statusbar,
18096    airEditor: airEditor,
18097    airEditable: airEditable,
18098    buttonGroup: buttonGroup,
18099    button: button,
18100    dropdown: dropdown,
18101    dropdownCheck: dropdownCheck,
18102    palette: palette,
18103    dialog: dialog,
18104    popover: popover,
18105    icon: icon,
18106
18107    toggleBtn: function ($btn, isEnable) {
18108      $btn.toggleClass('disabled', !isEnable);
18109      $btn.attr('disabled', !isEnable);
18110    },
18111
18112    toggleBtnActive: function ($btn, isActive) {
18113      $btn.toggleClass('active', isActive);
18114    },
18115
18116    onDialogShown: function ($dialog, handler) {
18117      $dialog.one('shown.bs.modal', handler);
18118    },
18119
18120    onDialogHidden: function ($dialog, handler) {
18121      $dialog.one('hidden.bs.modal', handler);
18122    },
18123
18124    showDialog: function ($dialog) {
18125      $dialog.modal('show');
18126    },
18127
18128    hideDialog: function ($dialog) {
18129      $dialog.modal('hide');
18130    },
18131
18132    createLayout: function ($note, options) {
18133      var $editor = (options.airMode ? ui.airEditor([
18134        ui.editingArea([
18135          ui.airEditable()
18136        ])
18137      ]) : ui.editor([
18138        ui.toolbar(),
18139        ui.editingArea([
18140          ui.codable(),
18141          ui.editable()
18142        ]),
18143        ui.statusbar()
18144      ])).render();
18145
18146      $editor.insertAfter($note);
18147
18148      return {
18149        note: $note,
18150        editor: $editor,
18151        toolbar: $editor.find('.note-toolbar'),
18152        editingArea: $editor.find('.note-editing-area'),
18153        editable: $editor.find('.note-editable'),
18154        codable: $editor.find('.note-codable'),
18155        statusbar: $editor.find('.note-statusbar')
18156      };
18157    },
18158
18159    removeLayout: function ($note, layoutInfo) {
18160      $note.html(layoutInfo.editable.html());
18161      layoutInfo.editor.remove();
18162      $note.show();
18163    }
18164  };
18165
18166  $.summernote = $.summernote || {
18167    lang: {}
18168  };
18169
18170  $.extend($.summernote.lang, {
18171    'en-US': {
18172      font: {
18173        bold: 'Bold',
18174        italic: 'Italic',
18175        underline: 'Underline',
18176        clear: 'Remove Font Style',
18177        height: 'Line Height',
18178        name: 'Font Family',
18179        strikethrough: 'Strikethrough',
18180        subscript: 'Subscript',
18181        superscript: 'Superscript',
18182        size: 'Font Size'
18183      },
18184      image: {
18185        image: 'Picture',
18186        insert: 'Insert Image',
18187        resizeFull: 'Resize Full',
18188        resizeHalf: 'Resize Half',
18189        resizeQuarter: 'Resize Quarter',
18190        floatLeft: 'Float Left',
18191        floatRight: 'Float Right',
18192        floatNone: 'Float None',
18193        shapeRounded: 'Shape: Rounded',
18194        shapeCircle: 'Shape: Circle',
18195        shapeThumbnail: 'Shape: Thumbnail',
18196        shapeNone: 'Shape: None',
18197        dragImageHere: 'Drag image or text here',
18198        dropImage: 'Drop image or Text',
18199        selectFromFiles: 'Select from files',
18200        maximumFileSize: 'Maximum file size',
18201        maximumFileSizeError: 'Maximum file size exceeded.',
18202        url: 'Image URL',
18203        remove: 'Remove Image'
18204      },
18205      video: {
18206        video: 'Video',
18207        videoLink: 'Video Link',
18208        insert: 'Insert Video',
18209        url: 'Video URL?',
18210        providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion or Youku)'
18211      },
18212      link: {
18213        link: 'Link',
18214        insert: 'Insert Link',
18215        unlink: 'Unlink',
18216        edit: 'Edit',
18217        textToDisplay: 'Text to display',
18218        url: 'To what URL should this link go?',
18219        openInNewWindow: 'Open in new window'
18220      },
18221      table: {
18222        table: 'Table'
18223      },
18224      hr: {
18225        insert: 'Insert Horizontal Rule'
18226      },
18227      style: {
18228        style: 'Style',
18229        normal: 'Normal',
18230        blockquote: 'Quote',
18231        pre: 'Code',
18232        h1: 'Header 1',
18233        h2: 'Header 2',
18234        h3: 'Header 3',
18235        h4: 'Header 4',
18236        h5: 'Header 5',
18237        h6: 'Header 6'
18238      },
18239      lists: {
18240        unordered: 'Unordered list',
18241        ordered: 'Ordered list'
18242      },
18243      options: {
18244        help: 'Help',
18245        fullscreen: 'Full Screen',
18246        codeview: 'Code View'
18247      },
18248      paragraph: {
18249        paragraph: 'Paragraph',
18250        outdent: 'Outdent',
18251        indent: 'Indent',
18252        left: 'Align left',
18253        center: 'Align center',
18254        right: 'Align right',
18255        justify: 'Justify full'
18256      },
18257      color: {
18258        recent: 'Recent Color',
18259        more: 'More Color',
18260        background: 'Background Color',
18261        foreground: 'Foreground Color',
18262        transparent: 'Transparent',
18263        setTransparent: 'Set transparent',
18264        reset: 'Reset',
18265        resetToDefault: 'Reset to default'
18266      },
18267      shortcut: {
18268        shortcuts: 'Keyboard shortcuts',
18269        close: 'Close',
18270        textFormatting: 'Text formatting',
18271        action: 'Action',
18272        paragraphFormatting: 'Paragraph formatting',
18273        documentStyle: 'Document Style',
18274        extraKeys: 'Extra keys'
18275      },
18276      help: {
18277        'insertParagraph': 'Insert Paragraph',
18278        'undo': 'Undoes the last command',
18279        'redo': 'Redoes the last command',
18280        'tab': 'Tab',
18281        'untab': 'Untab',
18282        'bold': 'Set a bold style',
18283        'italic': 'Set a italic style',
18284        'underline': 'Set a underline style',
18285        'strikethrough': 'Set a strikethrough style',
18286        'removeFormat': 'Clean a style',
18287        'justifyLeft': 'Set left align',
18288        'justifyCenter': 'Set center align',
18289        'justifyRight': 'Set right align',
18290        'justifyFull': 'Set full align',
18291        'insertUnorderedList': 'Toggle unordered list',
18292        'insertOrderedList': 'Toggle ordered list',
18293        'outdent': 'Outdent on current paragraph',
18294        'indent': 'Indent on current paragraph',
18295        'formatPara': 'Change current block\'s format as a paragraph(P tag)',
18296        'formatH1': 'Change current block\'s format as H1',
18297        'formatH2': 'Change current block\'s format as H2',
18298        'formatH3': 'Change current block\'s format as H3',
18299        'formatH4': 'Change current block\'s format as H4',
18300        'formatH5': 'Change current block\'s format as H5',
18301        'formatH6': 'Change current block\'s format as H6',
18302        'insertHorizontalRule': 'Insert horizontal rule',
18303        'linkDialog.show': 'Show Link Dialog'
18304      },
18305      history: {
18306        undo: 'Undo',
18307        redo: 'Redo'
18308      },
18309      specialChar: {
18310        specialChar: 'SPECIAL CHARACTERS',
18311        select: 'Select Special characters'
18312      }
18313    }
18314  });
18315
18316
18317  /**
18318   * @class core.key
18319   *
18320   * Object for keycodes.
18321   *
18322   * @singleton
18323   * @alternateClassName key
18324   */
18325  var key = (function () {
18326    var keyMap = {
18327      'BACKSPACE': 8,
18328      'TAB': 9,
18329      'ENTER': 13,
18330      'SPACE': 32,
18331
18332      // Arrow
18333      'LEFT': 37,
18334      'UP': 38,
18335      'RIGHT': 39,
18336      'DOWN': 40,
18337
18338      // Number: 0-9
18339      'NUM0': 48,
18340      'NUM1': 49,
18341      'NUM2': 50,
18342      'NUM3': 51,
18343      'NUM4': 52,
18344      'NUM5': 53,
18345      'NUM6': 54,
18346      'NUM7': 55,
18347      'NUM8': 56,
18348
18349      // Alphabet: a-z
18350      'B': 66,
18351      'E': 69,
18352      'I': 73,
18353      'J': 74,
18354      'K': 75,
18355      'L': 76,
18356      'R': 82,
18357      'S': 83,
18358      'U': 85,
18359      'V': 86,
18360      'Y': 89,
18361      'Z': 90,
18362
18363      'SLASH': 191,
18364      'LEFTBRACKET': 219,
18365      'BACKSLASH': 220,
18366      'RIGHTBRACKET': 221
18367    };
18368
18369    return {
18370      /**
18371       * @method isEdit
18372       *
18373       * @param {Number} keyCode
18374       * @return {Boolean}
18375       */
18376      isEdit: function (keyCode) {
18377        return list.contains([
18378          keyMap.BACKSPACE,
18379          keyMap.TAB,
18380          keyMap.ENTER,
18381          keyMap.SPACE
18382        ], keyCode);
18383      },
18384      /**
18385       * @method isMove
18386       *
18387       * @param {Number} keyCode
18388       * @return {Boolean}
18389       */
18390      isMove: function (keyCode) {
18391        return list.contains([
18392          keyMap.LEFT,
18393          keyMap.UP,
18394          keyMap.RIGHT,
18395          keyMap.DOWN
18396        ], keyCode);
18397      },
18398      /**
18399       * @property {Object} nameFromCode
18400       * @property {String} nameFromCode.8 "BACKSPACE"
18401       */
18402      nameFromCode: func.invertObject(keyMap),
18403      code: keyMap
18404    };
18405  })();
18406
18407  var range = (function () {
18408
18409    /**
18410     * return boundaryPoint from TextRange, inspired by Andy Na's HuskyRange.js
18411     *
18412     * @param {TextRange} textRange
18413     * @param {Boolean} isStart
18414     * @return {BoundaryPoint}
18415     *
18416     * @see http://msdn.microsoft.com/en-us/library/ie/ms535872(v=vs.85).aspx
18417     */
18418    var textRangeToPoint = function (textRange, isStart) {
18419      var container = textRange.parentElement(), offset;
18420  
18421      var tester = document.body.createTextRange(), prevContainer;
18422      var childNodes = list.from(container.childNodes);
18423      for (offset = 0; offset < childNodes.length; offset++) {
18424        if (dom.isText(childNodes[offset])) {
18425          continue;
18426        }
18427        tester.moveToElementText(childNodes[offset]);
18428        if (tester.compareEndPoints('StartToStart', textRange) >= 0) {
18429          break;
18430        }
18431        prevContainer = childNodes[offset];
18432      }
18433  
18434      if (offset !== 0 && dom.isText(childNodes[offset - 1])) {
18435        var textRangeStart = document.body.createTextRange(), curTextNode = null;
18436        textRangeStart.moveToElementText(prevContainer || container);
18437        textRangeStart.collapse(!prevContainer);
18438        curTextNode = prevContainer ? prevContainer.nextSibling : container.firstChild;
18439  
18440        var pointTester = textRange.duplicate();
18441        pointTester.setEndPoint('StartToStart', textRangeStart);
18442        var textCount = pointTester.text.replace(/[\r\n]/g, '').length;
18443  
18444        while (textCount > curTextNode.nodeValue.length && curTextNode.nextSibling) {
18445          textCount -= curTextNode.nodeValue.length;
18446          curTextNode = curTextNode.nextSibling;
18447        }
18448  
18449        /* jshint ignore:start */
18450        var dummy = curTextNode.nodeValue; // enforce IE to re-reference curTextNode, hack
18451        /* jshint ignore:end */
18452  
18453        if (isStart && curTextNode.nextSibling && dom.isText(curTextNode.nextSibling) &&
18454            textCount === curTextNode.nodeValue.length) {
18455          textCount -= curTextNode.nodeValue.length;
18456          curTextNode = curTextNode.nextSibling;
18457        }
18458  
18459        container = curTextNode;
18460        offset = textCount;
18461      }
18462  
18463      return {
18464        cont: container,
18465        offset: offset
18466      };
18467    };
18468    
18469    /**
18470     * return TextRange from boundary point (inspired by google closure-library)
18471     * @param {BoundaryPoint} point
18472     * @return {TextRange}
18473     */
18474    var pointToTextRange = function (point) {
18475      var textRangeInfo = function (container, offset) {
18476        var node, isCollapseToStart;
18477  
18478        if (dom.isText(container)) {
18479          var prevTextNodes = dom.listPrev(container, func.not(dom.isText));
18480          var prevContainer = list.last(prevTextNodes).previousSibling;
18481          node =  prevContainer || container.parentNode;
18482          offset += list.sum(list.tail(prevTextNodes), dom.nodeLength);
18483          isCollapseToStart = !prevContainer;
18484        } else {
18485          node = container.childNodes[offset] || container;
18486          if (dom.isText(node)) {
18487            return textRangeInfo(node, 0);
18488          }
18489  
18490          offset = 0;
18491          isCollapseToStart = false;
18492        }
18493  
18494        return {
18495          node: node,
18496          collapseToStart: isCollapseToStart,
18497          offset: offset
18498        };
18499      };
18500  
18501      var textRange = document.body.createTextRange();
18502      var info = textRangeInfo(point.node, point.offset);
18503  
18504      textRange.moveToElementText(info.node);
18505      textRange.collapse(info.collapseToStart);
18506      textRange.moveStart('character', info.offset);
18507      return textRange;
18508    };
18509    
18510    /**
18511     * Wrapped Range
18512     *
18513     * @constructor
18514     * @param {Node} sc - start container
18515     * @param {Number} so - start offset
18516     * @param {Node} ec - end container
18517     * @param {Number} eo - end offset
18518     */
18519    var WrappedRange = function (sc, so, ec, eo) {
18520      this.sc = sc;
18521      this.so = so;
18522      this.ec = ec;
18523      this.eo = eo;
18524  
18525      // nativeRange: get nativeRange from sc, so, ec, eo
18526      var nativeRange = function () {
18527        if (agent.isW3CRangeSupport) {
18528          var w3cRange = document.createRange();
18529          w3cRange.setStart(sc, so);
18530          w3cRange.setEnd(ec, eo);
18531
18532          return w3cRange;
18533        } else {
18534          var textRange = pointToTextRange({
18535            node: sc,
18536            offset: so
18537          });
18538
18539          textRange.setEndPoint('EndToEnd', pointToTextRange({
18540            node: ec,
18541            offset: eo
18542          }));
18543
18544          return textRange;
18545        }
18546      };
18547
18548      this.getPoints = function () {
18549        return {
18550          sc: sc,
18551          so: so,
18552          ec: ec,
18553          eo: eo
18554        };
18555      };
18556
18557      this.getStartPoint = function () {
18558        return {
18559          node: sc,
18560          offset: so
18561        };
18562      };
18563
18564      this.getEndPoint = function () {
18565        return {
18566          node: ec,
18567          offset: eo
18568        };
18569      };
18570
18571      /**
18572       * select update visible range
18573       */
18574      this.select = function () {
18575        var nativeRng = nativeRange();
18576        if (agent.isW3CRangeSupport) {
18577          var selection = document.getSelection();
18578          if (selection.rangeCount > 0) {
18579            selection.removeAllRanges();
18580          }
18581          selection.addRange(nativeRng);
18582        } else {
18583          nativeRng.select();
18584        }
18585        
18586        return this;
18587      };
18588
18589      /**
18590       * Moves the scrollbar to start container(sc) of current range
18591       *
18592       * @return {WrappedRange}
18593       */
18594      this.scrollIntoView = function (container) {
18595        var height = $(container).height();
18596        if (container.scrollTop + height < this.sc.offsetTop) {
18597          container.scrollTop += Math.abs(container.scrollTop + height - this.sc.offsetTop);
18598        }
18599
18600        return this;
18601      };
18602
18603      /**
18604       * @return {WrappedRange}
18605       */
18606      this.normalize = function () {
18607
18608        /**
18609         * @param {BoundaryPoint} point
18610         * @param {Boolean} isLeftToRight
18611         * @return {BoundaryPoint}
18612         */
18613        var getVisiblePoint = function (point, isLeftToRight) {
18614          if ((dom.isVisiblePoint(point) && !dom.isEdgePoint(point)) ||
18615              (dom.isVisiblePoint(point) && dom.isRightEdgePoint(point) && !isLeftToRight) ||
18616              (dom.isVisiblePoint(point) && dom.isLeftEdgePoint(point) && isLeftToRight) ||
18617              (dom.isVisiblePoint(point) && dom.isBlock(point.node) && dom.isEmpty(point.node))) {
18618            return point;
18619          }
18620
18621          // point on block's edge
18622          var block = dom.ancestor(point.node, dom.isBlock);
18623          if (((dom.isLeftEdgePointOf(point, block) || dom.isVoid(dom.prevPoint(point).node)) && !isLeftToRight) ||
18624              ((dom.isRightEdgePointOf(point, block) || dom.isVoid(dom.nextPoint(point).node)) && isLeftToRight)) {
18625
18626            // returns point already on visible point
18627            if (dom.isVisiblePoint(point)) {
18628              return point;
18629            }
18630            // reverse direction 
18631            isLeftToRight = !isLeftToRight;
18632          }
18633
18634          var nextPoint = isLeftToRight ? dom.nextPointUntil(dom.nextPoint(point), dom.isVisiblePoint) :
18635                                          dom.prevPointUntil(dom.prevPoint(point), dom.isVisiblePoint);
18636          return nextPoint || point;
18637        };
18638
18639        var endPoint = getVisiblePoint(this.getEndPoint(), false);
18640        var startPoint = this.isCollapsed() ? endPoint : getVisiblePoint(this.getStartPoint(), true);
18641
18642        return new WrappedRange(
18643          startPoint.node,
18644          startPoint.offset,
18645          endPoint.node,
18646          endPoint.offset
18647        );
18648      };
18649
18650      /**
18651       * returns matched nodes on range
18652       *
18653       * @param {Function} [pred] - predicate function
18654       * @param {Object} [options]
18655       * @param {Boolean} [options.includeAncestor]
18656       * @param {Boolean} [options.fullyContains]
18657       * @return {Node[]}
18658       */
18659      this.nodes = function (pred, options) {
18660        pred = pred || func.ok;
18661
18662        var includeAncestor = options && options.includeAncestor;
18663        var fullyContains = options && options.fullyContains;
18664
18665        // TODO compare points and sort
18666        var startPoint = this.getStartPoint();
18667        var endPoint = this.getEndPoint();
18668
18669        var nodes = [];
18670        var leftEdgeNodes = [];
18671
18672        dom.walkPoint(startPoint, endPoint, function (point) {
18673          if (dom.isEditable(point.node)) {
18674            return;
18675          }
18676
18677          var node;
18678          if (fullyContains) {
18679            if (dom.isLeftEdgePoint(point)) {
18680              leftEdgeNodes.push(point.node);
18681            }
18682            if (dom.isRightEdgePoint(point) && list.contains(leftEdgeNodes, point.node)) {
18683              node = point.node;
18684            }
18685          } else if (includeAncestor) {
18686            node = dom.ancestor(point.node, pred);
18687          } else {
18688            node = point.node;
18689          }
18690
18691          if (node && pred(node)) {
18692            nodes.push(node);
18693          }
18694        }, true);
18695
18696        return list.unique(nodes);
18697      };
18698
18699      /**
18700       * returns commonAncestor of range
18701       * @return {Element} - commonAncestor
18702       */
18703      this.commonAncestor = function () {
18704        return dom.commonAncestor(sc, ec);
18705      };
18706
18707      /**
18708       * returns expanded range by pred
18709       *
18710       * @param {Function} pred - predicate function
18711       * @return {WrappedRange}
18712       */
18713      this.expand = function (pred) {
18714        var startAncestor = dom.ancestor(sc, pred);
18715        var endAncestor = dom.ancestor(ec, pred);
18716
18717        if (!startAncestor && !endAncestor) {
18718          return new WrappedRange(sc, so, ec, eo);
18719        }
18720
18721        var boundaryPoints = this.getPoints();
18722
18723        if (startAncestor) {
18724          boundaryPoints.sc = startAncestor;
18725          boundaryPoints.so = 0;
18726        }
18727
18728        if (endAncestor) {
18729          boundaryPoints.ec = endAncestor;
18730          boundaryPoints.eo = dom.nodeLength(endAncestor);
18731        }
18732
18733        return new WrappedRange(
18734          boundaryPoints.sc,
18735          boundaryPoints.so,
18736          boundaryPoints.ec,
18737          boundaryPoints.eo
18738        );
18739      };
18740
18741      /**
18742       * @param {Boolean} isCollapseToStart
18743       * @return {WrappedRange}
18744       */
18745      this.collapse = function (isCollapseToStart) {
18746        if (isCollapseToStart) {
18747          return new WrappedRange(sc, so, sc, so);
18748        } else {
18749          return new WrappedRange(ec, eo, ec, eo);
18750        }
18751      };
18752
18753      /**
18754       * splitText on range
18755       */
18756      this.splitText = function () {
18757        var isSameContainer = sc === ec;
18758        var boundaryPoints = this.getPoints();
18759
18760        if (dom.isText(ec) && !dom.isEdgePoint(this.getEndPoint())) {
18761          ec.splitText(eo);
18762        }
18763
18764        if (dom.isText(sc) && !dom.isEdgePoint(this.getStartPoint())) {
18765          boundaryPoints.sc = sc.splitText(so);
18766          boundaryPoints.so = 0;
18767
18768          if (isSameContainer) {
18769            boundaryPoints.ec = boundaryPoints.sc;
18770            boundaryPoints.eo = eo - so;
18771          }
18772        }
18773
18774        return new WrappedRange(
18775          boundaryPoints.sc,
18776          boundaryPoints.so,
18777          boundaryPoints.ec,
18778          boundaryPoints.eo
18779        );
18780      };
18781
18782      /**
18783       * delete contents on range
18784       * @return {WrappedRange}
18785       */
18786      this.deleteContents = function () {
18787        if (this.isCollapsed()) {
18788          return this;
18789        }
18790
18791        var rng = this.splitText();
18792        var nodes = rng.nodes(null, {
18793          fullyContains: true
18794        });
18795
18796        // find new cursor point
18797        var point = dom.prevPointUntil(rng.getStartPoint(), function (point) {
18798          return !list.contains(nodes, point.node);
18799        });
18800
18801        var emptyParents = [];
18802        $.each(nodes, function (idx, node) {
18803          // find empty parents
18804          var parent = node.parentNode;
18805          if (point.node !== parent && dom.nodeLength(parent) === 1) {
18806            emptyParents.push(parent);
18807          }
18808          dom.remove(node, false);
18809        });
18810
18811        // remove empty parents
18812        $.each(emptyParents, function (idx, node) {
18813          dom.remove(node, false);
18814        });
18815
18816        return new WrappedRange(
18817          point.node,
18818          point.offset,
18819          point.node,
18820          point.offset
18821        ).normalize();
18822      };
18823      
18824      /**
18825       * makeIsOn: return isOn(pred) function
18826       */
18827      var makeIsOn = function (pred) {
18828        return function () {
18829          var ancestor = dom.ancestor(sc, pred);
18830          return !!ancestor && (ancestor === dom.ancestor(ec, pred));
18831        };
18832      };
18833  
18834      // isOnEditable: judge whether range is on editable or not
18835      this.isOnEditable = makeIsOn(dom.isEditable);
18836      // isOnList: judge whether range is on list node or not
18837      this.isOnList = makeIsOn(dom.isList);
18838      // isOnAnchor: judge whether range is on anchor node or not
18839      this.isOnAnchor = makeIsOn(dom.isAnchor);
18840      // isOnCell: judge whether range is on cell node or not
18841      this.isOnCell = makeIsOn(dom.isCell);
18842      // isOnData: judge whether range is on data node or not
18843      this.isOnData = makeIsOn(dom.isData);
18844
18845      /**
18846       * @param {Function} pred
18847       * @return {Boolean}
18848       */
18849      this.isLeftEdgeOf = function (pred) {
18850        if (!dom.isLeftEdgePoint(this.getStartPoint())) {
18851          return false;
18852        }
18853
18854        var node = dom.ancestor(this.sc, pred);
18855        return node && dom.isLeftEdgeOf(this.sc, node);
18856      };
18857
18858      /**
18859       * returns whether range was collapsed or not
18860       */
18861      this.isCollapsed = function () {
18862        return sc === ec && so === eo;
18863      };
18864
18865      /**
18866       * wrap inline nodes which children of body with paragraph
18867       *
18868       * @return {WrappedRange}
18869       */
18870      this.wrapBodyInlineWithPara = function () {
18871        if (dom.isBodyContainer(sc) && dom.isEmpty(sc)) {
18872          sc.innerHTML = dom.emptyPara;
18873          return new WrappedRange(sc.firstChild, 0, sc.firstChild, 0);
18874        }
18875
18876        /**
18877         * [workaround] firefox often create range on not visible point. so normalize here.
18878         *  - firefox: |<p>text</p>|
18879         *  - chrome: <p>|text|</p>
18880         */
18881        var rng = this.normalize();
18882        if (dom.isParaInline(sc) || dom.isPara(sc)) {
18883          return rng;
18884        }
18885
18886        // find inline top ancestor
18887        var topAncestor;
18888        if (dom.isInline(rng.sc)) {
18889          var ancestors = dom.listAncestor(rng.sc, func.not(dom.isInline));
18890          topAncestor = list.last(ancestors);
18891          if (!dom.isInline(topAncestor)) {
18892            topAncestor = ancestors[ancestors.length - 2] || rng.sc.childNodes[rng.so];
18893          }
18894        } else {
18895          topAncestor = rng.sc.childNodes[rng.so > 0 ? rng.so - 1 : 0];
18896        }
18897
18898        // siblings not in paragraph
18899        var inlineSiblings = dom.listPrev(topAncestor, dom.isParaInline).reverse();
18900        inlineSiblings = inlineSiblings.concat(dom.listNext(topAncestor.nextSibling, dom.isParaInline));
18901
18902        // wrap with paragraph
18903        if (inlineSiblings.length) {
18904          var para = dom.wrap(list.head(inlineSiblings), 'p');
18905          dom.appendChildNodes(para, list.tail(inlineSiblings));
18906        }
18907
18908        return this.normalize();
18909      };
18910
18911      /**
18912       * insert node at current cursor
18913       *
18914       * @param {Node} node
18915       * @return {Node}
18916       */
18917      this.insertNode = function (node) {
18918        var rng = this.wrapBodyInlineWithPara().deleteContents();
18919        var info = dom.splitPoint(rng.getStartPoint(), dom.isInline(node));
18920
18921        if (info.rightNode) {
18922          info.rightNode.parentNode.insertBefore(node, info.rightNode);
18923        } else {
18924          info.container.appendChild(node);
18925        }
18926
18927        return node;
18928      };
18929
18930      /**
18931       * insert html at current cursor
18932       */
18933      this.pasteHTML = function (markup) {
18934        var contentsContainer = $('<div></div>').html(markup)[0];
18935        var childNodes = list.from(contentsContainer.childNodes);
18936
18937        var rng = this.wrapBodyInlineWithPara().deleteContents();
18938
18939        return childNodes.reverse().map(function (childNode) {
18940          return rng.insertNode(childNode);
18941        }).reverse();
18942      };
18943  
18944      /**
18945       * returns text in range
18946       *
18947       * @return {String}
18948       */
18949      this.toString = function () {
18950        var nativeRng = nativeRange();
18951        return agent.isW3CRangeSupport ? nativeRng.toString() : nativeRng.text;
18952      };
18953
18954      /**
18955       * returns range for word before cursor
18956       *
18957       * @param {Boolean} [findAfter] - find after cursor, default: false
18958       * @return {WrappedRange}
18959       */
18960      this.getWordRange = function (findAfter) {
18961        var endPoint = this.getEndPoint();
18962
18963        if (!dom.isCharPoint(endPoint)) {
18964          return this;
18965        }
18966
18967        var startPoint = dom.prevPointUntil(endPoint, function (point) {
18968          return !dom.isCharPoint(point);
18969        });
18970
18971        if (findAfter) {
18972          endPoint = dom.nextPointUntil(endPoint, function (point) {
18973            return !dom.isCharPoint(point);
18974          });
18975        }
18976
18977        return new WrappedRange(
18978          startPoint.node,
18979          startPoint.offset,
18980          endPoint.node,
18981          endPoint.offset
18982        );
18983      };
18984  
18985      /**
18986       * create offsetPath bookmark
18987       *
18988       * @param {Node} editable
18989       */
18990      this.bookmark = function (editable) {
18991        return {
18992          s: {
18993            path: dom.makeOffsetPath(editable, sc),
18994            offset: so
18995          },
18996          e: {
18997            path: dom.makeOffsetPath(editable, ec),
18998            offset: eo
18999          }
19000        };
19001      };
19002
19003      /**
19004       * create offsetPath bookmark base on paragraph
19005       *
19006       * @param {Node[]} paras
19007       */
19008      this.paraBookmark = function (paras) {
19009        return {
19010          s: {
19011            path: list.tail(dom.makeOffsetPath(list.head(paras), sc)),
19012            offset: so
19013          },
19014          e: {
19015            path: list.tail(dom.makeOffsetPath(list.last(paras), ec)),
19016            offset: eo
19017          }
19018        };
19019      };
19020
19021      /**
19022       * getClientRects
19023       * @return {Rect[]}
19024       */
19025      this.getClientRects = function () {
19026        var nativeRng = nativeRange();
19027        return nativeRng.getClientRects();
19028      };
19029    };
19030
19031  /**
19032   * @class core.range
19033   *
19034   * Data structure
19035   *  * BoundaryPoint: a point of dom tree
19036   *  * BoundaryPoints: two boundaryPoints corresponding to the start and the end of the Range
19037   *
19038   * See to http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Position
19039   *
19040   * @singleton
19041   * @alternateClassName range
19042   */
19043    return {
19044      /**
19045       * create Range Object From arguments or Browser Selection
19046       *
19047       * @param {Node} sc - start container
19048       * @param {Number} so - start offset
19049       * @param {Node} ec - end container
19050       * @param {Number} eo - end offset
19051       * @return {WrappedRange}
19052       */
19053      create: function (sc, so, ec, eo) {
19054        if (arguments.length === 4) {
19055          return new WrappedRange(sc, so, ec, eo);
19056        } else if (arguments.length === 2) { //collapsed
19057          ec = sc;
19058          eo = so;
19059          return new WrappedRange(sc, so, ec, eo);
19060        } else {
19061          var wrappedRange = this.createFromSelection();
19062          if (!wrappedRange && arguments.length === 1) {
19063            wrappedRange = this.createFromNode(arguments[0]);
19064            return wrappedRange.collapse(dom.emptyPara === arguments[0].innerHTML);
19065          }
19066          return wrappedRange;
19067        }
19068      },
19069
19070      createFromSelection: function () {
19071        var sc, so, ec, eo;
19072        if (agent.isW3CRangeSupport) {
19073          var selection = document.getSelection();
19074          if (!selection || selection.rangeCount === 0) {
19075            return null;
19076          } else if (dom.isBody(selection.anchorNode)) {
19077            // Firefox: returns entire body as range on initialization.
19078            // We won't never need it.
19079            return null;
19080          }
19081
19082          var nativeRng = selection.getRangeAt(0);
19083          sc = nativeRng.startContainer;
19084          so = nativeRng.startOffset;
19085          ec = nativeRng.endContainer;
19086          eo = nativeRng.endOffset;
19087        } else { // IE8: TextRange
19088          var textRange = document.selection.createRange();
19089          var textRangeEnd = textRange.duplicate();
19090          textRangeEnd.collapse(false);
19091          var textRangeStart = textRange;
19092          textRangeStart.collapse(true);
19093
19094          var startPoint = textRangeToPoint(textRangeStart, true),
19095          endPoint = textRangeToPoint(textRangeEnd, false);
19096
19097          // same visible point case: range was collapsed.
19098          if (dom.isText(startPoint.node) && dom.isLeftEdgePoint(startPoint) &&
19099              dom.isTextNode(endPoint.node) && dom.isRightEdgePoint(endPoint) &&
19100              endPoint.node.nextSibling === startPoint.node) {
19101            startPoint = endPoint;
19102          }
19103
19104          sc = startPoint.cont;
19105          so = startPoint.offset;
19106          ec = endPoint.cont;
19107          eo = endPoint.offset;
19108        }
19109
19110        return new WrappedRange(sc, so, ec, eo);
19111      },
19112
19113      /**
19114       * @method 
19115       * 
19116       * create WrappedRange from node
19117       *
19118       * @param {Node} node
19119       * @return {WrappedRange}
19120       */
19121      createFromNode: function (node) {
19122        var sc = node;
19123        var so = 0;
19124        var ec = node;
19125        var eo = dom.nodeLength(ec);
19126
19127        // browsers can't target a picture or void node
19128        if (dom.isVoid(sc)) {
19129          so = dom.listPrev(sc).length - 1;
19130          sc = sc.parentNode;
19131        }
19132        if (dom.isBR(ec)) {
19133          eo = dom.listPrev(ec).length - 1;
19134          ec = ec.parentNode;
19135        } else if (dom.isVoid(ec)) {
19136          eo = dom.listPrev(ec).length;
19137          ec = ec.parentNode;
19138        }
19139
19140        return this.create(sc, so, ec, eo);
19141      },
19142
19143      /**
19144       * create WrappedRange from node after position
19145       *
19146       * @param {Node} node
19147       * @return {WrappedRange}
19148       */
19149      createFromNodeBefore: function (node) {
19150        return this.createFromNode(node).collapse(true);
19151      },
19152
19153      /**
19154       * create WrappedRange from node after position
19155       *
19156       * @param {Node} node
19157       * @return {WrappedRange}
19158       */
19159      createFromNodeAfter: function (node) {
19160        return this.createFromNode(node).collapse();
19161      },
19162
19163      /**
19164       * @method 
19165       * 
19166       * create WrappedRange from bookmark
19167       *
19168       * @param {Node} editable
19169       * @param {Object} bookmark
19170       * @return {WrappedRange}
19171       */
19172      createFromBookmark: function (editable, bookmark) {
19173        var sc = dom.fromOffsetPath(editable, bookmark.s.path);
19174        var so = bookmark.s.offset;
19175        var ec = dom.fromOffsetPath(editable, bookmark.e.path);
19176        var eo = bookmark.e.offset;
19177        return new WrappedRange(sc, so, ec, eo);
19178      },
19179
19180      /**
19181       * @method 
19182       *
19183       * create WrappedRange from paraBookmark
19184       *
19185       * @param {Object} bookmark
19186       * @param {Node[]} paras
19187       * @return {WrappedRange}
19188       */
19189      createFromParaBookmark: function (bookmark, paras) {
19190        var so = bookmark.s.offset;
19191        var eo = bookmark.e.offset;
19192        var sc = dom.fromOffsetPath(list.head(paras), bookmark.s.path);
19193        var ec = dom.fromOffsetPath(list.last(paras), bookmark.e.path);
19194
19195        return new WrappedRange(sc, so, ec, eo);
19196      }
19197    };
19198  })();
19199
19200  /**
19201   * @class core.async
19202   *
19203   * Async functions which returns `Promise`
19204   *
19205   * @singleton
19206   * @alternateClassName async
19207   */
19208  var async = (function () {
19209    /**
19210     * @method readFileAsDataURL
19211     *
19212     * read contents of file as representing URL
19213     *
19214     * @param {File} file
19215     * @return {Promise} - then: dataUrl
19216     */
19217    var readFileAsDataURL = function (file) {
19218      return $.Deferred(function (deferred) {
19219        $.extend(new FileReader(), {
19220          onload: function (e) {
19221            var dataURL = e.target.result;
19222            deferred.resolve(dataURL);
19223          },
19224          onerror: function () {
19225            deferred.reject(this);
19226          }
19227        }).readAsDataURL(file);
19228      }).promise();
19229    };
19230  
19231    /**
19232     * @method createImage
19233     *
19234     * create `<image>` from url string
19235     *
19236     * @param {String} url
19237     * @return {Promise} - then: $image
19238     */
19239    var createImage = function (url) {
19240      return $.Deferred(function (deferred) {
19241        var $img = $('<img>');
19242
19243        $img.one('load', function () {
19244          $img.off('error abort');
19245          deferred.resolve($img);
19246        }).one('error abort', function () {
19247          $img.off('load').detach();
19248          deferred.reject($img);
19249        }).css({
19250          display: 'none'
19251        }).appendTo(document.body).attr('src', url);
19252      }).promise();
19253    };
19254
19255    return {
19256      readFileAsDataURL: readFileAsDataURL,
19257      createImage: createImage
19258    };
19259  })();
19260
19261  /**
19262   * @class editing.History
19263   *
19264   * Editor History
19265   *
19266   */
19267  var History = function ($editable) {
19268    var stack = [], stackOffset = -1;
19269    var editable = $editable[0];
19270
19271    var makeSnapshot = function () {
19272      var rng = range.create(editable);
19273      var emptyBookmark = {s: {path: [], offset: 0}, e: {path: [], offset: 0}};
19274
19275      return {
19276        contents: $editable.html(),
19277        bookmark: (rng ? rng.bookmark(editable) : emptyBookmark)
19278      };
19279    };
19280
19281    var applySnapshot = function (snapshot) {
19282      if (snapshot.contents !== null) {
19283        $editable.html(snapshot.contents);
19284      }
19285      if (snapshot.bookmark !== null) {
19286        range.createFromBookmark(editable, snapshot.bookmark).select();
19287      }
19288    };
19289
19290    /**
19291    * @method rewind
19292    * Rewinds the history stack back to the first snapshot taken.
19293    * Leaves the stack intact, so that "Redo" can still be used.
19294    */
19295    this.rewind = function () {
19296      // Create snap shot if not yet recorded
19297      if ($editable.html() !== stack[stackOffset].contents) {
19298        this.recordUndo();
19299      }
19300
19301      // Return to the first available snapshot.
19302      stackOffset = 0;
19303
19304      // Apply that snapshot.
19305      applySnapshot(stack[stackOffset]);
19306    };
19307
19308    /**
19309    * @method reset
19310    * Resets the history stack completely; reverting to an empty editor.
19311    */
19312    this.reset = function () {
19313      // Clear the stack.
19314      stack = [];
19315
19316      // Restore stackOffset to its original value.
19317      stackOffset = -1;
19318
19319      // Clear the editable area.
19320      $editable.html('');
19321
19322      // Record our first snapshot (of nothing).
19323      this.recordUndo();
19324    };
19325
19326    /**
19327     * undo
19328     */
19329    this.undo = function () {
19330      // Create snap shot if not yet recorded
19331      if ($editable.html() !== stack[stackOffset].contents) {
19332        this.recordUndo();
19333      }
19334
19335      if (0 < stackOffset) {
19336        stackOffset--;
19337        applySnapshot(stack[stackOffset]);
19338      }
19339    };
19340
19341    /**
19342     * redo
19343     */
19344    this.redo = function () {
19345      if (stack.length - 1 > stackOffset) {
19346        stackOffset++;
19347        applySnapshot(stack[stackOffset]);
19348      }
19349    };
19350
19351    /**
19352     * recorded undo
19353     */
19354    this.recordUndo = function () {
19355      stackOffset++;
19356
19357      // Wash out stack after stackOffset
19358      if (stack.length > stackOffset) {
19359        stack = stack.slice(0, stackOffset);
19360      }
19361
19362      // Create new snapshot and push it to the end
19363      stack.push(makeSnapshot());
19364    };
19365  };
19366
19367  /**
19368   * @class editing.Style
19369   *
19370   * Style
19371   *
19372   */
19373  var Style = function () {
19374    /**
19375     * @method jQueryCSS
19376     *
19377     * [workaround] for old jQuery
19378     * passing an array of style properties to .css()
19379     * will result in an object of property-value pairs.
19380     * (compability with version < 1.9)
19381     *
19382     * @private
19383     * @param  {jQuery} $obj
19384     * @param  {Array} propertyNames - An array of one or more CSS properties.
19385     * @return {Object}
19386     */
19387    var jQueryCSS = function ($obj, propertyNames) {
19388      if (agent.jqueryVersion < 1.9) {
19389        var result = {};
19390        $.each(propertyNames, function (idx, propertyName) {
19391          result[propertyName] = $obj.css(propertyName);
19392        });
19393        return result;
19394      }
19395      return $obj.css.call($obj, propertyNames);
19396    };
19397
19398    /**
19399     * returns style object from node
19400     *
19401     * @param {jQuery} $node
19402     * @return {Object}
19403     */
19404    this.fromNode = function ($node) {
19405      var properties = ['font-family', 'font-size', 'text-align', 'list-style-type', 'line-height'];
19406      var styleInfo = jQueryCSS($node, properties) || {};
19407      styleInfo['font-size'] = parseInt(styleInfo['font-size'], 10);
19408      return styleInfo;
19409    };
19410
19411    /**
19412     * paragraph level style
19413     *
19414     * @param {WrappedRange} rng
19415     * @param {Object} styleInfo
19416     */
19417    this.stylePara = function (rng, styleInfo) {
19418      $.each(rng.nodes(dom.isPara, {
19419        includeAncestor: true
19420      }), function (idx, para) {
19421        $(para).css(styleInfo);
19422      });
19423    };
19424
19425    /**
19426     * insert and returns styleNodes on range.
19427     *
19428     * @param {WrappedRange} rng
19429     * @param {Object} [options] - options for styleNodes
19430     * @param {String} [options.nodeName] - default: `SPAN`
19431     * @param {Boolean} [options.expandClosestSibling] - default: `false`
19432     * @param {Boolean} [options.onlyPartialContains] - default: `false`
19433     * @return {Node[]}
19434     */
19435    this.styleNodes = function (rng, options) {
19436      rng = rng.splitText();
19437
19438      var nodeName = options && options.nodeName || 'SPAN';
19439      var expandClosestSibling = !!(options && options.expandClosestSibling);
19440      var onlyPartialContains = !!(options && options.onlyPartialContains);
19441
19442      if (rng.isCollapsed()) {
19443        return [rng.insertNode(dom.create(nodeName))];
19444      }
19445
19446      var pred = dom.makePredByNodeName(nodeName);
19447      var nodes = rng.nodes(dom.isText, {
19448        fullyContains: true
19449      }).map(function (text) {
19450        return dom.singleChildAncestor(text, pred) || dom.wrap(text, nodeName);
19451      });
19452
19453      if (expandClosestSibling) {
19454        if (onlyPartialContains) {
19455          var nodesInRange = rng.nodes();
19456          // compose with partial contains predication
19457          pred = func.and(pred, function (node) {
19458            return list.contains(nodesInRange, node);
19459          });
19460        }
19461
19462        return nodes.map(function (node) {
19463          var siblings = dom.withClosestSiblings(node, pred);
19464          var head = list.head(siblings);
19465          var tails = list.tail(siblings);
19466          $.each(tails, function (idx, elem) {
19467            dom.appendChildNodes(head, elem.childNodes);
19468            dom.remove(elem);
19469          });
19470          return list.head(siblings);
19471        });
19472      } else {
19473        return nodes;
19474      }
19475    };
19476
19477    /**
19478     * get current style on cursor
19479     *
19480     * @param {WrappedRange} rng
19481     * @return {Object} - object contains style properties.
19482     */
19483    this.current = function (rng) {
19484      var $cont = $(!dom.isElement(rng.sc) ? rng.sc.parentNode : rng.sc);
19485      var styleInfo = this.fromNode($cont);
19486
19487      // document.queryCommandState for toggle state
19488      // [workaround] prevent Firefox nsresult: "0x80004005 (NS_ERROR_FAILURE)"
19489      try {
19490        styleInfo = $.extend(styleInfo, {
19491          'font-bold': document.queryCommandState('bold') ? 'bold' : 'normal',
19492          'font-italic': document.queryCommandState('italic') ? 'italic' : 'normal',
19493          'font-underline': document.queryCommandState('underline') ? 'underline' : 'normal',
19494          'font-subscript': document.queryCommandState('subscript') ? 'subscript' : 'normal',
19495          'font-superscript': document.queryCommandState('superscript') ? 'superscript' : 'normal',
19496          'font-strikethrough': document.queryCommandState('strikethrough') ? 'strikethrough' : 'normal'
19497        });
19498      } catch (e) {}
19499
19500      // list-style-type to list-style(unordered, ordered)
19501      if (!rng.isOnList()) {
19502        styleInfo['list-style'] = 'none';
19503      } else {
19504        var orderedTypes = ['circle', 'disc', 'disc-leading-zero', 'square'];
19505        var isUnordered = $.inArray(styleInfo['list-style-type'], orderedTypes) > -1;
19506        styleInfo['list-style'] = isUnordered ? 'unordered' : 'ordered';
19507      }
19508
19509      var para = dom.ancestor(rng.sc, dom.isPara);
19510      if (para && para.style['line-height']) {
19511        styleInfo['line-height'] = para.style.lineHeight;
19512      } else {
19513        var lineHeight = parseInt(styleInfo['line-height'], 10) / parseInt(styleInfo['font-size'], 10);
19514        styleInfo['line-height'] = lineHeight.toFixed(1);
19515      }
19516
19517      styleInfo.anchor = rng.isOnAnchor() && dom.ancestor(rng.sc, dom.isAnchor);
19518      styleInfo.ancestors = dom.listAncestor(rng.sc, dom.isEditable);
19519      styleInfo.range = rng;
19520
19521      return styleInfo;
19522    };
19523  };
19524
19525
19526  /**
19527   * @class editing.Bullet
19528   *
19529   * @alternateClassName Bullet
19530   */
19531  var Bullet = function () {
19532    var self = this;
19533
19534    /**
19535     * toggle ordered list
19536     */
19537    this.insertOrderedList = function (editable) {
19538      this.toggleList('OL', editable);
19539    };
19540
19541    /**
19542     * toggle unordered list
19543     */
19544    this.insertUnorderedList = function (editable) {
19545      this.toggleList('UL', editable);
19546    };
19547
19548    /**
19549     * indent
19550     */
19551    this.indent = function (editable) {
19552      var self = this;
19553      var rng = range.create(editable).wrapBodyInlineWithPara();
19554
19555      var paras = rng.nodes(dom.isPara, { includeAncestor: true });
19556      var clustereds = list.clusterBy(paras, func.peq2('parentNode'));
19557
19558      $.each(clustereds, function (idx, paras) {
19559        var head = list.head(paras);
19560        if (dom.isLi(head)) {
19561          self.wrapList(paras, head.parentNode.nodeName);
19562        } else {
19563          $.each(paras, function (idx, para) {
19564            $(para).css('marginLeft', function (idx, val) {
19565              return (parseInt(val, 10) || 0) + 25;
19566            });
19567          });
19568        }
19569      });
19570
19571      rng.select();
19572    };
19573
19574    /**
19575     * outdent
19576     */
19577    this.outdent = function (editable) {
19578      var self = this;
19579      var rng = range.create(editable).wrapBodyInlineWithPara();
19580
19581      var paras = rng.nodes(dom.isPara, { includeAncestor: true });
19582      var clustereds = list.clusterBy(paras, func.peq2('parentNode'));
19583
19584      $.each(clustereds, function (idx, paras) {
19585        var head = list.head(paras);
19586        if (dom.isLi(head)) {
19587          self.releaseList([paras]);
19588        } else {
19589          $.each(paras, function (idx, para) {
19590            $(para).css('marginLeft', function (idx, val) {
19591              val = (parseInt(val, 10) || 0);
19592              return val > 25 ? val - 25 : '';
19593            });
19594          });
19595        }
19596      });
19597
19598      rng.select();
19599    };
19600
19601    /**
19602     * toggle list
19603     *
19604     * @param {String} listName - OL or UL
19605     */
19606    this.toggleList = function (listName, editable) {
19607      var rng = range.create(editable).wrapBodyInlineWithPara();
19608
19609      var paras = rng.nodes(dom.isPara, { includeAncestor: true });
19610      var bookmark = rng.paraBookmark(paras);
19611      var clustereds = list.clusterBy(paras, func.peq2('parentNode'));
19612
19613      // paragraph to list
19614      if (list.find(paras, dom.isPurePara)) {
19615        var wrappedParas = [];
19616        $.each(clustereds, function (idx, paras) {
19617          wrappedParas = wrappedParas.concat(self.wrapList(paras, listName));
19618        });
19619        paras = wrappedParas;
19620      // list to paragraph or change list style
19621      } else {
19622        var diffLists = rng.nodes(dom.isList, {
19623          includeAncestor: true
19624        }).filter(function (listNode) {
19625          return !$.nodeName(listNode, listName);
19626        });
19627
19628        if (diffLists.length) {
19629          $.each(diffLists, function (idx, listNode) {
19630            dom.replace(listNode, listName);
19631          });
19632        } else {
19633          paras = this.releaseList(clustereds, true);
19634        }
19635      }
19636
19637      range.createFromParaBookmark(bookmark, paras).select();
19638    };
19639
19640    /**
19641     * @param {Node[]} paras
19642     * @param {String} listName
19643     * @return {Node[]}
19644     */
19645    this.wrapList = function (paras, listName) {
19646      var head = list.head(paras);
19647      var last = list.last(paras);
19648
19649      var prevList = dom.isList(head.previousSibling) && head.previousSibling;
19650      var nextList = dom.isList(last.nextSibling) && last.nextSibling;
19651
19652      var listNode = prevList || dom.insertAfter(dom.create(listName || 'UL'), last);
19653
19654      // P to LI
19655      paras = paras.map(function (para) {
19656        return dom.isPurePara(para) ? dom.replace(para, 'LI') : para;
19657      });
19658
19659      // append to list(<ul>, <ol>)
19660      dom.appendChildNodes(listNode, paras);
19661
19662      if (nextList) {
19663        dom.appendChildNodes(listNode, list.from(nextList.childNodes));
19664        dom.remove(nextList);
19665      }
19666
19667      return paras;
19668    };
19669
19670    /**
19671     * @method releaseList
19672     *
19673     * @param {Array[]} clustereds
19674     * @param {Boolean} isEscapseToBody
19675     * @return {Node[]}
19676     */
19677    this.releaseList = function (clustereds, isEscapseToBody) {
19678      var releasedParas = [];
19679
19680      $.each(clustereds, function (idx, paras) {
19681        var head = list.head(paras);
19682        var last = list.last(paras);
19683
19684        var headList = isEscapseToBody ? dom.lastAncestor(head, dom.isList) :
19685                                         head.parentNode;
19686        var lastList = headList.childNodes.length > 1 ? dom.splitTree(headList, {
19687          node: last.parentNode,
19688          offset: dom.position(last) + 1
19689        }, {
19690          isSkipPaddingBlankHTML: true
19691        }) : null;
19692
19693        var middleList = dom.splitTree(headList, {
19694          node: head.parentNode,
19695          offset: dom.position(head)
19696        }, {
19697          isSkipPaddingBlankHTML: true
19698        });
19699
19700        paras = isEscapseToBody ? dom.listDescendant(middleList, dom.isLi) :
19701                                  list.from(middleList.childNodes).filter(dom.isLi);
19702
19703        // LI to P
19704        if (isEscapseToBody || !dom.isList(headList.parentNode)) {
19705          paras = paras.map(function (para) {
19706            return dom.replace(para, 'P');
19707          });
19708        }
19709
19710        $.each(list.from(paras).reverse(), function (idx, para) {
19711          dom.insertAfter(para, headList);
19712        });
19713
19714        // remove empty lists
19715        var rootLists = list.compact([headList, middleList, lastList]);
19716        $.each(rootLists, function (idx, rootList) {
19717          var listNodes = [rootList].concat(dom.listDescendant(rootList, dom.isList));
19718          $.each(listNodes.reverse(), function (idx, listNode) {
19719            if (!dom.nodeLength(listNode)) {
19720              dom.remove(listNode, true);
19721            }
19722          });
19723        });
19724
19725        releasedParas = releasedParas.concat(paras);
19726      });
19727
19728      return releasedParas;
19729    };
19730  };
19731
19732
19733  /**
19734   * @class editing.Typing
19735   *
19736   * Typing
19737   *
19738   */
19739  var Typing = function () {
19740
19741    // a Bullet instance to toggle lists off
19742    var bullet = new Bullet();
19743
19744    /**
19745     * insert tab
19746     *
19747     * @param {WrappedRange} rng
19748     * @param {Number} tabsize
19749     */
19750    this.insertTab = function (rng, tabsize) {
19751      var tab = dom.createText(new Array(tabsize + 1).join(dom.NBSP_CHAR));
19752      rng = rng.deleteContents();
19753      rng.insertNode(tab, true);
19754
19755      rng = range.create(tab, tabsize);
19756      rng.select();
19757    };
19758
19759    /**
19760     * insert paragraph
19761     */
19762    this.insertParagraph = function (editable) {
19763      var rng = range.create(editable);
19764
19765      // deleteContents on range.
19766      rng = rng.deleteContents();
19767
19768      // Wrap range if it needs to be wrapped by paragraph
19769      rng = rng.wrapBodyInlineWithPara();
19770
19771      // finding paragraph
19772      var splitRoot = dom.ancestor(rng.sc, dom.isPara);
19773
19774      var nextPara;
19775      // on paragraph: split paragraph
19776      if (splitRoot) {
19777        // if it is an empty line with li
19778        if (dom.isEmpty(splitRoot) && dom.isLi(splitRoot)) {
19779          // toogle UL/OL and escape
19780          bullet.toggleList(splitRoot.parentNode.nodeName);
19781          return;
19782        // if it is an empty line with para on blockquote
19783        } else if (dom.isEmpty(splitRoot) && dom.isPara(splitRoot) && dom.isBlockquote(splitRoot.parentNode)) {
19784          // escape blockquote
19785          dom.insertAfter(splitRoot, splitRoot.parentNode);
19786          nextPara = splitRoot;
19787        // if new line has content (not a line break)
19788        } else {
19789          nextPara = dom.splitTree(splitRoot, rng.getStartPoint());
19790
19791          var emptyAnchors = dom.listDescendant(splitRoot, dom.isEmptyAnchor);
19792          emptyAnchors = emptyAnchors.concat(dom.listDescendant(nextPara, dom.isEmptyAnchor));
19793
19794          $.each(emptyAnchors, function (idx, anchor) {
19795            dom.remove(anchor);
19796          });
19797
19798          // replace empty heading or pre with P tag
19799          if ((dom.isHeading(nextPara) || dom.isPre(nextPara)) && dom.isEmpty(nextPara)) {
19800            nextPara = dom.replace(nextPara, 'p');
19801          }
19802        }
19803      // no paragraph: insert empty paragraph
19804      } else {
19805        var next = rng.sc.childNodes[rng.so];
19806        nextPara = $(dom.emptyPara)[0];
19807        if (next) {
19808          rng.sc.insertBefore(nextPara, next);
19809        } else {
19810          rng.sc.appendChild(nextPara);
19811        }
19812      }
19813
19814      range.create(nextPara, 0).normalize().select().scrollIntoView(editable);
19815    };
19816  };
19817
19818  /**
19819   * @class editing.Table
19820   *
19821   * Table
19822   *
19823   */
19824  var Table = function () {
19825    /**
19826     * handle tab key
19827     *
19828     * @param {WrappedRange} rng
19829     * @param {Boolean} isShift
19830     */
19831    this.tab = function (rng, isShift) {
19832      var cell = dom.ancestor(rng.commonAncestor(), dom.isCell);
19833      var table = dom.ancestor(cell, dom.isTable);
19834      var cells = dom.listDescendant(table, dom.isCell);
19835
19836      var nextCell = list[isShift ? 'prev' : 'next'](cells, cell);
19837      if (nextCell) {
19838        range.create(nextCell, 0).select();
19839      }
19840    };
19841
19842    /**
19843     * create empty table element
19844     *
19845     * @param {Number} rowCount
19846     * @param {Number} colCount
19847     * @return {Node}
19848     */
19849    this.createTable = function (colCount, rowCount, options) {
19850      var tds = [], tdHTML;
19851      for (var idxCol = 0; idxCol < colCount; idxCol++) {
19852        tds.push('<td>' + dom.blank + '</td>');
19853      }
19854      tdHTML = tds.join('');
19855
19856      var trs = [], trHTML;
19857      for (var idxRow = 0; idxRow < rowCount; idxRow++) {
19858        trs.push('<tr>' + tdHTML + '</tr>');
19859      }
19860      trHTML = trs.join('');
19861      var $table = $('<table>' + trHTML + '</table>');
19862      if (options && options.tableClassName) {
19863        $table.addClass(options.tableClassName);
19864      }
19865
19866      return $table[0];
19867    };
19868  };
19869
19870
19871  var KEY_BOGUS = 'bogus';
19872
19873  /**
19874   * @class Editor
19875   */
19876  var Editor = function (context) {
19877    var self = this;
19878
19879    var $note = context.layoutInfo.note;
19880    var $editor = context.layoutInfo.editor;
19881    var $editable = context.layoutInfo.editable;
19882    var options = context.options;
19883    var lang = options.langInfo;
19884
19885    var editable = $editable[0];
19886    var lastRange = null;
19887
19888    var style = new Style();
19889    var table = new Table();
19890    var typing = new Typing();
19891    var bullet = new Bullet();
19892    var history = new History($editable);
19893
19894    this.initialize = function () {
19895      // bind custom events
19896      $editable.on('keydown', function (event) {
19897        if (event.keyCode === key.code.ENTER) {
19898          context.triggerEvent('enter', event);
19899        }
19900        context.triggerEvent('keydown', event);
19901
19902        if (!event.isDefaultPrevented()) {
19903          if (options.shortcuts) {
19904            self.handleKeyMap(event);
19905          } else {
19906            self.preventDefaultEditableShortCuts(event);
19907          }
19908        }
19909      }).on('keyup', function (event) {
19910        context.triggerEvent('keyup', event);
19911      }).on('focus', function (event) {
19912        context.triggerEvent('focus', event);
19913      }).on('blur', function (event) {
19914        context.triggerEvent('blur', event);
19915      }).on('mousedown', function (event) {
19916        context.triggerEvent('mousedown', event);
19917      }).on('mouseup', function (event) {
19918        context.triggerEvent('mouseup', event);
19919      }).on('scroll', function (event) {
19920        context.triggerEvent('scroll', event);
19921      }).on('paste', function (event) {
19922        context.triggerEvent('paste', event);
19923      });
19924
19925      // init content before set event
19926      $editable.html(dom.html($note) || dom.emptyPara);
19927
19928      // [workaround] IE doesn't have input events for contentEditable
19929      // - see: https://goo.gl/4bfIvA
19930      var changeEventName = agent.isMSIE ? 'DOMCharacterDataModified DOMSubtreeModified DOMNodeInserted' : 'input';
19931      $editable.on(changeEventName, func.debounce(function () {
19932        context.triggerEvent('change', $editable.html());
19933      }, 250));
19934
19935      $editor.on('focusin', function (event) {
19936        context.triggerEvent('focusin', event);
19937      }).on('focusout', function (event) {
19938        context.triggerEvent('focusout', event);
19939      });
19940
19941      if (!options.airMode) {
19942        if (options.width) {
19943          $editor.outerWidth(options.width);
19944        }
19945        if (options.height) {
19946          $editable.outerHeight(options.height);
19947        }
19948        if (options.maxHeight) {
19949          $editable.css('max-height', options.maxHeight);
19950        }
19951        if (options.minHeight) {
19952          $editable.css('min-height', options.minHeight);
19953        }
19954      }
19955
19956      history.recordUndo();
19957    };
19958
19959    this.destroy = function () {
19960      $editable.off();
19961    };
19962
19963    this.handleKeyMap = function (event) {
19964      var keyMap = options.keyMap[agent.isMac ? 'mac' : 'pc'];
19965      var keys = [];
19966
19967      if (event.metaKey) { keys.push('CMD'); }
19968      if (event.ctrlKey && !event.altKey) { keys.push('CTRL'); }
19969      if (event.shiftKey) { keys.push('SHIFT'); }
19970
19971      var keyName = key.nameFromCode[event.keyCode];
19972      if (keyName) {
19973        keys.push(keyName);
19974      }
19975
19976      var eventName = keyMap[keys.join('+')];
19977      if (eventName) {
19978        event.preventDefault();
19979        context.invoke(eventName);
19980      } else if (key.isEdit(event.keyCode)) {
19981        this.afterCommand();
19982      }
19983    };
19984
19985    this.preventDefaultEditableShortCuts = function (event) {
19986      // B(Bold, 66) / I(Italic, 73) / U(Underline, 85)
19987      if ((event.ctrlKey || event.metaKey) &&
19988        list.contains([66, 73, 85], event.keyCode)) {
19989        event.preventDefault();
19990      }
19991    };
19992
19993    /**
19994     * create range
19995     * @return {WrappedRange}
19996     */
19997    this.createRange = function () {
19998      this.focus();
19999      return range.create(editable);
20000    };
20001
20002    /**
20003     * saveRange
20004     *
20005     * save current range
20006     *
20007     * @param {Boolean} [thenCollapse=false]
20008     */
20009    this.saveRange = function (thenCollapse) {
20010      lastRange = this.createRange();
20011      if (thenCollapse) {
20012        lastRange.collapse().select();
20013      }
20014    };
20015
20016    /**
20017     * restoreRange
20018     *
20019     * restore lately range
20020     */
20021    this.restoreRange = function () {
20022      if (lastRange) {
20023        lastRange.select();
20024        this.focus();
20025      }
20026    };
20027
20028    this.saveTarget = function (node) {
20029      $editable.data('target', node);
20030    };
20031
20032    this.clearTarget = function () {
20033      $editable.removeData('target');
20034    };
20035
20036    this.restoreTarget = function () {
20037      return $editable.data('target');
20038    };
20039
20040    /**
20041     * currentStyle
20042     *
20043     * current style
20044     * @return {Object|Boolean} unfocus
20045     */
20046    this.currentStyle = function () {
20047      var rng = range.create();
20048      if (rng) {
20049        rng = rng.normalize();
20050      }
20051      return rng ? style.current(rng) : style.fromNode($editable);
20052    };
20053
20054    /**
20055     * style from node
20056     *
20057     * @param {jQuery} $node
20058     * @return {Object}
20059     */
20060    this.styleFromNode = function ($node) {
20061      return style.fromNode($node);
20062    };
20063
20064    /**
20065     * undo
20066     */
20067    this.undo = function () {
20068      context.triggerEvent('before.command', $editable.html());
20069      history.undo();
20070      context.triggerEvent('change', $editable.html());
20071    };
20072    context.memo('help.undo', lang.help.undo);
20073
20074    /**
20075     * redo
20076     */
20077    this.redo = function () {
20078      context.triggerEvent('before.command', $editable.html());
20079      history.redo();
20080      context.triggerEvent('change', $editable.html());
20081    };
20082    context.memo('help.redo', lang.help.redo);
20083
20084    /**
20085     * before command
20086     */
20087    var beforeCommand = this.beforeCommand = function () {
20088      context.triggerEvent('before.command', $editable.html());
20089      // keep focus on editable before command execution
20090      self.focus();
20091    };
20092
20093    /**
20094     * after command
20095     * @param {Boolean} isPreventTrigger
20096     */
20097    var afterCommand = this.afterCommand = function (isPreventTrigger) {
20098      history.recordUndo();
20099      if (!isPreventTrigger) {
20100        context.triggerEvent('change', $editable.html());
20101      }
20102    };
20103
20104    /* jshint ignore:start */
20105    // native commands(with execCommand), generate function for execCommand
20106    var commands = ['bold', 'italic', 'underline', 'strikethrough', 'superscript', 'subscript',
20107                    'justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull',
20108                    'formatBlock', 'removeFormat',
20109                    'backColor', 'foreColor', 'fontName'];
20110
20111    for (var idx = 0, len = commands.length; idx < len; idx ++) {
20112      this[commands[idx]] = (function (sCmd) {
20113        return function (value) {
20114          beforeCommand();
20115          document.execCommand(sCmd, false, value);
20116          afterCommand(true);
20117        };
20118      })(commands[idx]);
20119      context.memo('help.' + commands[idx], lang.help[commands[idx]]);
20120    }
20121    /* jshint ignore:end */
20122
20123    /**
20124     * handle tab key
20125     */
20126    this.tab = function () {
20127      var rng = this.createRange();
20128      if (rng.isCollapsed() && rng.isOnCell()) {
20129        table.tab(rng);
20130      } else {
20131        beforeCommand();
20132        typing.insertTab(rng, options.tabSize);
20133        afterCommand();
20134      }
20135    };
20136    context.memo('help.tab', lang.help.tab);
20137
20138    /**
20139     * handle shift+tab key
20140     */
20141    this.untab = function () {
20142      var rng = this.createRange();
20143      if (rng.isCollapsed() && rng.isOnCell()) {
20144        table.tab(rng, true);
20145      }
20146    };
20147    context.memo('help.untab', lang.help.untab);
20148
20149    /**
20150     * run given function between beforeCommand and afterCommand
20151     */
20152    this.wrapCommand = function (fn) {
20153      return function () {
20154        beforeCommand();
20155        fn.apply(self, arguments);
20156        afterCommand();
20157      };
20158    };
20159
20160    /**
20161     * insert paragraph
20162     */
20163    this.insertParagraph = this.wrapCommand(function () {
20164      typing.insertParagraph(editable);
20165    });
20166    context.memo('help.insertParagraph', lang.help.insertParagraph);
20167
20168    this.insertOrderedList = this.wrapCommand(function () {
20169      bullet.insertOrderedList(editable);
20170    });
20171    context.memo('help.insertOrderedList', lang.help.insertOrderedList);
20172
20173    this.insertUnorderedList = this.wrapCommand(function () {
20174      bullet.insertUnorderedList(editable);
20175    });
20176    context.memo('help.insertUnorderedList', lang.help.insertUnorderedList);
20177
20178    this.indent = this.wrapCommand(function () {
20179      bullet.indent(editable);
20180    });
20181    context.memo('help.indent', lang.help.indent);
20182
20183    this.outdent = this.wrapCommand(function () {
20184      bullet.outdent(editable);
20185    });
20186    context.memo('help.outdent', lang.help.outdent);
20187
20188    /**
20189     * insert image
20190     *
20191     * @param {String} src
20192     * @param {String|Function} param
20193     * @return {Promise}
20194     */
20195    this.insertImage = function (src, param) {
20196      return async.createImage(src, param).then(function ($image) {
20197        beforeCommand();
20198
20199        if (typeof param === 'function') {
20200          param($image);
20201        } else {
20202          if (typeof param === 'string') {
20203            $image.attr('data-filename', param);
20204          }
20205          $image.css('width', Math.min($editable.width(), $image.width()));
20206        }
20207
20208        $image.show();
20209        range.create(editable).insertNode($image[0]);
20210        range.createFromNodeAfter($image[0]).select();
20211        afterCommand();
20212      }).fail(function (e) {
20213        context.triggerEvent('image.upload.error', e);
20214      });
20215    };
20216
20217    /**
20218     * insertImages
20219     * @param {File[]} files
20220     */
20221    this.insertImages = function (files) {
20222      $.each(files, function (idx, file) {
20223        var filename = file.name;
20224        if (options.maximumImageFileSize && options.maximumImageFileSize < file.size) {
20225          context.triggerEvent('image.upload.error', lang.image.maximumFileSizeError);
20226        } else {
20227          async.readFileAsDataURL(file).then(function (dataURL) {
20228            return self.insertImage(dataURL, filename);
20229          }).fail(function () {
20230            context.triggerEvent('image.upload.error');
20231          });
20232        }
20233      });
20234    };
20235
20236    /**
20237     * insertImagesOrCallback
20238     * @param {File[]} files
20239     */
20240    this.insertImagesOrCallback = function (files) {
20241      var callbacks = options.callbacks;
20242
20243      // If onImageUpload options setted
20244      if (callbacks.onImageUpload) {
20245        context.triggerEvent('image.upload', files);
20246      // else insert Image as dataURL
20247      } else {
20248        this.insertImages(files);
20249      }
20250    };
20251
20252    /**
20253     * insertNode
20254     * insert node
20255     * @param {Node} node
20256     */
20257    this.insertNode = this.wrapCommand(function (node) {
20258      var rng = this.createRange();
20259      rng.insertNode(node);
20260      range.createFromNodeAfter(node).select();
20261    });
20262
20263    /**
20264     * insert text
20265     * @param {String} text
20266     */
20267    this.insertText = this.wrapCommand(function (text) {
20268      var rng = this.createRange();
20269      var textNode = rng.insertNode(dom.createText(text));
20270      range.create(textNode, dom.nodeLength(textNode)).select();
20271    });
20272
20273    /**
20274     * return selected plain text
20275     * @return {String} text
20276     */
20277    this.getSelectedText = function () {
20278      var rng = this.createRange();
20279
20280      // if range on anchor, expand range with anchor
20281      if (rng.isOnAnchor()) {
20282        rng = range.createFromNode(dom.ancestor(rng.sc, dom.isAnchor));
20283      }
20284
20285      return rng.toString();
20286    };
20287
20288    /**
20289     * paste HTML
20290     * @param {String} markup
20291     */
20292    this.pasteHTML = this.wrapCommand(function (markup) {
20293      var contents = this.createRange().pasteHTML(markup);
20294      range.createFromNodeAfter(list.last(contents)).select();
20295    });
20296
20297    /**
20298     * formatBlock
20299     *
20300     * @param {String} tagName
20301     */
20302    this.formatBlock = this.wrapCommand(function (tagName) {
20303      // [workaround] for MSIE, IE need `<`
20304      tagName = agent.isMSIE ? '<' + tagName + '>' : tagName;
20305      document.execCommand('FormatBlock', false, tagName);
20306    });
20307
20308    this.formatPara = function () {
20309      this.formatBlock('P');
20310    };
20311    context.memo('help.formatPara', lang.help.formatPara);
20312
20313    /* jshint ignore:start */
20314    for (var idx = 1; idx <= 6; idx ++) {
20315      this['formatH' + idx] = function (idx) {
20316        return function () {
20317          this.formatBlock('H' + idx);
20318        };
20319      }(idx);
20320      context.memo('help.formatH'+idx, lang.help['formatH' + idx]);
20321    };
20322    /* jshint ignore:end */
20323
20324    /**
20325     * fontSize
20326     *
20327     * @param {String} value - px
20328     */
20329    this.fontSize = function (value) {
20330      var rng = this.createRange();
20331
20332      if (rng && rng.isCollapsed()) {
20333        var spans = style.styleNodes(rng);
20334        var firstSpan = list.head(spans);
20335
20336        $(spans).css({
20337          'font-size': value + 'px'
20338        });
20339
20340        // [workaround] added styled bogus span for style
20341        //  - also bogus character needed for cursor position
20342        if (firstSpan && !dom.nodeLength(firstSpan)) {
20343          firstSpan.innerHTML = dom.ZERO_WIDTH_NBSP_CHAR;
20344          range.createFromNodeAfter(firstSpan.firstChild).select();
20345          $editable.data(KEY_BOGUS, firstSpan);
20346        }
20347      } else {
20348        beforeCommand();
20349        $(style.styleNodes(rng)).css({
20350          'font-size': value + 'px'
20351        });
20352        afterCommand();
20353      }
20354    };
20355
20356    /**
20357     * insert horizontal rule
20358     */
20359    this.insertHorizontalRule = this.wrapCommand(function () {
20360      var hrNode = this.createRange().insertNode(dom.create('HR'));
20361      if (hrNode.nextSibling) {
20362        range.create(hrNode.nextSibling, 0).normalize().select();
20363      }
20364    });
20365    context.memo('help.insertHorizontalRule', lang.help.insertHorizontalRule);
20366
20367    /**
20368     * remove bogus node and character
20369     */
20370    this.removeBogus = function () {
20371      var bogusNode = $editable.data(KEY_BOGUS);
20372      if (!bogusNode) {
20373        return;
20374      }
20375
20376      var textNode = list.find(list.from(bogusNode.childNodes), dom.isText);
20377
20378      var bogusCharIdx = textNode.nodeValue.indexOf(dom.ZERO_WIDTH_NBSP_CHAR);
20379      if (bogusCharIdx !== -1) {
20380        textNode.deleteData(bogusCharIdx, 1);
20381      }
20382
20383      if (dom.isEmpty(bogusNode)) {
20384        dom.remove(bogusNode);
20385      }
20386
20387      $editable.removeData(KEY_BOGUS);
20388    };
20389
20390    /**
20391     * lineHeight
20392     * @param {String} value
20393     */
20394    this.lineHeight = this.wrapCommand(function (value) {
20395      style.stylePara(this.createRange(), {
20396        lineHeight: value
20397      });
20398    });
20399
20400    /**
20401     * unlink
20402     *
20403     * @type command
20404     */
20405    this.unlink = function () {
20406      var rng = this.createRange();
20407      if (rng.isOnAnchor()) {
20408        var anchor = dom.ancestor(rng.sc, dom.isAnchor);
20409        rng = range.createFromNode(anchor);
20410        rng.select();
20411
20412        beforeCommand();
20413        document.execCommand('unlink');
20414        afterCommand();
20415      }
20416    };
20417
20418    /**
20419     * create link (command)
20420     *
20421     * @param {Object} linkInfo
20422     */
20423    this.createLink = this.wrapCommand(function (linkInfo) {
20424      var linkUrl = linkInfo.url;
20425      var linkText = linkInfo.text;
20426      var isNewWindow = linkInfo.isNewWindow;
20427      var rng = linkInfo.range || this.createRange();
20428      var isTextChanged = rng.toString() !== linkText;
20429
20430      // handle spaced urls from input
20431      if (typeof linkUrl === 'string') {
20432        linkUrl = linkUrl.trim();
20433      }
20434
20435      if (options.onCreateLink) {
20436        linkUrl = options.onCreateLink(linkUrl);
20437      }
20438
20439      var anchors = [];
20440      if (isTextChanged) {
20441        rng = rng.deleteContents();
20442        var anchor = rng.insertNode($('<A>' + linkText + '</A>')[0]);
20443        anchors.push(anchor);
20444      } else {
20445        anchors = style.styleNodes(rng, {
20446          nodeName: 'A',
20447          expandClosestSibling: true,
20448          onlyPartialContains: true
20449        });
20450      }
20451
20452      $.each(anchors, function (idx, anchor) {
20453        // if url doesn't match an URL schema, set http:// as default
20454        linkUrl = /^[A-Za-z][A-Za-z0-9+-.]*\:[\/\/]?/.test(linkUrl) ?
20455          linkUrl : 'http://' + linkUrl;
20456
20457        $(anchor).attr('href', linkUrl);
20458        if (isNewWindow) {
20459          $(anchor).attr('target', '_blank');
20460        } else {
20461          $(anchor).removeAttr('target');
20462        }
20463      });
20464
20465      var startRange = range.createFromNodeBefore(list.head(anchors));
20466      var startPoint = startRange.getStartPoint();
20467      var endRange = range.createFromNodeAfter(list.last(anchors));
20468      var endPoint = endRange.getEndPoint();
20469
20470      range.create(
20471        startPoint.node,
20472        startPoint.offset,
20473        endPoint.node,
20474        endPoint.offset
20475      ).select();
20476    });
20477
20478    /**
20479     * returns link info
20480     *
20481     * @return {Object}
20482     * @return {WrappedRange} return.range
20483     * @return {String} return.text
20484     * @return {Boolean} [return.isNewWindow=true]
20485     * @return {String} [return.url=""]
20486     */
20487    this.getLinkInfo = function () {
20488      var rng = this.createRange().expand(dom.isAnchor);
20489
20490      // Get the first anchor on range(for edit).
20491      var $anchor = $(list.head(rng.nodes(dom.isAnchor)));
20492
20493      return {
20494        range: rng,
20495        text: rng.toString(),
20496        isNewWindow: $anchor.length ? $anchor.attr('target') === '_blank' : false,
20497        url: $anchor.length ? $anchor.attr('href') : ''
20498      };
20499    };
20500
20501    /**
20502     * setting color
20503     *
20504     * @param {Object} sObjColor  color code
20505     * @param {String} sObjColor.foreColor foreground color
20506     * @param {String} sObjColor.backColor background color
20507     */
20508    this.color = this.wrapCommand(function (colorInfo) {
20509      var foreColor = colorInfo.foreColor;
20510      var backColor = colorInfo.backColor;
20511
20512      if (foreColor) { document.execCommand('foreColor', false, foreColor); }
20513      if (backColor) { document.execCommand('backColor', false, backColor); }
20514    });
20515
20516    /**
20517     * insert Table
20518     *
20519     * @param {String} dimension of table (ex : "5x5")
20520     */
20521    this.insertTable = this.wrapCommand(function (dim) {
20522      var dimension = dim.split('x');
20523
20524      var rng = this.createRange().deleteContents();
20525      rng.insertNode(table.createTable(dimension[0], dimension[1], options));
20526    });
20527
20528    /**
20529     * float me
20530     *
20531     * @param {String} value
20532     */
20533    this.floatMe = this.wrapCommand(function (value) {
20534      var $target = $(this.restoreTarget());
20535      $target.css('float', value);
20536    });
20537
20538    /**
20539     * resize overlay element
20540     * @param {String} value
20541     */
20542    this.resize = this.wrapCommand(function (value) {
20543      var $target = $(this.restoreTarget());
20544      $target.css({
20545        width: value * 100 + '%',
20546        height: ''
20547      });
20548    });
20549
20550    /**
20551     * @param {Position} pos
20552     * @param {jQuery} $target - target element
20553     * @param {Boolean} [bKeepRatio] - keep ratio
20554     */
20555    this.resizeTo = function (pos, $target, bKeepRatio) {
20556      var imageSize;
20557      if (bKeepRatio) {
20558        var newRatio = pos.y / pos.x;
20559        var ratio = $target.data('ratio');
20560        imageSize = {
20561          width: ratio > newRatio ? pos.x : pos.y / ratio,
20562          height: ratio > newRatio ? pos.x * ratio : pos.y
20563        };
20564      } else {
20565        imageSize = {
20566          width: pos.x,
20567          height: pos.y
20568        };
20569      }
20570
20571      $target.css(imageSize);
20572    };
20573
20574    /**
20575     * remove media object
20576     */
20577    this.removeMedia = this.wrapCommand(function () {
20578      var $target = $(this.restoreTarget()).detach();
20579      context.triggerEvent('media.delete', $target, $editable);
20580    });
20581
20582    /**
20583     * returns whether editable area has focus or not.
20584     */
20585    this.hasFocus = function () {
20586      return $editable.is(':focus');
20587    };
20588
20589    /**
20590     * set focus
20591     */
20592    this.focus = function () {
20593      // [workaround] Screen will move when page is scolled in IE.
20594      //  - do focus when not focused
20595      if (!this.hasFocus()) {
20596        $editable.focus();
20597      }
20598    };
20599
20600    /**
20601     * returns whether contents is empty or not.
20602     * @return {Boolean}
20603     */
20604    this.isEmpty = function () {
20605      return dom.isEmpty($editable[0]) || dom.emptyPara === $editable.html();
20606    };
20607
20608    /**
20609     * Removes all contents and restores the editable instance to an _emptyPara_.
20610     */
20611    this.empty = function () {
20612      context.invoke('code', dom.emptyPara);
20613    };
20614  };
20615
20616  var Clipboard = function (context) {
20617    var self = this;
20618
20619    var $editable = context.layoutInfo.editable;
20620
20621    this.events = {
20622      'summernote.keydown': function (we, e) {
20623        if (self.needKeydownHook()) {
20624          if ((e.ctrlKey || e.metaKey) && e.keyCode === key.code.V) {
20625            context.invoke('editor.saveRange');
20626            self.$paste.focus();
20627
20628            setTimeout(function () {
20629              self.pasteByHook();
20630            }, 0);
20631          }
20632        }
20633      }
20634    };
20635
20636    this.needKeydownHook = function () {
20637      return (agent.isMSIE && agent.browserVersion > 10) || agent.isFF;
20638    };
20639
20640    this.initialize = function () {
20641      // [workaround] getting image from clipboard
20642      //  - IE11 and Firefox: CTRL+v hook
20643      //  - Webkit: event.clipboardData
20644      if (this.needKeydownHook()) {
20645        this.$paste = $('<div tabindex="-1" />').attr('contenteditable', true).css({
20646          position: 'absolute',
20647          left: -100000,
20648          opacity: 0
20649        });
20650        $editable.before(this.$paste);
20651
20652        this.$paste.on('paste', function (event) {
20653          context.triggerEvent('paste', event);
20654        });
20655      } else {
20656        $editable.on('paste', this.pasteByEvent);
20657      }
20658    };
20659
20660    this.destroy = function () {
20661      if (this.needKeydownHook()) {
20662        this.$paste.remove();
20663        this.$paste = null;
20664      }
20665    };
20666
20667    this.pasteByHook = function () {
20668      var node = this.$paste[0].firstChild;
20669
20670      if (dom.isImg(node)) {
20671        var dataURI = node.src;
20672        var decodedData = atob(dataURI.split(',')[1]);
20673        var array = new Uint8Array(decodedData.length);
20674        for (var i = 0; i < decodedData.length; i++) {
20675          array[i] = decodedData.charCodeAt(i);
20676        }
20677
20678        var blob = new Blob([array], { type: 'image/png' });
20679        blob.name = 'clipboard.png';
20680
20681        context.invoke('editor.restoreRange');
20682        context.invoke('editor.focus');
20683        context.invoke('editor.insertImagesOrCallback', [blob]);
20684      } else {
20685        var pasteContent = $('<div />').html(this.$paste.html()).html();
20686        context.invoke('editor.restoreRange');
20687        context.invoke('editor.focus');
20688
20689        if (pasteContent) {
20690          context.invoke('editor.pasteHTML', pasteContent);
20691        }
20692      }
20693
20694      this.$paste.empty();
20695    };
20696
20697    /**
20698     * paste by clipboard event
20699     *
20700     * @param {Event} event
20701     */
20702    this.pasteByEvent = function (event) {
20703      var clipboardData = event.originalEvent.clipboardData;
20704      if (clipboardData && clipboardData.items && clipboardData.items.length) {
20705        var item = list.head(clipboardData.items);
20706        if (item.kind === 'file' && item.type.indexOf('image/') !== -1) {
20707          context.invoke('editor.insertImagesOrCallback', [item.getAsFile()]);
20708        }
20709        context.invoke('editor.afterCommand');
20710      }
20711    };
20712  };
20713
20714  var Dropzone = function (context) {
20715    var $document = $(document);
20716    var $editor = context.layoutInfo.editor;
20717    var $editable = context.layoutInfo.editable;
20718    var options = context.options;
20719    var lang = options.langInfo;
20720    var documentEventHandlers = {};
20721
20722    var $dropzone = $([
20723      '<div class="note-dropzone">',
20724      '  <div class="note-dropzone-message"/>',
20725      '</div>'
20726    ].join('')).prependTo($editor);
20727
20728    var detachDocumentEvent = function () {
20729      Object.keys(documentEventHandlers).forEach(function (key) {
20730        $document.off(key.substr(2).toLowerCase(), documentEventHandlers[key]);
20731      });
20732      documentEventHandlers = {};
20733    };
20734
20735    /**
20736     * attach Drag and Drop Events
20737     */
20738    this.initialize = function () {
20739      if (options.disableDragAndDrop) {
20740        // prevent default drop event
20741        documentEventHandlers.onDrop = function (e) {
20742          e.preventDefault();
20743        };
20744        $document.on('drop', documentEventHandlers.onDrop);
20745      } else {
20746        this.attachDragAndDropEvent();
20747      }
20748    };
20749
20750    /**
20751     * attach Drag and Drop Events
20752     */
20753    this.attachDragAndDropEvent = function () {
20754      var collection = $(),
20755          $dropzoneMessage = $dropzone.find('.note-dropzone-message');
20756
20757      documentEventHandlers.onDragenter = function (e) {
20758        var isCodeview = context.invoke('codeview.isActivated');
20759        var hasEditorSize = $editor.width() > 0 && $editor.height() > 0;
20760        if (!isCodeview && !collection.length && hasEditorSize) {
20761          $editor.addClass('dragover');
20762          $dropzone.width($editor.width());
20763          $dropzone.height($editor.height());
20764          $dropzoneMessage.text(lang.image.dragImageHere);
20765        }
20766        collection = collection.add(e.target);
20767      };
20768
20769      documentEventHandlers.onDragleave = function (e) {
20770        collection = collection.not(e.target);
20771        if (!collection.length) {
20772          $editor.removeClass('dragover');
20773        }
20774      };
20775
20776      documentEventHandlers.onDrop = function () {
20777        collection = $();
20778        $editor.removeClass('dragover');
20779      };
20780
20781      // show dropzone on dragenter when dragging a object to document
20782      // -but only if the editor is visible, i.e. has a positive width and height
20783      $document.on('dragenter', documentEventHandlers.onDragenter)
20784        .on('dragleave', documentEventHandlers.onDragleave)
20785        .on('drop', documentEventHandlers.onDrop);
20786
20787      // change dropzone's message on hover.
20788      $dropzone.on('dragenter', function () {
20789        $dropzone.addClass('hover');
20790        $dropzoneMessage.text(lang.image.dropImage);
20791      }).on('dragleave', function () {
20792        $dropzone.removeClass('hover');
20793        $dropzoneMessage.text(lang.image.dragImageHere);
20794      });
20795
20796      // attach dropImage
20797      $dropzone.on('drop', function (event) {
20798        var dataTransfer = event.originalEvent.dataTransfer;
20799
20800        if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {
20801          event.preventDefault();
20802          $editable.focus();
20803          context.invoke('editor.insertImagesOrCallback', dataTransfer.files);
20804        } else {
20805          $.each(dataTransfer.types, function (idx, type) {
20806            var content = dataTransfer.getData(type);
20807
20808            if (type.toLowerCase().indexOf('text') > -1) {
20809              context.invoke('editor.pasteHTML', content);
20810            } else {
20811              $(content).each(function () {
20812                context.invoke('editor.insertNode', this);
20813              });
20814            }
20815          });
20816        }
20817      }).on('dragover', false); // prevent default dragover event
20818    };
20819
20820    this.destroy = function () {
20821      detachDocumentEvent();
20822    };
20823  };
20824
20825
20826  var CodeMirror;
20827  if (agent.hasCodeMirror) {
20828    if (agent.isSupportAmd) {
20829      require(['codemirror'], function (cm) {
20830        CodeMirror = cm;
20831      });
20832    } else {
20833      CodeMirror = window.CodeMirror;
20834    }
20835  }
20836
20837  /**
20838   * @class Codeview
20839   */
20840  var Codeview = function (context) {
20841    var $editor = context.layoutInfo.editor;
20842    var $editable = context.layoutInfo.editable;
20843    var $codable = context.layoutInfo.codable;
20844    var options = context.options;
20845
20846    this.sync = function () {
20847      var isCodeview = this.isActivated();
20848      if (isCodeview && agent.hasCodeMirror) {
20849        $codable.data('cmEditor').save();
20850      }
20851    };
20852
20853    /**
20854     * @return {Boolean}
20855     */
20856    this.isActivated = function () {
20857      return $editor.hasClass('codeview');
20858    };
20859
20860    /**
20861     * toggle codeview
20862     */
20863    this.toggle = function () {
20864      if (this.isActivated()) {
20865        this.deactivate();
20866      } else {
20867        this.activate();
20868      }
20869      context.triggerEvent('codeview.toggled');
20870    };
20871
20872    /**
20873     * activate code view
20874     */
20875    this.activate = function () {
20876      $codable.val(dom.html($editable, options.prettifyHtml));
20877      $codable.height($editable.height());
20878
20879      context.invoke('toolbar.updateCodeview', true);
20880      $editor.addClass('codeview');
20881      $codable.focus();
20882
20883      // activate CodeMirror as codable
20884      if (agent.hasCodeMirror) {
20885        var cmEditor = CodeMirror.fromTextArea($codable[0], options.codemirror);
20886
20887        // CodeMirror TernServer
20888        if (options.codemirror.tern) {
20889          var server = new CodeMirror.TernServer(options.codemirror.tern);
20890          cmEditor.ternServer = server;
20891          cmEditor.on('cursorActivity', function (cm) {
20892            server.updateArgHints(cm);
20893          });
20894        }
20895
20896        // CodeMirror hasn't Padding.
20897        cmEditor.setSize(null, $editable.outerHeight());
20898        $codable.data('cmEditor', cmEditor);
20899      }
20900    };
20901
20902    /**
20903     * deactivate code view
20904     */
20905    this.deactivate = function () {
20906      // deactivate CodeMirror as codable
20907      if (agent.hasCodeMirror) {
20908        var cmEditor = $codable.data('cmEditor');
20909        $codable.val(cmEditor.getValue());
20910        cmEditor.toTextArea();
20911      }
20912
20913      var value = dom.value($codable, options.prettifyHtml) || dom.emptyPara;
20914      var isChange = $editable.html() !== value;
20915
20916      $editable.html(value);
20917      $editable.height(options.height ? $codable.height() : 'auto');
20918      $editor.removeClass('codeview');
20919
20920      if (isChange) {
20921        context.triggerEvent('change', $editable.html(), $editable);
20922      }
20923
20924      $editable.focus();
20925
20926      context.invoke('toolbar.updateCodeview', false);
20927    };
20928
20929    this.destroy = function () {
20930      if (this.isActivated()) {
20931        this.deactivate();
20932      }
20933    };
20934  };
20935
20936  var EDITABLE_PADDING = 24;
20937
20938  var Statusbar = function (context) {
20939    var $document = $(document);
20940    var $statusbar = context.layoutInfo.statusbar;
20941    var $editable = context.layoutInfo.editable;
20942    var options = context.options;
20943
20944    this.initialize = function () {
20945      if (options.airMode || options.disableResizeEditor) {
20946        return;
20947      }
20948
20949      $statusbar.on('mousedown', function (event) {
20950        event.preventDefault();
20951        event.stopPropagation();
20952
20953        var editableTop = $editable.offset().top - $document.scrollTop();
20954
20955        $document.on('mousemove', function (event) {
20956          var height = event.clientY - (editableTop + EDITABLE_PADDING);
20957
20958          height = (options.minheight > 0) ? Math.max(height, options.minheight) : height;
20959          height = (options.maxHeight > 0) ? Math.min(height, options.maxHeight) : height;
20960
20961          $editable.height(height);
20962        }).one('mouseup', function () {
20963          $document.off('mousemove');
20964        });
20965      });
20966    };
20967
20968    this.destroy = function () {
20969      $statusbar.off();
20970      $statusbar.remove();
20971    };
20972  };
20973
20974  var Fullscreen = function (context) {
20975    var $editor = context.layoutInfo.editor;
20976    var $toolbar = context.layoutInfo.toolbar;
20977    var $editable = context.layoutInfo.editable;
20978    var $codable = context.layoutInfo.codable;
20979
20980    var $window = $(window);
20981    var $scrollbar = $('html, body');
20982
20983    /**
20984     * toggle fullscreen
20985     */
20986    this.toggle = function () {
20987      var resize = function (size) {
20988        $editable.css('height', size.h);
20989        $codable.css('height', size.h);
20990        if ($codable.data('cmeditor')) {
20991          $codable.data('cmeditor').setsize(null, size.h);
20992        }
20993      };
20994
20995      $editor.toggleClass('fullscreen');
20996      if (this.isFullscreen()) {
20997        $editable.data('orgHeight', $editable.css('height'));
20998
20999        $window.on('resize', function () {
21000          resize({
21001            h: $window.height() - $toolbar.outerHeight()
21002          });
21003        }).trigger('resize');
21004
21005        $scrollbar.css('overflow', 'hidden');
21006      } else {
21007        $window.off('resize');
21008        resize({
21009          h: $editable.data('orgHeight')
21010        });
21011        $scrollbar.css('overflow', 'visible');
21012      }
21013
21014      context.invoke('toolbar.updateFullscreen', this.isFullscreen());
21015    };
21016
21017    this.isFullscreen = function () {
21018      return $editor.hasClass('fullscreen');
21019    };
21020  };
21021
21022  var Handle = function (context) {
21023    var self = this;
21024
21025    var $document = $(document);
21026    var $editingArea = context.layoutInfo.editingArea;
21027    var options = context.options;
21028
21029    this.events = {
21030      'summernote.mousedown': function (we, e) {
21031        if (self.update(e.target)) {
21032          e.preventDefault();
21033        }
21034      },
21035      'summernote.keyup summernote.scroll summernote.change summernote.dialog.shown': function () {
21036        self.update();
21037      }
21038    };
21039
21040    this.initialize = function () {
21041      this.$handle = $([
21042        '<div class="note-handle">',
21043        '<div class="note-control-selection">',
21044        '<div class="note-control-selection-bg"></div>',
21045        '<div class="note-control-holder note-control-nw"></div>',
21046        '<div class="note-control-holder note-control-ne"></div>',
21047        '<div class="note-control-holder note-control-sw"></div>',
21048        '<div class="',
21049        (options.disableResizeImage ? 'note-control-holder' : 'note-control-sizing'),
21050        ' note-control-se"></div>',
21051        (options.disableResizeImage ? '' : '<div class="note-control-selection-info"></div>'),
21052        '</div>',
21053        '</div>'
21054      ].join('')).prependTo($editingArea);
21055
21056      this.$handle.on('mousedown', function (event) {
21057        if (dom.isControlSizing(event.target)) {
21058          event.preventDefault();
21059          event.stopPropagation();
21060
21061          var $target = self.$handle.find('.note-control-selection').data('target'),
21062              posStart = $target.offset(),
21063              scrollTop = $document.scrollTop();
21064
21065          $document.on('mousemove', function (event) {
21066            context.invoke('editor.resizeTo', {
21067              x: event.clientX - posStart.left,
21068              y: event.clientY - (posStart.top - scrollTop)
21069            }, $target, !event.shiftKey);
21070
21071            self.update($target[0]);
21072          }).one('mouseup', function (e) {
21073            e.preventDefault();
21074            $document.off('mousemove');
21075            context.invoke('editor.afterCommand');
21076          });
21077
21078          if (!$target.data('ratio')) { // original ratio.
21079            $target.data('ratio', $target.height() / $target.width());
21080          }
21081        }
21082      });
21083    };
21084
21085    this.destroy = function () {
21086      this.$handle.remove();
21087    };
21088
21089    this.update = function (target) {
21090      var isImage = dom.isImg(target);
21091      var $selection = this.$handle.find('.note-control-selection');
21092
21093      context.invoke('imagePopover.update', target);
21094
21095      if (isImage) {
21096        var $image = $(target);
21097        var pos = $image.position();
21098
21099        // include margin
21100        var imageSize = {
21101          w: $image.outerWidth(true),
21102          h: $image.outerHeight(true)
21103        };
21104
21105        $selection.css({
21106          display: 'block',
21107          left: pos.left,
21108          top: pos.top,
21109          width: imageSize.w,
21110          height: imageSize.h
21111        }).data('target', $image); // save current image element.
21112
21113        var sizingText = imageSize.w + 'x' + imageSize.h;
21114        $selection.find('.note-control-selection-info').text(sizingText);
21115        context.invoke('editor.saveTarget', target);
21116      } else {
21117        this.hide();
21118      }
21119
21120      return isImage;
21121    };
21122
21123    /**
21124     * hide
21125     *
21126     * @param {jQuery} $handle
21127     */
21128    this.hide = function () {
21129      context.invoke('editor.clearTarget');
21130      this.$handle.children().hide();
21131    };
21132  };
21133
21134  var AutoLink = function (context) {
21135    var self = this;
21136    var defaultScheme = 'http://';
21137    var linkPattern = /^([A-Za-z][A-Za-z0-9+-.]*\:[\/\/]?|mailto:[A-Z0-9._%+-]+@)?(www\.)?(.+)$/i;
21138
21139    this.events = {
21140      'summernote.keyup': function (we, e) {
21141        if (!e.isDefaultPrevented()) {
21142          self.handleKeyup(e);
21143        }
21144      },
21145      'summernote.keydown': function (we, e) {
21146        self.handleKeydown(e);
21147      }
21148    };
21149
21150    this.initialize = function () {
21151      this.lastWordRange = null;
21152    };
21153
21154    this.destroy = function () {
21155      this.lastWordRange = null;
21156    };
21157
21158    this.replace = function () {
21159      if (!this.lastWordRange) {
21160        return;
21161      }
21162
21163      var keyword = this.lastWordRange.toString();
21164      var match = keyword.match(linkPattern);
21165
21166      if (match && (match[1] || match[2])) {
21167        var link = match[1] ? keyword : defaultScheme + keyword;
21168        var node = $('<a />').html(keyword).attr('href', link)[0];
21169
21170        this.lastWordRange.insertNode(node);
21171        this.lastWordRange = null;
21172        context.invoke('editor.focus');
21173      }
21174
21175    };
21176
21177    this.handleKeydown = function (e) {
21178      if (list.contains([key.code.ENTER, key.code.SPACE], e.keyCode)) {
21179        var wordRange = context.invoke('editor.createRange').getWordRange();
21180        this.lastWordRange = wordRange;
21181      }
21182    };
21183
21184    this.handleKeyup = function (e) {
21185      if (list.contains([key.code.ENTER, key.code.SPACE], e.keyCode)) {
21186        this.replace();
21187      }
21188    };
21189  };
21190
21191  /**
21192   * textarea auto sync.
21193   */
21194  var AutoSync = function (context) {
21195    var $note = context.layoutInfo.note;
21196
21197    this.events = {
21198      'summernote.change': function () {
21199        $note.val(context.invoke('code'));
21200      }
21201    };
21202
21203    this.shouldInitialize = function () {
21204      return dom.isTextarea($note[0]);
21205    };
21206  };
21207
21208  var Placeholder = function (context) {
21209    var self = this;
21210    var $editingArea = context.layoutInfo.editingArea;
21211    var options = context.options;
21212
21213    this.events = {
21214      'summernote.init summernote.change': function () {
21215        self.update();
21216      },
21217      'summernote.codeview.toggled': function () {
21218        self.update();
21219      }
21220    };
21221
21222    this.shouldInitialize = function () {
21223      return !!options.placeholder;
21224    };
21225
21226    this.initialize = function () {
21227      this.$placeholder = $('<div class="note-placeholder">');
21228      this.$placeholder.on('click', function () {
21229        context.invoke('focus');
21230      }).text(options.placeholder).prependTo($editingArea);
21231    };
21232
21233    this.destroy = function () {
21234      this.$placeholder.remove();
21235    };
21236
21237    this.update = function () {
21238      var isShow = !context.invoke('codeview.isActivated') && context.invoke('editor.isEmpty');
21239      this.$placeholder.toggle(isShow);
21240    };
21241  };
21242
21243  var Buttons = function (context) {
21244    var self = this;
21245    var ui = $.summernote.ui;
21246
21247    var $toolbar = context.layoutInfo.toolbar;
21248    var options = context.options;
21249    var lang = options.langInfo;
21250
21251    var invertedKeyMap = func.invertObject(options.keyMap[agent.isMac ? 'mac' : 'pc']);
21252
21253    var representShortcut = this.representShortcut = function (editorMethod) {
21254      var shortcut = invertedKeyMap[editorMethod];
21255      if (!options.shortcuts || !shortcut) {
21256        return '';
21257      }
21258      
21259      if (agent.isMac) {
21260        shortcut = shortcut.replace('CMD', '⌘').replace('SHIFT', '⇧');
21261      }
21262
21263      shortcut = shortcut.replace('BACKSLASH', '\\')
21264                         .replace('SLASH', '/')
21265                         .replace('LEFTBRACKET', '[')
21266                         .replace('RIGHTBRACKET', ']');
21267
21268      return ' (' + shortcut + ')';
21269    };
21270
21271    this.initialize = function () {
21272      this.addToolbarButtons();
21273      this.addImagePopoverButtons();
21274      this.addLinkPopoverButtons();
21275      this.fontInstalledMap = {};
21276    };
21277
21278    this.destroy = function () {
21279      delete this.fontInstalledMap;
21280    };
21281
21282    this.isFontInstalled = function (name) {
21283      if (!self.fontInstalledMap.hasOwnProperty(name)) {
21284        self.fontInstalledMap[name] = agent.isFontInstalled(name) ||
21285          list.contains(options.fontNamesIgnoreCheck, name);
21286      }
21287
21288      return self.fontInstalledMap[name];
21289    };
21290
21291    this.addToolbarButtons = function () {
21292      context.memo('button.style', function () {
21293        return ui.buttonGroup([
21294          ui.button({
21295            className: 'dropdown-toggle',
21296            contents: ui.icon(options.icons.magic) + ' ' + ui.icon(options.icons.caret, 'span'),
21297            tooltip: lang.style.style,
21298            data: {
21299              toggle: 'dropdown'
21300            }
21301          }),
21302          ui.dropdown({
21303            className: 'dropdown-style',
21304            items: context.options.styleTags,
21305            template: function (item) {
21306
21307              if (typeof item === 'string') {
21308                item = { tag: item, title: (lang.style.hasOwnProperty(item) ? lang.style[item] : item) };
21309              }
21310
21311              var tag = item.tag;
21312              var title = item.title;
21313              var style = item.style ? ' style="' + item.style + '" ' : '';
21314              var className = item.className ? ' class="' + item.className + '"' : '';
21315
21316              return '<' + tag + style + className + '>' + title + '</' + tag +  '>';
21317            },
21318            click: context.createInvokeHandler('editor.formatBlock')
21319          })
21320        ]).render();
21321      });
21322
21323      context.memo('button.bold', function () {
21324        return ui.button({
21325          className: 'note-btn-bold',
21326          contents: ui.icon(options.icons.bold),
21327          tooltip: lang.font.bold + representShortcut('bold'),
21328          click: context.createInvokeHandler('editor.bold')
21329        }).render();
21330      });
21331
21332      context.memo('button.italic', function () {
21333        return ui.button({
21334          className: 'note-btn-italic',
21335          contents: ui.icon(options.icons.italic),
21336          tooltip: lang.font.italic + representShortcut('italic'),
21337          click: context.createInvokeHandler('editor.italic')
21338        }).render();
21339      });
21340
21341      context.memo('button.underline', function () {
21342        return ui.button({
21343          className: 'note-btn-underline',
21344          contents: ui.icon(options.icons.underline),
21345          tooltip: lang.font.underline + representShortcut('underline'),
21346          click: context.createInvokeHandler('editor.underline')
21347        }).render();
21348      });
21349
21350      context.memo('button.clear', function () {
21351        return ui.button({
21352          contents: ui.icon(options.icons.eraser),
21353          tooltip: lang.font.clear + representShortcut('removeFormat'),
21354          click: context.createInvokeHandler('editor.removeFormat')
21355        }).render();
21356      });
21357
21358      context.memo('button.strikethrough', function () {
21359        return ui.button({
21360          className: 'note-btn-strikethrough',
21361          contents: ui.icon(options.icons.strikethrough),
21362          tooltip: lang.font.strikethrough + representShortcut('strikethrough'),
21363          click: context.createInvokeHandler('editor.strikethrough')
21364        }).render();
21365      });
21366
21367      context.memo('button.superscript', function () {
21368        return ui.button({
21369          className: 'note-btn-superscript',
21370          contents: ui.icon(options.icons.superscript),
21371          tooltip: lang.font.superscript,
21372          click: context.createInvokeHandler('editor.superscript')
21373        }).render();
21374      });
21375
21376      context.memo('button.subscript', function () {
21377        return ui.button({
21378          className: 'note-btn-subscript',
21379          contents: ui.icon(options.icons.subscript),
21380          tooltip: lang.font.subscript,
21381          click: context.createInvokeHandler('editor.subscript')
21382        }).render();
21383      });
21384
21385      context.memo('button.fontname', function () {
21386        return ui.buttonGroup([
21387          ui.button({
21388            className: 'dropdown-toggle',
21389            contents: '<span class="note-current-fontname"/> ' + ui.icon(options.icons.caret, 'span'),
21390            tooltip: lang.font.name,
21391            data: {
21392              toggle: 'dropdown'
21393            }
21394          }),
21395          ui.dropdownCheck({
21396            className: 'dropdown-fontname',
21397            checkClassName: options.icons.menuCheck,
21398            items: options.fontNames.filter(self.isFontInstalled),
21399            template: function (item) {
21400              return '<span style="font-family:' + item + '">' + item + '</span>';
21401            },
21402            click: context.createInvokeHandler('editor.fontName')
21403          })
21404        ]).render();
21405      });
21406
21407      context.memo('button.fontsize', function () {
21408        return ui.buttonGroup([
21409          ui.button({
21410            className: 'dropdown-toggle',
21411            contents: '<span class="note-current-fontsize"/>' + ui.icon(options.icons.caret, 'span'),
21412            tooltip: lang.font.size,
21413            data: {
21414              toggle: 'dropdown'
21415            }
21416          }),
21417          ui.dropdownCheck({
21418            className: 'dropdown-fontsize',
21419            checkClassName: options.icons.menuCheck,
21420            items: options.fontSizes,
21421            click: context.createInvokeHandler('editor.fontSize')
21422          })
21423        ]).render();
21424      });
21425
21426      context.memo('button.color', function () {
21427        return ui.buttonGroup({
21428          className: 'note-color',
21429          children: [
21430            ui.button({
21431              className: 'note-current-color-button',
21432              contents: ui.icon(options.icons.font + ' note-recent-color'),
21433              tooltip: lang.color.recent,
21434              click: function (e) {
21435                var $button = $(e.currentTarget);
21436                context.invoke('editor.color', {
21437                  backColor: $button.attr('data-backColor'),
21438                  foreColor: $button.attr('data-foreColor')
21439                });
21440              },
21441              callback: function ($button) {
21442                var $recentColor = $button.find('.note-recent-color');
21443                $recentColor.css('background-color', '#FFFF00');
21444                $button.attr('data-backColor', '#FFFF00');
21445              }
21446            }),
21447            ui.button({
21448              className: 'dropdown-toggle',
21449              contents: ui.icon(options.icons.caret, 'span'),
21450              tooltip: lang.color.more,
21451              data: {
21452                toggle: 'dropdown'
21453              }
21454            }),
21455            ui.dropdown({
21456              items: [
21457                '<li>',
21458                '<div class="btn-group">',
21459                '  <div class="note-palette-title">' + lang.color.background + '</div>',
21460                '  <div>',
21461                '    <button type="button" class="note-color-reset btn btn-default" data-event="backColor" data-value="inherit">',
21462                lang.color.transparent,
21463                '    </button>',
21464                '  </div>',
21465                '  <div class="note-holder" data-event="backColor"/>',
21466                '</div>',
21467                '<div class="btn-group">',
21468                '  <div class="note-palette-title">' + lang.color.foreground + '</div>',
21469                '  <div>',
21470                '    <button type="button" class="note-color-reset btn btn-default" data-event="removeFormat" data-value="foreColor">',
21471                lang.color.resetToDefault,
21472                '    </button>',
21473                '  </div>',
21474                '  <div class="note-holder" data-event="foreColor"/>',
21475                '</div>',
21476                '</li>'
21477              ].join(''),
21478              callback: function ($dropdown) {
21479                $dropdown.find('.note-holder').each(function () {
21480                  var $holder = $(this);
21481                  $holder.append(ui.palette({
21482                    colors: options.colors,
21483                    eventName: $holder.data('event')
21484                  }).render());
21485                });
21486              },
21487              click: function (event) {
21488                var $button = $(event.target);
21489                var eventName = $button.data('event');
21490                var value = $button.data('value');
21491
21492                if (eventName && value) {
21493                  var key = eventName === 'backColor' ? 'background-color' : 'color';
21494                  var $color = $button.closest('.note-color').find('.note-recent-color');
21495                  var $currentButton = $button.closest('.note-color').find('.note-current-color-button');
21496
21497                  $color.css(key, value);
21498                  $currentButton.attr('data-' + eventName, value);
21499                  context.invoke('editor.' + eventName, value);
21500                }
21501              }
21502            })
21503          ]
21504        }).render();
21505      });
21506
21507      context.memo('button.ul',  function () {
21508        return ui.button({
21509          contents: ui.icon(options.icons.unorderedlist),
21510          tooltip: lang.lists.unordered + representShortcut('insertUnorderedList'),
21511          click: context.createInvokeHandler('editor.insertUnorderedList')
21512        }).render();
21513      });
21514
21515      context.memo('button.ol', function () {
21516        return ui.button({
21517          contents: ui.icon(options.icons.orderedlist),
21518          tooltip: lang.lists.ordered + representShortcut('insertOrderedList'),
21519          click:  context.createInvokeHandler('editor.insertOrderedList')
21520        }).render();
21521      });
21522
21523      var justifyLeft = ui.button({
21524        contents: ui.icon(options.icons.alignLeft),
21525        tooltip: lang.paragraph.left + representShortcut('justifyLeft'),
21526        click: context.createInvokeHandler('editor.justifyLeft')
21527      });
21528
21529      var justifyCenter = ui.button({
21530        contents: ui.icon(options.icons.alignCenter),
21531        tooltip: lang.paragraph.center + representShortcut('justifyCenter'),
21532        click: context.createInvokeHandler('editor.justifyCenter')
21533      });
21534
21535      var justifyRight = ui.button({
21536        contents: ui.icon(options.icons.alignRight),
21537        tooltip: lang.paragraph.right + representShortcut('justifyRight'),
21538        click: context.createInvokeHandler('editor.justifyRight')
21539      });
21540
21541      var justifyFull = ui.button({
21542        contents: ui.icon(options.icons.alignJustify),
21543        tooltip: lang.paragraph.justify + representShortcut('justifyFull'),
21544        click: context.createInvokeHandler('editor.justifyFull')
21545      });
21546
21547      var outdent = ui.button({
21548        contents: ui.icon(options.icons.outdent),
21549        tooltip: lang.paragraph.outdent + representShortcut('outdent'),
21550        click: context.createInvokeHandler('editor.outdent')
21551      });
21552
21553      var indent = ui.button({
21554        contents: ui.icon(options.icons.indent),
21555        tooltip: lang.paragraph.indent + representShortcut('indent'),
21556        click: context.createInvokeHandler('editor.indent')
21557      });
21558
21559      context.memo('button.justifyLeft', func.invoke(justifyLeft, 'render'));
21560      context.memo('button.justifyCenter', func.invoke(justifyCenter, 'render'));
21561      context.memo('button.justifyRight', func.invoke(justifyRight, 'render'));
21562      context.memo('button.justifyFull', func.invoke(justifyFull, 'render'));
21563      context.memo('button.outdent', func.invoke(outdent, 'render'));
21564      context.memo('button.indent', func.invoke(indent, 'render'));
21565
21566      context.memo('button.paragraph', function () {
21567        return ui.buttonGroup([
21568          ui.button({
21569            className: 'dropdown-toggle',
21570            contents: ui.icon(options.icons.alignLeft) + ' ' + ui.icon(options.icons.caret, 'span'),
21571            tooltip: lang.paragraph.paragraph,
21572            data: {
21573              toggle: 'dropdown'
21574            }
21575          }),
21576          ui.dropdown([
21577            ui.buttonGroup({
21578              className: 'note-align',
21579              children: [justifyLeft, justifyCenter, justifyRight, justifyFull]
21580            }),
21581            ui.buttonGroup({
21582              className: 'note-list',
21583              children: [outdent, indent]
21584            })
21585          ])
21586        ]).render();
21587      });
21588
21589      context.memo('button.height', function () {
21590        return ui.buttonGroup([
21591          ui.button({
21592            className: 'dropdown-toggle',
21593            contents: ui.icon(options.icons.textHeight) + ' ' + ui.icon(options.icons.caret, 'span'),
21594            tooltip: lang.font.height,
21595            data: {
21596              toggle: 'dropdown'
21597            }
21598          }),
21599          ui.dropdownCheck({
21600            items: options.lineHeights,
21601            checkClassName: options.icons.menuCheck,
21602            className: 'dropdown-line-height',
21603            click: context.createInvokeHandler('editor.lineHeight')
21604          })
21605        ]).render();
21606      });
21607
21608      context.memo('button.table', function () {
21609        return ui.buttonGroup([
21610          ui.button({
21611            className: 'dropdown-toggle',
21612            contents: ui.icon(options.icons.table) + ' ' + ui.icon(options.icons.caret, 'span'),
21613            tooltip: lang.table.table,
21614            data: {
21615              toggle: 'dropdown'
21616            }
21617          }),
21618          ui.dropdown({
21619            className: 'note-table',
21620            items: [
21621              '<div class="note-dimension-picker">',
21622              '  <div class="note-dimension-picker-mousecatcher" data-event="insertTable" data-value="1x1"/>',
21623              '  <div class="note-dimension-picker-highlighted"/>',
21624              '  <div class="note-dimension-picker-unhighlighted"/>',
21625              '</div>',
21626              '<div class="note-dimension-display">1 x 1</div>'
21627            ].join('')
21628          })
21629        ], {
21630          callback: function ($node) {
21631            var $catcher = $node.find('.note-dimension-picker-mousecatcher');
21632            $catcher.css({
21633              width: options.insertTableMaxSize.col + 'em',
21634              height: options.insertTableMaxSize.row + 'em'
21635            }).mousedown(context.createInvokeHandler('editor.insertTable'))
21636              .on('mousemove', self.tableMoveHandler);
21637          }
21638        }).render();
21639      });
21640
21641      context.memo('button.link', function () {
21642        return ui.button({
21643          contents: ui.icon(options.icons.link),
21644          tooltip: lang.link.link + representShortcut('linkDialog.show'),
21645          click: context.createInvokeHandler('linkDialog.show')
21646        }).render();
21647      });
21648
21649      context.memo('button.picture', function () {
21650        return ui.button({
21651          contents: ui.icon(options.icons.picture),
21652          tooltip: lang.image.image,
21653          click: context.createInvokeHandler('imageDialog.show')
21654        }).render();
21655      });
21656
21657      context.memo('button.video', function () {
21658        return ui.button({
21659          contents: ui.icon(options.icons.video),
21660          tooltip: lang.video.video,
21661          click: context.createInvokeHandler('videoDialog.show')
21662        }).render();
21663      });
21664
21665      context.memo('button.hr', function () {
21666        return ui.button({
21667          contents: ui.icon(options.icons.minus),
21668          tooltip: lang.hr.insert + representShortcut('insertHorizontalRule'),
21669          click: context.createInvokeHandler('editor.insertHorizontalRule')
21670        }).render();
21671      });
21672
21673      context.memo('button.fullscreen', function () {
21674        return ui.button({
21675          className: 'btn-fullscreen',
21676          contents: ui.icon(options.icons.arrowsAlt),
21677          tooltip: lang.options.fullscreen,
21678          click: context.createInvokeHandler('fullscreen.toggle')
21679        }).render();
21680      });
21681
21682      context.memo('button.codeview', function () {
21683        return ui.button({
21684          className: 'btn-codeview',
21685          contents: ui.icon(options.icons.code),
21686          tooltip: lang.options.codeview,
21687          click: context.createInvokeHandler('codeview.toggle')
21688        }).render();
21689      });
21690
21691      context.memo('button.redo', function () {
21692        return ui.button({
21693          contents: ui.icon(options.icons.redo),
21694          tooltip: lang.history.redo + representShortcut('redo'),
21695          click: context.createInvokeHandler('editor.redo')
21696        }).render();
21697      });
21698
21699      context.memo('button.undo', function () {
21700        return ui.button({
21701          contents: ui.icon(options.icons.undo),
21702          tooltip: lang.history.undo + representShortcut('undo'),
21703          click: context.createInvokeHandler('editor.undo')
21704        }).render();
21705      });
21706
21707      context.memo('button.help', function () {
21708        return ui.button({
21709          contents: ui.icon(options.icons.question),
21710          tooltip: lang.options.help,
21711          click: context.createInvokeHandler('helpDialog.show')
21712        }).render();
21713      });
21714    };
21715
21716    /**
21717     * image : [
21718     *   ['imagesize', ['imageSize100', 'imageSize50', 'imageSize25']],
21719     *   ['float', ['floatLeft', 'floatRight', 'floatNone' ]],
21720     *   ['remove', ['removeMedia']]
21721     * ],
21722     */
21723    this.addImagePopoverButtons = function () {
21724      // Image Size Buttons
21725      context.memo('button.imageSize100', function () {
21726        return ui.button({
21727          contents: '<span class="note-fontsize-10">100%</span>',
21728          tooltip: lang.image.resizeFull,
21729          click: context.createInvokeHandler('editor.resize', '1')
21730        }).render();
21731      });
21732      context.memo('button.imageSize50', function () {
21733        return  ui.button({
21734          contents: '<span class="note-fontsize-10">50%</span>',
21735          tooltip: lang.image.resizeHalf,
21736          click: context.createInvokeHandler('editor.resize', '0.5')
21737        }).render();
21738      });
21739      context.memo('button.imageSize25', function () {
21740        return ui.button({
21741          contents: '<span class="note-fontsize-10">25%</span>',
21742          tooltip: lang.image.resizeQuarter,
21743          click: context.createInvokeHandler('editor.resize', '0.25')
21744        }).render();
21745      });
21746
21747      // Float Buttons
21748      context.memo('button.floatLeft', function () {
21749        return ui.button({
21750          contents: ui.icon(options.icons.alignLeft),
21751          tooltip: lang.image.floatLeft,
21752          click: context.createInvokeHandler('editor.floatMe', 'left')
21753        }).render();
21754      });
21755
21756      context.memo('button.floatRight', function () {
21757        return ui.button({
21758          contents: ui.icon(options.icons.alignRight),
21759          tooltip: lang.image.floatRight,
21760          click: context.createInvokeHandler('editor.floatMe', 'right')
21761        }).render();
21762      });
21763
21764      context.memo('button.floatNone', function () {
21765        return ui.button({
21766          contents: ui.icon(options.icons.alignJustify),
21767          tooltip: lang.image.floatNone,
21768          click: context.createInvokeHandler('editor.floatMe', 'none')
21769        }).render();
21770      });
21771
21772      // Remove Buttons
21773      context.memo('button.removeMedia', function () {
21774        return ui.button({
21775          contents: ui.icon(options.icons.trash),
21776          tooltip: lang.image.remove,
21777          click: context.createInvokeHandler('editor.removeMedia')
21778        }).render();
21779      });
21780    };
21781
21782    this.addLinkPopoverButtons = function () {
21783      context.memo('button.linkDialogShow', function () {
21784        return ui.button({
21785          contents: ui.icon(options.icons.link),
21786          tooltip: lang.link.edit,
21787          click: context.createInvokeHandler('linkDialog.show')
21788        }).render();
21789      });
21790
21791      context.memo('button.unlink', function () {
21792        return ui.button({
21793          contents: ui.icon(options.icons.unlink),
21794          tooltip: lang.link.unlink,
21795          click: context.createInvokeHandler('editor.unlink')
21796        }).render();
21797      });
21798    };
21799
21800    this.build = function ($container, groups) {
21801      for (var groupIdx = 0, groupLen = groups.length; groupIdx < groupLen; groupIdx++) {
21802        var group = groups[groupIdx];
21803        var groupName = group[0];
21804        var buttons = group[1];
21805
21806        var $group = ui.buttonGroup({
21807          className: 'note-' + groupName
21808        }).render();
21809
21810        for (var idx = 0, len = buttons.length; idx < len; idx++) {
21811          var button = context.memo('button.' + buttons[idx]);
21812          if (button) {
21813            $group.append(typeof button === 'function' ? button(context) : button);
21814          }
21815        }
21816        $group.appendTo($container);
21817      }
21818    };
21819
21820    this.updateCurrentStyle = function () {
21821      var styleInfo = context.invoke('editor.currentStyle');
21822      this.updateBtnStates({
21823        '.note-btn-bold': function () {
21824          return styleInfo['font-bold'] === 'bold';
21825        },
21826        '.note-btn-italic': function () {
21827          return styleInfo['font-italic'] === 'italic';
21828        },
21829        '.note-btn-underline': function () {
21830          return styleInfo['font-underline'] === 'underline';
21831        },
21832        '.note-btn-subscript': function () {
21833          return styleInfo['font-subscript'] === 'subscript';
21834        },
21835        '.note-btn-superscript': function () {
21836          return styleInfo['font-superscript'] === 'superscript';
21837        },
21838        '.note-btn-strikethrough': function () {
21839          return styleInfo['font-strikethrough'] === 'strikethrough';
21840        }
21841      });
21842
21843      if (styleInfo['font-family']) {
21844        var fontNames = styleInfo['font-family'].split(',').map(function (name) {
21845          return name.replace(/[\'\"]/g, '')
21846            .replace(/\s+$/, '')
21847            .replace(/^\s+/, '');
21848        });
21849        var fontName = list.find(fontNames, self.isFontInstalled);
21850
21851        $toolbar.find('.dropdown-fontname li a').each(function () {
21852          // always compare string to avoid creating another func.
21853          var isChecked = ($(this).data('value') + '') === (fontName + '');
21854          this.className = isChecked ? 'checked' : '';
21855        });
21856        $toolbar.find('.note-current-fontname').text(fontName);
21857      }
21858
21859      if (styleInfo['font-size']) {
21860        var fontSize = styleInfo['font-size'];
21861        $toolbar.find('.dropdown-fontsize li a').each(function () {
21862          // always compare with string to avoid creating another func.
21863          var isChecked = ($(this).data('value') + '') === (fontSize + '');
21864          this.className = isChecked ? 'checked' : '';
21865        });
21866        $toolbar.find('.note-current-fontsize').text(fontSize);
21867      }
21868
21869      if (styleInfo['line-height']) {
21870        var lineHeight = styleInfo['line-height'];
21871        $toolbar.find('.dropdown-line-height li a').each(function () {
21872          // always compare with string to avoid creating another func.
21873          var isChecked = ($(this).data('value') + '') === (lineHeight + '');
21874          this.className = isChecked ? 'checked' : '';
21875        });
21876      }
21877    };
21878
21879    this.updateBtnStates = function (infos) {
21880      $.each(infos, function (selector, pred) {
21881        ui.toggleBtnActive($toolbar.find(selector), pred());
21882      });
21883    };
21884
21885    this.tableMoveHandler = function (event) {
21886      var PX_PER_EM = 18;
21887      var $picker = $(event.target.parentNode); // target is mousecatcher
21888      var $dimensionDisplay = $picker.next();
21889      var $catcher = $picker.find('.note-dimension-picker-mousecatcher');
21890      var $highlighted = $picker.find('.note-dimension-picker-highlighted');
21891      var $unhighlighted = $picker.find('.note-dimension-picker-unhighlighted');
21892
21893      var posOffset;
21894      // HTML5 with jQuery - e.offsetX is undefined in Firefox
21895      if (event.offsetX === undefined) {
21896        var posCatcher = $(event.target).offset();
21897        posOffset = {
21898          x: event.pageX - posCatcher.left,
21899          y: event.pageY - posCatcher.top
21900        };
21901      } else {
21902        posOffset = {
21903          x: event.offsetX,
21904          y: event.offsetY
21905        };
21906      }
21907
21908      var dim = {
21909        c: Math.ceil(posOffset.x / PX_PER_EM) || 1,
21910        r: Math.ceil(posOffset.y / PX_PER_EM) || 1
21911      };
21912
21913      $highlighted.css({ width: dim.c + 'em', height: dim.r + 'em' });
21914      $catcher.data('value', dim.c + 'x' + dim.r);
21915
21916      if (3 < dim.c && dim.c < options.insertTableMaxSize.col) {
21917        $unhighlighted.css({ width: dim.c + 1 + 'em'});
21918      }
21919
21920      if (3 < dim.r && dim.r < options.insertTableMaxSize.row) {
21921        $unhighlighted.css({ height: dim.r + 1 + 'em'});
21922      }
21923
21924      $dimensionDisplay.html(dim.c + ' x ' + dim.r);
21925    };
21926  };
21927
21928  var Toolbar = function (context) {
21929    var ui = $.summernote.ui;
21930
21931    var $note = context.layoutInfo.note;
21932    var $toolbar = context.layoutInfo.toolbar;
21933    var options = context.options;
21934
21935    this.shouldInitialize = function () {
21936      return !options.airMode;
21937    };
21938
21939    this.initialize = function () {
21940      options.toolbar = options.toolbar || [];
21941
21942      if (!options.toolbar.length) {
21943        $toolbar.hide();
21944      } else {
21945        context.invoke('buttons.build', $toolbar, options.toolbar);
21946      }
21947
21948      if (options.toolbarContainer) {
21949        $toolbar.appendTo(options.toolbarContainer);
21950      }
21951
21952      $note.on('summernote.keyup summernote.mouseup summernote.change', function () {
21953        context.invoke('buttons.updateCurrentStyle');
21954      });
21955
21956      context.invoke('buttons.updateCurrentStyle');
21957    };
21958
21959    this.destroy = function () {
21960      $toolbar.children().remove();
21961    };
21962
21963    this.updateFullscreen = function (isFullscreen) {
21964      ui.toggleBtnActive($toolbar.find('.btn-fullscreen'), isFullscreen);
21965    };
21966
21967    this.updateCodeview = function (isCodeview) {
21968      ui.toggleBtnActive($toolbar.find('.btn-codeview'), isCodeview);
21969      if (isCodeview) {
21970        this.deactivate();
21971      } else {
21972        this.activate();
21973      }
21974    };
21975
21976    this.activate = function (isIncludeCodeview) {
21977      var $btn = $toolbar.find('button');
21978      if (!isIncludeCodeview) {
21979        $btn = $btn.not('.btn-codeview');
21980      }
21981      ui.toggleBtn($btn, true);
21982    };
21983
21984    this.deactivate = function (isIncludeCodeview) {
21985      var $btn = $toolbar.find('button');
21986      if (!isIncludeCodeview) {
21987        $btn = $btn.not('.btn-codeview');
21988      }
21989      ui.toggleBtn($btn, false);
21990    };
21991  };
21992
21993  var LinkDialog = function (context) {
21994    var self = this;
21995    var ui = $.summernote.ui;
21996
21997    var $editor = context.layoutInfo.editor;
21998    var options = context.options;
21999    var lang = options.langInfo;
22000
22001    this.initialize = function () {
22002      var $container = options.dialogsInBody ? $(document.body) : $editor;
22003
22004      var body = '<div class="form-group">' +
22005                   '<label>' + lang.link.textToDisplay + '</label>' +
22006                   '<input class="note-link-text form-control" type="text" />' +
22007                 '</div>' +
22008                 '<div class="form-group">' +
22009                   '<label>' + lang.link.url + '</label>' +
22010                   '<input class="note-link-url form-control" type="text" value="http://" />' +
22011                 '</div>' +
22012                 (!options.disableLinkTarget ?
22013                   '<div class="checkbox">' +
22014                     '<label>' + '<input type="checkbox" checked> ' + lang.link.openInNewWindow + '</label>' +
22015                   '</div>' : ''
22016                 );
22017      var footer = '<button href="#" class="btn btn-primary note-link-btn disabled" disabled>' + lang.link.insert + '</button>';
22018
22019      this.$dialog = ui.dialog({
22020        className: 'link-dialog',
22021        title: lang.link.insert,
22022        fade: options.dialogsFade,
22023        body: body,
22024        footer: footer
22025      }).render().appendTo($container);
22026    };
22027
22028    this.destroy = function () {
22029      ui.hideDialog(this.$dialog);
22030      this.$dialog.remove();
22031    };
22032
22033    this.bindEnterKey = function ($input, $btn) {
22034      $input.on('keypress', function (event) {
22035        if (event.keyCode === key.code.ENTER) {
22036          $btn.trigger('click');
22037        }
22038      });
22039    };
22040
22041    /**
22042     * toggle update button
22043     */
22044    this.toggleLinkBtn = function ($linkBtn, $linkText, $linkUrl) {
22045      ui.toggleBtn($linkBtn, $linkText.val() && $linkUrl.val());
22046    };
22047
22048    /**
22049     * Show link dialog and set event handlers on dialog controls.
22050     *
22051     * @param {Object} linkInfo
22052     * @return {Promise}
22053     */
22054    this.showLinkDialog = function (linkInfo) {
22055      return $.Deferred(function (deferred) {
22056        var $linkText = self.$dialog.find('.note-link-text'),
22057        $linkUrl = self.$dialog.find('.note-link-url'),
22058        $linkBtn = self.$dialog.find('.note-link-btn'),
22059        $openInNewWindow = self.$dialog.find('input[type=checkbox]');
22060
22061        ui.onDialogShown(self.$dialog, function () {
22062          context.triggerEvent('dialog.shown');
22063
22064          // if no url was given, copy text to url
22065          if (!linkInfo.url) {
22066            linkInfo.url = linkInfo.text;
22067          }
22068
22069          $linkText.val(linkInfo.text);
22070
22071          var handleLinkTextUpdate = function () {
22072            self.toggleLinkBtn($linkBtn, $linkText, $linkUrl);
22073            // if linktext was modified by keyup,
22074            // stop cloning text from linkUrl
22075            linkInfo.text = $linkText.val();
22076          };
22077
22078          $linkText.on('input', handleLinkTextUpdate).on('paste', function () {
22079            setTimeout(handleLinkTextUpdate, 0);
22080          });
22081
22082          var handleLinkUrlUpdate = function () {
22083            self.toggleLinkBtn($linkBtn, $linkText, $linkUrl);
22084            // display same link on `Text to display` input
22085            // when create a new link
22086            if (!linkInfo.text) {
22087              $linkText.val($linkUrl.val());
22088            }
22089          };
22090
22091          $linkUrl.on('input', handleLinkUrlUpdate).on('paste', function () {
22092            setTimeout(handleLinkUrlUpdate, 0);
22093          }).val(linkInfo.url).trigger('focus');
22094
22095          self.toggleLinkBtn($linkBtn, $linkText, $linkUrl);
22096          self.bindEnterKey($linkUrl, $linkBtn);
22097          self.bindEnterKey($linkText, $linkBtn);
22098
22099          $openInNewWindow.prop('checked', linkInfo.isNewWindow);
22100
22101          $linkBtn.one('click', function (event) {
22102            event.preventDefault();
22103
22104            deferred.resolve({
22105              range: linkInfo.range,
22106              url: $linkUrl.val(),
22107              text: $linkText.val(),
22108              isNewWindow: $openInNewWindow.is(':checked')
22109            });
22110            self.$dialog.modal('hide');
22111          });
22112        });
22113
22114        ui.onDialogHidden(self.$dialog, function () {
22115          // detach events
22116          $linkText.off('input paste keypress');
22117          $linkUrl.off('input paste keypress');
22118          $linkBtn.off('click');
22119
22120          if (deferred.state() === 'pending') {
22121            deferred.reject();
22122          }
22123        });
22124
22125        ui.showDialog(self.$dialog);
22126      }).promise();
22127    };
22128
22129    /**
22130     * @param {Object} layoutInfo
22131     */
22132    this.show = function () {
22133      var linkInfo = context.invoke('editor.getLinkInfo');
22134
22135      context.invoke('editor.saveRange');
22136      this.showLinkDialog(linkInfo).then(function (linkInfo) {
22137        context.invoke('editor.restoreRange');
22138        context.invoke('editor.createLink', linkInfo);
22139      }).fail(function () {
22140        context.invoke('editor.restoreRange');
22141      });
22142    };
22143    context.memo('help.linkDialog.show', options.langInfo.help['linkDialog.show']);
22144  };
22145
22146  var LinkPopover = function (context) {
22147    var self = this;
22148    var ui = $.summernote.ui;
22149
22150    var options = context.options;
22151
22152    this.events = {
22153      'summernote.keyup summernote.mouseup summernote.change summernote.scroll': function () {
22154        self.update();
22155      },
22156      'summernote.dialog.shown': function () {
22157        self.hide();
22158      }
22159    };
22160
22161    this.shouldInitialize = function () {
22162      return !list.isEmpty(options.popover.link);
22163    };
22164
22165    this.initialize = function () {
22166      this.$popover = ui.popover({
22167        className: 'note-link-popover',
22168        callback: function ($node) {
22169          var $content = $node.find('.popover-content');
22170          $content.prepend('<span><a target="_blank"></a>&nbsp;</span>');
22171        }
22172      }).render().appendTo('body');
22173      var $content = this.$popover.find('.popover-content');
22174
22175      context.invoke('buttons.build', $content, options.popover.link);
22176    };
22177
22178    this.destroy = function () {
22179      this.$popover.remove();
22180    };
22181
22182    this.update = function () {
22183      // Prevent focusing on editable when invoke('code') is executed
22184      if (!context.invoke('editor.hasFocus')) {
22185        this.hide();
22186        return;
22187      }
22188
22189      var rng = context.invoke('editor.createRange');
22190      if (rng.isCollapsed() && rng.isOnAnchor()) {
22191        var anchor = dom.ancestor(rng.sc, dom.isAnchor);
22192        var href = $(anchor).attr('href');
22193        this.$popover.find('a').attr('href', href).html(href);
22194
22195        var pos = dom.posFromPlaceholder(anchor);
22196        this.$popover.css({
22197          display: 'block',
22198          left: pos.left,
22199          top: pos.top
22200        });
22201      } else {
22202        this.hide();
22203      }
22204    };
22205
22206    this.hide = function () {
22207      this.$popover.hide();
22208    };
22209  };
22210
22211  var ImageDialog = function (context) {
22212    var self = this;
22213    var ui = $.summernote.ui;
22214
22215    var $editor = context.layoutInfo.editor;
22216    var options = context.options;
22217    var lang = options.langInfo;
22218
22219    this.initialize = function () {
22220      var $container = options.dialogsInBody ? $(document.body) : $editor;
22221
22222      var imageLimitation = '';
22223      if (options.maximumImageFileSize) {
22224        var unit = Math.floor(Math.log(options.maximumImageFileSize) / Math.log(1024));
22225        var readableSize = (options.maximumImageFileSize / Math.pow(1024, unit)).toFixed(2) * 1 +
22226                           ' ' + ' KMGTP'[unit] + 'B';
22227        imageLimitation = '<small>' + lang.image.maximumFileSize + ' : ' + readableSize + '</small>';
22228      }
22229
22230      var body = '<div class="form-group note-group-select-from-files">' +
22231                   '<label>' + lang.image.selectFromFiles + '</label>' +
22232                   '<input class="note-image-input form-control" type="file" name="files" accept="image/*" multiple="multiple" />' +
22233                   imageLimitation +
22234                 '</div>' +
22235                 '<div class="form-group note-group-image-url" style="overflow:auto;">' +
22236                   '<label>' + lang.image.url + '</label>' +
22237                   '<input class="note-image-url form-control col-md-12" type="text" />' +
22238                 '</div>';
22239      var footer = '<button href="#" class="btn btn-primary note-image-btn disabled" disabled>' + lang.image.insert + '</button>';
22240
22241      this.$dialog = ui.dialog({
22242        title: lang.image.insert,
22243        fade: options.dialogsFade,
22244        body: body,
22245        footer: footer
22246      }).render().appendTo($container);
22247    };
22248
22249    this.destroy = function () {
22250      ui.hideDialog(this.$dialog);
22251      this.$dialog.remove();
22252    };
22253
22254    this.bindEnterKey = function ($input, $btn) {
22255      $input.on('keypress', function (event) {
22256        if (event.keyCode === key.code.ENTER) {
22257          $btn.trigger('click');
22258        }
22259      });
22260    };
22261
22262    this.show = function () {
22263      context.invoke('editor.saveRange');
22264      this.showImageDialog().then(function (data) {
22265        // [workaround] hide dialog before restore range for IE range focus
22266        ui.hideDialog(self.$dialog);
22267        context.invoke('editor.restoreRange');
22268
22269        if (typeof data === 'string') { // image url
22270          context.invoke('editor.insertImage', data);
22271        } else { // array of files
22272          context.invoke('editor.insertImagesOrCallback', data);
22273        }
22274      }).fail(function () {
22275        context.invoke('editor.restoreRange');
22276      });
22277    };
22278
22279    /**
22280     * show image dialog
22281     *
22282     * @param {jQuery} $dialog
22283     * @return {Promise}
22284     */
22285    this.showImageDialog = function () {
22286      return $.Deferred(function (deferred) {
22287        var $imageInput = self.$dialog.find('.note-image-input'),
22288            $imageUrl = self.$dialog.find('.note-image-url'),
22289            $imageBtn = self.$dialog.find('.note-image-btn');
22290
22291        ui.onDialogShown(self.$dialog, function () {
22292          context.triggerEvent('dialog.shown');
22293
22294          // Cloning imageInput to clear element.
22295          $imageInput.replaceWith($imageInput.clone()
22296            .on('change', function () {
22297              deferred.resolve(this.files || this.value);
22298            })
22299            .val('')
22300          );
22301
22302          $imageBtn.click(function (event) {
22303            event.preventDefault();
22304
22305            deferred.resolve($imageUrl.val());
22306          });
22307
22308          $imageUrl.on('keyup paste', function () {
22309            var url = $imageUrl.val();
22310            ui.toggleBtn($imageBtn, url);
22311          }).val('').trigger('focus');
22312          self.bindEnterKey($imageUrl, $imageBtn);
22313        });
22314
22315        ui.onDialogHidden(self.$dialog, function () {
22316          $imageInput.off('change');
22317          $imageUrl.off('keyup paste keypress');
22318          $imageBtn.off('click');
22319
22320          if (deferred.state() === 'pending') {
22321            deferred.reject();
22322          }
22323        });
22324
22325        ui.showDialog(self.$dialog);
22326      });
22327    };
22328  };
22329
22330  var ImagePopover = function (context) {
22331    var ui = $.summernote.ui;
22332
22333    var options = context.options;
22334
22335    this.shouldInitialize = function () {
22336      return !list.isEmpty(options.popover.image);
22337    };
22338
22339    this.initialize = function () {
22340      this.$popover = ui.popover({
22341        className: 'note-image-popover'
22342      }).render().appendTo('body');
22343      var $content = this.$popover.find('.popover-content');
22344
22345      context.invoke('buttons.build', $content, options.popover.image);
22346    };
22347
22348    this.destroy = function () {
22349      this.$popover.remove();
22350    };
22351
22352    this.update = function (target) {
22353      if (dom.isImg(target)) {
22354        var pos = dom.posFromPlaceholder(target);
22355        this.$popover.css({
22356          display: 'block',
22357          left: pos.left,
22358          top: pos.top
22359        });
22360      } else {
22361        this.hide();
22362      }
22363    };
22364
22365    this.hide = function () {
22366      this.$popover.hide();
22367    };
22368  };
22369
22370  var VideoDialog = function (context) {
22371    var self = this;
22372    var ui = $.summernote.ui;
22373
22374    var $editor = context.layoutInfo.editor;
22375    var options = context.options;
22376    var lang = options.langInfo;
22377
22378    this.initialize = function () {
22379      var $container = options.dialogsInBody ? $(document.body) : $editor;
22380
22381      var body = '<div class="form-group row-fluid">' +
22382          '<label>' + lang.video.url + ' <small class="text-muted">' + lang.video.providers + '</small></label>' +
22383          '<input class="note-video-url form-control span12" type="text" />' +
22384          '</div>';
22385      var footer = '<button href="#" class="btn btn-primary note-video-btn disabled" disabled>' + lang.video.insert + '</button>';
22386
22387      this.$dialog = ui.dialog({
22388        title: lang.video.insert,
22389        fade: options.dialogsFade,
22390        body: body,
22391        footer: footer
22392      }).render().appendTo($container);
22393    };
22394
22395    this.destroy = function () {
22396      ui.hideDialog(this.$dialog);
22397      this.$dialog.remove();
22398    };
22399
22400    this.bindEnterKey = function ($input, $btn) {
22401      $input.on('keypress', function (event) {
22402        if (event.keyCode === key.code.ENTER) {
22403          $btn.trigger('click');
22404        }
22405      });
22406    };
22407
22408    this.createVideoNode = function (url) {
22409      // video url patterns(youtube, instagram, vimeo, dailymotion, youku, mp4, ogg, webm)
22410      var ytRegExp = /^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
22411      var ytMatch = url.match(ytRegExp);
22412
22413      var igRegExp = /(?:www\.|\/\/)instagram\.com\/p\/(.[a-zA-Z0-9_-]*)/;
22414      var igMatch = url.match(igRegExp);
22415
22416      var vRegExp = /\/\/vine\.co\/v\/([a-zA-Z0-9]+)/;
22417      var vMatch = url.match(vRegExp);
22418
22419      var vimRegExp = /\/\/(player\.)?vimeo\.com\/([a-z]*\/)*([0-9]{6,11})[?]?.*/;
22420      var vimMatch = url.match(vimRegExp);
22421
22422      var dmRegExp = /.+dailymotion.com\/(video|hub)\/([^_]+)[^#]*(#video=([^_&]+))?/;
22423      var dmMatch = url.match(dmRegExp);
22424
22425      var youkuRegExp = /\/\/v\.youku\.com\/v_show\/id_(\w+)=*\.html/;
22426      var youkuMatch = url.match(youkuRegExp);
22427
22428      var mp4RegExp = /^.+.(mp4|m4v)$/;
22429      var mp4Match = url.match(mp4RegExp);
22430
22431      var oggRegExp = /^.+.(ogg|ogv)$/;
22432      var oggMatch = url.match(oggRegExp);
22433
22434      var webmRegExp = /^.+.(webm)$/;
22435      var webmMatch = url.match(webmRegExp);
22436
22437      var $video;
22438      if (ytMatch && ytMatch[1].length === 11) {
22439        var youtubeId = ytMatch[1];
22440        $video = $('<iframe>')
22441            .attr('frameborder', 0)
22442            .attr('src', '//www.youtube.com/embed/' + youtubeId)
22443            .attr('width', '640').attr('height', '360');
22444      } else if (igMatch && igMatch[0].length) {
22445        $video = $('<iframe>')
22446            .attr('frameborder', 0)
22447            .attr('src', 'https://instagram.com/p/' + igMatch[1] + '/embed/')
22448            .attr('width', '612').attr('height', '710')
22449            .attr('scrolling', 'no')
22450            .attr('allowtransparency', 'true');
22451      } else if (vMatch && vMatch[0].length) {
22452        $video = $('<iframe>')
22453            .attr('frameborder', 0)
22454            .attr('src', vMatch[0] + '/embed/simple')
22455            .attr('width', '600').attr('height', '600')
22456            .attr('class', 'vine-embed');
22457      } else if (vimMatch && vimMatch[3].length) {
22458        $video = $('<iframe webkitallowfullscreen mozallowfullscreen allowfullscreen>')
22459            .attr('frameborder', 0)
22460            .attr('src', '//player.vimeo.com/video/' + vimMatch[3])
22461            .attr('width', '640').attr('height', '360');
22462      } else if (dmMatch && dmMatch[2].length) {
22463        $video = $('<iframe>')
22464            .attr('frameborder', 0)
22465            .attr('src', '//www.dailymotion.com/embed/video/' + dmMatch[2])
22466            .attr('width', '640').attr('height', '360');
22467      } else if (youkuMatch && youkuMatch[1].length) {
22468        $video = $('<iframe webkitallowfullscreen mozallowfullscreen allowfullscreen>')
22469            .attr('frameborder', 0)
22470            .attr('height', '498')
22471            .attr('width', '510')
22472            .attr('src', '//player.youku.com/embed/' + youkuMatch[1]);
22473      } else if (mp4Match || oggMatch || webmMatch) {
22474        $video = $('<video controls>')
22475            .attr('src', url)
22476            .attr('width', '640').attr('height', '360');
22477      } else {
22478        // this is not a known video link. Now what, Cat? Now what?
22479        return false;
22480      }
22481
22482      $video.addClass('note-video-clip');
22483
22484      return $video[0];
22485    };
22486
22487    this.show = function () {
22488      var text = context.invoke('editor.getSelectedText');
22489      context.invoke('editor.saveRange');
22490      this.showVideoDialog(text).then(function (url) {
22491        // [workaround] hide dialog before restore range for IE range focus
22492        ui.hideDialog(self.$dialog);
22493        context.invoke('editor.restoreRange');
22494
22495        // build node
22496        var $node = self.createVideoNode(url);
22497
22498        if ($node) {
22499          // insert video node
22500          context.invoke('editor.insertNode', $node);
22501        }
22502      }).fail(function () {
22503        context.invoke('editor.restoreRange');
22504      });
22505    };
22506
22507    /**
22508     * show image dialog
22509     *
22510     * @param {jQuery} $dialog
22511     * @return {Promise}
22512     */
22513    this.showVideoDialog = function (text) {
22514      return $.Deferred(function (deferred) {
22515        var $videoUrl = self.$dialog.find('.note-video-url'),
22516            $videoBtn = self.$dialog.find('.note-video-btn');
22517
22518        ui.onDialogShown(self.$dialog, function () {
22519          context.triggerEvent('dialog.shown');
22520
22521          $videoUrl.val(text).on('input', function () {
22522            ui.toggleBtn($videoBtn, $videoUrl.val());
22523          }).trigger('focus');
22524
22525          $videoBtn.click(function (event) {
22526            event.preventDefault();
22527
22528            deferred.resolve($videoUrl.val());
22529          });
22530
22531          self.bindEnterKey($videoUrl, $videoBtn);
22532        });
22533
22534        ui.onDialogHidden(self.$dialog, function () {
22535          $videoUrl.off('input');
22536          $videoBtn.off('click');
22537
22538          if (deferred.state() === 'pending') {
22539            deferred.reject();
22540          }
22541        });
22542
22543        ui.showDialog(self.$dialog);
22544      });
22545    };
22546  };
22547
22548  var HelpDialog = function (context) {
22549    var self = this;
22550    var ui = $.summernote.ui;
22551
22552    var $editor = context.layoutInfo.editor;
22553    var options = context.options;
22554    var lang = options.langInfo;
22555
22556    this.createShortCutList = function () {
22557      var keyMap = options.keyMap[agent.isMac ? 'mac' : 'pc'];
22558      return Object.keys(keyMap).map(function (key) {
22559        var command = keyMap[key];
22560        var $row = $('<div><div class="help-list-item"/></div>');
22561        $row.append($('<label><kbd>' + key + '</kdb></label>').css({
22562          'width': 180,
22563          'margin-right': 10
22564        })).append($('<span/>').html(context.memo('help.' + command) || command));
22565        return $row.html();
22566      }).join('');
22567    };
22568
22569    this.initialize = function () {
22570      var $container = options.dialogsInBody ? $(document.body) : $editor;
22571
22572      var body = [
22573        '<p class="text-center">',
22574        '<a href="http://summernote.org/" target="_blank">Summernote 0.8.2</a> · ',
22575        '<a href="https://github.com/summernote/summernote" target="_blank">Project</a> · ',
22576        '<a href="https://github.com/summernote/summernote/issues" target="_blank">Issues</a>',
22577        '</p>'
22578      ].join('');
22579
22580      this.$dialog = ui.dialog({
22581        title: lang.options.help,
22582        fade: options.dialogsFade,
22583        body: this.createShortCutList(),
22584        footer: body,
22585        callback: function ($node) {
22586          $node.find('.modal-body').css({
22587            'max-height': 300,
22588            'overflow': 'scroll'
22589          });
22590        }
22591      }).render().appendTo($container);
22592    };
22593
22594    this.destroy = function () {
22595      ui.hideDialog(this.$dialog);
22596      this.$dialog.remove();
22597    };
22598
22599    /**
22600     * show help dialog
22601     *
22602     * @return {Promise}
22603     */
22604    this.showHelpDialog = function () {
22605      return $.Deferred(function (deferred) {
22606        ui.onDialogShown(self.$dialog, function () {
22607          context.triggerEvent('dialog.shown');
22608          deferred.resolve();
22609        });
22610        ui.showDialog(self.$dialog);
22611      }).promise();
22612    };
22613
22614    this.show = function () {
22615      context.invoke('editor.saveRange');
22616      this.showHelpDialog().then(function () {
22617        context.invoke('editor.restoreRange');
22618      });
22619    };
22620  };
22621
22622  var AirPopover = function (context) {
22623    var self = this;
22624    var ui = $.summernote.ui;
22625
22626    var options = context.options;
22627
22628    var AIR_MODE_POPOVER_X_OFFSET = 20;
22629
22630    this.events = {
22631      'summernote.keyup summernote.mouseup summernote.scroll': function () {
22632        self.update();
22633      },
22634      'summernote.change summernote.dialog.shown': function () {
22635        self.hide();
22636      },
22637      'summernote.focusout': function (we, e) {
22638        // [workaround] Firefox doesn't support relatedTarget on focusout
22639        //  - Ignore hide action on focus out in FF.
22640        if (agent.isFF) {
22641          return;
22642        }
22643
22644        if (!e.relatedTarget || !dom.ancestor(e.relatedTarget, func.eq(self.$popover[0]))) {
22645          self.hide();
22646        }
22647      }
22648    };
22649
22650    this.shouldInitialize = function () {
22651      return options.airMode && !list.isEmpty(options.popover.air);
22652    };
22653
22654    this.initialize = function () {
22655      this.$popover = ui.popover({
22656        className: 'note-air-popover'
22657      }).render().appendTo('body');
22658      var $content = this.$popover.find('.popover-content');
22659
22660      context.invoke('buttons.build', $content, options.popover.air);
22661    };
22662
22663    this.destroy = function () {
22664      this.$popover.remove();
22665    };
22666
22667    this.update = function () {
22668      var styleInfo = context.invoke('editor.currentStyle');
22669      if (styleInfo.range && !styleInfo.range.isCollapsed()) {
22670        var rect = list.last(styleInfo.range.getClientRects());
22671        if (rect) {
22672          var bnd = func.rect2bnd(rect);
22673          this.$popover.css({
22674            display: 'block',
22675            left: Math.max(bnd.left + bnd.width / 2, 0) - AIR_MODE_POPOVER_X_OFFSET,
22676            top: bnd.top + bnd.height
22677          });
22678        }
22679      } else {
22680        this.hide();
22681      }
22682    };
22683
22684    this.hide = function () {
22685      this.$popover.hide();
22686    };
22687  };
22688
22689  var HintPopover = function (context) {
22690    var self = this;
22691    var ui = $.summernote.ui;
22692
22693    var POPOVER_DIST = 5;
22694    var hint = context.options.hint || [];
22695    var direction = context.options.hintDirection || 'bottom';
22696    var hints = $.isArray(hint) ? hint : [hint];
22697
22698    this.events = {
22699      'summernote.keyup': function (we, e) {
22700        if (!e.isDefaultPrevented()) {
22701          self.handleKeyup(e);
22702        }
22703      },
22704      'summernote.keydown': function (we, e) {
22705        self.handleKeydown(e);
22706      },
22707      'summernote.dialog.shown': function () {
22708        self.hide();
22709      }
22710    };
22711
22712    this.shouldInitialize = function () {
22713      return hints.length > 0;
22714    };
22715
22716    this.initialize = function () {
22717      this.lastWordRange = null;
22718      this.$popover = ui.popover({
22719        className: 'note-hint-popover',
22720        hideArrow: true,
22721        direction: ''
22722      }).render().appendTo('body');
22723
22724      this.$popover.hide();
22725
22726      this.$content = this.$popover.find('.popover-content');
22727
22728      this.$content.on('click', '.note-hint-item', function () {
22729        self.$content.find('.active').removeClass('active');
22730        $(this).addClass('active');
22731        self.replace();
22732      });
22733    };
22734
22735    this.destroy = function () {
22736      this.$popover.remove();
22737    };
22738
22739    this.selectItem = function ($item) {
22740      this.$content.find('.active').removeClass('active');
22741      $item.addClass('active');
22742
22743      this.$content[0].scrollTop = $item[0].offsetTop - (this.$content.innerHeight() / 2);
22744    };
22745
22746    this.moveDown = function () {
22747      var $current = this.$content.find('.note-hint-item.active');
22748      var $next = $current.next();
22749
22750      if ($next.length) {
22751        this.selectItem($next);
22752      } else {
22753        var $nextGroup = $current.parent().next();
22754
22755        if (!$nextGroup.length) {
22756          $nextGroup = this.$content.find('.note-hint-group').first();
22757        }
22758
22759        this.selectItem($nextGroup.find('.note-hint-item').first());
22760      }
22761    };
22762
22763    this.moveUp = function () {
22764      var $current = this.$content.find('.note-hint-item.active');
22765      var $prev = $current.prev();
22766
22767      if ($prev.length) {
22768        this.selectItem($prev);
22769      } else {
22770        var $prevGroup = $current.parent().prev();
22771
22772        if (!$prevGroup.length) {
22773          $prevGroup = this.$content.find('.note-hint-group').last();
22774        }
22775
22776        this.selectItem($prevGroup.find('.note-hint-item').last());
22777      }
22778    };
22779
22780    this.replace = function () {
22781      var $item = this.$content.find('.note-hint-item.active');
22782
22783      if ($item.length) {
22784        var node = this.nodeFromItem($item);
22785        this.lastWordRange.insertNode(node);
22786        range.createFromNode(node).collapse().select();
22787
22788        this.lastWordRange = null;
22789        this.hide();
22790        context.invoke('editor.focus');
22791      }
22792
22793    };
22794
22795    this.nodeFromItem = function ($item) {
22796      var hint = hints[$item.data('index')];
22797      var item = $item.data('item');
22798      var node = hint.content ? hint.content(item) : item;
22799      if (typeof node === 'string') {
22800        node = dom.createText(node);
22801      }
22802      return node;
22803    };
22804
22805    this.createItemTemplates = function (hintIdx, items) {
22806      var hint = hints[hintIdx];
22807      return items.map(function (item, idx) {
22808        var $item = $('<div class="note-hint-item"/>');
22809        $item.append(hint.template ? hint.template(item) : item + '');
22810        $item.data({
22811          'index': hintIdx,
22812          'item': item
22813        });
22814
22815        if (hintIdx === 0 && idx === 0) {
22816          $item.addClass('active');
22817        }
22818        return $item;
22819      });
22820    };
22821
22822    this.handleKeydown = function (e) {
22823      if (!this.$popover.is(':visible')) {
22824        return;
22825      }
22826
22827      if (e.keyCode === key.code.ENTER) {
22828        e.preventDefault();
22829        this.replace();
22830      } else if (e.keyCode === key.code.UP) {
22831        e.preventDefault();
22832        this.moveUp();
22833      } else if (e.keyCode === key.code.DOWN) {
22834        e.preventDefault();
22835        this.moveDown();
22836      }
22837    };
22838
22839    this.searchKeyword = function (index, keyword, callback) {
22840      var hint = hints[index];
22841      if (hint && hint.match.test(keyword) && hint.search) {
22842        var matches = hint.match.exec(keyword);
22843        hint.search(matches[1], callback);
22844      } else {
22845        callback();
22846      }
22847    };
22848
22849    this.createGroup = function (idx, keyword) {
22850      var $group = $('<div class="note-hint-group note-hint-group-' + idx + '"/>');
22851      this.searchKeyword(idx, keyword, function (items) {
22852        items = items || [];
22853        if (items.length) {
22854          $group.html(self.createItemTemplates(idx, items));
22855          self.show();
22856        }
22857      });
22858
22859      return $group;
22860    };
22861
22862    this.handleKeyup = function (e) {
22863      if (list.contains([key.code.ENTER, key.code.UP, key.code.DOWN], e.keyCode)) {
22864        if (e.keyCode === key.code.ENTER) {
22865          if (this.$popover.is(':visible')) {
22866            return;
22867          }
22868        }
22869      } else {
22870        var wordRange = context.invoke('editor.createRange').getWordRange();
22871        var keyword = wordRange.toString();
22872        if (hints.length && keyword) {
22873          this.$content.empty();
22874
22875          var bnd = func.rect2bnd(list.last(wordRange.getClientRects()));
22876          if (bnd) {
22877
22878            this.$popover.hide();
22879
22880            this.lastWordRange = wordRange;
22881
22882            hints.forEach(function (hint, idx) {
22883              if (hint.match.test(keyword)) {
22884                self.createGroup(idx, keyword).appendTo(self.$content);
22885              }
22886            });
22887
22888            // set position for popover after group is created
22889            if (direction === 'top') {
22890              this.$popover.css({
22891                left: bnd.left,
22892                top: bnd.top - this.$popover.outerHeight() - POPOVER_DIST
22893              });
22894            } else {
22895              this.$popover.css({
22896                left: bnd.left,
22897                top: bnd.top + bnd.height + POPOVER_DIST
22898              });
22899            }
22900
22901          }
22902        } else {
22903          this.hide();
22904        }
22905      }
22906    };
22907
22908    this.show = function () {
22909      this.$popover.show();
22910    };
22911
22912    this.hide = function () {
22913      this.$popover.hide();
22914    };
22915  };
22916
22917
22918  $.summernote = $.extend($.summernote, {
22919    version: '0.8.2',
22920    ui: ui,
22921    dom: dom,
22922
22923    plugins: {},
22924
22925    options: {
22926      modules: {
22927        'editor': Editor,
22928        'clipboard': Clipboard,
22929        'dropzone': Dropzone,
22930        'codeview': Codeview,
22931        'statusbar': Statusbar,
22932        'fullscreen': Fullscreen,
22933        'handle': Handle,
22934        // FIXME: HintPopover must be front of autolink
22935        //  - Script error about range when Enter key is pressed on hint popover
22936        'hintPopover': HintPopover,
22937        'autoLink': AutoLink,
22938        'autoSync': AutoSync,
22939        'placeholder': Placeholder,
22940        'buttons': Buttons,
22941        'toolbar': Toolbar,
22942        'linkDialog': LinkDialog,
22943        'linkPopover': LinkPopover,
22944        'imageDialog': ImageDialog,
22945        'imagePopover': ImagePopover,
22946        'videoDialog': VideoDialog,
22947        'helpDialog': HelpDialog,
22948        'airPopover': AirPopover
22949      },
22950
22951      buttons: {},
22952      
22953      lang: 'en-US',
22954
22955      // toolbar
22956      toolbar: [
22957        ['style', ['style']],
22958        ['font', ['bold', 'underline', 'clear']],
22959        ['fontname', ['fontname']],
22960        ['color', ['color']],
22961        ['para', ['ul', 'ol', 'paragraph']],
22962        ['table', ['table']],
22963        ['insert', ['link', 'picture', 'video']],
22964        ['view', ['fullscreen', 'codeview', 'help']]
22965      ],
22966
22967      // popover
22968      popover: {
22969        image: [
22970          ['imagesize', ['imageSize100', 'imageSize50', 'imageSize25']],
22971          ['float', ['floatLeft', 'floatRight', 'floatNone']],
22972          ['remove', ['removeMedia']]
22973        ],
22974        link: [
22975          ['link', ['linkDialogShow', 'unlink']]
22976        ],
22977        air: [
22978          ['color', ['color']],
22979          ['font', ['bold', 'underline', 'clear']],
22980          ['para', ['ul', 'paragraph']],
22981          ['table', ['table']],
22982          ['insert', ['link', 'picture']]
22983        ]
22984      },
22985
22986      // air mode: inline editor
22987      airMode: false,
22988
22989      width: null,
22990      height: null,
22991
22992      focus: false,
22993      tabSize: 4,
22994      styleWithSpan: true,
22995      shortcuts: true,
22996      textareaAutoSync: true,
22997      direction: null,
22998
22999      styleTags: ['p', 'blockquote', 'pre', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'],
23000
23001      fontNames: [
23002        'Arial', 'Arial Black', 'Comic Sans MS', 'Courier New',
23003        'Helvetica Neue', 'Helvetica', 'Impact', 'Lucida Grande',
23004        'Tahoma', 'Times New Roman', 'Verdana'
23005      ],
23006
23007      fontSizes: ['8', '9', '10', '11', '12', '14', '18', '24', '36'],
23008
23009      // pallete colors(n x n)
23010      colors: [
23011        ['#000000', '#424242', '#636363', '#9C9C94', '#CEC6CE', '#EFEFEF', '#F7F7F7', '#FFFFFF'],
23012        ['#FF0000', '#FF9C00', '#FFFF00', '#00FF00', '#00FFFF', '#0000FF', '#9C00FF', '#FF00FF'],
23013        ['#F7C6CE', '#FFE7CE', '#FFEFC6', '#D6EFD6', '#CEDEE7', '#CEE7F7', '#D6D6E7', '#E7D6DE'],
23014        ['#E79C9C', '#FFC69C', '#FFE79C', '#B5D6A5', '#A5C6CE', '#9CC6EF', '#B5A5D6', '#D6A5BD'],
23015        ['#E76363', '#F7AD6B', '#FFD663', '#94BD7B', '#73A5AD', '#6BADDE', '#8C7BC6', '#C67BA5'],
23016        ['#CE0000', '#E79439', '#EFC631', '#6BA54A', '#4A7B8C', '#3984C6', '#634AA5', '#A54A7B'],
23017        ['#9C0000', '#B56308', '#BD9400', '#397B21', '#104A5A', '#085294', '#311873', '#731842'],
23018        ['#630000', '#7B3900', '#846300', '#295218', '#083139', '#003163', '#21104A', '#4A1031']
23019      ],
23020
23021      lineHeights: ['1.0', '1.2', '1.4', '1.5', '1.6', '1.8', '2.0', '3.0'],
23022
23023      tableClassName: 'table table-bordered',
23024
23025      insertTableMaxSize: {
23026        col: 10,
23027        row: 10
23028      },
23029
23030      dialogsInBody: false,
23031      dialogsFade: false,
23032
23033      maximumImageFileSize: null,
23034
23035      callbacks: {
23036        onInit: null,
23037        onFocus: null,
23038        onBlur: null,
23039        onEnter: null,
23040        onKeyup: null,
23041        onKeydown: null,
23042        onImageUpload: null,
23043        onImageUploadError: null
23044      },
23045
23046      codemirror: {
23047        mode: 'text/html',
23048        htmlMode: true,
23049        lineNumbers: true
23050      },
23051
23052      keyMap: {
23053        pc: {
23054          'ENTER': 'insertParagraph',
23055          'CTRL+Z': 'undo',
23056          'CTRL+Y': 'redo',
23057          'TAB': 'tab',
23058          'SHIFT+TAB': 'untab',
23059          'CTRL+B': 'bold',
23060          'CTRL+I': 'italic',
23061          'CTRL+U': 'underline',
23062          'CTRL+SHIFT+S': 'strikethrough',
23063          'CTRL+BACKSLASH': 'removeFormat',
23064          'CTRL+SHIFT+L': 'justifyLeft',
23065          'CTRL+SHIFT+E': 'justifyCenter',
23066          'CTRL+SHIFT+R': 'justifyRight',
23067          'CTRL+SHIFT+J': 'justifyFull',
23068          'CTRL+SHIFT+NUM7': 'insertUnorderedList',
23069          'CTRL+SHIFT+NUM8': 'insertOrderedList',
23070          'CTRL+LEFTBRACKET': 'outdent',
23071          'CTRL+RIGHTBRACKET': 'indent',
23072          'CTRL+NUM0': 'formatPara',
23073          'CTRL+NUM1': 'formatH1',
23074          'CTRL+NUM2': 'formatH2',
23075          'CTRL+NUM3': 'formatH3',
23076          'CTRL+NUM4': 'formatH4',
23077          'CTRL+NUM5': 'formatH5',
23078          'CTRL+NUM6': 'formatH6',
23079          'CTRL+ENTER': 'insertHorizontalRule',
23080          'CTRL+K': 'linkDialog.show'
23081        },
23082
23083        mac: {
23084          'ENTER': 'insertParagraph',
23085          'CMD+Z': 'undo',
23086          'CMD+SHIFT+Z': 'redo',
23087          'TAB': 'tab',
23088          'SHIFT+TAB': 'untab',
23089          'CMD+B': 'bold',
23090          'CMD+I': 'italic',
23091          'CMD+U': 'underline',
23092          'CMD+SHIFT+S': 'strikethrough',
23093          'CMD+BACKSLASH': 'removeFormat',
23094          'CMD+SHIFT+L': 'justifyLeft',
23095          'CMD+SHIFT+E': 'justifyCenter',
23096          'CMD+SHIFT+R': 'justifyRight',
23097          'CMD+SHIFT+J': 'justifyFull',
23098          'CMD+SHIFT+NUM7': 'insertUnorderedList',
23099          'CMD+SHIFT+NUM8': 'insertOrderedList',
23100          'CMD+LEFTBRACKET': 'outdent',
23101          'CMD+RIGHTBRACKET': 'indent',
23102          'CMD+NUM0': 'formatPara',
23103          'CMD+NUM1': 'formatH1',
23104          'CMD+NUM2': 'formatH2',
23105          'CMD+NUM3': 'formatH3',
23106          'CMD+NUM4': 'formatH4',
23107          'CMD+NUM5': 'formatH5',
23108          'CMD+NUM6': 'formatH6',
23109          'CMD+ENTER': 'insertHorizontalRule',
23110          'CMD+K': 'linkDialog.show'
23111        }
23112      },
23113      icons: {
23114        'align': 'note-icon-align',
23115        'alignCenter': 'note-icon-align-center',
23116        'alignJustify': 'note-icon-align-justify',
23117        'alignLeft': 'note-icon-align-left',
23118        'alignRight': 'note-icon-align-right',
23119        'indent': 'note-icon-align-indent',
23120        'outdent': 'note-icon-align-outdent',
23121        'arrowsAlt': 'note-icon-arrows-alt',
23122        'bold': 'note-icon-bold',
23123        'caret': 'note-icon-caret',
23124        'circle': 'note-icon-circle',
23125        'close': 'note-icon-close',
23126        'code': 'note-icon-code',
23127        'eraser': 'note-icon-eraser',
23128        'font': 'note-icon-font',
23129        'frame': 'note-icon-frame',
23130        'italic': 'note-icon-italic',
23131        'link': 'note-icon-link',
23132        'unlink': 'note-icon-chain-broken',
23133        'magic': 'note-icon-magic',
23134        'menuCheck': 'note-icon-check',
23135        'minus': 'note-icon-minus',
23136        'orderedlist': 'note-icon-orderedlist',
23137        'pencil': 'note-icon-pencil',
23138        'picture': 'note-icon-picture',
23139        'question': 'note-icon-question',
23140        'redo': 'note-icon-redo',
23141        'square': 'note-icon-square',
23142        'strikethrough': 'note-icon-strikethrough',
23143        'subscript': 'note-icon-subscript',
23144        'superscript': 'note-icon-superscript',
23145        'table': 'note-icon-table',
23146        'textHeight': 'note-icon-text-height',
23147        'trash': 'note-icon-trash',
23148        'underline': 'note-icon-underline',
23149        'undo': 'note-icon-undo',
23150        'unorderedlist': 'note-icon-unorderedlist',
23151        'video': 'note-icon-video'
23152      }
23153    }
23154  });
23155
23156}));
23157
23158(function ($) {
23159  $.extend($.summernote.lang, {
23160    'sk-SK': {
23161      font: {
23162        bold: 'Tučné',
23163        italic: 'Kurzíva',
23164        underline: 'Podčiarknutie',
23165        clear: 'Odstrániť štýl písma',
23166        height: 'Výška riadku',
23167        strikethrough: 'Prečiarknuté',
23168        size: 'Veľkosť písma'
23169      },
23170      image: {
23171        image: 'Obrázok',
23172        insert: 'Vložiť obrázok',
23173        resizeFull: 'Pôvodná veľkosť',
23174        resizeHalf: 'Polovičná veľkosť',
23175        resizeQuarter: 'Štvrtinová veľkosť',
23176        floatLeft: 'Umiestniť doľava',
23177        floatRight: 'Umiestniť doprava',
23178        floatNone: 'Bez zarovnania',
23179        dragImageHere: 'Pretiahnuť sem obrázok',
23180        selectFromFiles: 'Vybrať súbor',
23181        url: 'URL obrázku'
23182      },
23183      video: {
23184        video: 'Video',
23185        videoLink: 'Odkaz videa',
23186        insert: 'Vložiť video',
23187        url: 'URL videa?',
23188        providers: '(YouTube, Vimeo, Vine, Instagram, DailyMotion alebo Youku)'
23189      },
23190      link: {
23191        link: 'Odkaz',
23192        insert: 'Vytvoriť odkaz',
23193        unlink: 'Zrušiť odkaz',
23194        edit: 'Upraviť',
23195        textToDisplay: 'Zobrazovaný text',
23196        url: 'Na akú URL adresu má tento odkaz viesť?',
23197        openInNewWindow: 'Otvoriť v novom okne'
23198      },
23199      table: {
23200        table: 'Tabuľka'
23201      },
23202      hr: {
23203        insert: 'Vložit vodorovnú čiaru'
23204      },
23205      style: {
23206        style: 'Štýl',
23207        p: 'Normálny',
23208        blockquote: 'Citácia',
23209        pre: 'Kód',
23210        h1: 'Nadpis 1',
23211        h2: 'Nadpis 2',
23212        h3: 'Nadpis 3',
23213        h4: 'Nadpis 4',
23214        h5: 'Nadpis 5',
23215        h6: 'Nadpis 6'
23216      },
23217      lists: {
23218        unordered: 'Odrážkový zoznam',
23219        ordered: 'Číselný zoznam'
23220      },
23221      options: {
23222        help: 'Pomoc',
23223        fullscreen: 'Celá obrazovka',
23224        codeview: 'HTML kód'
23225      },
23226      paragraph: {
23227        paragraph: 'Odsek',
23228        outdent: 'Zväčšiť odsadenie',
23229        indent: 'Zmenšiť odsadenie',
23230        left: 'Zarovnať doľava',
23231        center: 'Zarovnať na stred',
23232        right: 'Zarovnať doprava',
23233        justify: 'Zarovnať obojstranne'
23234      },
23235      color: {
23236        recent: 'Aktuálna farba',
23237        more: 'Dalšie farby',
23238        background: 'Farba pozadia',
23239        foreground: 'Farba písma',
23240        transparent: 'Priehľadnosť',
23241        setTransparent: 'Nastaviť priehľadnosť',
23242        reset: 'Obnoviť',
23243        resetToDefault: 'Obnoviť prednastavené'
23244      },
23245      shortcut: {
23246        shortcuts: 'Klávesové skratky',
23247        close: 'Zavrieť',
23248        textFormatting: 'Formátovanie textu',
23249        action: 'Akcia',
23250        paragraphFormatting: 'Formátovanie odseku',
23251        documentStyle: 'Štýl dokumentu'
23252      },
23253      history: {
23254        undo: 'Krok vzad',
23255        redo: 'Krok dopredu'
23256      }
23257    }
23258  });
23259})(jQuery);
23260
23261/*!
23262 * Chart.js
23263 * http://chartjs.org/
23264 * Version: 2.4.0
23265 *
23266 * Copyright 2016 Nick Downie
23267 * Released under the MIT license
23268 * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md
23269 */
23270!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Chart=t()}}(function(){var t;return function e(t,n,i){function a(o,s){if(!n[o]){if(!t[o]){var l="function"==typeof require&&require;if(!s&&l)return l(o,!0);if(r)return r(o,!0);var u=new Error("Cannot find module '"+o+"'");throw u.code="MODULE_NOT_FOUND",u}var d=n[o]={exports:{}};t[o][0].call(d.exports,function(e){var n=t[o][1][e];return a(n?n:e)},d,d.exports,e,t,n,i)}return n[o].exports}for(var r="function"==typeof require&&require,o=0;o<i.length;o++)a(i[o]);return a}({1:[function(t,e,n){function i(t){if(t){var e=/^#([a-fA-F0-9]{3})$/,n=/^#([a-fA-F0-9]{6})$/,i=/^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,a=/^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,r=/(\w+)/,o=[0,0,0],s=1,l=t.match(e);if(l){l=l[1];for(var u=0;u<o.length;u++)o[u]=parseInt(l[u]+l[u],16)}else if(l=t.match(n)){l=l[1];for(var u=0;u<o.length;u++)o[u]=parseInt(l.slice(2*u,2*u+2),16)}else if(l=t.match(i)){for(var u=0;u<o.length;u++)o[u]=parseInt(l[u+1]);s=parseFloat(l[4])}else if(l=t.match(a)){for(var u=0;u<o.length;u++)o[u]=Math.round(2.55*parseFloat(l[u+1]));s=parseFloat(l[4])}else if(l=t.match(r)){if("transparent"==l[1])return[0,0,0,0];if(o=x[l[1]],!o)return}for(var u=0;u<o.length;u++)o[u]=b(o[u],0,255);return s=s||0==s?b(s,0,1):1,o[3]=s,o}}function a(t){if(t){var e=/^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/,n=t.match(e);if(n){var i=parseFloat(n[4]),a=b(parseInt(n[1]),0,360),r=b(parseFloat(n[2]),0,100),o=b(parseFloat(n[3]),0,100),s=b(isNaN(i)?1:i,0,1);return[a,r,o,s]}}}function r(t){if(t){var e=/^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/,n=t.match(e);if(n){var i=parseFloat(n[4]),a=b(parseInt(n[1]),0,360),r=b(parseFloat(n[2]),0,100),o=b(parseFloat(n[3]),0,100),s=b(isNaN(i)?1:i,0,1);return[a,r,o,s]}}}function o(t){var e=i(t);return e&&e.slice(0,3)}function s(t){var e=a(t);return e&&e.slice(0,3)}function l(t){var e=i(t);return e?e[3]:(e=a(t))?e[3]:(e=r(t))?e[3]:void 0}function u(t){return"#"+y(t[0])+y(t[1])+y(t[2])}function d(t,e){return 1>e||t[3]&&t[3]<1?c(t,e):"rgb("+t[0]+", "+t[1]+", "+t[2]+")"}function c(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"rgba("+t[0]+", "+t[1]+", "+t[2]+", "+e+")"}function h(t,e){if(1>e||t[3]&&t[3]<1)return f(t,e);var n=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),a=Math.round(t[2]/255*100);return"rgb("+n+"%, "+i+"%, "+a+"%)"}function f(t,e){var n=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),a=Math.round(t[2]/255*100);return"rgba("+n+"%, "+i+"%, "+a+"%, "+(e||t[3]||1)+")"}function g(t,e){return 1>e||t[3]&&t[3]<1?m(t,e):"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"}function m(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hsla("+t[0]+", "+t[1]+"%, "+t[2]+"%, "+e+")"}function p(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"}function v(t){return k[t.slice(0,3)]}function b(t,e,n){return Math.min(Math.max(e,t),n)}function y(t){var e=t.toString(16).toUpperCase();return e.length<2?"0"+e:e}var x=t(5);e.exports={getRgba:i,getHsla:a,getRgb:o,getHsl:s,getHwb:r,getAlpha:l,hexString:u,rgbString:d,rgbaString:c,percentStr
23270ing:h,percentaString:f,hslString:g,hslaString:m,hwbString:p,keyword:v};var k={};for(var _ in x)k[x[_]]=_},{5:5}],2:[function(t,e,n){var i=t(4),a=t(1),r=function(t){if(t instanceof r)return t;if(!(this instanceof r))return new r(t);this.values={rgb:[0,0,0],hsl:[0,0,0],hsv:[0,0,0],hwb:[0,0,0],cmyk:[0,0,0,0],alpha:1};var e;if("string"==typeof t)if(e=a.getRgba(t))this.setValues("rgb",e);else if(e=a.getHsla(t))this.setValues("hsl",e);else{if(!(e=a.getHwb(t)))throw new Error('Unable to parse color from string "'+t+'"');this.setValues("hwb",e)}else if("object"==typeof t)if(e=t,void 0!==e.r||void 0!==e.red)this.setValues("rgb",e);else if(void 0!==e.l||void 0!==e.lightness)this.setValues("hsl",e);else if(void 0!==e.v||void 0!==e.value)this.setValues("hsv",e);else if(void 0!==e.w||void 0!==e.whiteness)this.setValues("hwb",e);else{if(void 0===e.c&&void 0===e.cyan)throw new Error("Unable to parse color from object "+JSON.stringify(t));this.setValues("cmyk",e)}};r.prototype={rgb:function(){return this.setSpace("rgb",arguments)},hsl:function(){return this.setSpace("hsl",arguments)},hsv:function(){return this.setSpace("hsv",arguments)},hwb:function(){return this.setSpace("hwb",arguments)},cmyk:function(){return this.setSpace("cmyk",arguments)},rgbArray:function(){return this.values.rgb},hslArray:function(){return this.values.hsl},hsvArray:function(){return this.values.hsv},hwbArray:function(){var t=this.values;return 1!==t.alpha?t.hwb.concat([t.alpha]):t.hwb},cmykArray:function(){return this.values.cmyk},rgbaArray:function(){var t=this.values;return t.rgb.concat([t.alpha])},hslaArray:function(){var t=this.values;return t.hsl.concat([t.alpha])},alpha:function(t){return void 0===t?this.values.alpha:(this.setValues("alpha",t),this)},red:function(t){return this.setChannel("rgb",0,t)},green:function(t){return this.setChannel("rgb",1,t)},blue:function(t){return this.setChannel("rgb",2,t)},hue:function(t){return t&&(t%=360,t=0>t?360+t:t),this.setChannel("hsl",0,t)},saturation:function(t){return this.setChannel("hsl",1,t)},lightness:function(t){return this.setChannel("hsl",2,t)},saturationv:function(t){return this.setChannel("hsv",1,t)},whiteness:function(t){return this.setChannel("hwb",1,t)},blackness:function(t){return this.setChannel("hwb",2,t)},value:function(t){return this.setChannel("hsv",2,t)},cyan:function(t){return this.setChannel("cmyk",0,t)},magenta:function(t){return this.setChannel("cmyk",1,t)},yellow:function(t){return this.setChannel("cmyk",2,t)},black:function(t){return this.setChannel("cmyk",3,t)},hexString:function(){return a.hexString(this.values.rgb)},rgbString:function(){return a.rgbString(this.values.rgb,this.values.alpha)},rgbaString:function(){return a.rgbaString(this.values.rgb,this.values.alpha)},percentString:function(){return a.percentString(this.values.rgb,this.values.alpha)},hslString:function(){return a.hslString(this.values.hsl,this.values.alpha)},hslaString:function(){return a.hslaString(this.values.hsl,this.values.alpha)},hwbString:function(){return a.hwbString(this.values.hwb,this.values.alpha)},keyword:function(){return a.keyword(this.values.rgb,this.values.alpha)},rgbNumber:function(){var t=this.values.rgb;return t[0]<<16|t[1]<<8|t[2]},luminosity:function(){for(var t=this.values.rgb,e=[],n=0;n<t.length;n++){var i=t[n]/255;e[n]=.03928>=i?i/12.92:Math.pow((i+.055)/1.055,2.4)}return.2126*e[0]+.7152*e[1]+.0722*e[2]},contrast:function(t){var e=this.luminosity(),n=t.luminosity();return e>n?(e+.05)/(n+.05):(n+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb,e=(299*t[0]+587*t[1]+114*t[2])/1e3;return 128>e},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;3>e;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;
23270return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,n=(e[0]+t)%360;return e[0]=0>n?360+n:n,this.setValues("hsl",e),this},mix:function(t,e){var n=this,i=t,a=void 0===e?.5:e,r=2*a-1,o=n.alpha()-i.alpha(),s=((r*o===-1?r:(r+o)/(1+r*o))+1)/2,l=1-s;return this.rgb(s*n.red()+l*i.red(),s*n.green()+l*i.green(),s*n.blue()+l*i.blue()).alpha(n.alpha()*a+i.alpha()*(1-a))},toJSON:function(){return this.rgb()},clone:function(){var t,e,n=new r,i=this.values,a=n.values;for(var o in i)i.hasOwnProperty(o)&&(t=i[o],e={}.toString.call(t),"[object Array]"===e?a[o]=t.slice(0):"[object Number]"===e?a[o]=t:console.error("unexpected color value:",t));return n}},r.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},r.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},r.prototype.getValues=function(t){for(var e=this.values,n={},i=0;i<t.length;i++)n[t.charAt(i)]=e[t][i];return 1!==e.alpha&&(n.a=e.alpha),n},r.prototype.setValues=function(t,e){var n,a=this.values,r=this.spaces,o=this.maxes,s=1;if("alpha"===t)s=e;else if(e.length)a[t]=e.slice(0,t.length),s=e[t.length];else if(void 0!==e[t.charAt(0)]){for(n=0;n<t.length;n++)a[t][n]=e[t.charAt(n)];s=e.a}else if(void 0!==e[r[t][0]]){var l=r[t];for(n=0;n<t.length;n++)a[t][n]=e[l[n]];s=e.alpha}if(a.alpha=Math.max(0,Math.min(1,void 0===s?a.alpha:s)),"alpha"===t)return!1;var u;for(n=0;n<t.length;n++)u=Math.max(0,Math.min(o[t][n],a[t][n])),a[t][n]=Math.round(u);for(var d in r)d!==t&&(a[d]=i[t][d](a[t]));return!0},r.prototype.setSpace=function(t,e){var n=e[0];return void 0===n?this.getValues(t):("number"==typeof n&&(n=Array.prototype.slice.call(e)),this.setValues(t,n),this)},r.prototype.setChannel=function(t,e,n){var i=this.values[t];return void 0===n?i[e]:n===i[e]?this:(i[e]=n,this.setValues(t,i),this)},"undefined"!=typeof window&&(window.Color=r),e.exports=r},{1:1,4:4}],3:[function(t,e,n){function i(t){var e,n,i,a=t[0]/255,r=t[1]/255,o=t[2]/255,s=Math.min(a,r,o),l=Math.max(a,r,o),u=l-s;return l==s?e=0:a==l?e=(r-o)/u:r==l?e=2+(o-a)/u:o==l&&(e=4+(a-r)/u),e=Math.min(60*e,360),0>e&&(e+=360),i=(s+l)/2,n=l==s?0:.5>=i?u/(l+s):u/(2-l-s),[e,100*n,100*i]}function a(t){var e,n,i,a=t[0],r=t[1],o=t[2],s=Math.min(a,r,o),l=Math.max(a,r,o),u=l-s;return n=0==l?0:u/l*1e3/10,l==s?e=0:a==l?e=(r-o)/u:r==l?e=2+(o-a)/u:o==l&&(e=4+(a-r)/u),e=Math.min(60*e,360),0>e&&(e+=360),i=l/255*1e3/10,[e,n,i]}function o(t){var e=t[0],n=t[1],a=t[2],r=i(t)[0],o=1/255*Math.min(e,Math.min(n,a)),a=1-1/255*Math.max(e,Math.max(n,a));return[r,100*o,100*a]}function s(t){var e,n,i,a,r=t[0]/255,o=t[1]/255,s=t[2]/255;return a=Math.min(1-r,1-o,1-s),e=(1-r-a)/(1-a)||0,n=(1-o-a)/(1-a)||0,i=(1-s-a)/(1-a)||0,[100*e,100*n,100*i,100*a]}function l(t){return K[JSON.stringify(t)]}function u(t){var e=t[0]/255,n=t[1]/255,i=t[2]/255;e=e>.04045?Math.pow((e+.055)/1.055,2.4):e/12.92,n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92,i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92;var a=.4124*e+.3576*n+.1805*i,r=.2126*e+.7152*n+.0722*i,o=.0193*e+.1192*n+.9505*i;return[100*a,100*r,100*o]}function d(t){var e,n,i,a=u(t),r=a[0],o=a[1],s=a[2];return r/=95.047,o/=100,s/=108.883,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,s=s>.008856?Math.pow(s,1/3):7.787*s+16/116,e=116*o-16,n=500*(r-o),i=200*(o-s),[e,n,i]}function c(t){return Y(d(t))}function h(t){var e,n,i,a,r,o=t[0]/360,s=t[1]/100,l=t[2]/100;if(0==s)return r=255*l,[r,r,r];n=.5>l?l*(1+s):l+s-l*s,e=2*l-n,a=[0,0,0];for(var u=0;3>u;u++)i=o+1/3*-(u-1),0>i&&i++,i>1&&i--,r=1>6*i?e+6*(n-e)*i:1>2*i?n:2>3*i?e+(n-e)*(2/3-i)*6:e,a[u]=255*r;return a}function f(t){var e,n,i=t[0],a=t[1]/100,r=t[2]/100;return 0===r?[0,0,0]:(r*=2,a*=1>=r?r:2-r,n=(r+a)/2,e=2*a/(r+a),[i,100*e,100*n])}function m(t){return o(h(t))}function p(t){return s(h(t))}function v(t){return l(h(t))}function y(t){var e=t[0]/60,n=t[1]/100,i=t[2]/100,a=Math.floor(e)%6,r=e-Math.floor(e),o=255*i*(1-n),s=255*i*(1-n*r),l=255*i*(1-n*(1-r)),i=255*i;switch(a){case 0:return[i,l,o];case 1:return[s,i,o];case 2:return[o,i,l];case 3:return[o,s,i];case 4:return[l,o,i];case 5:return[i,o,s]}}function x(t){var e,n,i=t[0],a=t[1]/100,r=t[2]/100;return n=(2-a)*r,e=a*r,e/=1>=n?n:2-n,e=e||0,n/=2,[i,100*e,100*n]}function k(t){return o(y(t))}function _(t){return s(y(t))}function w(t){return l(y(t))}function S(t){var e,n,i,a,o=t[0]/360,s=t[1]/100,l=t[2]/100,u=s+l;switch(u>1&&(s/=u,l/=u),e=Math.floor(6*o),n=1-l,i=6*o-e,0!=(1&e)&&(i=1-i),a=s+i*(n-s),e){default:case 6:case 0:r=n,g=a,b=s;break;case 1:r=a,g=n,b=s;break;case 2:r=s,g=n,b=a;break;case 3:r=s,g=a,b=n;break;case 4:r=a,g=s,b=n;break;case 5:r=n,g=s,b=a}return[255*r,255*g,255*b]}function M(t){return i(S(t))}function D(t){return a(S(t))}function C(t){return s(S(t))}function T(t){return l(S(t))}function P(t){var e,n,i,a=t[0]/100,r=t[1]/100,o=t[2]/100,s=t[3]/100;return e=1-Math.min(1,a*(1-s)+s),n=1-Math.min(1,r*(1-s)+s),i=1-Math.min(1,o*(1-s)+s),[255*e,255*n,255*i]}function I(t){return i(P(t))}function F(t){return a(P(t))}function A(t){return o(P(t))}function O(t){return l(P(t))}function R(t){var e,n,i,a=t[0]/100,r=t[1]/100,o=t[2]/100;return e=3.2406*a+-1.5372*r+o*-.4986,n=a*-.9689+1.8758*r+.0415*o,i=.0557*a+r*-.204+1.057*o,e=e>.0031308?1.055*Math.pow(e,1/2.4)-.055:e=12.92*e,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:n=12.92*n,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:i=12.92*i,e=Math.min(Math.max(0,e),1),n=Math.min(Math.max(0,n),1),i=Math.min(Math.max(0,i),1),[255*e,255*n,255*i]}function L(t){var e,n,i,a=t[0],r=t[1],o=t[2];return a/=95.047,r/=100,o/=108.883,a=a>.008856?Math.pow(a,1/3):7.787*a+16/116,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,e=116*r-16,n=500*(a-r),i=200*(r-o),[e,n,i]}function W(t){return Y(L(t))}function V(t){var e,n,i,a,r=t[0],o=t[1],s=t[2];return 8>=r?(n=100*r/903.3,a=7.787*(n/100)+16/116):(n=100*Math.pow((r+16)/116,3),a=Math.pow(n/100,1/3)),e=.008856>=e/95.047?e=95.047*(o/500+a-16/116)/7.787:95.047*Math.pow(o/500+a,3),i=.008859>=i/108.883?i=108.883*(a-s/200-16/116)/7.787:108.883*Math.pow(a-s/200,3),[e,n,i]}function Y(t){var e,n,i,a=t[0],r=t[1],o=t[2];return e=Math.atan2(o,r),n=360*e/2/Math.PI,0>n&&(n+=360),i=Math.sqrt(r*r+o*o),[a,i,n]}function B(t){return R(V(t))}function z(t){var e,n,i,a=t[0],r=t[1],o=t[2];return i=o/360*2*Math.PI,e=r*Math.cos(i),n=r*Math.sin(i),[a,e,n]}function N(t){return V(z(t))}function H(t){return B(z(t))}function E(t){return J[t]}function U(t){return i(E(t))}function j(t){return a(E(t))}function G(t){return o(E(t))}function q(t){return s(E(t))}function Z(t){return d(E(t))}function X(t){return u(E(t))}e.exports={rgb2hsl:i,rgb2hsv:a,rgb2hwb:o,rgb2cmyk:s,rgb2keyword:l,rgb2xyz:u,rgb2lab:d,rgb2lch:c,hsl2rgb:h,hsl2hsv:f,hsl2hwb:m,hsl2cmyk:p,hsl2keyword:v,hsv2rgb:y,hsv2hsl:x,hsv2hwb:k,hsv2cmyk:_,hsv2keyword:w,hwb2rgb:S,hwb2hsl:M,hwb2hsv:D,hwb2cmyk:C,hwb2keyword:T,cmyk2rgb:P,cmyk2hsl:I,cmyk2hsv:F,cmyk2hwb:A,cmyk2keyword:O,keyword2rgb:E,keyword2hsl:U,keyword2hsv:j,keyword2hwb:G,keyword2cmyk:q,keyword2lab:Z,keyword2xyz:X,xyz2rgb:R,xyz2lab:L,xyz2lch:W,lab2xyz:V,lab2rgb:B,lab2l
vendor: 6,966 bytes, line 23270
23270ch:Y,lch2lab:z,lch2xyz:N,lch2rgb:H};var J={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},K={};for(var Q in J)K[JSON.stringify(J[Q])]=Q},{}],4:[function(t,e,n){var i=t(3),a=function(){return new u};for(var r in i){a[r+"Raw"]=function(t){return function(e){return"number"==typeof e&&(e=Array.prototype.slice.call(arguments)),i[t](e)}}(r);var o=/(\w+)2(\w+)/.exec(r),s=o[1],l=o[2];a[s]=a[s]||{},a[s][l]=a[r]=function(t){return function(e){"number"==typeof e&&(e=Array.prototype.slice.call(arguments));var n=i[t](e);if("string"==typeof n||void 0===n)return n;for(var a=0;a<n.length;a++)n[a]=Math.round(n[a]);return n}}(r)}var u=function(){this.convs={}};u.prototype.routeSpace=function(t,e){var n=e[0];return void 0===n?this.getValues(t):("number"==typeof n&&(n=Array.prototype.slice.call(e)),this.setValues(t,n))},u.prototype.setValues=function(t,e){return this.space=t,this.convs={},this.convs[t]=e,this},u.prototype.getValues=function(t){var e=this.convs[t];if(!e){var n=this.space,i=this.convs[n];e=a[n][t](i),this.convs[t]=e}return e},["rgb","hsl","hsv","cmyk","keyword"].forEach(function(t){u.prototype[t]=function(e){return this.routeSpace(t,arguments)}}),e.exports=a},{3:3}],5:[function(t,e,n){e.exports={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],ol
23270ive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}},{}],6:[function(e,n,i){!function(e,a){"object"==typeof i&&"undefined"!=typeof n?n.exports=a():"function"==typeof t&&t.amd?t(a):e.moment=a()}(this,function(){"use strict";function t(){return vi.apply(null,arguments)}function i(t){vi=t}function a(t){return t instanceof Array||"[object Array]"===Object.prototype.toString.call(t)}function r(t){return null!=t&&"[object Object]"===Object.prototype.toString.call(t)}function o(t){var e;for(e in t)return!1;return!0}function s(t){return"number"==typeof value||"[object Number]"===Object.prototype.toString.call(t)}function l(t){return t instanceof Date||"[object Date]"===Object.prototype.toString.call(t)}function u(t,e){var n,i=[];for(n=0;n<t.length;++n)i.push(e(t[n],n));return i}function d(t,e){return Object.prototype.hasOwnProperty.call(t,e)}function c(t,e){for(var n in e)d(e,n)&&(t[n]=e[n]);return d(e,"toString")&&(t.toString=e.toString),d(e,"valueOf")&&(t.valueOf=e.valueOf),t}function h(t,e,n,i){return ye(t,e,n,i,!0).utc()}function f(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1,parsedDateParts:[],meridiem:null}}function g(t){return null==t._pf&&(t._pf=f()),t._pf}function m(t){if(null==t._isValid){var e=g(t),n=yi.call(e.parsedDateParts,function(t){return null!=t}),i=!isNaN(t._d.getTime())&&e.overflow<0&&!e.empty&&!e.invalidMonth&&!e.invalidWeekday&&!e.nullInput&&!e.invalidFormat&&!e.userInvalidated&&(!e.meridiem||e.meridiem&&n);if(t._strict&&(i=i&&0===e.charsLeftOver&&0===e.unusedTokens.length&&void 0===e.bigHour),null!=Object.isFrozen&&Object.isFrozen(t))return i;t._isValid=i}return t._isValid}function p(t){var e=h(NaN);return null!=t?c(g(e),t):g(e).userInvalidated=!0,e}function v(t){return void 0===t}function b(t,e){var n,i,a;if(v(e._isAMomentObject)||(t._isAMomentObject=e._isAMomentObject),v(e._i)||(t._i=e._i),v(e._f)||(t._f=e._f),v(e._l)||(t._l=e._l),v(e._strict)||(t._strict=e._strict),v(e._tzm)||(t._tzm=e._tzm),v(e._isUTC)||(t._isUTC=e._isUTC),v(e._offset)||(t._offset=e._offset),v(e._pf)||(t._pf=g(e)),v(e._locale)||(t._locale=e._locale),xi.length>0)for(n in xi)i=xi[n],a=e[i],v(a)||(t[i]=a);return t}function y(e){b(this,e),this._d=new Date(null!=e._d?e._d.getTime():NaN),ki===!1&&(ki=!0,t.updateOffset(this),ki=!1)}function x(t){return t instanceof y||null!=t&&null!=t._isAMomentObject}function k(t){return 0>t?Math.ceil(t)||0:Math.floor(t)}function _(t){var e=+t,n=0;return 0!==e&&isFinite(e)&&(n=k(e)),n}function w(t,e,n){var i,a=Math.min(t.length,e.length),r=Math.abs(t.length-e.length),o=0;for(i=0;a>i;i++)(n&&t[i]!==e[i]||!n&&_(t[i])!==_(e[i]))&&o++;return o+r}function S(e){t.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+e)}function M(e,n){var i=!0;return c(function(){if(null!=t.deprecationHandler&&t.deprecationHandler(null,e),i){for(var a,r=[],o=0;o<arguments.length;o++){if(a="","object"==typeof arguments[o]){a+="\n["+o+"] ";for(var s in arguments[0])a+=s+": "+arguments[0][s]+", ";a=a.slice(0,-2)}else a=arguments[o];r.push(a)}S(e+"\nArguments: "+Array.prototype.slice.call(r).join("")+"\n"+(new Error).stack),i=!1}return n.apply(this,arguments)},n)}function D(e,n){null!=t.deprecationHandler&&t.deprecationHandler(e,n),_i[e]||(S(n),_i[e]=!0)}function C(t){return t instanceof Function||"[object Function]"===Object.prototype.toString.call(t)}function T(t){var e,n;for(n in t)e=t[n],C(e)?this[n]=e:this["_"+n]=e;this._config=t,this._ordinalParseLenient=new RegExp(this._ordinalParse.source+"|"+/\d{1,2}/.source)}function P(t,e){var n,i=c({},t);for(n in e)d(e,n)&&(r(t[n])&&r(e[n])?(i[n]={},c(i[n],t[n]),c(i[n],e[n])):null!=e[n]?i[n]=e[n]:delete i[n]);for(n in t)d(t,n)&&!d(e,n)&&r(t[n])&&(i[n]=c({},i[n]));return i}function I(t){null!=t&&this.set(t)}function F(t,e,n){var i=this._calendar[t]||this._calendar.sameElse;return C(i)?i.call(e,n):i}function A(t){var e=this._longDateFormat[t],n=this._longDateFormat[t.toUpperCase()];return e||!n?e:(this._longDateFormat[t]=n.replace(/MMMM|MM|DD|dddd/g,function(t){return t.slice(1)}),this._longDateFormat[t])}function O(){return this._invalidDate}function R(t){return this._ordinal.replace("%d",t)}function L(t,e,n,i){var a=this._relativeTime[n];return C(a)?a(t,e,n,i):a.replace(/%d/i,t)}function W(t,e){var n=this._relativeTime[t>0?"future":"past"];return C(n)?n(e):n.replace(/%s/i,e)}function V(t,e){var n=t.toLowerCase();Ai[n]=Ai[n+"s"]=Ai[e]=t}function Y(t){return"string"==typeof t?Ai[t]||Ai[t.toLowerCase()]:void 0}function B(t){var e,n,i={};
vendor: 43,989 bytes, lines 23270-23272
23270for(n in t)d(t,n)&&(e=Y(n),e&&(i[e]=t[n]));return i}function z(t,e){Oi[t]=e}function N(t){var e=[];for(var n in t)e.push({unit:n,priority:Oi[n]});return e.sort(function(t,e){return t.priority-e.priority}),e}function H(e,n){return function(i){return null!=i?(U(this,e,i),t.updateOffset(this,n),this):E(this,e)}}function E(t,e){return t.isValid()?t._d["get"+(t._isUTC?"UTC":"")+e]():NaN}function U(t,e,n){t.isValid()&&t._d["set"+(t._isUTC?"UTC":"")+e](n)}function j(t){return t=Y(t),C(this[t])?this[t]():this}function G(t,e){if("object"==typeof t){t=B(t);for(var n=N(t),i=0;i<n.length;i++)this[n[i].unit](t[n[i].unit])}else if(t=Y(t),C(this[t]))return this[t](e);return this}function q(t,e,n){var i=""+Math.abs(t),a=e-i.length,r=t>=0;return(r?n?"+":"":"-")+Math.pow(10,Math.max(0,a)).toString().substr(1)+i}function Z(t,e,n,i){var a=i;"string"==typeof i&&(a=function(){return this[i]()}),t&&(Vi[t]=a),e&&(Vi[e[0]]=function(){return q(a.apply(this,arguments),e[1],e[2])}),n&&(Vi[n]=function(){return this.localeData().ordinal(a.apply(this,arguments),t)})}function X(t){return t.match(/\[[\s\S]/)?t.replace(/^\[|\]$/g,""):t.replace(/\\/g,"")}function J(t){var e,n,i=t.match(Ri);for(e=0,n=i.length;n>e;e++)Vi[i[e]]?i[e]=Vi[i[e]]:i[e]=X(i[e]);return function(e){var a,r="";for(a=0;n>a;a++)r+=i[a]instanceof Function?i[a].call(e,t):i[a];return r}}function K(t,e){return t.isValid()?(e=Q(e,t.localeData()),Wi[e]=Wi[e]||J(e),Wi[e](t)):t.localeData().invalidDate()}function Q(t,e){function n(t){return e.longDateFormat(t)||t}var i=5;for(Li.lastIndex=0;i>=0&&Li.test(t);)t=t.replace(Li,n),Li.lastIndex=0,i-=1;return t}function $(t,e,n){ea[t]=C(e)?e:function(t,i){return t&&n?n:e}}function tt(t,e){return d(ea,t)?ea[t](e._strict,e._locale):new RegExp(et(t))}function et(t){return nt(t.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(t,e,n,i,a){return e||n||i||a}))}function nt(t){return t.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function it(t,e){var n,i=e;for("string"==typeof t&&(t=[t]),s(e)&&(i=function(t,n){n[e]=_(t)}),n=0;n<t.length;n++)na[t[n]]=i}function at(t,e){it(t,function(t,n,i,a){i._w=i._w||{},e(t,i._w,i,a)})}function rt(t,e,n){null!=e&&d(na,t)&&na[t](e,n._a,n,t)}function ot(t,e){return new Date(Date.UTC(t,e+1,0)).getUTCDate()}function st(t,e){return t?a(this._months)?this._months[t.month()]:this._months[(this._months.isFormat||fa).test(e)?"format":"standalone"][t.month()]:this._months}function lt(t,e){return t?a(this._monthsShort)?this._monthsShort[t.month()]:this._monthsShort[fa.test(e)?"format":"standalone"][t.month()]:this._monthsShort}function ut(t,e,n){var i,a,r,o=t.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],i=0;12>i;++i)r=h([2e3,i]),this._shortMonthsParse[i]=this.monthsShort(r,"").toLocaleLowerCase(),this._longMonthsParse[i]=this.months(r,"").toLocaleLowerCase();return n?"MMM"===e?(a=ha.call(this._shortMonthsParse,o),-1!==a?a:null):(a=ha.call(this._longMonthsParse,o),-1!==a?a:null):"MMM"===e?(a=ha.call(this._shortMonthsParse,o),-1!==a?a:(a=ha.call(this._longMonthsParse,o),-1!==a?a:null)):(a=ha.call(this._longMonthsParse,o),-1!==a?a:(a=ha.call(this._shortMonthsParse,o),-1!==a?a:null))}function dt(t,e,n){var i,a,r;if(this._monthsParseExact)return ut.call(this,t,e,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),i=0;12>i;i++){if(a=h([2e3,i]),n&&!this._longMonthsParse[i]&&(this._longMonthsParse[i]=new RegExp("^"+this.months(a,"").replace(".","")+"$","i"),this._shortMonthsParse[i]=new RegExp("^"+this.monthsShort(a,"").replace(".","")+"$","i")),n||this._monthsParse[i]||(r="^"+this.months(a,"")+"|^"+this.monthsShort(a,""),this._monthsParse[i]=new RegExp(r.replace(".",""),"i")),n&&"MMMM"===e&&this._longMonthsParse[i].test(t))return i;if(n&&"MMM"===e&&this._shortMonthsParse[i].test(t))return i;if(!n&&this._monthsParse[i].test(t))return i}}function ct(t,e){var n;if(!t.isValid())return t;if("string"==typeof e)if(/^\d+$/.test(e))e=_(e);else if(e=t.localeData().monthsParse(e),!s(e))return t;return n=Math.min(t.date(),ot(t.year(),e)),t._d["set"+(t._isUTC?"UTC":"")+"Month"](e,n),
23271    t}function ht(e){return null!=e?(ct(this,e),t.updateOffset(this,!0),this):E(this,"Month")}function ft(){return ot(this.year(),this.month())}function gt(t){return this._monthsParseExact?(d(this,"_monthsRegex")||pt.call(this),t?this._monthsShortStrictRegex:this._monthsShortRegex):(d(this,"_monthsShortRegex")||(this._monthsShortRegex=pa),this._monthsShortStrictRegex&&t?this._monthsShortStrictRegex:this._monthsShortRegex)}function mt(t){return this._monthsParseExact?(d(this,"_monthsRegex")||pt.call(this),t?this._monthsStrictRegex:this._monthsRegex):(d(this,"_monthsRegex")||(this._monthsRegex=va),this._monthsStrictRegex&&t?this._monthsStrictRegex:this._monthsRegex)}function pt(){function t(t,e){return e.length-t.length}var e,n,i=[],a=[],r=[];for(e=0;12>e;e++)n=h([2e3,e]),i.push(this.monthsShort(n,"")),a.push(this.months(n,"")),r.push(this.months(n,"")),r.push(this.monthsShort(n,""));for(i.sort(t),a.sort(t),r.sort(t),e=0;12>e;e++)i[e]=nt(i[e]),a[e]=nt(a[e]);for(e=0;24>e;e++)r[e]=nt(r[e]);this._monthsRegex=new RegExp("^("+r.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+a.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+i.join("|")+")","i")}function vt(t){return bt(t)?366:365}function bt(t){return t%4===0&&t%100!==0||t%400===0}function yt(){return bt(this.year())}function xt(t,e,n,i,a,r,o){var s=new Date(t,e,n,i,a,r,o);return 100>t&&t>=0&&isFinite(s.getFullYear())&&s.setFullYear(t),s}function kt(t){var e=new Date(Date.UTC.apply(null,arguments));return 100>t&&t>=0&&isFinite(e.getUTCFullYear())&&e.setUTCFullYear(t),e}function _t(t,e,n){var i=7+e-n,a=(7+kt(t,0,i).getUTCDay()-e)%7;return-a+i-1}function wt(t,e,n,i,a){var r,o,s=(7+n-i)%7,l=_t(t,i,a),u=1+7*(e-1)+s+l;return 0>=u?(r=t-1,o=vt(r)+u):u>vt(t)?(r=t+1,o=u-vt(t)):(r=t,o=u),{year:r,dayOfYear:o}}function St(t,e,n){var i,a,r=_t(t.year(),e,n),o=Math.floor((t.dayOfYear()-r-1)/7)+1;return 1>o?(a=t.year()-1,i=o+Mt(a,e,n)):o>Mt(t.year(),e,n)?(i=o-Mt(t.year(),e,n),a=t.year()+1):(a=t.year(),i=o),{week:i,year:a}}function Mt(t,e,n){var i=_t(t,e,n),a=_t(t+1,e,n);return(vt(t)-i+a)/7}function Dt(t){return St(t,this._week.dow,this._week.doy).week}function Ct(){return this._week.dow}function Tt(){return this._week.doy}function Pt(t){var e=this.localeData().week(this);return null==t?e:this.add(7*(t-e),"d")}function It(t){var e=St(this,1,4).week;return null==t?e:this.add(7*(t-e),"d")}function Ft(t,e){return"string"!=typeof t?t:isNaN(t)?(t=e.weekdaysParse(t),"number"==typeof t?t:null):parseInt(t,10)}function At(t,e){return"string"==typeof t?e.weekdaysParse(t)%7||7:isNaN(t)?null:t}function Ot(t,e){return t?a(this._weekdays)?this._weekdays[t.day()]:this._weekdays[this._weekdays.isFormat.test(e)?"format":"standalone"][t.day()]:this._weekdays}function Rt(t){return t?this._weekdaysShort[t.day()]:this._weekdaysShort}function Lt(t){return t?this._weekdaysMin[t.day()]:this._weekdaysMin}function Wt(t,e,n){var i,a,r,o=t.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],i=0;7>i;++i)r=h([2e3,1]).day(i),this._minWeekdaysParse[i]=this.weekdaysMin(r,"").toLocaleLowerCase(),this._shortWeekdaysParse[i]=this.weekdaysShort(r,"").toLocaleLowerCase(),this._weekdaysParse[i]=this.weekdays(r,"").toLocaleLowerCase();return n?"dddd"===e?(a=ha.call(this._weekdaysParse,o),-1!==a?a:null):"ddd"===e?(a=ha.call(this._shortWeekdaysParse,o),-1!==a?a:null):(a=ha.call(this._minWeekdaysParse,o),-1!==a?a:null):"dddd"===e?(a=ha.call(this._weekdaysParse,o),-1!==a?a:(a=ha.call(this._shortWeekdaysParse,o),-1!==a?a:(a=ha.call(this._minWeekdaysParse,o),-1!==a?a:null))):"ddd"===e?(a=ha.call(this._shortWeekdaysParse,o),-1!==a?a:(a=ha.call(this._weekdaysParse,o),-1!==a?a:(a=ha.call(this._minWeekdaysParse,o),-1!==a?a:null))):(a=ha.call(this._minWeekdaysParse,o),-1!==a?a:(a=ha.call(this._weekdaysParse,o),-1!==a?a:(a=ha.call(this._shortWeekdaysParse,o),-1!==a?a:null)))}function Vt(t,e,n){var i,a,r;if(this._weekdaysParseExact)return Wt.call(this,t,e,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),i=0;7>i;i++){if(a=h([2e3,1]).day(i),n&&!this._fullWeekdaysParse[i]&&(this._fullWeekdaysParse[i]=new RegExp("^"+this.weekdays(a,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[i]=new RegExp("^"+this.weekdaysShort(a,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[i]=new RegExp("^"+this.weekdaysMin(a,"").replace(".",".?")+"$","i")),this._weekdaysParse[i]||(r="^"+this.weekdays(a,"")+"|^"+this.weekdaysShort(a,"")+"|^"+this.weekdaysMin(a,""),this._weekdaysParse[i]=new RegExp(r.replace(".",""),"i")),n&&"dddd"===e&&this._fullWeekdaysParse[i].test(t))return i;if(n&&"ddd"===e&&this._shortWeekdaysParse[i].test(t))return i;if(n&&"dd"===e&&this._minWeekdaysParse[i].test(t))return i;if(!n&&this._weekdaysParse[i].test(t))return i}}function Yt(t){if(!this.isValid())return null!=t?this:NaN;var e=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=t?(t=Ft(t,this.localeData()),this.add(t-e,"d")):e}function Bt(t){if(!this.isValid())return null!=t?this:NaN;var e=(this.day()+7-this.localeData()._week.dow)%7;return null==t?e:this.add(t-e,"d")}function zt(t){if(!this.isValid())return null!=t?this:NaN;if(null!=t){var e=At(t,this.localeData());return this.day(this.day()%7?e:e-7)}return this.day()||7}function Nt(t){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||Ut.call(this),t?this._weekdaysStrictRegex:this._weekdaysRegex):(d(this,"_weekdaysRegex")||(this._weekdaysRegex=wa),this._weekdaysStrictRegex&&t?this._weekdaysStrictRegex:this._weekdaysRegex)}function Ht(t){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||Ut.call(this),t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(d(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=Sa),this._weekdaysShortStrictRegex&&t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)}function Et(t){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||Ut.call(this),t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(d(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Ma),this._weekdaysMinStrictRegex&&t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)}function Ut(){function t(t,e){return e.length-t.length}var e,n,i,a,r,o=[],s=[],l=[],u=[];for(e=0;7>e;e++)n=h([2e3,1]).day(e),i=this.weekdaysMin(n,""),a=this.weekdaysShort(n,""),r=this.weekdays(n,""),o.push(i),s.push(a),l.push(r),u.push(i),u.push(a),u.push(r);for(o.sort(t),s.sort(t),l.sort(t),u.sort(t),e=0;7>e;e++)s[e]=nt(s[e]),l[e]=nt(l[e]),u[e]=nt(u[e]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function jt(){return this.hours()%12||12}function Gt(){return this.hours()||24}function qt(t,e){Z(t,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),e)})}function Zt(t,e){return e._meridiemParse}function Xt(t){return"p"===(t+"").toLowerCase().charAt(0)}function Jt(t,e,n){return t>11?n?"pm":"PM":n?"am":"AM"}function Kt(t){return t?t.toLowerCase().replace("_","-"):t}function Qt(t){for(var e,n,i,a,r=0;r<t.length;){for(a=Kt(t[r]).split("-"),e=a.length,n=Kt(t[r+1]),n=n?n.split("-"):null;e>0;){if(i=$t(a.slice(0,e).join("-")))return i;if(n&&n.length>=e&&w(a,n,!0)>=e-1)break;e--}r++}return null}function $t(t){var i=null;if(!Ia[t]&&"undefined"!=typeof n&&n&&n.exports)try{i=Da._abbr,e("./locale/"+t),te(i)}catch(a){}return Ia[t]}function te(t,e){var n;return t&&(n=v(e)?ie(t):ee(t,e),n&&(Da=n)),Da._abbr}function ee(t,e){if(null!==e){var n=Pa;if(e.abbr=t,null!=Ia[t])D("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),n=Ia[t]._config;else if(null!=e.parentLocale){if(null==Ia[e.parentLocale])return Fa[e.parentLocale]||(Fa[e.parentLocale]=[]),Fa[e.parentLocale].push({name:t,config:e}),null;n=Ia[e.parentLocale]._config}return Ia[t]=new I(P(n,e)),Fa[t]&&Fa[t].forEach(function(t){ee(t.name,t.config)}),te(t),Ia[t]}return delete Ia[t],null}function ne(t,e){if(null!=e){var n,i=Pa;null!=Ia[t]&&(i=Ia[t]._config),e=P(i,e),n=new I(e),n.parentLocale=Ia[t],Ia[t]=n,te(t)}else null!=Ia[t]&&(null!=Ia[t].parentLocale?Ia[t]=Ia[t].parentLocale:null!=Ia[t]&&delete Ia[t]);return Ia[t]}function ie(t){var e;if(t&&t._locale&&t._locale._abbr&&(t=t._locale._abbr),!t)return Da;if(!a(t)){if(e=$t(t))return e;t=[t]}return Qt(t)}function ae(){return Mi(Ia)}function re(t){var e,n=t._a;return n&&-2===g(t).overflow&&(e=n[aa]<0||n[aa]>11?aa:n[ra]<1||n[ra]>ot(n[ia],n[aa])?ra:n[oa]<0||n[oa]>24||24===n[oa]&&(0!==n[sa]||0!==n[la]||0!==n[ua])?oa:n[sa]<0||n[sa]>59?sa:n[la]<0||n[la]>59?la:n[ua]<0||n[ua]>999?ua:-1,g(t)._overflowDayOfYear&&(ia>e||e>ra)&&(e=ra),g(t)._overflowWeeks&&-1===e&&(e=da),g(t)._overflowWeekday&&-1===e&&(e=ca),g(t).overflow=e),t}function oe(t){var e,n,i,a,r,o,s=t._i,l=Aa.exec(s)||Oa.exec(s);if(l){for(g(t).iso=!0,e=0,n=La.length;n>e;e++)if(La[e][1].exec(l[1])){a=La[e][0],i=La[e][2]!==!1;break}if(null==a)return void(t._isValid=!1);if(l[3]){for(e=0,n=Wa.length;n>e;e++)if(Wa[e][1].exec(l[3])){r=(l[2]||" ")+Wa[e][0];break}if(null==r)return void(t._isValid=!1)}if(!i&&null!=r)return void(t._isValid=!1);if(l[4]){if(!Ra.exec(l[4]))return void(t._isValid=!1);o="Z"}t._f=a+(r||"")+(o||""),he(t)}else t._isValid=!1}function se(e){var n=Va.exec(e._i);return null!==n?void(e._d=new Date(+n[1])):(oe(e),void(e._isValid===!1&&(delete e._isValid,t.createFromInputFallback(e))))}function le(t,e,n){return null!=t?t:null!=e?e:n}function ue(e){var n=new Date(t.now());return e._useUTC?[n.getUTCFullYear(),n.getUTCMonth(),n.getUTCDate()]:[n.getFullYear(),n.getMonth(),n.getDate()]}function de(t){var e,n,i,a,r=[];if(!t._d){for(i=ue(t),t._w&&null==t._a[ra]&&null==t._a[aa]&&ce(t),t._dayOfYear&&(a=le(t._a[ia],i[ia]),t._dayOfYear>vt(a)&&(g(t)._overflowDayOfYear=!0),n=kt(a,0,t._dayOfYear),t._a[aa]=n.getUTCMonth(),t._a[ra]=n.getUTCDate()),e=0;3>e&&null==t._a[e];++e)t._a[e]=r[e]=i[e];for(;7>e;e++)t._a[e]=r[e]=null==t._a[e]?2===e?1:0:t._a[e];24===t._a[oa]&&0===t._a[sa]&&0===t._a[la]&&0===t._a[ua]&&(t._nextDay=!0,t._a[oa]=0),t._d=(t._useUTC?kt:xt).apply(null,r),null!=t._tzm&&t._d.setUTCMinutes(t._d.getUTCMinutes()-t._tzm),t._nextDay&&(t._a[oa]=24)}}function ce(t){var e,n,i,a,r,o,s,l;if(e=t._w,null!=e.GG||null!=e.W||null!=e.E)r=1,o=4,n=le(e.GG,t._a[ia],St(xe(),1,4).year),i=le(e.W,1),a=le(e.E,1),(1>a||a>7)&&(l=!0);else{r=t._locale._week.dow,o=t._locale._week.doy;var u=St(xe(),r,o);n=le(e.gg,t._a[ia],u.year),i=le(e.w,u.week),null!=e.d?(a=e.d,(0>a||a>6)&&(l=!0)):null!=e.e?(a=e.e+r,(e.e<0||e.e>6)&&(l=!0)):a=r}1>i||i>Mt(n,r,o)?g(t)._overflowWeeks=!0:null!=l?g(t)._overflowWeekday=!0:(s=wt(n,i,a,r,o),t._a[ia]=s.year,t._dayOfYear=s.dayOfYear)}function he(e){if(e._f===t.ISO_8601)return void oe(e);e._a=[],g(e).empty=!0;var n,i,a,r,o,s=""+e._i,l=s.length,u=0;for(a=Q(e._f,e._locale).match(Ri)||[],n=0;n<a.length;n++)r=a[n],i=(s.match(tt(r,e))||[])[0],i&&(o=s.substr(0,s.indexOf(i)),o.length>0&&g(e).unusedInput.push(o),s=s.slice(s.indexOf(i)+i.length),u+=i.length),Vi[r]?(i?g(e).empty=!1:g(e).unusedTokens.push(r),rt(r,i,e)):e._strict&&!i&&g(e).unusedTokens.push(r);g(e).charsLeftOver=l-u,s.length>0&&g(e).unusedInput.push(s),e._a[oa]<=12&&g(e).bigHour===!0&&e._a[oa]>0&&(g(e).bigHour=void 0),g(e).parsedDateParts=e._a.slice(0),g(e).meridiem=e._meridiem,e._a[oa]=fe(e._locale,e._a[oa],e._meridiem),de(e),re(e)}function fe(t,e,n){var i;return null==n?e:null!=t.meridiemHour?t.meridiemHour(e,n):null!=t.isPM?(i=t.isPM(n),i&&12>e&&(e+=12),i||12!==e||(e=0),e):e}function ge(t){var e,n,i,a,r;if(0===t._f.length)return g(t).invalidFormat=!0,void(t._d=new Date(NaN));for(a=0;a<t._f.length;a++)r=0,e=b({},t),null!=t._useUTC&&(e._useUTC=t._useUTC),e._f=t._f[a],he(e),m(e)&&(r+=g(e).charsLeftOver,r+=10*g(e).unusedTokens.length,g(e).score=r,(null==i||i>r)&&(i=r,n=e));c(t,n||e)}function me(t){if(!t._d){var e=B(t._i);t._a=u([e.year,e.month,e.day||e.date,e.hour,e.minute,e.second,e.millisecond],function(t){return t&&parseInt(t,10)}),de(t)}}function pe(t){var e=new y(re(ve(t)));return e._nextDay&&(e.add(1,"d"),e._nextDay=void 0),e}function ve(t){var e=t._i,n=t._f;return t._locale=t._locale||ie(t._l),null===e||void 0===n&&""===e?p({nullInput:!0}):("string"==typeof e&&(t._i=e=t._locale.preparse(e)),x(e)?new y(re(e)):(l(e)?t._d=e:a(n)?ge(t):n?he(t):be(t),m(t)||(t._d=null),t))}function be(e){var n=e._i;void 0===n?e._d=new Date(t.now()):l(n)?e._d=new Date(n.valueOf()):"string"==typeof n?se(e):a(n)?(e._a=u(n.slice(0),function(t){return parseInt(t,10)}),de(e)):"object"==typeof n?me(e):s(n)?e._d=new Date(n):t.createFromInputFallback(e)}function ye(t,e,n,i,s){var l={};return(n===!0||n===!1)&&(i=n,n=void 0),(r(t)&&o(t)||a(t)&&0===t.length)&&(t=void 0),l._isAMomentObject=!0,l._useUTC=l._isUTC=s,l._l=n,l._i=t,l._f=e,l._strict=i,pe(l)}function xe(t,e,n,i){return ye(t,e,n,i,!1)}function ke(t,e){var n,i;if(1===e.length&&a(e[0])&&(e=e[0]),!e.length)return xe();for(n=e[0],i=1;i<e.length;++i)(!e[i].isValid()||e[i][t](n))&&(n=e[i]);return n}function _e(){var t=[].slice.call(arguments,0);return ke("isBefore",t)}function we(){var t=[].slice.call(arguments,0);return ke("isAfter",t)}function Se(t){var e=B(t),n=e.year||0,i=e.quarter||0,a=e.month||0,r=e.week||0,o=e.day||0,s=e.hour||0,l=e.minute||0,u=e.second||0,d=e.millisecond||0;this._milliseconds=+d+1e3*u+6e4*l+1e3*s*60*60,this._days=+o+7*r,this._months=+a+3*i+12*n,this._data={},this._locale=ie(),this._bubble()}function Me(t){return t instanceof Se}function De(t){return 0>t?-1*Math.round(-1*t):Math.round(t)}function Ce(t,e){Z(t,0,0,function(){var t=this.utcOffset(),n="+";return 0>t&&(t=-t,n="-"),n+q(~~(t/60),2)+e+q(~~t%60,2)})}function Te(t,e){var n=(e||"").match(t);if(null===n)return null;var i=n[n.length-1]||[],a=(i+"").match(Na)||["-",0,0],r=+(60*a[1])+_(a[2]);return 0===r?0:"+"===a[0]?r:-r}function Pe(e,n){var i,a;return n._isUTC?(i=n.clone(),a=(x(e)||l(e)?e.valueOf():xe(e).valueOf())-i.valueOf(),i._d.setTime(i._d.valueOf()+a),t.updateOffset(i,!1),i):xe(e).local()}function Ie(t){return 15*-Math.round(t._d.getTimezoneOffset()/15)}function Fe(e,n){var i,a=this._offset||0;if(!this.isValid())return null!=e?this:NaN;if(null!=e){if("string"==typeof e){if(e=Te(Qi,e),null===e)return this}else Math.abs(e)<16&&(e=60*e);return!this._isUTC&&n&&(i=Ie(this)),this._offset=e,this._isUTC=!0,null!=i&&this.add(i,"m"),a!==e&&(!n||this._changeInProgress?qe(this,He(e-a,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,t.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?a:Ie(this)}function Ae(t,e){return null!=t?("string"!=typeof t&&(t=-t),this.utcOffset(t,e),this):-this.utcOffset()}function Oe(t){return this.utcOffset(0,t)}function Re(t){return this._isUTC&&(this.utcOffset(0,t),this._isUTC=!1,t&&this.subtract(Ie(this),"m")),this}function Le(){if(null!=this._tzm)this.utcOffset(this._tzm);else if("string"==typeof this._i){var t=Te(Ki,this._i);null!=t?this.utcOffset(t):this.utcOffset(0,!0)}return this}function We(t){return this.isValid()?(t=t?xe(t).utcOffset():0,(this.utcOffset()-t)%60===0):!1}function Ve(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function Ye(){if(!v(this._isDSTShifted))return this._isDSTShifted;var t={};if(b(t,this),t=ve(t),t._a){var e=t._isUTC?h(t._a):xe(t._a);this._isDSTShifted=this.isValid()&&w(t._a,e.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function Be(){return this.isValid()?!this._isUTC:!1}function ze(){return this.isValid()?this._isUTC:!1}function Ne(){return this.isValid()?this._isUTC&&0===this._offset:!1}function He(t,e){var n,i,a,r=t,o=null;return Me(t)?r={ms:t._milliseconds,d:t._days,M:t._months}:s(t)?(r={},e?r[e]=t:r.milliseconds=t):(o=Ha.exec(t))?(n="-"===o[1]?-1:1,r={y:0,d:_(o[ra])*n,h:_(o[oa])*n,m:_(o[sa])*n,s:_(o[la])*n,ms:_(De(1e3*o[ua]))*n}):(o=Ea.exec(t))?(n="-"===o[1]?-1:1,r={y:Ee(o[2],n),M:Ee(o[3],n),w:Ee(o[4],n),d:Ee(o[5],n),h:Ee(o[6],n),m:Ee(o[7],n),s:Ee(o[8],n)}):null==r?r={}:"object"==typeof r&&("from"in r||"to"in r)&&(a=je(xe(r.from),xe(r.to)),r={},r.ms=a.milliseconds,r.M=a.months),i=new Se(r),Me(t)&&d(t,"_locale")&&(i._locale=t._locale),i}function Ee(t,e){var n=t&&parseFloat(t.replace(",","."));return(isNaN(n)?0:n)*e}function Ue(t,e){var n={milliseconds:0,months:0};return n.months=e.month()-t.month()+12*(e.year()-t.year()),t.clone().add(n.months,"M").isAfter(e)&&--n.months,n.milliseconds=+e-+t.clone().add(n.months,"M"),n}function je(t,e){var n;return t.isValid()&&e.isValid()?(e=Pe(e,t),t.isBefore(e)?n=Ue(t,e):(n=Ue(e,t),n.milliseconds=-n.milliseconds,n.months=-n.months),n):{milliseconds:0,months:0}}function Ge(t,e){return function(n,i){var a,r;return null===i||isNaN(+i)||(D(e,"moment()."+e+"(period, number) is deprecated. Please use moment()."+e+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),r=n,n=i,i=r),n="string"==typeof n?+n:n,a=He(n,i),qe(this,a,t),this}}function qe(e,n,i,a){var r=n._milliseconds,o=De(n._days),s=De(n._months);e.isValid()&&(a=null==a?!0:a,r&&e._d.setTime(e._d.valueOf()+r*i),o&&U(e,"Date",E(e,"Date")+o*i),s&&ct(e,E(e,"Month")+s*i),a&&t.updateOffset(e,o||s))}function Ze(t,e){var n=t.diff(e,"days",!0);return-6>n?"sameElse":-1>n?"lastWeek":0>n?"lastDay":1>n?"sameDay":2>n?"nextDay":7>n?"nextWeek":"sameElse"}function Xe(e,n){var i=e||xe(),a=Pe(i,this).startOf("day"),r=t.calendarFormat(this,a)||"sameElse",o=n&&(C(n[r])?n[r].call(this,i):n[r]);return this.format(o||this.localeData().calendar(r,this,xe(i)))}function Je(){return new y(this)}function Ke(t,e){var n=x(t)?t:xe(t);return this.isValid()&&n.isValid()?(e=Y(v(e)?"millisecond":e),"millisecond"===e?this.valueOf()>n.valueOf():n.valueOf()<this.clone().startOf(e).valueOf()):!1}function Qe(t,e){var n=x(t)?t:xe(t);return this.isValid()&&n.isValid()?(e=Y(v(e)?"millisecond":e),"millisecond"===e?this.valueOf()<n.valueOf():this.clone().endOf(e).valueOf()<n.valueOf()):!1}function $e(t,e,n,i){return i=i||"()",("("===i[0]?this.isAfter(t,n):!this.isBefore(t,n))&&(")"===i[1]?this.isBefore(e,n):!this.isAfter(e,n))}function tn(t,e){var n,i=x(t)?t:xe(t);return this.isValid()&&i.isValid()?(e=Y(e||"millisecond"),"millisecond"===e?this.valueOf()===i.valueOf():(n=i.valueOf(),this.clone().startOf(e).valueOf()<=n&&n<=this.clone().endOf(e).valueOf())):!1}function en(t,e){return this.isSame(t,e)||this.isAfter(t,e)}function nn(t,e){return this.isSame(t,e)||this.isBefore(t,e)}function an(t,e,n){var i,a,r,o;return this.isValid()?(i=Pe(t,this),i.isValid()?(a=6e4*(i.utcOffset()-this.utcOffset()),e=Y(e),"year"===e||"month"===e||"quarter"===e?(o=rn(this,i),"quarter"===e?o/=3:"year"===e&&(o/=12)):(r=this-i,o="second"===e?r/1e3:"minute"===e?r/6e4:"hour"===e?r/36e5:"day"===e?(r-a)/864e5:"week"===e?(r-a)/6048e5:r),n?o:k(o)):NaN):NaN}function rn(t,e){var n,i,a=12*(e.year()-t.year())+(e.month()-t.month()),r=t.clone().add(a,"months");return 0>e-r?(n=t.clone().add(a-1,"months"),i=(e-r)/(r-n)):(n=t.clone().add(a+1,"months"),i=(e-r)/(n-r)),-(a+i)||0}function on(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")}function sn(){var t=this.clone().utc();return 0<t.year()&&t.year()<=9999?C(Date.prototype.toISOString)?this.toDate().toISOString():K(t,"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]"):K(t,"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]")}function ln(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var t="moment",e="";this.isLocal()||(t=0===this.utcOffset()?"moment.utc":"moment.parseZone",e="Z");var n="["+t+'("]',i=0<this.year()&&this.year()<=9999?"YYYY":"YYYYYY",a="-MM-DD[T]HH:mm:ss.SSS",r=e+'[")]';return this.format(n+i+a+r)}function un(e){e||(e=this.isUtc()?t.defaultFormatUtc:t.defaultFormat);var n=K(this,e);return this.localeData().postformat(n)}function dn(t,e){return this.isValid()&&(x(t)&&t.isValid()||xe(t).isValid())?He({to:this,from:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()}function cn(t){return this.from(xe(),t)}function hn(t,e){return this.isValid()&&(x(t)&&t.isValid()||xe(t).isValid())?He({from:this,to:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()}function fn(t){return this.to(xe(),t)}function gn(t){var e;return void 0===t?this._locale._abbr:(e=ie(t),null!=e&&(this._locale=e),this)}function mn(){return this._locale}function pn(t){switch(t=Y(t)){case"year":this.month(0);case"quarter":case"month":this.date(1);case"week":case"isoWeek":case"day":case"date":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return"week"===t&&this.weekday(0),"isoWeek"===t&&this.isoWeekday(1),"quarter"===t&&this.month(3*Math.floor(this.month()/3)),this}function vn(t){return t=Y(t),void 0===t||"millisecond"===t?this:("date"===t&&(t="day"),this.startOf(t).add(1,"isoWeek"===t?"week":t).subtract(1,"ms"))}function bn(){return this._d.valueOf()-6e4*(this._offset||0)}function yn(){return Math.floor(this.valueOf()/1e3)}function xn(){return new Date(this.valueOf())}function kn(){var t=this;return[t.year(),t.month(),t.date(),t.hour(),t.minute(),t.second(),t.millisecond()]}function _n(){var t=this;return{years:t.year(),months:t.month(),date:t.date(),hours:t.hours(),minutes:t.minutes(),seconds:t.seconds(),milliseconds:t.milliseconds()}}function wn(){return this.isValid()?this.toISOString():null}function Sn(){return m(this)}function Mn(){return c({},g(this))}function Dn(){return g(this).overflow}function Cn(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}}function Tn(t,e){Z(0,[t,t.length],0,e)}function Pn(t){return On.call(this,t,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)}function In(t){return On.call(this,t,this.isoWeek(),this.isoWeekday(),1,4)}function Fn(){return Mt(this.year(),1,4)}function An(){var t=this.localeData()._week;return Mt(this.year(),t.dow,t.doy)}function On(t,e,n,i,a){var r;return null==t?St(this,i,a).year:(r=Mt(t,i,a),e>r&&(e=r),Rn.call(this,t,e,n,i,a))}function Rn(t,e,n,i,a){var r=wt(t,e,n,i,a),o=kt(r.year,0,r.dayOfYear);return this.year(o.getUTCFullYear()),this.month(o.getUTCMonth()),this.date(o.getUTCDate()),this}function Ln(t){return null==t?Math.ceil((this.month()+1)/3):this.month(3*(t-1)+this.month()%3)}function Wn(t){var e=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==t?e:this.add(t-e,"d")}function Vn(t,e){e[ua]=_(1e3*("0."+t))}function Yn(){return this._isUTC?"UTC":""}function Bn(){return this._isUTC?"Coordinated Universal Time":""}function zn(t){return xe(1e3*t)}function Nn(){return xe.apply(null,arguments).parseZone()}function Hn(t){return t}function En(t,e,n,i){var a=ie(),r=h().set(i,e);return a[n](r,t)}function Un(t,e,n){if(s(t)&&(e=t,t=void 0),t=t||"",null!=e)return En(t,e,n,"month");var i,a=[];for(i=0;12>i;i++)a[i]=En(t,i,n,"month");return a}function jn(t,e,n,i){"boolean"==typeof t?(s(e)&&(n=e,e=void 0),e=e||""):(e=t,n=e,t=!1,s(e)&&(n=e,e=void 0),e=e||"");var a=ie(),r=t?a._week.dow:0;if(null!=n)return En(e,(n+r)%7,i,"day");var o,l=[];for(o=0;7>o;o++)l[o]=En(e,(o+r)%7,i,"day");return l}function Gn(t,e){return Un(t,e,"months")}function qn(t,e){return Un(t,e,"monthsShort")}function Zn(t,e,n){return jn(t,e,n,"weekdays")}function Xn(t,e,n){return jn(t,e,n,"weekdaysShort")}function Jn(t,e,n){return jn(t,e,n,"weekdaysMin")}function Kn(){var t=this._data;return this._milliseconds=tr(this._milliseconds),this._days=tr(this._days),this._months=tr(this._months),t.milliseconds=tr(t.milliseconds),t.seconds=tr(t.seconds),t.minutes=tr(t.minutes),t.hours=tr(t.hours),t.months=tr(t.months),t.years=tr(t.years),this}function Qn(t,e,n,i){var a=He(e,n);return t._milliseconds+=i*a._milliseconds,t._days+=i*a._days,t._months+=i*a._months,t._bubble()}function $n(t,e){return Qn(this,t,e,1)}function ti(t,e){return Qn(this,t,e,-1)}function ei(t){return 0>t?Math.floor(t):Math.ceil(t)}function ni(){var t,e,n,i,a,r=this._milliseconds,o=this._days,s=this._months,l=this._data;return r>=0&&o>=0&&s>=0||0>=r&&0>=o&&0>=s||(r+=864e5*ei(ai(s)+o),o=0,s=0),l.milliseconds=r%1e3,t=k(r/1e3),l.seconds=t%60,e=k(t/60),l.minutes=e%60,n=k(e/60),l.hours=n%24,o+=k(n/24),a=k(ii(o)),s+=a,o-=ei(ai(a)),i=k(s/12),s%=12,l.days=o,l.months=s,l.years=i,this}function ii(t){return 4800*t/146097}function ai(t){return 146097*t/4800}function ri(t){var e,n,i=this._milliseconds;if(t=Y(t),"month"===t||"year"===t)return e=this._days+i/864e5,n=this._months+ii(e),"month"===t?n:n/12;switch(e=this._days+Math.round(ai(this._months)),t){case"week":return e/7+i/6048e5;case"day":return e+i/864e5;case"hour":return 24*e+i/36e5;case"minute":return 1440*e+i/6e4;case"second":return 86400*e+i/1e3;case"millisecond":return Math.floor(864e5*e)+i;default:throw new Error("Unknown unit "+t)}}function oi(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*_(this._months/12)}function si(t){return function(){return this.as(t)}}function li(t){return t=Y(t),this[t+"s"]()}function ui(t){return function(){return this._data[t]}}function di(){return k(this.days()/7)}function ci(t,e,n,i,a){return a.relativeTime(e||1,!!n,t,i)}function hi(t,e,n){var i=He(t).abs(),a=pr(i.as("s")),r=pr(i.as("m")),o=pr(i.as("h")),s=pr(i.as("d")),l=pr(i.as("M")),u=pr(i.as("y")),d=a<vr.s&&["s",a]||1>=r&&["m"]||r<vr.m&&["mm",r]||1>=o&&["h"]||o<vr.h&&["hh",o]||1>=s&&["d"]||s<vr.d&&["dd",s]||1>=l&&["M"]||l<vr.M&&["MM",l]||1>=u&&["y"]||["yy",u];return d[2]=e,d[3]=+t>0,d[4]=n,ci.apply(null,d)}function fi(t){return void 0===t?pr:"function"==typeof t?(pr=t,!0):!1}function gi(t,e){return void 0===vr[t]?!1:void 0===e?vr[t]:(vr[t]=e,!0)}function mi(t){var e=this.localeData(),n=hi(this,!t,e);return t&&(n=e.pastFuture(+this,n)),e.postformat(n)}function pi(){var t,e,n,i=br(this._milliseconds)/1e3,a=br(this._days),r=br(this._months);t=k(i/60),e=k(t/60),i%=60,t%=60,n=k(r/12),r%=12;var o=n,s=r,l=a,u=e,d=t,c=i,h=this.asSeconds();return h?(0>h?"-":"")+"P"+(o?o+"Y":"")+(s?s+"M":"")+(l?l+"D":"")+(u||d||c?"T":"")+(u?u+"H":"")+(d?d+"M":"")+(c?c+"S":""):"P0D"}var vi,bi;bi=Array.prototype.some?Array.prototype.some:function(t){for(var e=Object(this),n=e.length>>>0,i=0;n>i;i++)if(i in e&&t.call(this,e[i],i,e))return!0;return!1};var yi=bi,xi=t.momentProperties=[],ki=!1,_i={};t.suppressDeprecationWarnings=!1,t.deprecationHandler=null;var wi;wi=Object.keys?Object.keys:function(t){var e,n=[];for(e in t)d(t,e)&&n.push(e);return n};var Si,Mi=wi,Di={sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},Ci={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},Ti="Invalid date",Pi="%d",Ii=/\d{1,2}/,Fi={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},Ai={},Oi={},Ri=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,Li=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,Wi={},Vi={},Yi=/\d/,Bi=/\d\d/,zi=/\d{3}/,Ni=/\d{4}/,Hi=/[+-]?\d{6}/,Ei=/\d\d?/,Ui=/\d\d\d\d?/,ji=/\d\d\d\d\d\d?/,Gi=/\d{1,3}/,qi=/\d{1,4}/,Zi=/[+-]?\d{1,6}/,Xi=/\d+/,Ji=/[+-]?\d+/,Ki=/Z|[+-]\d\d:?\d\d/gi,Qi=/Z|[+-]\d\d(?::?\d\d)?/gi,$i=/[+-]?\d+(\.\d{1,3})?/,ta=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,ea={},na={},ia=0,aa=1,ra=2,oa=3,sa=4,la=5,ua=6,da=7,ca=8;Si=Array.prototype.indexOf?Array.prototype.indexOf:function(t){var e;for(e=0;e<this.length;++e)if(this[e]===t)return e;return-1};var ha=Si;Z("M",["MM",2],"Mo",function(){return this.month()+1}),Z("MMM",0,0,function(t){return this.localeData().monthsShort(this,t)}),Z("MMMM",0,0,function(t){return this.localeData().months(this,t)}),V("month","M"),z("month",8),$("M",Ei),$("MM",Ei,Bi),$("MMM",function(t,e){return e.monthsShortRegex(t)}),$("MMMM",function(t,e){return e.monthsRegex(t)}),it(["M","MM"],function(t,e){e[aa]=_(t)-1}),it(["MMM","MMMM"],function(t,e,n,i){var a=n._locale.monthsParse(t,i,n._strict);null!=a?e[aa]=a:g(n).invalidMonth=t});var fa=/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,ga="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ma="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),pa=ta,va=ta;Z("Y",0,0,function(){var t=this.year();return 9999>=t?""+t:"+"+t}),Z(0,["YY",2],0,function(){return this.year()%100}),Z(0,["YYYY",4],0,"year"),Z(0,["YYYYY",5],0,"year"),Z(0,["YYYYYY",6,!0],0,"year"),V("year","y"),z("year",1),$("Y",Ji),$("YY",Ei,Bi),$("YYYY",qi,Ni),$("YYYYY",Zi,Hi),$("YYYYYY",Zi,Hi),it(["YYYYY","YYYYYY"],ia),it("YYYY",function(e,n){n[ia]=2===e.length?t.parseTwoDigitYear(e):_(e)}),it("YY",function(e,n){n[ia]=t.parseTwoDigitYear(e)}),it("Y",function(t,e){e[ia]=parseInt(t,10)}),t.parseTwoDigitYear=function(t){return _(t)+(_(t)>68?1900:2e3)};var ba=H("FullYear",!0);Z("w",["ww",2],"wo","week"),Z("W",["WW",2],"Wo","isoWeek"),V("week","w"),V("isoWeek","W"),z("week",5),z("isoWeek",5),$("w",Ei),$("ww",Ei,Bi),$("W",Ei),$("WW",Ei,Bi),at(["w","ww","W","WW"],function(t,e,n,i){e[i.substr(0,1)]=_(t)});var ya={dow:0,doy:6};Z("d",0,"do","day"),Z("dd",0,0,function(t){return this.localeData().weekdaysMin(this,t)}),Z("ddd",0,0,function(t){return this.localeData().weekdaysShort(this,t)}),Z("dddd",0,0,function(t){return this.localeData().weekdays(this,t)}),Z("e",0,0,"weekday"),Z("E",0,0,"isoWeekday"),V("day","d"),V("weekday","e"),V("isoWeekday","E"),z("day",11),z("weekday",11),z("isoWeekday",11),$("d",Ei),$("e",Ei),$("E",Ei),$("dd",function(t,e){return e.weekdaysMinRegex(t)}),$("ddd",function(t,e){return e.weekdaysShortRegex(t)}),$("dddd",function(t,e){return e.weekdaysRegex(t)}),at(["dd","ddd","dddd"],function(t,e,n,i){var a=n._locale.weekdaysParse(t,i,n._strict);null!=a?e.d=a:g(n).invalidWeekday=t}),at(["d","e","E"],function(t,e,n,i){e[i]=_(t)});var xa="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),ka="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),_a="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),wa=ta,Sa=ta,Ma=ta;Z("H",["HH",2],0,"hour"),Z("h",["hh",2],0,jt),Z("k",["kk",2],0,Gt),Z("hmm",0,0,function(){return""+jt.apply(this)+q(this.minutes(),2)}),Z("hmmss",0,0,function(){return""+jt.apply(this)+q(this.minutes(),2)+q(this.seconds(),2)}),Z("Hmm",0,0,function(){return""+this.hours()+q(this.minutes(),2)}),Z("Hmmss",0,0,function(){return""+this.hours()+q(this.minutes(),2)+q(this.seconds(),2)}),qt("a",!0),qt("A",!1),V("hour","h"),z("hour",13),$("a",Zt),$("A",Zt),$("H",Ei),$("h",Ei),$("HH",Ei,Bi),$("hh",Ei,Bi),$("hmm",Ui),$("hmmss",ji),$("Hmm",Ui),$("Hmmss",ji),it(["H","HH"],oa),it(["a","A"],function(t,e,n){n._isPm=n._locale.isPM(t),n._meridiem=t}),it(["h","hh"],function(t,e,n){e[oa]=_(t),g(n).bigHour=!0}),it("hmm",function(t,e,n){var i=t.length-2;e[oa]=_(t.substr(0,i)),e[sa]=_(t.substr(i)),g(n).bigHour=!0}),it("hmmss",function(t,e,n){var i=t.length-4,a=t.length-2;e[oa]=_(t.substr(0,i)),e[sa]=_(t.substr(i,2)),e[la]=_(t.substr(a)),g(n).bigHour=!0}),it("Hmm",function(t,e,n){var i=t.length-2;e[oa]=_(t.substr(0,i)),e[sa]=_(t.substr(i))}),it("Hmmss",function(t,e,n){var i=t.length-4,a=t.length-2;e[oa]=_(t.substr(0,i)),e[sa]=_(t.substr(i,2)),e[la]=_(t.substr(a))});var Da,Ca=/[ap]\.?m?\.?/i,Ta=H("Hours",!0),Pa={calendar:Di,longDateFormat:Ci,invalidDate:Ti,ordinal:Pi,ordinalParse:Ii,relativeTime:Fi,months:ga,monthsShort:ma,week:ya,weekdays:xa,weekdaysMin:_a,weekdaysShort:ka,meridiemParse:Ca},Ia={},Fa={},Aa=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Oa=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Ra=/Z|[+-]\d\d(?::?\d\d)?/,La=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Wa=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],Va=/^\/?Date\((\-?\d+)/i;
23272    t.createFromInputFallback=M("value provided is not in a recognized ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(t){t._d=new Date(t._i+(t._useUTC?" UTC":""))}),t.ISO_8601=function(){};var Ya=M("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var t=xe.apply(null,arguments);return this.isValid()&&t.isValid()?this>t?this:t:p()}),Ba=M("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var t=xe.apply(null,arguments);return this.isValid()&&t.isValid()?t>this?this:t:p()}),za=function(){return Date.now?Date.now():+new Date};Ce("Z",":"),Ce("ZZ",""),$("Z",Qi),$("ZZ",Qi),it(["Z","ZZ"],function(t,e,n){n._useUTC=!0,n._tzm=Te(Qi,t)});var Na=/([\+\-]|\d\d)/gi;t.updateOffset=function(){};var Ha=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,Ea=/^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;He.fn=Se.prototype;var Ua=Ge(1,"add"),ja=Ge(-1,"subtract");t.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",t.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var Ga=M("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(t){return void 0===t?this.localeData():this.locale(t)});Z(0,["gg",2],0,function(){return this.weekYear()%100}),Z(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Tn("gggg","weekYear"),Tn("ggggg","weekYear"),Tn("GGGG","isoWeekYear"),Tn("GGGGG","isoWeekYear"),V("weekYear","gg"),V("isoWeekYear","GG"),z("weekYear",1),z("isoWeekYear",1),$("G",Ji),$("g",Ji),$("GG",Ei,Bi),$("gg",Ei,Bi),$("GGGG",qi,Ni),$("gggg",qi,Ni),$("GGGGG",Zi,Hi),$("ggggg",Zi,Hi),at(["gggg","ggggg","GGGG","GGGGG"],function(t,e,n,i){e[i.substr(0,2)]=_(t)}),at(["gg","GG"],function(e,n,i,a){n[a]=t.parseTwoDigitYear(e)}),Z("Q",0,"Qo","quarter"),V("quarter","Q"),z("quarter",7),$("Q",Yi),it("Q",function(t,e){e[aa]=3*(_(t)-1)}),Z("D",["DD",2],"Do","date"),V("date","D"),z("date",9),$("D",Ei),$("DD",Ei,Bi),$("Do",function(t,e){return t?e._ordinalParse:e._ordinalParseLenient}),it(["D","DD"],ra),it("Do",function(t,e){e[ra]=_(t.match(Ei)[0],10)});var qa=H("Date",!0);Z("DDD",["DDDD",3],"DDDo","dayOfYear"),V("dayOfYear","DDD"),z("dayOfYear",4),$("DDD",Gi),$("DDDD",zi),it(["DDD","DDDD"],function(t,e,n){n._dayOfYear=_(t)}),Z("m",["mm",2],0,"minute"),V("minute","m"),z("minute",14),$("m",Ei),$("mm",Ei,Bi),it(["m","mm"],sa);var Za=H("Minutes",!1);Z("s",["ss",2],0,"second"),V("second","s"),z("second",15),$("s",Ei),$("ss",Ei,Bi),it(["s","ss"],la);var Xa=H("Seconds",!1);Z("S",0,0,function(){return~~(this.millisecond()/100)}),Z(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),Z(0,["SSS",3],0,"millisecond"),Z(0,["SSSS",4],0,function(){return 10*this.millisecond()}),Z(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),Z(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),Z(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),Z(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),Z(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),V("millisecond","ms"),z("millisecond",16),$("S",Gi,Yi),$("SS",Gi,Bi),$("SSS",Gi,zi);var Ja;for(Ja="SSSS";Ja.length<=9;Ja+="S")$(Ja,Xi);for(Ja="S";Ja.length<=9;Ja+="S")it(Ja,Vn);var Ka=H("Milliseconds",!1);Z("z",0,0,"zoneAbbr"),Z("zz",0,0,"zoneName");var Qa=y.prototype;Qa.add=Ua,Qa.calendar=Xe,Qa.clone=Je,Qa.diff=an,Qa.endOf=vn,Qa.format=un,Qa.from=dn,Qa.fromNow=cn,Qa.to=hn,Qa.toNow=fn,Qa.get=j,Qa.invalidAt=Dn,Qa.isAfter=Ke,Qa.isBefore=Qe,Qa.isBetween=$e,Qa.isSame=tn,Qa.isSameOrAfter=en,Qa.isSameOrBefore=nn,Qa.isValid=Sn,Qa.lang=Ga,Qa.locale=gn,Qa.localeData=mn,Qa.max=Ba,Qa.min=Ya,Qa.parsingFlags=Mn,Qa.set=G,Qa.startOf=pn,Qa.subtract=ja,Qa.toArray=kn,Qa.toObject=_n,Qa.toDate=xn,Qa.toISOString=sn,Qa.inspect=ln,Qa.toJSON=wn,Qa.toString=on,Qa.unix=yn,Qa.valueOf=bn,Qa.creationData=Cn,Qa.year=ba,Qa.isLeapYear=yt,Qa.weekYear=Pn,Qa.isoWeekYear=In,Qa.quarter=Qa.quarters=Ln,Qa.month=ht,Qa.daysInMonth=ft,Qa.week=Qa.weeks=Pt,Qa.isoWeek=Qa.isoWeeks=It,Qa.weeksInYear=An,Qa.isoWeeksInYear=Fn,Qa.date=qa,Qa.day=Qa.days=Yt,Qa.weekday=Bt,Qa.isoWeekday=zt,Qa.dayOfYear=Wn,Qa.hour=Qa.hours=Ta,Qa.minute=Qa.minutes=Za,Qa.second=Qa.seconds=Xa,Qa.millisecond=Qa.milliseconds=Ka,Qa.utcOffset=Fe,Qa.utc=Oe,Qa.local=Re,Qa.parseZone=Le,Qa.hasAlignedHourOffset=We,Qa.isDST=Ve,Qa.isLocal=Be,Qa.isUtcOffset=ze,Qa.isUtc=Ne,Qa.isUTC=Ne,Qa.zoneAbbr=Yn,Qa.zoneName=Bn,Qa.dates=M("dates accessor is deprecated. Use date instead.",qa),Qa.months=M("months accessor is deprecated. Use month instead",ht),Qa.years=M("years accessor is deprecated. Use year instead",ba),Qa.zone=M("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",Ae),Qa.isDSTShifted=M("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",Ye);var $a=I.prototype;$a.calendar=F,$a.longDateFormat=A,$a.invalidDate=O,$a.ordinal=R,$a.preparse=Hn,$a.postformat=Hn,$a.relativeTime=L,$a.pastFuture=W,$a.set=T,$a.months=st,$a.monthsShort=lt,$a.monthsParse=dt,$a.monthsRegex=mt,$a.monthsShortRegex=gt,$a.week=Dt,$a.firstDayOfYear=Tt,$a.firstDayOfWeek=Ct,$a.weekdays=Ot,$a.weekdaysMin=Lt,$a.weekdaysShort=Rt,$a.weekdaysParse=Vt,$a.weekdaysRegex=Nt,$a.weekdaysShortRegex=Ht,$a.weekdaysMinRegex=Et,$a.isPM=Xt,$a.meridiem=Jt,te("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(t){var e=t%10,n=1===_(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th";return t+n}}),t.lang=M("moment.lang is deprecated. Use moment.locale instead.",te),t.langData=M("moment.langData is deprecated. Use moment.localeData instead.",ie);var tr=Math.abs,er=si("ms"),nr=si("s"),ir=si("m"),ar=si("h"),rr=si("d"),or=si("w"),sr=si("M"),lr=si("y"),ur=ui("milliseconds"),dr=ui("seconds"),cr=ui("minutes"),hr=ui("hours"),fr=ui("days"),gr=ui("months"),mr=ui("years"),pr=Math.round,vr={s:45,m:45,h:22,d:26,M:11},br=Math.abs,yr=Se.prototype;return yr.abs=Kn,yr.add=$n,yr.subtract=ti,yr.as=ri,yr.asMilliseconds=er,yr.asSeconds=nr,yr.asMinutes=ir,yr.asHours=ar,yr.asDays=rr,yr.asWeeks=or,yr.asMonths=sr,yr.asYears=lr,yr.valueOf=oi,yr._bubble=ni,yr.get=li,yr.milliseconds=ur,yr.seconds=dr,yr.minutes=cr,yr.hours=hr,yr.days=fr,yr.weeks=di,yr.months=gr,yr.years=mr,yr.humanize=mi,yr.toISOString=pi,yr.toString=pi,yr.toJSON=pi,yr.locale=gn,yr.localeData=mn,yr.toIsoString=M("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",pi),yr.lang=Ga,Z("X",0,0,"unix"),Z("x",0,0,"valueOf"),$("x",Ji),$("X",$i),it("X",function(t,e,n){n._d=new Date(1e3*parseFloat(t,10))}
23272),it("x",function(t,e,n){n._d=new Date(_(t))}),t.version="2.16.0",i(xe),t.fn=Qa,t.min=_e,t.max=we,t.now=za,t.utc=h,t.unix=zn,t.months=Gn,t.isDate=l,t.locale=te,t.invalid=p,t.duration=He,t.isMoment=x,t.weekdays=Zn,t.parseZone=Nn,t.localeData=ie,t.isDuration=Me,t.monthsShort=qn,t.weekdaysMin=Jn,t.defineLocale=ee,t.updateLocale=ne,t.locales=ae,t.weekdaysShort=Xn,t.normalizeUnits=Y,t.relativeTimeRounding=fi,t.relativeTimeThreshold=gi,t.calendarFormat=Ze,t.prototype=Qa,t})},{}],7:[function(t,e,n){var i=t(28)();t(26)(i),t(22)(i),t(25)(i),t(21)(i),t(23)(i),t(24)(i),t(29)(i),t(33)(i),t(31)(i),t(34)(i),t(32)(i),t(35)(i),t(30)(i),t(27)(i),t(36)(i),t(37)(i),t(38)(i),t(39)(i),t(40)(i),t(43)(i),t(41)(i),t(42)(i),t(44)(i),t(45)(i),t(46)(i),t(15)(i),t(16)(i),t(17)(i),t(18)(i),t(19)(i),t(20)(i),t(8)(i),t(9)(i),t(10)(i),t(11)(i),t(12)(i),t(13)(i),t(14)(i),window.Chart=e.exports=i},{10:10,11:11,12:12,13:13,14:14,15:15,16:16,17:17,18:18,19:19,20:20,21:21,22:22,23:23,24:24,25:25,26:26,27:27,28:28,29:29,30:30,31:31,32:32,33:33,34:34,35:35,36:36,37:37,38:38,39:39,40:40,41:41,42:42,43:43,44:44,45:45,46:46,8:8,9:9}],8:[function(t,e,n){"use strict";e.exports=function(t){t.Bar=function(e,n){return n.type="bar",new t(e,n)}}},{}],9:[function(t,e,n){"use strict";e.exports=function(t){t.Bubble=function(e,n){return n.type="bubble",new t(e,n)}}},{}],10:[function(t,e,n){"use strict";e.exports=function(t){t.Doughnut=function(e,n){return n.type="doughnut",new t(e,n)}}},{}],11:[function(t,e,n){"use strict";e.exports=function(t){t.Line=function(e,n){return n.type="line",new t(e,n)}}},{}],12:[function(t,e,n){"use strict";e.exports=function(t){t.PolarArea=function(e,n){return n.type="polarArea",new t(e,n)}}},{}],13:[function(t,e,n){"use strict";e.exports=function(t){t.Radar=function(e,n){return n.type="radar",new t(e,n)}}},{}],14:[function(t,e,n){"use strict";e.exports=function(t){var e={hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-1"}],yAxes:[{type:"linear",position:"left",id:"y-axis-1"}]},tooltips:{callbacks:{title:function(){return""},label:function(t){return"("+t.xLabel+", "+t.yLabel+")"}}}};t.defaults.scatter=e,t.controllers.scatter=t.controllers.line,t.Scatter=function(e,n){return n.type="scatter",new t(e,n)}}},{}],15:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.bar={hover:{mode:"label"},scales:{xAxes:[{type:"category",categoryPercentage:.8,barPercentage:.9,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}},t.controllers.bar=t.DatasetController.extend({dataElementType:t.elements.Rectangle,initialize:function(e,n){t.DatasetController.prototype.initialize.call(this,e,n),this.getMeta().bar=!0},getBarCount:function(){var t=this,n=0;return e.each(t.chart.data.datasets,function(e,i){var a=t.chart.getDatasetMeta(i);a.bar&&t.chart.isDatasetVisible(i)&&++n},t),n},update:function(t){var n=this;e.each(n.getMeta().data,function(e,i){n.updateElement(e,i,t)},n)},updateElement:function(t,n,i){var a=this,r=a.getMeta(),o=a.getScaleForId(r.xAxisID),s=a.getScaleForId(r.yAxisID),l=s.getBasePixel(),u=a.chart.options.elements.rectangle,d=t.custom||{},c=a.getDataset();t._xScale=o,t._yScale=s,t._datasetIndex=a.index,t._index=n;var h=a.getRuler(n);t._model={x:a.calculateBarX(n,a.index,h),y:i?l:a.calculateBarY(n,a.index),label:a.chart.data.labels[n],datasetLabel:c.label,base:i?l:a.calculateBarBase(a.index,n),width:a.calculateBarWidth(h),backgroundColor:d.backgroundColor?d.backgroundColor:e.getValueAtIndexOrDefault(c.backgroundColor,n,u.backgroundColor),borderSkipped:d.borderSkipped?d.borderSkipped:u.borderSkipped,borderColor:d.borderColor?d.borderColor:e.getValueAtIndexOrDefault(c.borderColor,n,u.borderColor),borderWidth:d.borderWidth?d.borderWidth:e.getValueAtIndexOrDefault(c.borderWidth,n,u.borderWidth)},t.pivot()},calculateBarBase:function(t,e){var n=this,i=n.getMeta(),a=n.getScaleForId(i.yAxisID),r=0;if(a.options.stacked){for(var o=n.chart,s=o.data.datasets,l=Number(s[t].data[e]),u=0;t>u;u++){var d=s[u],c=o.getDatasetMeta(u);if(c.bar&&c.yAxisID===a.id&&o.isDatasetVisible(u)){var h=Number(d.data[e]);r+=0>l?Math.min(h,0):Math.max(h,0)}}return a.getPixelForValue(r)}return a.getBasePixel()}
23272,getRuler:function(t){var e,n=this,i=n.getMeta(),a=n.getScaleForId(i.xAxisID),r=n.getBarCount();e="category"===a.options.type?a.getPixelForTick(t+1)-a.getPixelForTick(t):a.width/a.ticks.length;var o=e*a.options.categoryPercentage,s=(e-e*a.options.categoryPercentage)/2,l=o/r;if(a.ticks.length!==n.chart.data.labels.length){var u=a.ticks.length/n.chart.data.labels.length;l*=u}var d=l*a.options.barPercentage,c=l-l*a.options.barPercentage;return{datasetCount:r,tickWidth:e,categoryWidth:o,categorySpacing:s,fullBarWidth:l,barWidth:d,barSpacing:c}},calculateBarWidth:function(t){var e=this.getScaleForId(this.getMeta().xAxisID);return e.options.barThickness?e.options.barThickness:e.options.stacked?t.categoryWidth:t.barWidth},getBarIndex:function(t){var e,n,i=0;for(n=0;t>n;++n)e=this.chart.getDatasetMeta(n),e.bar&&this.chart.isDatasetVisible(n)&&++i;return i},calculateBarX:function(t,e,n){var i=this,a=i.getMeta(),r=i.getScaleForId(a.xAxisID),o=i.getBarIndex(e),s=r.getPixelForValue(null,t,e,i.chart.isCombo);return s-=i.chart.isCombo?n.tickWidth/2:0,r.options.stacked?s+n.categoryWidth/2+n.categorySpacing:s+n.barWidth/2+n.categorySpacing+n.barWidth*o+n.barSpacing/2+n.barSpacing*o},calculateBarY:function(t,e){var n=this,i=n.getMeta(),a=n.getScaleForId(i.yAxisID),r=Number(n.getDataset().data[t]);if(a.options.stacked){for(var o=0,s=0,l=0;e>l;l++){var u=n.chart.data.datasets[l],d=n.chart.getDatasetMeta(l);if(d.bar&&d.yAxisID===a.id&&n.chart.isDatasetVisible(l)){var c=Number(u.data[t]);0>c?s+=c||0:o+=c||0}}return 0>r?a.getPixelForValue(s+r):a.getPixelForValue(o+r)}return a.getPixelForValue(r)},draw:function(t){var e,n,i=this,a=t||1,r=i.getMeta().data,o=i.getDataset();for(e=0,n=r.length;n>e;++e){var s=o.data[e];null===s||void 0===s||isNaN(s)||r[e].transition(a).draw()}},setHoverStyle:function(t){var n=this.chart.data.datasets[t._datasetIndex],i=t._index,a=t.custom||{},r=t._model;r.backgroundColor=a.hoverBackgroundColor?a.hoverBackgroundColor:e.getValueAtIndexOrDefault(n.hoverBackgroundColor,i,e.getHoverColor(r.backgroundColor)),r.borderColor=a.hoverBorderColor?a.hoverBorderColor:e.getValueAtIndexOrDefault(n.hoverBorderColor,i,e.getHoverColor(r.borderColor)),r.borderWidth=a.hoverBorderWidth?a.hoverBorderWidth:e.getValueAtIndexOrDefault(n.hoverBorderWidth,i,r.borderWidth)},removeHoverStyle:function(t){var n=this.chart.data.datasets[t._datasetIndex],i=t._index,a=t.custom||{},r=t._model,o=this.chart.options.elements.rectangle;r.backgroundColor=a.backgroundColor?a.backgroundColor:e.getValueAtIndexOrDefault(n.backgroundColor,i,o.backgroundColor),r.borderColor=a.borderColor?a.borderColor:e.getValueAtIndexOrDefault(n.borderColor,i,o.borderColor),r.borderWidth=a.borderWidth?a.borderWidth:e.getValueAtIndexOrDefault(n.borderWidth,i,o.borderWidth)}}),t.defaults.horizontalBar={hover:{mode:"label"},scales:{xAxes:[{type:"linear",position:"bottom"}],yAxes:[{position:"left",type:"category",categoryPercentage:.8,barPercentage:.9,gridLines:{offsetGridLines:!0}}]},elements:{rectangle:{borderSkipped:"left"}},tooltips:{callbacks:{title:function(t,e){var n="";return t.length>0&&(t[0].yLabel?n=t[0].yLabel:e.labels.length>0&&t[0].index<e.labels.length&&(n=e.labels[t[0].index])),n},label:function(t,e){var n=e.datasets[t.datasetIndex].label||"";return n+": "+t.xLabel}}}},t.controllers.horizontalBar=t.controllers.bar.extend({updateElement:function(t,n,i){var a=this,r=a.getMeta(),o=a.getScaleForId(r.xAxisID),s=a.getScaleForId(r.yAxisID),l=o.getBasePixel(),u=t.custom||{},d=a.getDataset(),c=a.chart.options.elements.rectangle;t._xScale=o,t._yScale=s,t._datasetIndex=a.index,t._index=n;var h=a.getRuler(n);t._model={x:i?l:a.calculateBarX(n,a.index),y:a.calculateBarY(n,a.index,h),label:a.chart.data.labels[n],datasetLabel:d.label,base:i?l:a.calculateBarBase(a.index,n),height:a.calculateBarHeight(h),backgroundColor:u.backgroundColor?u.backgroundColor:e.getValueAtIndexOrDefault(d.backgroundColor,n,c.backgroundColor),borderSkipped:u.borderSkipped?u.borderSkipped:c.borderSkipped,borderColor:u.borderColor?u.borderColor:e.getValueAtIndexOrDefault(d.borderColor,n,c.borderColor),borderWidth:u.borderWidth?u.borderWidth:e.getValueAtIndexOrDefault(d.borderWidth,n,c.borderWidth)},t.draw=function(){function t(t){return l[(d+t)%4]}var e=this._chart.ctx,n=this._view,i=n.height/2,a=n.y-i,r=n.y+i,o=n.base-(n.base-n.x),s=n.borderWidth/2;n.borderWidth&&(a+=s,r-=s,o+=s),e.beginPath(),e.fillStyle=n.backgroundColor,e.strokeStyle=n.borderColor,e.lineWidth=n.borderWidth;var l=[[n.base,r],[n.base,a],[o,a],[o,r]],u=["bottom","left","top","right"],d=u.indexOf(n.borderSkipped,0);-1===d&&(d=0),e.moveTo.apply(e,t(0));for(var c=1;4>c;c++)e.lineTo.apply(e,t(c));e.fill(),n.borderWidth&&e.stroke()},t.pivot()},calculateBarBase:function(t,e){var n=this,i=n.getMeta(),a=n.get
23272ScaleForId(i.xAxisID),r=0;if(a.options.stacked){for(var o=n.chart,s=o.data.datasets,l=Number(s[t].data[e]),u=0;t>u;u++){var d=s[u],c=o.getDatasetMeta(u);if(c.bar&&c.xAxisID===a.id&&o.isDatasetVisible(u)){var h=Number(d.data[e]);r+=0>l?Math.min(h,0):Math.max(h,0)}}return a.getPixelForValue(r)}return a.getBasePixel()},getRuler:function(t){var e,n=this,i=n.getMeta(),a=n.getScaleForId(i.yAxisID),r=n.getBarCount();e="category"===a.options.type?a.getPixelForTick(t+1)-a.getPixelForTick(t):a.width/a.ticks.length;var o=e*a.options.categoryPercentage,s=(e-e*a.options.categoryPercentage)/2,l=o/r;if(a.ticks.length!==n.chart.data.labels.length){var u=a.ticks.length/n.chart.data.labels.length;l*=u}var d=l*a.options.barPercentage,c=l-l*a.options.barPercentage;return{datasetCount:r,tickHeight:e,categoryHeight:o,categorySpacing:s,fullBarHeight:l,barHeight:d,barSpacing:c}},calculateBarHeight:function(t){var e=this,n=e.getScaleForId(e.getMeta().yAxisID);return n.options.barThickness?n.options.barThickness:n.options.stacked?t.categoryHeight:t.barHeight},calculateBarX:function(t,e){var n=this,i=n.getMeta(),a=n.getScaleForId(i.xAxisID),r=Number(n.getDataset().data[t]);if(a.options.stacked){for(var o=0,s=0,l=0;e>l;l++){var u=n.chart.data.datasets[l],d=n.chart.getDatasetMeta(l);if(d.bar&&d.xAxisID===a.id&&n.chart.isDatasetVisible(l)){var c=Number(u.data[t]);0>c?s+=c||0:o+=c||0}}return 0>r?a.getPixelForValue(s+r):a.getPixelForValue(o+r)}return a.getPixelForValue(r)},calculateBarY:function(t,e,n){var i=this,a=i.getMeta(),r=i.getScaleForId(a.yAxisID),o=i.getBarIndex(e),s=r.getPixelForValue(null,t,e,i.chart.isCombo);return s-=i.chart.isCombo?n.tickHeight/2:0,r.options.stacked?s+n.categoryHeight/2+n.categorySpacing:s+n.barHeight/2+n.categorySpacing+n.barHeight*o+n.barSpacing/2+n.barSpacing*o}})}},{}],16:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.bubble={hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-0"}],yAxes:[{type:"linear",position:"left",id:"y-axis-0"}]},tooltips:{callbacks:{title:function(){return""},label:function(t,e){var n=e.datasets[t.datasetIndex].label||"",i=e.datasets[t.datasetIndex].data[t.index];return n+": ("+t.xLabel+", "+t.yLabel+", "+i.r+")"}}}},t.controllers.bubble=t.DatasetController.extend({dataElementType:t.elements.Point,update:function(t){var n=this,i=n.getMeta(),a=i.data;e.each(a,function(e,i){n.updateElement(e,i,t)})},updateElement:function(n,i,a){var r=this,o=r.getMeta(),s=r.getScaleForId(o.xAxisID),l=r.getScaleForId(o.yAxisID),u=n.custom||{},d=r.getDataset(),c=d.data[i],h=r.chart.options.elements.point,f=r.index;e.extend(n,{_xScale:s,_yScale:l,_datasetIndex:f,_index:i,_model:{x:a?s.getPixelForDecimal(.5):s.getPixelForValue("object"==typeof c?c:NaN,i,f,r.chart.isCombo),y:a?l.getBasePixel():l.getPixelForValue(c,i,f),radius:a?0:u.radius?u.radius:r.getRadius(c),hitRadius:u.hitRadius?u.hitRadius:e.getValueAtIndexOrDefault(d.hitRadius,i,h.hitRadius)}}),t.DatasetController.prototype.removeHoverStyle.call(r,n,h);var g=n._model;g.skip=u.skip?u.skip:isNaN(g.x)||isNaN(g.y),n.pivot()},getRadius:function(t){return t.r||this.chart.options.elements.point.radius},setHoverStyle:function(n){var i=this;t.DatasetController.prototype.setHoverStyle.call(i,n);var a=i.chart.data.datasets[n._datasetIndex],r=n._index,o=n.custom||{},s=n._model;s.radius=o.hoverRadius?o.hoverRadius:e.getValueAtIndexOrDefault(a.hoverRadius,r,i.chart.options.elements.point.hoverRadius)+i.getRadius(a.data[r])},removeHoverStyle:function(e){var n=this;t.DatasetController.prototype.removeHoverStyle.call(n,e,n.chart.options.elements.point);var i=n.chart.data.datasets[e._datasetIndex].data[e._index],a=e.custom||{},r=e._model;r.radius=a.radius?a.radius:n.getRadius(i)}})}},{}],17:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n=t.defaults;n.doughnut={animation:{animateRotate:!0,animateScale:!1},aspectRatio:1,hover:{mode:"single"},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');var n=t.data,i=n.datasets,a=n.labels;if(i.length)for(var r=0;r<i[0].data.length;++r)e.push('<li><span style="background-color:'+i[0].backgroundColor[r]+'"></span>'),a[r]&&e.push(a[r]),e.push("</li>");return e.push("</ul>"),e.join("")},legend:{labels:{generateLabels:function(t){var n=t.data;return n.labels.length&&n.datasets.length?n.labels.map(function(i,a){var r=t.getDatasetMeta(0),o=n.datasets[0],s=r.data[a],l=s&&s.custom||{}
23272,u=e.getValueAtIndexOrDefault,d=t.options.elements.arc,c=l.backgroundColor?l.backgroundColor:u(o.backgroundColor,a,d.backgroundColor),h=l.borderColor?l.borderColor:u(o.borderColor,a,d.borderColor),f=l.borderWidth?l.borderWidth:u(o.borderWidth,a,d.borderWidth);return{text:i,fillStyle:c,strokeStyle:h,lineWidth:f,hidden:isNaN(o.data[a])||r.data[a].hidden,index:a}}):[]}},onClick:function(t,e){var n,i,a,r=e.index,o=this.chart;for(n=0,i=(o.data.datasets||[]).length;i>n;++n)a=o.getDatasetMeta(n),a.data[r]&&(a.data[r].hidden=!a.data[r].hidden);o.update()}},cutoutPercentage:50,rotation:Math.PI*-.5,circumference:2*Math.PI,tooltips:{callbacks:{title:function(){return""},label:function(t,n){var i=n.labels[t.index],a=": "+n.datasets[t.datasetIndex].data[t.index];return e.isArray(i)?(i=i.slice(),i[0]+=a):i+=a,i}}}},n.pie=e.clone(n.doughnut),e.extend(n.pie,{cutoutPercentage:0}),t.controllers.doughnut=t.controllers.pie=t.DatasetController.extend({dataElementType:t.elements.Arc,linkScales:e.noop,getRingIndex:function(t){for(var e=0,n=0;t>n;++n)this.chart.isDatasetVisible(n)&&++e;return e},update:function(t){var n=this,i=n.chart,a=i.chartArea,r=i.options,o=r.elements.arc,s=a.right-a.left-o.borderWidth,l=a.bottom-a.top-o.borderWidth,u=Math.min(s,l),d={x:0,y:0},c=n.getMeta(),h=r.cutoutPercentage,f=r.circumference;if(f<2*Math.PI){var g=r.rotation%(2*Math.PI);g+=2*Math.PI*(g>=Math.PI?-1:g<-Math.PI?1:0);var m=g+f,p={x:Math.cos(g),y:Math.sin(g)},v={x:Math.cos(m),y:Math.sin(m)},b=0>=g&&m>=0||g<=2*Math.PI&&2*Math.PI<=m,y=g<=.5*Math.PI&&.5*Math.PI<=m||g<=2.5*Math.PI&&2.5*Math.PI<=m,x=g<=-Math.PI&&-Math.PI<=m||g<=Math.PI&&Math.PI<=m,k=g<=.5*-Math.PI&&.5*-Math.PI<=m||g<=1.5*Math.PI&&1.5*Math.PI<=m,_=h/100,w={x:x?-1:Math.min(p.x*(p.x<0?1:_),v.x*(v.x<0?1:_)),y:k?-1:Math.min(p.y*(p.y<0?1:_),v.y*(v.y<0?1:_))},S={x:b?1:Math.max(p.x*(p.x>0?1:_),v.x*(v.x>0?1:_)),y:y?1:Math.max(p.y*(p.y>0?1:_),v.y*(v.y>0?1:_))},M={width:.5*(S.x-w.x),height:.5*(S.y-w.y)};u=Math.min(s/M.width,l/M.height),d={x:(S.x+w.x)*-.5,y:(S.y+w.y)*-.5}}i.borderWidth=n.getMaxBorderWidth(c.data),i.outerRadius=Math.max((u-i.borderWidth)/2,0),i.innerRadius=Math.max(h?i.outerRadius/100*h:1,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),i.offsetX=d.x*i.outerRadius,i.offsetY=d.y*i.outerRadius,c.total=n.calculateTotal(),n.outerRadius=i.outerRadius-i.radiusLength*n.getRingIndex(n.index),n.innerRadius=n.outerRadius-i.radiusLength,e.each(c.data,function(e,i){n.updateElement(e,i,t)})},updateElement:function(t,n,i){var a=this,r=a.chart,o=r.chartArea,s=r.options,l=s.animation,u=(o.left+o.right)/2,d=(o.top+o.bottom)/2,c=s.rotation,h=s.rotation,f=a.getDataset(),g=i&&l.animateRotate?0:t.hidden?0:a.calculateCircumference(f.data[n])*(s.circumference/(2*Math.PI)),m=i&&l.animateScale?0:a.innerRadius,p=i&&l.animateScale?0:a.outerRadius,v=e.getValueAtIndexOrDefault;e.extend(t,{_datasetIndex:a.index,_index:n,_model:{x:u+r.offsetX,y:d+r.offsetY,startAngle:c,endAngle:h,circumference:g,outerRadius:p,innerRadius:m,label:v(f.label,n,r.data.labels[n])}});var b=t._model;this.removeHoverStyle(t),i&&l.animateRotate||(0===n?b.startAngle=s.rotation:b.startAngle=a.getMeta().data[n-1]._model.endAngle,b.endAngle=b.startAngle+b.circumference),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},calculateTotal:function(){var t,n=this.getDataset(),i=this.getMeta(),a=0;return e.each(i.data,function(e,i){t=n.data[i],isNaN(t)||e.hidden||(a+=Math.abs(t))}),a},calculateCircumference:function(t){var e=this.getMeta().total;return e>0&&!isNaN(t)?2*Math.PI*(t/e):0},getMaxBorderWidth:function(t){for(var e,n,i=0,a=this.index,r=t.length,o=0;r>o;o++)e=t[o]._model?t[o]._model.borderWidth:0,n=t[o]._chart?t[o]._chart.config.data.datasets[a].hoverBorderWidth:0,i=e>i?e:i,i=n>i?n:i;return i}})}},{}],18:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){return n.getValueOrDefault(t.showLine,e.showLines)}var n=t.helpers;t.defaults.line={showLines:!0,spanGaps:!1,hover:{mode:"label"},scales:{xAxes:[{type:"category",id:"x-axis-0"}],yAxes:[{type:"linear",id:"y-axis-0"}]}},t.controllers.line=t.DatasetController.extend({datasetElementType:t.elements.Line,dataElementType:t.elements.Point,update:function(t){var i,a,r,o=this,s=o.getMeta(),l=s.dataset,u=s.data||[],d=o.chart.options,c=d.elements.line,h=o.getScaleForId(s.yAxisID),f=o.getDataset(),g=e(f,d);for(g&&(r=l.custom||{},void 0!==f.tension&&void 0===f.lineTension&&(f.lineTension=f.tension),l._scale=h,l._datasetIndex=o.index,l._children=u,l._model={spanGaps:f.spanGaps?f.spanGaps:d.spanGaps,tension:r.tension?r.tension:n.getValueOrDefault(f.lineTension,c.tension),backgroundColor:r.backgroundColor?r.backgroundColor:f.backgroundColor||c.backgroundColor,borderWidth:r.borderWidth?r.borderWidth:f.borderWidth||c.borderWidth,borderColor:r.borderColor?r.borderColor:f.borderColor||c.borderColor,borderCapStyle:r.borderCapStyle?r.borderCapStyle:f.borderCapStyle||c.borderCapStyle,borderDash:r.borderDash?r.borderDash:f.borderDash||c.borderDash,borderDashOffset:r.borderDashOffset?r.borderDashOffset:f.borderDashOffset||c.borderDashOffset,borderJoinStyle:r.borderJoinStyle?r.borderJoinStyle:f.borderJoinStyle||c.borderJoinStyle,fill:r.fill?r.fill:void 0!==f.fill?f.fill:c.fill,steppedLine:r.steppedLine?r.steppedLine:n.getValueOrDefault(f.steppedLine,c.stepped),cubicInterpolationMode:r.cubicInterpolationMode?r.cubicInterpolationMode:n.getValueOrDefault(f.cubicInterpolationMode,c.cubicInterpolationMode),scaleTop:h.top,scaleBottom:h.bottom,scaleZero:h.getBasePixel()},l.pivot()),i=0,a=u.length;a>i;++i)o.updateElement(u[i],i,t);for(g&&0!==l._model.tension&&o.updateBezierControlPoints(),i=0,a=u.length;a>i;++i)u[i].pivot()}
23272,getPointBackgroundColor:function(t,e){var i=this.chart.options.elements.point.backgroundColor,a=this.getDataset(),r=t.custom||{};return r.backgroundColor?i=r.backgroundColor:a.pointBackgroundColor?i=n.getValueAtIndexOrDefault(a.pointBackgroundColor,e,i):a.backgroundColor&&(i=a.backgroundColor),i},getPointBorderColor:function(t,e){var i=this.chart.options.elements.point.borderColor,a=this.getDataset(),r=t.custom||{};return r.borderColor?i=r.borderColor:a.pointBorderColor?i=n.getValueAtIndexOrDefault(a.pointBorderColor,e,i):a.borderColor&&(i=a.borderColor),i},getPointBorderWidth:function(t,e){var i=this.chart.options.elements.point.borderWidth,a=this.getDataset(),r=t.custom||{};return r.borderWidth?i=r.borderWidth:a.pointBorderWidth?i=n.getValueAtIndexOrDefault(a.pointBorderWidth,e,i):a.borderWidth&&(i=a.borderWidth),i},updateElement:function(t,e,i){var a,r,o=this,s=o.getMeta(),l=t.custom||{},u=o.getDataset(),d=o.index,c=u.data[e],h=o.getScaleForId(s.yAxisID),f=o.getScaleForId(s.xAxisID),g=o.chart.options.elements.point,m=o.chart.data.labels||[],p=1===m.length||1===u.data.length||o.chart.isCombo;void 0!==u.radius&&void 0===u.pointRadius&&(u.pointRadius=u.radius),void 0!==u.hitRadius&&void 0===u.pointHitRadius&&(u.pointHitRadius=u.hitRadius),a=f.getPixelForValue("object"==typeof c?c:NaN,e,d,p),r=i?h.getBasePixel():o.calculatePointY(c,e,d),t._xScale=f,t._yScale=h,t._datasetIndex=d,t._index=e,t._model={x:a,y:r,skip:l.skip||isNaN(a)||isNaN(r),radius:l.radius||n.getValueAtIndexOrDefault(u.pointRadius,e,g.radius),pointStyle:l.pointStyle||n.getValueAtIndexOrDefault(u.pointStyle,e,g.pointStyle),backgroundColor:o.getPointBackgroun
23272dColor(t,e),borderColor:o.getPointBorderColor(t,e),borderWidth:o.getPointBorderWidth(t,e),tension:s.dataset._model?s.dataset._model.tension:0,steppedLine:s.dataset._model?s.dataset._model.steppedLine:!1,hitRadius:l.hitRadius||n.getValueAtIndexOrDefault(u.pointHitRadius,e,g.hitRadius)}},calculatePointY:function(t,e,n){var i,a,r,o=this,s=o.chart,l=o.getMeta(),u=o.getScaleForId(l.yAxisID),d=0,c=0;if(u.options.stacked){for(i=0;n>i;i++)if(a=s.data.datasets[i],r=s.getDatasetMeta(i),"line"===r.type&&r.yAxisID===u.id&&s.isDatasetVisible(i)){var h=Number(u.getRightValue(a.data[e]));0>h?c+=h||0:d+=h||0}var f=Number(u.getRightValue(t));return 0>f?u.getPixelForValue(c+f):u.getPixelForValue(d+f)}return u.getPixelForValue(t)},updateBezierControlPoints:function(){function t(t,e,n){return Math.max(Math.min(t,n),e)}var e,i,a,r,o,s=this,l=s.getMeta(),u=s.chart.chartArea,d=l.data||[];if(l.dataset._model.spanGaps&&(d=d.filter(function(t){return!t._model.skip})),"monotone"===l.dataset._model.cubicInterpolationMode)n.splineCurveMonotone(d);else for(e=0,i=d.length;i>e;++e)a=d[e],r=a._model,o=n.splineCurve(n.previousItem(d,e)._model,r,n.nextItem(d,e)._model,l.dataset._model.tension),r.controlPointPreviousX=o.previous.x,r.controlPointPreviousY=o.previous.y,r.controlPointNextX=o.next.x,r.controlPointNextY=o.next.y;if(s.chart.options.elements.line.capBezierPoints)for(e=0,i=d.length;i>e;++e)r=d[e]._model,r.controlPointPreviousX=t(r.controlPointPreviousX,u.left,u.right),r.controlPointPreviousY=t(r.controlPointPreviousY,u.top,u.bottom),r.controlPointNextX=t(r.controlPointNextX,u.left,u.right),r.controlPointNextY=t(r.controlPointNextY,u.top,u.bottom)},draw:function(t){var n,i,a=this,r=a.getMeta(),o=r.data||[],s=t||1;for(n=0,i=o.length;i>n;++n)o[n].transition(s);for(e(a.getDataset(),a.chart.options)&&r.dataset.transition(s).draw(),n=0,i=o.length;i>n;++n)o[n].draw()},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t._index,a=t.custom||{},r=t._model;r.radius=a.hoverRadius||n.getValueAtIndexOrDefault(e.pointHoverRadius,i,this.chart.options.elements.point.hoverRadius),r.backgroundColor=a.hoverBackgroundColor||n.getValueAtIndexOrDefault(e.pointHoverBackgroundColor,i,n.getHoverColor(r.backgroundColor)),r.borderColor=a.hoverBorderColor||n.getValueAtIndexOrDefault(e.pointHoverBorderColor,i,n.getHoverColor(r.borderColor)),r.borderWidth=a.hoverBorderWidth||n.getValueAtIndexOrDefault(e.pointHoverBorderWidth,i,r.borderWidth)},removeHoverStyle:function(t){var e=this,i=e.chart.data.datasets[t._datasetIndex],a=t._index,r=t.custom||{},o=t._model;void 0!==i.radius&&void 0===i.pointRadius&&(i.pointRadius=i.radius),o.radius=r.radius||n.getValueAtIndexOrDefault(i.pointRadius,a,e.chart.options.elements.point.radius),o.backgroundColor=e.getPointBackgroun
23272dColor(t,a),o.borderColor=e.getPointBorderColor(t,a),o.borderWidth=e.getPointBorderWidth(t,a)}})}},{}],19:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.polarArea={scale:{type:"radialLinear",lineArc:!0,ticks:{beginAtZero:!0}},animation:{animateRotate:!0,animateScale:!0},startAngle:-.5*Math.PI,aspectRatio:1,legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');var n=t.data,i=n.datasets,a=n.labels;if(i.length)for(var r=0;r<i[0].data.length;++r)e.push('<li><span style="background-color:'+i[0].backgroundColor[r]+'"></span>'),a[r]&&e.push(a[r]),e.push("</li>");return e.push("</ul>"),e.join("")},legend:{labels:{generateLabels:function(t){var n=t.data;return n.labels.length&&n.datasets.length?n.labels.map(function(i,a){var r=t.getDatasetMeta(0),o=n.datasets[0],s=r.data[a],l=s.custom||{},u=e.getValueAtIndexOrDefault,d=t.options.elements.arc,c=l.backgroundColor?l.backgroundColor:u(o.backgroundColor,a,d.backgroundColor),h=l.borderColor?l.borderColor:u(o.borderColor,a,d.borderColor),f=l.borderWidth?l.borderWidth:u(o.borderWidth,a,d.borderWidth);return{text:i,fillStyle:c,strokeStyle:h,lineWidth:f,hidden:isNaN(o.data[a])||r.data[a].hidden,index:a}}):[]}},onClick:function(t,e){var n,i,a,r=e.index,o=this.chart;for(n=0,i=(o.data.datasets||[]).length;i>n;++n)a=o.getDatasetMeta(n),a.data[r].hidden=!a.data[r].hidden;o.update()}},tooltips:{callbacks:{title:function(){return""},label:function(t,e){return e.labels[t.index]+": "+t.yLabel}}}},t.controllers.polarArea=t.DatasetController.extend({
23273    dataElementType:t.elements.Arc,linkScales:e.noop,update:function(t){var n=this,i=n.chart,a=i.chartArea,r=n.getMeta(),o=i.options,s=o.elements.arc,l=Math.min(a.right-a.left,a.bottom-a.top);i.outerRadius=Math.max((l-s.borderWidth/2)/2,0),i.innerRadius=Math.max(o.cutoutPercentage?i.outerRadius/100*o.cutoutPercentage:1,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),n.outerRadius=i.outerRadius-i.radiusLength*n.index,n.innerRadius=n.outerRadius-i.radiusLength,r.count=n.countVisibleElements(),e.each(r.data,function(e,i){n.updateElement(e,i,t)})},updateElement:function(t,n,i){for(var a=this,r=a.chart,o=a.getDataset(),s=r.options,l=s.animation,u=r.scale,d=e.getValueAtIndexOrDefault,c=r.data.labels,h=a.calculateCircumference(o.data[n]),f=u.xCenter,g=u.yCenter,m=0,p=a.getMeta(),v=0;n>v;++v)isNaN(o.data[v])||p.data[v].hidden||++m;var b=s.startAngle,y=t.hidden?0:u.getDistanceFromCenterForValue(o.data[n]),x=b+h*m,k=x+(t.hidden?0:h),_=l.animateScale?0:u.getDistanceFromCenterForValue(o.data[n]);e.extend(t,{_datasetIndex:a.index,_index:n,_scale:u,_model:{x:f,y:g,innerRadius:0,outerRadius:i?_:y,startAngle:i&&l.animateRotate?b:x,endAngle:i&&l.animateRotate?b:k,label:d(c,n,c[n])}}),a.removeHoverStyle(t),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},countVisibleElements:function(){var t=this.getDataset(),n=this.getMeta(),i=0;return e.each(n.data,function(e,n){isNaN(t.data[n])||e.hidden||i++}),i},calculateCircumference:function(t){var e=this.getMeta().count;return e>0&&!isNaN(t)?2*Math.PI/e:0}})}},{}],20:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.radar={aspectRatio:1,scale:{type:"radialLinear"},elements:{line:{tension:0}}},t.controllers.radar=t.DatasetController.extend({datasetElementType:t.elements.Line,dataElementType:t.elements.Point,linkScales:e.noop,update:function(t){var n=this,i=n.getMeta(),a=i.dataset,r=i.data,o=a.custom||{},s=n.getDataset(),l=n.chart.options.elements.line,u=n.chart.scale;void 0!==s.tension&&void 0===s.lineTension&&(s.lineTension=s.tension),e.extend(i.dataset,{_datasetIndex:n.index,_children:r,_loop:!0,_model:{tension:o.tension?o.tension:e.getValueOrDefault(s.lineTension,l.tension),backgroundColor:o.backgroundColor?o.backgroundColor:s.backgroundColor||l.backgroundColor,borderWidth:o.borderWidth?o.borderWidth:s.borderWidth||l.borderWidth,borderColor:o.borderColor?o.borderColor:s.borderColor||l.borderColor,fill:o.fill?o.fill:void 0!==s.fill?s.fill:l.fill,borderCapStyle:o.borderCapStyle?o.borderCapStyle:s.borderCapStyle||l.borderCapStyle,borderDash:o.borderDash?o.borderDash:s.borderDash||l.borderDash,borderDashOffset:o.borderDashOffset?o.borderDashOffset:s.borderDashOffset||l.borderDashOffset,borderJoinStyle:o.borderJoinStyle?o.borderJoinStyle:s.borderJoinStyle||l.borderJoinStyle,scaleTop:u.top,scaleBottom:u.bottom,scaleZero:u.getBasePosition()}}),i.dataset.pivot(),e.each(r,function(e,i){n.updateElement(e,i,t)},n),n.updateBezierControlPoints()},updateElement:function(t,n,i){var a=this,r=t.custom||{},o=a.getDataset(),s=a.chart.scale,l=a.chart.options.elements.point,u=s.getPointPositionForValue(n,o.data[n]);e.extend(t,{_datasetIndex:a.index,_index:n,_scale:s,_model:{x:i?s.xCenter:u.x,y:i?s.yCenter:u.y,tension:r.tension?r.tension:e.getValueOrDefault(o.tension,a.chart.options.elements.line.tension),radius:r.radius?r.radiu
23273s:e.getValueAtIndexOrDefault(o.pointRadius,n,l.radius),backgroundColor:r.backgroundColor?r.backgroundColor:e.getValueAtIndexOrDefault(o.pointBackgroundColor,n,l.backgroundColor),borderColor:r.borderColor?r.borderColor:e.getValueAtIndexOrDefault(o.pointBorderColor,n,l.borderColor),borderWidth:r.borderWidth?r.borderWidth:e.getValueAtIndexOrDefault(o.pointBorderWidth,n,l.borderWidth),pointStyle:r.pointStyle?r.pointStyle:e.getValueAtIndexOrDefault(o.pointStyle,n,l.pointStyle),hitRadius:r.hitRadius?r.hitRadius:e.getValueAtIndexOrDefault(o.hitRadius,n,l.hitRadius)}}),t._model.skip=r.skip?r.skip:isNaN(t._model.x)||isNaN(t._model.y)},updateBezierControlPoints:function(){var t=this.chart.chartArea,n=this.getMeta();e.each(n.data,function(i,a){var r=i._model,o=e.splineCurve(e.previousItem(n.data,a,!0)._model,r,e.nextItem(n.data,a,!0)._model,r.tension);r.controlPointPreviousX=Math.max(Math.min(o.previous.x,t.right),t.left),r.controlPointPreviousY=Math.max(Math.min(o.previous.y,t.bottom),t.top),r.controlPointNextX=Math.max(Math.min(o.next.x,t.right),t.left),r.controlPointNextY=Math.max(Math.min(o.next.y,t.bottom),t.top),i.pivot()})},draw:function(t){var n=this.getMeta(),i=t||1;e.each(n.data,function(t){t.transition(i)}),n.dataset.transition(i).draw(),e.each(n.data,function(t){t.draw()})},setHoverStyle:function(t){var n=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},a=t._index,r=t._model;r.radius=i.hoverRadius?i.hoverRadius:e.getValueAtIndexOrDefault(n.pointHoverRadius,a,this.chart.options.elements.point.hoverRadius),r.backgroundColor=i.hoverBackgroundColor?i.hoverBackgroundColor:e.getValueAtIndexOrDefault(n.pointHoverBackgroundColor,a,e.getHoverColor(r.backgroundColor)),r.borderColor=i.hoverBorderColor?i.hoverBorderColor:e.getValueAtIndexOrDefault(n.pointHoverBorderColor,a,e.getHoverColor(r.borderColor)),r.borderWidth=i.hoverBorderWidth?i.hoverBorderWidth:e.getValueAtIndexOrDefault(n.pointHoverBorderWidth,a,r.borderWidth)},removeHoverStyle:function(t){var n=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},a=t._index,r=t._model,o=this.chart.options.elements.point;r.radius=i.radius?i.radius:e.getValueAtIndexOrDefault(n.radius,a,o.radius),r.backgroundColor=i.backgroundColor?i.backgroundColor:e.getValueAtIndexOrDefault(n.pointBackgroun
23273dColor,a,o.backgroundColor),r.borderColor=i.borderColor?i.borderColor:e.getValueAtIndexOrDefault(n.pointBorderColor,a,o.borderColor),r.borderWidth=i.borderWidth?i.borderWidth:e.getValueAtIndexOrDefault(n.pointBorderWidth,a,o.borderWidth)}})}},{}],21:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.animation={duration:1e3,easing:"easeOutQuart",onProgress:e.noop,onComplete:e.noop},t.Animation=t.Element.extend({currentStep:null,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),t.animationService={frameDuration:17,animations:[],dropFrames:0,request:null,addAnimation:function(t,e,n,i){var a=this;i||(t.animating=!0);for(var r=0;r<a.animations.length;++r)if(a.animations[r].chartInstance===t)return void(a.animations[r].animationObject=e);a.animations.push({chartInstance:t,animationObject:e}),1===a.animations.length&&a.requestAnimationFrame()},cancelAnimation:function(t){var n=e.findIndex(this.animations,function(e){return e.chartInstance===t});-1!==n&&(this.animations.splice(n,1),t.animating=!1)},requestAnimationFrame:function(){var t=this;null===t.request&&(t.request=e.requestAnimFrame.call(window,function(){t.request=null,t.startDigest()}))},startDigest:function(){var t=this,e=Date.now(),n=0;t.dropFrames>1&&(n=Math.floor(t.dropFrames),t.dropFrames=t.dropFrames%1);for(var i=0;i<t.animations.length;)null===t.animations[i].animationObject.currentStep&&(t.animations[i].animationObject.currentStep=0),t.animations[i].animationObject.currentStep+=1+n,t.animations[i].animationObject.currentStep>t.animations[i].animationObject.numSteps&&(t.animations[i].animationObject.currentStep=t.animations[i].animationObject.numSteps),t.animations[i].animationObject.render(t.animations[i].chartInstance,t.animations[i].animationObject),t.animations[i].animationObject.onAnimationProgress&&t.animations[i].animationObject.onAnimationProgress.call&&t.animations[i].animationObject.onAnimationProgress.call(t.animations[i].chartInstance,t.animations[i]),t.animations[i].animationObject.currentStep===t.animations[i].animationObject.numSteps?(t.animations[i].animationObject.onAnimationComplete&&t.animations[i].animationObject.onAnimationComplete.call&&t.animations[i].animationObject.onAnimationComplete.call(t.animations[i].chartInstance,t.animations[i]),t.animations[i].chartInstance.animating=!1,t.animations.splice(i,1)):++i;var a=Date.now(),r=(a-e)/t.frameDuration;t.dropFrames+=r,t.animations.length>0&&t.requestAnimationFrame()}}}},{}],22:[function(t,e,n){"use strict";e.exports=function(t){var e=t.canvasHelpers={};e.drawPoint=function(t,e,n,i,a){var r,o,s,l,u,d;if("object"==typeof e&&(r=e.toString(),"[object HTMLImageElement]"===r||"[object HTMLCanvasElement]"===r))return void t.drawImage(e,i-e.width/2,a-e.height/2);if(!(isNaN(n)||0>=n)){switch(e){default:t.beginPath(),t.arc(i,a,n,0,2*Math.PI),t.closePath(),t.fill();break;case"triangle":t.beginPath(),o=3*n/Math.sqrt(3),u=o*Math.sqrt(3)/2,t.moveTo(i-o/2,a+u/3),t.lineTo(i+o/2,a+u/3),t.lineTo(i,a-2*u/3),t.closePath(),t.fill();break;case"rect":d=1/Math.SQRT2*n,t.beginPath(),t.fillRect(i-d,a-d,2*d,2*d),t.strokeRect(i-d,a-d,2*d,2*d);break;case"rectRot":d=1/Math.SQRT2*n,t.beginPath(),t.moveTo(i-d,a),t.lineTo(i,a+d),t.lineTo(i+d,a),t.lineTo(i,a-d),t.closePath(),t.fill();break;case"cross":t.beginPath(),t.moveTo(i,a+n),t.lineTo(i,a-n),t.moveTo(i-n,a),t.lineTo(i+n,a),t.closePath();break;case"crossRot":t.beginPath(),s=Math.cos(Math.PI/4)*n,l=Math.sin(Math.PI/4)*n,t.moveTo(i-s,a-l),t.lineTo(i+s,a+l),t.moveTo(i-s,a+l),t.lineTo(i+s,a-l),t.closePath();break;case"star":t.beginPath(),t.moveTo(i,a+n),t.lineTo(i,a-n),t.moveTo(i-n,a),t.lineTo(i+n,a),s=Math.cos(Math.PI/4)*n,l=Math.sin(Math.PI/4)*n,t.moveTo(i-s,a-l),t.lineTo(i+s,a+l),t.moveTo(i-s,a+l),t.lineTo(i+s,a-l),t.closePath();break;case"line":t.beginPath(),t.moveTo(i-n,a),t.lineTo(i+n,a),t.closePath();break;case"dash":t.beginPath(),t.moveTo(i,a),t.lineTo(i+n,a),t.closePath()}t.stroke()}}}},{}],23:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){var n=o.getStyle(t,e),i=n&&n.match(/(\d+)px/);return i?Number(i[1]):void 0}function n(t,n){var i=t.style,a=t.getAttribute("height"),r=t.getAttribute("width");
23273if(t._chartjs={initial:{height:a,width:r,style:{display:i.display,height:i.height,width:i.width}}},i.display=i.display||"block",null===r||""===r){var o=e(t,"width");void 0!==o&&(t.width=o)}if(null===a||""===a)if(""===t.style.height)t.height=t.width/(n.options.aspectRatio||2);else{var s=e(t,"height");void 0!==o&&(t.height=s)}return t}function i(t){if(t._chartjs){var e=t._chartjs.initial;["height","width"].forEach(function(n){var i=e[n];void 0===i||null===i?t.removeAttribute(n):t.setAttribute(n,i)}),o.each(e.style||{},function(e,n){t.style[n]=e}),t.width=t.width,delete t._chartjs}}function a(t,e){if("string"==typeof t?t=document.getElementById(t):t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas),t instanceof HTMLCanvasElement){var i=t.getContext&&t.getContext("2d");if(i instanceof CanvasRenderingContext2D)return n(t,e),i}return null}function r(e){e=e||{};var n=e.data=e.data||{};return n.datasets=n.datasets||[],n.labels=n.labels||[],e.options=o.configMerge(t.defaults.global,t.defaults[e.type],e.options||{}),e}var o=t.helpers;t.types={},t.instances={},t.controllers={},t.Controller=function(e,n,i){var s=this;n=r(n);var l=a(e,n),u=l&&l.canvas,d=u&&u.height,c=u&&u.width;return i.ctx=l,i.canvas=u,i.config=n,i.width=c,i.height=d,i.aspectRatio=d?c/d:null,s.id=o.uid(),s.chart=i,s.config=n,s.options=n.options,s._bufferedRender=!1,t.instances[s.id]=s,Object.defineProperty(s,"data",{get:function(){return s.config.data}}),l&&u?(o.retinaScale(i),s.options.responsive&&(o.addResizeListener(u.parentNode,function(){s.resize()}),s.resize(!0)),s.initialize(),s):(console.error("Failed to create chart: can't acquire context from the given item"),s)},o.extend(t.Controller.prototype,{initialize:function(){var e=this;return t.plugins.notify("beforeInit",[e]),e.bindEvents(),e.ensureScalesHaveIDs(),e.buildOrUpdateControllers(),e.buildScales(),e.updateLayout(),e.resetElements(),e.initToolTip(),e.update(),t.plugins.notify("afterInit",[e]),e},clear:function(){return o.clear(this.chart),this},stop:function(){return t.animationService.cancelAnimation(this),this},resize:function(e){var n=this,i=n.chart,a=n.options,r=i.canvas,s=a.maintainAspectRatio&&i.aspectRatio||null,l=Math.floor(o.getMaximumWidth(r)),u=Math.floor(s?l/s:o.getMaximumHeight(r));if(i.width!==l||i.height!==u){r.width=i.width=l,r.height=i.height=u,r.style.width=l+"px",r.style.height=u+"px",o.retinaScale(i);var d={width:l,height:u};t.plugins.notify("resize",[n,d]),n.options.onResize&&n.options.onResize(n,d),e||(n.stop(),n.update(n.options.responsiveAnimationDuration))}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},n=t.scale;o.each(e.xAxes,function(t,e){t.id=t.id||"x-axis-"+e}),o.each(e.yAxes,function(t,e){t.id=t.id||"y-axis-"+e}),n&&(n.id=n.id||"scale")},buildScales:function(){var e=this,n=e.options,i=e.scales={},a=[];n.scales&&(a=a.concat((n.scales.xAxes||[]).map(function(t){return{options:t,dtype:"category"}}),(n.scales.yAxes||[]).map(function(t){return{options:t,dtype:"linear"}}))),n.scale&&a.push({options:n.scale,dtype:"radialLinear",isDefault:!0}),o.each(a,function(n){var a=n.options,r=o.getValueOrDefault(a.type,n.dtype),s=t.scaleService.getScaleConstructor(r);if(s){var l=new s({id:a.id,options:a,ctx:e.chart.ctx,chart:e});i[l.id]=l,n.isDefault&&(e.scale=l)}}),t.scaleService.addScalesToLayout(this)},updateLayout:function(){t.layoutService.update(this,this.chart.width,this.chart.height)},buildOrUpdateControllers:function(){var e=this,n=[],i=[];if(o.each(e.data.datasets,function(a,r){var o=e.getDatasetMeta(r);o.type||(o.type=a.type||e.config.type),n.push(o.type),o.controller?o.controller.updateIndex(r):(o.controller=new t.controllers[o.type](e,r),i.push(o.controller))},e),n.length>1)for(var a=1;a<n.length;a++)if(n[a]!==n[a-1]){e.isCombo=!0;break}return i},resetElements:function(){var t=this;o.each(t.data.datasets,function(e,n){t.getDatasetMeta(n).controller.reset()},t)},reset:function(){this.resetElements(),this.tooltip.initialize()},update:function(e,n){var i=this;t.plugins.notify("beforeUpdate",[i]),i.tooltip._data=i.data;var a=i.buildOrUpdateControllers();o.each(i.data.datasets,function(t,e){i.getDatasetMeta(e).controller.buildOrUpdateElements()},i),t.layoutService.update(i,i.chart.width,i.chart.height),t.plugins.notify("afterScaleUpdate",[i]),o.each(a,function(t){t.reset()}),i.updateDatasets(),t.plugins.notify("afterUpdate",[i]),i._bufferedRender?i._bufferedRequest={lazy:n,duration:e}:i.render(e,n)},updateDatasets:function(){var e,n,i=this;if(t.plugins.notify("beforeDatasetsUpdate",[i])){for(e=0,n=i.data.datasets.length;n>e;
23273++e)i.getDatasetMeta(e).controller.update();t.plugins.notify("afterDatasetsUpdate",[i])}},render:function(e,n){var i=this;t.plugins.notify("beforeRender",[i]);var a=i.options.animation;if(a&&("undefined"!=typeof e&&0!==e||"undefined"==typeof e&&0!==a.duration)){var r=new t.Animation;r.numSteps=(e||a.duration)/16.66,r.easing=a.easing,r.render=function(t,e){var n=o.easingEffects[e.easing],i=e.currentStep/e.numSteps,a=n(i);t.draw(a,i,e.currentStep)},r.onAnimationProgress=a.onProgress,r.onAnimationComplete=a.onComplete,t.animationService.addAnimation(i,r,e,n)}else i.draw(),a&&a.onComplete&&a.onComplete.call&&a.onComplete.call(i);return i},draw:function(e){var n=this,i=e||1;n.clear(),t.plugins.notify("beforeDraw",[n,i]),o.each(n.boxes,function(t){t.draw(n.chartArea)},n),n.scale&&n.scale.draw(),t.plugins.notify("beforeDatasetsDraw",[n,i]),o.each(n.data.datasets,function(t,i){n.isDatasetVisible(i)&&n.getDatasetMeta(i).controller.draw(e)},n,!0),t.plugins.notify("afterDatasetsDraw",[n,i]),n.tooltip.transition(i).draw(),t.plugins.notify("afterDraw",[n,i])},getElementAtEvent:function(e){return t.Interaction.modes.single(this,e)},getElementsAtEvent:function(e){return t.Interaction.modes.label(this,e,{intersect:!0})},getElementsAtXAxis:function(e){return t.Interaction.modes["x-axis"](this,e,{intersect:!0})},getElementsAtEventForMode:function(e,n,i){var a=t.Interaction.modes[n];return"function"==typeof a?a(this,e,i):[]},getDatasetAtEvent:function(e){return t.Interaction.modes.dataset(this,e)},getDatasetMeta:function(t){var e=this,n=e.data.datasets[t];n._meta||(n._meta={});var i=n._meta[e.id];return i||(i=n._meta[e.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null}),i},getVisibleDatasetCount:function(){for(var t=0,e=0,n=this.data.datasets.length;n>e;++e)this.isDatasetVisible(e)&&t++;return t},isDatasetVisible:function(t){var e=this.getDatasetMeta(t);return"boolean"==typeof e.hidden?!e.hidden:!this.data.datasets[t].hidden},generateLegend:function(){return this.options.legendCallback(this)},destroy:function(){var e,n,a,r=this,s=r.chart.canvas;for(r.stop(),n=0,a=r.data.datasets.length;a>n;++n)e=r.getDatasetMeta(n),e.controller&&(e.controller.destroy(),e.controller=null);s&&(o.unbindEvents(r,r.events),o.removeResizeListener(s.parentNode),o.clear(r.chart),i(s),r.chart.canvas=null,r.chart.ctx=null),t.plugins.notify("destroy",[r]),delete t.instances[r.id]},toBase64Image:function(){return this.chart.canvas.toDataURL.apply(this.chart.canvas,arguments)},initToolTip:function(){var e=this;e.tooltip=new t.Tooltip({_chart:e.chart,_chartInstance:e,_data:e.data,_options:e.options.tooltips},e),e.tooltip.initialize()},bindEvents:function(){var t=this;o.bindEvents(t,t.options.events,function(e){t.eventHandler(e)})},updateHoverStyle:function(t,e,n){var i,a,r,o=n?"setHoverStyle":"removeHoverStyle";for(a=0,r=t.length;r>a;++a)i=t[a],i&&this.getDatasetMeta(i._datasetIndex).controller[o](i)},eventHandler:function(t){var e=this,n=e.legend,i=e.tooltip,a=e.options.hover;e._bufferedRender=!0,e._bufferedRequest=null;var r=e.handleEvent(t);r|=n&&n.handleEvent(t),r|=i&&i.handleEvent(t);var o=e._bufferedRequest;return o?e.render(o.duration,o.lazy):r&&!e.animating&&(e.stop(),e.render(a.animationDuration,!0)),e._bufferedRender=!1,e._bufferedRequest=null,e},handleEvent:function(t){var e=this,n=e.options||{},i=n.hover,a=!1;return e.lastActive=e.lastActive||[],"mouseout"===t.type?e.active=[]:e.active=e.getElementsAtEventForMode(t,i.mode,i),i.onHover&&i.onHover.call(e,e.active),("mouseup"===t.type||"click"===t.type)&&n.onClick&&n.onClick.call(e,t,e.active),e.lastActive.length&&e.updateHoverStyle(e.lastActive,i.mode,!1),e.active.length&&i.mode&&e.updateHoverStyle(e.active,i.mode,!0),a=!o.arrayEquals(e.active,e.lastActive),e.lastActive=e.active,a}})}},{}],24:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){return t._chartjs?void t._chartjs.listeners.push(e):(Object.defineProperty(t,"_chartjs",{configurable:!0,enumerable:!1,value:{listeners:[e]}}),void a.forEach(function(e){var n="onData"+e.charAt(0).toUpperCase()+e.slice(1),a=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value:function(){var e=Array.prototype.slice.call(arguments),r=a.apply(this,e);return i.each(t._chartjs.listeners,function(t){"function"==typeof t[n]&&t[n].apply(t,e)}),r}})}
23273))}function n(t,e){var n=t._chartjs;if(n){var i=n.listeners,r=i.indexOf(e);-1!==r&&i.splice(r,1),i.length>0||(a.forEach(function(e){delete t[e]}),delete t._chartjs)}}var i=t.helpers,a=["push","pop","shift","splice","unshift"];t.DatasetController=function(t,e){this.initialize(t,e)},i.extend(t.DatasetController.prototype,{datasetElementType:null,dataElementType:null,initialize:function(t,e){var n=this;n.chart=t,n.index=e,n.linkScales(),n.addElements()},updateIndex:function(t){this.index=t},linkScales:function(){var t=this,e=t.getMeta(),n=t.getDataset();null===e.xAxisID&&(e.xAxisID=n.xAxisID||t.chart.options.scales.xAxes[0].id),null===e.yAxisID&&(e.yAxisID=n.yAxisID||t.chart.options.scales.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},reset:function(){this.update(!0)},destroy:function(){this._data&&n(this._data,this)},createMetaDataset:function(){var t=this,e=t.datasetElementType;return e&&new e({_chart:t.chart.chart,_datasetIndex:t.index})},createMetaData:function(t){var e=this,n=e.dataElementType;return n&&new n({_chart:e.chart.chart,_datasetIndex:e.index,_index:t})},addElements:function(){var t,e,n=this,i=n.getMeta(),a=n.getDataset().data||[],r=i.data;for(t=0,e=a.length;e>t;++t)r[t]=r[t]||n.createMetaData(t);i.dataset=i.dataset||n.createMetaDataset()},addElementAndReset:function(t){var e=this.createMetaData(t);this.getMeta().data.splice(t,0,e),this.updateElement(e,t,!0)},buildOrUpdateElements:function(){var t=this,i=t.getDataset(),a=i.data||(i.data=[]);t._data!==a&&(t._data&&n(t._data,t),e(a,t),t._data=a),t.resyncElements()},update:i.noop,draw:function(t){var e,n,i=t||1,a=this.getMeta().data;for(e=0,n=a.length;n>e;++e)a[e].transition(i).draw()},removeHoverStyle:function(t,e){var n=this.chart.data.datasets[t._datasetIndex],a=t._index,r=t.custom||{},o=i.getValueAtIndexOrDefault,s=t._model;s.backgroundColor=r.backgroundColor?r.backgroundColor:o(n.backgroundColor,a,e.backgroundColor),s.borderColor=r.borderColor?r.borderColor:o(n.borderColor,a,e.borderColor),s.borderWidth=r.borderWidth?r.borderWidth:o(n.borderWidth,a,e.borderWidth)},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],n=t._index,a=t.custom||{},r=i.getValueAtIndexOrDefault,o=i.getHoverColor,s=t._model;s.backgroundColor=a.hoverBackgroundColor?a.hoverBackgroundColor:r(e.hoverBackgroundColor,n,o(s.backgroundColor)),s.borderColor=a.hoverBorderColor?a.hoverBorderColor:r(e.hoverBorderColor,n,o(s.borderColor)),s.borderWidth=a.hoverBorderWidth?a.hoverBorderWidth:r(e.hoverBorderWidth,n,s.borderWidth)},resyncElements:function(){var t=this,e=t.getMeta(),n=t.getDataset().data,i=e.data.length,a=n.length;i>a?e.data.splice(a,i-a):a>i&&t.insertElements(i,a-i)},insertElements:function(t,e){for(var n=0;e>n;++n)this.addElementAndReset(t+n)},onDataPush:function(){this.insertElements(this.getDataset().data.length-1,arguments.length)},onDataPop:function(){this.getMeta().data.pop()},onDataShift:function(){this.getMeta().data.shift()},onDataSplice:function(t,e){this.getMeta().data.splice(t,e),this.insertElements(t,arguments.length-2)},onDataUnshift:function(){this.insertElements(0,arguments.length)}}),t.DatasetController.extend=i.inherits}},{}],25:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.elements={},t.Element=function(t){e.extend(this,t),this.initialize.apply(this,arguments)},e.extend(t.Element.prototype,{initialize:function(){this.hidden=!1},pivot:function(){var t=this;return t._view||(t._view=e.clone(t._model)),t._start=e.clone(t._view),t},transition:function(t){var n=this;return n._view||(n._view=e.clone(n._model)),1===t?(n._view=n._model,n._start=null,n):(n._start||n.pivot(),e.each(n._model,function(i,a){if("_"===a[0]);else if(n._view.hasOwnProperty(a))if(i===n._view[a]);else if("string"==typeof i)try{var r=e.color(n._model[a]).mix(e.color(n._start[a]),t);n._view[a]=r.rgbString()}catch(o){n._view[a]=i}else if("number"==typeof i){var s=void 0!==n._start[a]&&isNaN(n._start[a])===!1?n._start[a]:0;n._view[a]=(n._model[a]-s)*t+s}else n._view[a]=i;else"number"!=typeof i||isNaN(n._view[a])?n._view[a]=i:n._view[a]=i*t},n),n)},tooltipPosition:function(){return{x:this._model.x,y:this._model.y}},hasValue:function(){return e.isNumber(this._model.x)&&e.isNumber(this._model.y)}}),t.Element.extend=e.inherits}},{}],26:[function(t,e,n){"use strict";var i=t(2);e.exports=function(t){function e(t,e,n){var i;return"string"==typeof t?(i=parseInt(t,10),-1!==t.indexOf("%")&&(i=i/100*e.parentNode[n])):i=t,i}function n(t){return void 0!==t&&null!==t&&"none"!==t}function a(t,i,a){var r=document.defaultView,o=t.parentNode,s=r.getComputedStyle(t)[i],l=r.getComputedStyle(o)[i],u=n(s),d=n(l),c=Number.POSITIVE_INFINITY;return u||d?Math.min(u?e(s,t,a):c,d?e(l,o,a):c):"none"}var r=t.helpers={};r.each=function(t,e,n,i){var a,o;if(r.isArray(t))if(o=t.length,i)for(a=o-1;a>=0;a--)e.call(n,t[a],a);else for(a=0;o>a;a++)e.call(n,t[a],a);else if("object"==typeof t){var s=Object.keys(t);for(o=s.length,a=0;o>a;a++)e.call(n,t[s[a]],s[a])}},r.clone=function(t){var e={};return r.each(t,function(t,n){r.isArray(t)?e[n]=t.slice(0):"object"==typeof t&&null!==t?e[n]=r.clone(t):e[n]=t}),e},r.extend=function(t){for(var e=function(e,n){t[n]=e},n=1,i=arguments.length;i>n;n++)r.each(arguments[n],e);return t},r.configMerge=function(e){var n=r.clone(e);
23273return r.each(Array.prototype.slice.call(arguments,1),function(e){r.each(e,function(e,i){var a=n.hasOwnProperty(i),o=a?n[i]:{};"scales"===i?n[i]=r.scaleMerge(o,e):"scale"===i?n[i]=r.configMerge(o,t.scaleService.getScaleDefaults(e.type),e):!a||"object"!=typeof o||r.isArray(o)||null===o||"object"!=typeof e||r.isArray(e)?n[i]=e:n[i]=r.configMerge(o,e)})}),n},r.scaleMerge=function(e,n){var i=r.clone(e);return r.each(n,function(e,n){"xAxes"===n||"yAxes"===n?i.hasOwnProperty(n)?r.each(e,function(e,a){var o=r.getValueOrDefault(e.type,"xAxes"===n?"category":"linear"),s=t.scaleService.getScaleDefaults(o);a>=i[n].length||!i[n][a].type?i[n].push(r.configMerge(s,e)):e.type&&e.type!==i[n][a].type?i[n][a]=r.configMerge(i[n][a],s,e):i[n][a]=r.configMerge(i[n][a],e)}):(i[n]=[],r.each(e,function(e){var a=r.getValueOrDefault(e.type,"xAxes"===n?"category":"linear");i[n].push(r.configMerge(t.scaleService.getScaleDefaults(a),e))})):i.hasOwnProperty(n)&&"object"==typeof i[n]&&null!==i[n]&&"object"==typeof e?i[n]=r.configMerge(i[n],e):i[n]=e}),i},r.getValueAtIndexOrDefault=function(t,e,n){return void 0===t||null===t?n:r.isArray(t)?e<t.length?t[e]:n:t},r.getValueOrDefault=function(t,e){return void 0===t?e:t},r.indexOf=Array.prototype.indexOf?function(t,e){return t.indexOf(e)}:function(t,e){for(var n=0,i=t.length;i>n;++n)if(t[n]===e)return n;return-1},r.where=function(t,e){if(r.isArray(t)&&Array.prototype.filter)return t.filter(e);var n=[];return r.each(t,function(t){e(t)&&n.push(t)}),n},r.findIndex=Array.prototype.findIndex?function(t,e,n){return t.findIndex(e,n)}:function(t,e,n){n=void 0===n?t:n;for(var i=0,a=t.length;a>i;++i)if(e.call(n,t[i],i,t))return i;return-1},r.findNextWhere=function(t,e,n){(void 0===n||null===n)&&(n=-1);for(var i=n+1;i<t.length;i++){var a=t[i];if(e(a))return a}},r.findPreviousWhere=function(t,e,n){(void 0===n||null===n)&&(n=t.length);for(var i=n-1;i>=0;i--){var a=t[i];if(e(a))return a}},r.inherits=function(t){var e=this,n=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return e.apply(this,arguments)},i=function(){this.constructor=n};return i.prototype=e.prototype,n.prototype=new i,n.extend=r.inherits,t&&r.extend(n.prototype,t),n.__super__=e.prototype,n},r.noop=function(){},r.uid=function(){var t=0;return function(){return t++}}(),r.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},r.almostEquals=function(t,e,n){return Math.abs(t-e)<n},r.max=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.max(t,e)},Number.NEGATIVE_INFINITY)},r.min=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.min(t,e)},Number.POSITIVE_INFINITY)},r.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return t=+t,0===t||isNaN(t)?t:t>0?1:-1},r.log10=Math.log10?function(t){return Math.log10(t)}:function(t){return Math.log(t)/Math.LN10},r.toRadians=function(t){return t*(Math.PI/180)},r.toDegrees=function(t){return t*(180/Math.PI)},r.getAngleFromPoint=function(t,e){var n=e.x-t.x,i=e.y-t.y,a=Math.sqrt(n*n+i*i),r=Math.atan2(i,n);return r<-.5*Math.PI&&(r+=2*Math.PI),{angle:r,distance:a}},r.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},r.aliasPixel=function(t){return t%2===0?0:.5},r.splineCurve=function(t,e,n,i){var a=t.skip?e:t,r=e,o=n.skip?e:n,s=Math.sqrt(Math.pow(r.x-a.x,2)+Math.pow(r.y-a.y,2)),l=Math.sqrt(Math.pow(o.x-r.x,2)+Math.pow(o.y-r.y,2)),u=s/(s+l),d=l/(s+l);u=isNaN(u)?0:u,d=isNaN(d)?0:d;var c=i*u,h=i*d;return{previous:{x:r.x-c*(o.x-a.x),y:r.y-c*(o.y-a.y)},next:{x:r.x+h*(o.x-a.x),y:r.y+h*(o.y-a.y)}}},r.EPSILON=Number.EPSILON||1e-14,r.splineCurveMonotone=function(t){var e,n,i,a,o=(t||[]).map(function(t){return{model:t._model,deltaK:0,mK:0}}),s=o.length;for(e=0;s>e;++e)i=o[e],i.model.skip||(n=e>0?o[e-1]:null,a=s-1>e?o[e+1]:null,a&&!a.model.skip&&(i.deltaK=(a.model.y-i.model.y)/(a.model.x-i.model.x)),!n||n.model.skip?i.mK=i.deltaK:!a||a.model.skip?i.mK=n.deltaK:this.sign(n.deltaK)!==this.sign(i.deltaK)?i.mK=0:i.mK=(n.deltaK+i.deltaK)/2);var l,u,d,c;for(e=0;s-1>e;++e)i=o[e],a=o[e+1],i.model.skip||a.model.skip||(r.almostEquals(i.deltaK,0,this.EPSILON)?i.mK=a.mK=0:(l=i.mK/i.deltaK,u=a.mK/i.deltaK,c=Math.pow(l,2)+Math.pow(u,2),9>=c||(d=3/Math.sqrt(c),i.mK=l*d*i.deltaK,a.mK=u*d*i.deltaK)));var h;for(e=0;s>e;++e)i=o[e],i.model.skip||(n=e>0?o[e-1]:null,a=s-1>e?o[e+1]:null,n&&!n.model.skip&&(h=(i.model.x-n.model.x)/3,i.model.controlPointPreviousX=i.model.x-h,i.model.controlPointPreviousY=i.model.y-h*i.mK),a&&!a.model.skip&&(h=(a.model.x-i.model.x)/3,i.model.controlPointNextX=i.model.x+h,i.model.controlPointNextY=i.model.y+h*i.mK))},r.nextItem=function(t,e,n){return n?e>=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},r.previousItem=function(t,e,n){return n?0>=e?t[t.length-1]:t[e-1]:0>=e?t[0]:t[e-1]},r.niceNum=function(t,e){var n,i=Math.floor(r.log10(t)),a=t/Math.pow(10,i);return n=e?1.5>a?1:3>a?2:7>a?5:10:1>=a?1:2>=a?2:5>=a?5:10,n*Math.pow(10,i)};
23273var o=r.easingEffects={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-1*t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-0.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return 1*((t=t/1-1)*t*t+1)},easeInOutCubic:function(t){return(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return-1*((t=t/1-1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-0.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return 1*(t/=1)*t*t*t*t},easeOutQuint:function(t){return 1*((t=t/1-1)*t*t*t*t+1)},easeInOutQuint:function(t){return(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},easeInSine:function(t){return-1*Math.cos(t/1*(Math.PI/2))+1},easeOutSine:function(t){return 1*Math.sin(t/1*(Math.PI/2))},easeInOutSine:function(t){return-0.5*(Math.cos(Math.PI*t/1)-1)},easeInExpo:function(t){return 0===t?1:1*Math.pow(2,10*(t/1-1))},easeOutExpo:function(t){return 1===t?1:1*(-Math.pow(2,-10*t/1)+1)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(-Math.pow(2,-10*--t)+2)},easeInCirc:function(t){return t>=1?t:-1*(Math.sqrt(1-(t/=1)*t)-1)},easeOutCirc:function(t){return 1*Math.sqrt(1-(t=t/1-1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-0.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===(t/=1)?1:(n||(n=.3),i<Math.abs(1)?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),-(i*Math.pow(2,10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/n)))},easeOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===(t/=1)?1:(n||(n=.3),i<Math.abs(1)?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),i*Math.pow(2,-10*t)*Math.sin((1*t-e)*(2*Math.PI)/n)+1)},easeInOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:2===(t/=.5)?1:(n||(n=1*(.3*1.5)),i<Math.abs(1)?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),1>t?-.5*(i*Math.pow(2,10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/n)):i*Math.pow(2,-10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/n)*.5+1)},easeInBack:function(t){var e=1.70158;return 1*(t/=1)*t*((e+1)*t-e)},easeOutBack:function(t){var e=1.70158;return 1*((t=t/1-1)*t*((e+1)*t+e)+1)},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?.5*(t*t*(((e*=1.525)+1)*t-e)):.5*((t-=2)*t*(((e*=1.525)+1)*t+e)+2)},easeInBounce:function(t){return 1-o.easeOutBounce(1-t)},easeOutBounce:function(t){return(t/=1)<1/2.75?1*(7.5625*t*t):2/2.75>t?1*(7.5625*(t-=1.5/2.75)*t+.75):2.5/2.75>t?1*(7.5625*(t-=2.25/2.75)*t+.9375):1*(7.5625*(t-=2.625/2.75)*t+.984375)},easeInOutBounce:function(t){return.5>t?.5*o.easeInBounce(2*t):.5*o.easeOutBounce(2*t-1)+.5}};r.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){
23274        return window.setTimeout(t,1e3/60)}}(),r.cancelAnimFrame=function(){return window.cancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||window.oCancelAnimationFrame||window.msCancelAnimationFrame||function(t){return window.clearTimeout(t,1e3/60)}}(),r.getRelativePosition=function(t,e){var n,i,a=t.originalEvent||t,o=t.currentTarget||t.srcElement,s=o.getBoundingClientRect(),l=a.touches;l&&l.length>0?(n=l[0].clientX,i=l[0].clientY):(n=a.clientX,i=a.clientY);var u=parseFloat(r.getStyle(o,"padding-left")),d=parseFloat(r.getStyle(o,"padding-top")),c=parseFloat(r.getStyle(o,"padding-right")),h=parseFloat(r.getStyle(o,"padding-bottom")),f=s.right-s.left-u-c,g=s.bottom-s.top-d-h;return n=Math.round((n-s.left-u)/f*o.width/e.currentDevicePixelRatio),i=Math.round((i-s.top-d)/g*o.height/e.currentDevicePixelRatio),{x:n,y:i}},r.addEvent=function(t,e,n){t.addEventListener?t.addEventListener(e,n):t.attachEvent?t.attachEvent("on"+e,n):t["on"+e]=n},r.removeEvent=function(t,e,n){t.removeEventListener?t.removeEventListener(e,n,!1):t.detachEvent?t.detachEvent("on"+e,n):t["on"+e]=r.noop},r.bindEvents=function(t,e,n){var i=t.events=t.events||{};r.each(e,function(e){i[e]=function(){n.apply(t,arguments)},r.addEvent(t.chart.canvas,e,i[e])})},r.unbindEvents=function(t,e){var n=t.chart.canvas;r.each(e,function(t,e){r.removeEvent(n,e,t)})},r.getConstraintWidth=function(t){return a(t,"max-width","clientWidth")},r.getConstraintHeight=function(t){return a(t,"max-height","clientHeight")},r.getMaximumWidth=function(t){var e=t.parentNode,n=parseInt(r.getStyle(e,"padding-left"),10),i=parseInt(r.getStyle(e,"padding-right"),10),a=e.clientWidth-n-i,o=r.getConstraintWidth(t);return isNaN(o)?a:Math.min(a,o)},r.getMaximumHeight=function(t){var e=t.parentNode,n=parseInt(r.getStyle(e,"padding-top"),10),i=parseInt(r.getStyle(e,"padding-bottom"),10),a=e.clientHeight-n-i,o=r.getConstraintHeight(t);return isNaN(o)?a:Math.min(a,o)},r.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},r.retinaScale=function(t){var e=t.currentDevicePixelRatio=window.devicePixelRatio||1;if(1!==e){var n=t.canvas,i=t.height,a=t.width;n.height=i*e,n.width=a*e,t.ctx.scale(e,e),n.style.height=i+"px",n.style.width=a+"px"}},r.clear=function(t){t.ctx.clearRect(0,0,t.width,t.height)},r.fontString=function(t,e,n){return e+" "+t+"px "+n},r.longestText=function(t,e,n,i){i=i||{};var a=i.data=i.data||{},o=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(a=i.data={},o=i.garbageCollect=[],i.font=e),t.font=e;var s=0;r.each(n,function(e){void 0!==e&&null!==e&&r.isArray(e)!==!0?s=r.measureText(t,a,o,s,e):r.isArray(e)&&r.each(e,function(e){void 0===e||null===e||r.isArray(e)||(s=r.measureText(t,a,o,s,e))})});var l=o.length/2;if(l>n.length){for(var u=0;l>u;u++)delete a[o[u]];o.splice(0,l)}return s},r.measureText=function(t,e,n,i,a){var r=e[a];return r||(r=e[a]=t.measureText(a).width,n.push(a)),r>i&&(i=r),i},r.numberOfLabelLines=function(t){var e=1;return r.each(t,function(t){r.isArray(t)&&t.length>e&&(e=t.length)}),e},r.drawRoundedRectangle=function(t,e,n,i,a,r){t.beginPath(),t.moveTo(e+r,n),t.lineTo(e+i-r,n),t.quadraticCurveTo(e+i,n,e+i,n+r),t.lineTo(e+i,n+a-r),t.quadraticCurveTo(e+i,n+a,e+i-r,n+a),t.lineTo(e+r,n+a),t.quadraticCurveTo(e,n+a,e,n+a-r),t.lineTo(e,n+r),t.quadraticCurveTo(e,n,e+r,n),t.closePath()},r.color=function(e){return i?i(e instanceof CanvasGradient?t.defaults.global.defaultColor:e):(console.error("Color.js not found!"),e)},r.addResizeListener=function(t,e){var n=document.createElement("iframe");
23274n.className="chartjs-hidden-iframe",n.style.cssText="display:block;overflow:hidden;border:0;margin:0;top:0;left:0;bottom:0;right:0;height:100%;width:100%;position:absolute;pointer-events:none;z-index:-1;",n.tabIndex=-1;var i=t._chartjs={resizer:n,ticking:!1},a=function(){i.ticking||(i.ticking=!0,r.requestAnimFrame.call(window,function(){return i.resizer?(i.ticking=!1,e()):void 0}))};r.addEvent(n,"load",function(){r.addEvent(n.contentWindow||n,"resize",a),a()}),t.insertBefore(n,t.firstChild)},r.removeResizeListener=function(t){if(t&&t._chartjs){var e=t._chartjs.resizer;e&&(e.parentNode.removeChild(e),t._chartjs.resizer=null),delete t._chartjs}},r.isArray=Array.isArray?function(t){return Array.isArray(t)}:function(t){return"[object Array]"===Object.prototype.toString.call(t)},r.arrayEquals=function(t,e){var n,i,a,o;if(!t||!e||t.length!==e.length)return!1;for(n=0,i=t.length;i>n;++n)if(a=t[n],o=e[n],a instanceof Array&&o instanceof Array){if(!r.arrayEquals(a,o))return!1}else if(a!==o)return!1;return!0},r.callCallback=function(t,e,n){t&&"function"==typeof t.call&&t.apply(n,e)},r.getHoverColor=function(t){return t instanceof CanvasPattern?t:r.color(t).saturate(.5).darken(.1).rgbString()}}},{2:2}],27:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){var n,i,a,r,o,s=t.data.datasets;for(i=0,r=s.length;r>i;++i)if(t.isDatasetVisible(i))for(n=t.getDatasetMeta(i),a=0,o=n.data.length;o>a;++a){var l=n.data[a];l._view.skip||e(l)}}function n(t,n){var i=[];return e(t,function(t){t.inRange(n.x,n.y)&&i.push(t)}),i}function i(t,n,i,a){var o=Number.POSITIVE_INFINITY,s=[];return a||(a=r.distanceBetweenPoints),e(t,function(t){if(!i||t.inRange(n.x,n.y)){var e=t.getCenterPoint(),r=a(n,e);o>r?(s=[t],o=r):r===o&&s.push(t)}}),s}function a(t,e,a){var o=r.getRelativePosition(e,t.chart),s=function(t,e){return Math.abs(t.x-e.x)},l=a.intersect?n(t,o):i(t,o,!1,s),u=[];return l.length?(t.data.datasets.forEach(function(e,n){if(t.isDatasetVisible(n)){var i=t.getDatasetMeta(n),a=i.data[l[0]._index];a&&!a._view.skip&&u.push(a)}}),u):[]}var r=t.helpers;t.Interaction={modes:{single:function(t,n){var i=r.getRelativePosition(n,t.chart),a=[];return e(t,function(t){return t.inRange(i.x,i.y)?(a.push(t),a):void 0}),a.slice(0,1)},label:a,index:a,dataset:function(t,e,a){var o=r.getRelativePosition(e,t.chart),s=a.intersect?n(t,o):i(t,o,!1);return s.length>0&&(s=t.getDatasetMeta(s[0]._datasetIndex).data),s},"x-axis":function(t,e){return a(t,e,!0)},point:function(t,e){var i=r.getRelativePosition(e,t.chart);return n(t,i)},nearest:function(t,e,n){var a=r.getRelativePosition(e,t.chart),o=i(t,a,n.intersect);return o.length>1&&o.sort(function(t,e){var n=t.getArea(),i=e.getArea(),a=n-i;return 0===a&&(a=t._datasetIndex-e._datasetIndex),a}),o.slice(0,1)},x:function(t,n,i){var a=r.getRelativePosition(n,t.chart),o=[],s=!1;return e(t,function(t){t.inXRange(a.x)&&o.push(t),t.inRange(a.x,a.y)&&(s=!0)}),i.intersect&&!s&&(o=[]),o},y:function(t,n,i){var a=r.getRelativePosition(n,t.chart),o=[],s=!1;return e(t,function(t){t.inYRange(a.y)&&o.push(t),t.inRange(a.x,a.y)&&(s=!0)}),i.intersect&&!s&&(o=[]),o}}}}},{}],28:[function(t,e,n){"use strict";e.exports=function(){var t=function(e,n){return this.controller=new t.Controller(e,n,this),this.controller};return t.defaults={global:{responsive:!0,responsiveAnimationDuration:0,maintainAspectRatio:!0,events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,defaultColor:"rgba(0,0,0,0.1)",defaultFontColor:"#666",defaultFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",defaultFontSize:12,defaultFontStyle:"normal",showLines:!0,elements:{},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');for(var n=0;n<t.data.datasets.length;n++)e.push('<li><span style="background-color:'+t.data.datasets[n].backgroundColor+'"></span>'),t.data.datasets[n].label&&e.push(t.data.datasets[n].label),e.push("</li>");return e.push("</ul>"),e.join("")}}},t.Chart=t,t}},{}],29:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.layoutService={defaults:{}
23274,addBox:function(t,e){t.boxes||(t.boxes=[]),t.boxes.push(e)},removeBox:function(t,e){t.boxes&&t.boxes.splice(t.boxes.indexOf(e),1)},update:function(t,n,i){function a(t){var e,n=t.isHorizontal();n?(e=t.update(t.options.fullWidth?y:M,S),D-=e.height):(e=t.update(w,_),M-=e.width),C.push({horizontal:n,minSize:e,box:t})}function r(t){var n=e.findNextWhere(C,function(e){return e.box===t});if(n)if(t.isHorizontal()){var i={left:T,right:P,top:0,bottom:0};t.update(t.options.fullWidth?y:M,x/2,i)}else t.update(n.minSize.width,D)}function o(t){var n=e.findNextWhere(C,function(e){return e.box===t}),i={left:0,right:0,top:I,bottom:F};n&&t.update(n.minSize.width,D,i)}function s(t){t.isHorizontal()?(t.left=t.options.fullWidth?d:T,t.right=t.options.fullWidth?n-c:T+M,t.top=L,t.bottom=L+t.height,L=t.bottom):(t.left=R,t.right=R+t.width,t.top=I,t.bottom=I+D,R=t.right)}if(t){var l=t.options.layout,u=l?l.padding:null,d=0,c=0,h=0,f=0;isNaN(u)?(d=u.left||0,c=u.right||0,h=u.top||0,f=u.bottom||0):(d=u,c=u,h=u,f=u);var g=e.where(t.boxes,function(t){return"left"===t.options.position}),m=e.where(t.boxes,function(t){return"right"===t.options.position}),p=e.where(t.boxes,function(t){return"top"===t.options.position}),v=e.where(t.boxes,function(t){return"bottom"===t.options.position}),b=e.where(t.boxes,function(t){return"chartArea"===t.options.position});p.sort(function(t,e){return(e.options.fullWidth?1:0)-(t.options.fullWidth?1:0)}),v.sort(function(t,e){return(t.options.fullWidth?1:0)-(e.options.fullWidth?1:0)});var y=n-d-c,x=i-h-f,k=y/2,_=x/2,w=(n-k)/(g.length+m.length),S=(i-_)/(p.length+v.length),M=y,D=x,C=[];e.each(g.concat(m,p,v),a);var T=d,P=c,I=h,F=f;e.each(g.concat(m),r),e.each(g,function(t){T+=t.width}),e.each(m,function(t){P+=t.width}),e.each(p.concat(v),r),e.each(p,function(t){I+=t.height}),e.each(v,function(t){F+=t.height}),e.each(g.concat(m),o),T=d,P=c,I=h,F=f,e.each(g,function(t){T+=t.width}),e.each(m,function(t){P+=t.width}),e.each(p,function(t){I+=t.height}),e.each(v,function(t){F+=t.height});var A=i-I-F,O=n-T-P;(O!==M||A!==D)&&(e.each(g,function(t){t.height=A}),e.each(m,function(t){t.height=A}),e.each(p,function(t){t.options.fullWidth||(t.width=O)}),e.each(v,function(t){t.options.fullWidth||(t.width=O)}),D=A,M=O);var R=d,L=h;e.each(g.concat(p),s),R+=M,L+=D,e.each(m,s),e.each(v,s),t.chartArea={left:T,top:I,right:T+M,bottom:I+D},e.each(b,function(e){e.left=t.chartArea.left,e.top=t.chartArea.top,e.right=t.chartArea.right,e.bottom=t.chartArea.bottom,e.update(M,D)})}}}}},{}],30:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){return t.usePointStyle?e*Math.SQRT2:t.boxWidth}var n=t.helpers,i=n.noop;t.defaults.global.legend={display:!0,position:"top",fullWidth:!0,reverse:!1,onClick:function(t,e){var n=e.datasetIndex,i=this.chart,a=i.getDatasetMeta(n);a.hidden=null===a.hidden?!i.data.datasets[n].hidden:null,i.update()},onHover:null,labels:{boxWidth:40,padding:10,generateLabels:function(t){var e=t.data;return n.isArray(e.datasets)?e.datasets.map(function(e,i){return{text:e.label,fillStyle:n.isArray(e.backgroundColor)?e.backgroundColor[0]:e.backgroundColor,hidden:!t.isDatasetVisible(i),lineCap:e.borderCapStyle,lineDash:e.borderDash,lineDashOffset:e.borderDashOffset,lineJoin:e.borderJoinStyle,lineWidth:e.borderWidth,strokeStyle:e.borderColor,pointStyle:e.pointStyle,datasetIndex:i}},this):[]}}},t.Legend=t.Element.extend({initialize:function(t){n.extend(this,t),this.legendHitBoxes=[],this.doughnutMode=!1},beforeUpdate:i,update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:i,beforeSetDimensions:i,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:i,beforeBuildLabels:i,buildLabels:function(){var t=this;t.legendItems=t.options.labels.generateLabels.call(t,t.chart),t.options.reverse&&t.legendItems.reverse()},afterBuildLabels:i,beforeFit:i,fit:function(){var i=this,a=i.options,r=a.labels,o=a.display,s=i.ctx,l=t.defaults.global,u=n.getValueOrDefault,d=u(r.fontSize,l.defaultFontSize),c=u(r.fontStyle,l.defaultFontStyle),h=u(r.fontFamily,l.defaultFontFamily),f=n.fontString(d,c,h),g=i.legendHitBoxes=[],m=i.minSize,p=i.isHorizontal();if(p?(m.width=i.maxWidth,m.height=o?10:0):(m.width=o?10:0,m.height=i.maxHeight),o)if(s.font=f,p){var v=i.lineWidths=[0],b=i.legendItems.length?d+r.padding:0;s.textAlign="left",s.textBaseline="top",n.each(i.legendItems,function(t,n){var a=e(r,d),o=a+d/2+s.measureText(t.text).width;v[v.length-1]+o+r.padding>=i.width&&(b+=d+r.padding,v[v.length]=i.left),g[n]={left:0,top:0,width:o,height:d},v[v.length-1]+=o+r.padding}),m.height+=b}else{var y=r.padding,x=i.columnWidths=[],k=r.padding,_=0,w=0,S=d+y;n.each(i.legendItems,function(t,n){var i=e(r,d),a=i+d/2+s.measureText(t.text).width;w+S>m.height&&(k+=_+r.padding,x.push(_),_=0,w=0),_=Math.max(_,a),w+=S,g[n]={left:0,top:0,width:a,height:d}}
23274),k+=_,x.push(_),m.width+=k}i.width=m.width,i.height=m.height},afterFit:i,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var i=this,a=i.options,r=a.labels,o=t.defaults.global,s=o.elements.line,l=i.width,u=i.lineWidths;if(a.display){var d,c=i.ctx,h=n.getValueOrDefault,f=h(r.fontColor,o.defaultFontColor),g=h(r.fontSize,o.defaultFontSize),m=h(r.fontStyle,o.defaultFontStyle),p=h(r.fontFamily,o.defaultFontFamily),v=n.fontString(g,m,p);c.textAlign="left",c.textBaseline="top",c.lineWidth=.5,c.strokeStyle=f,c.fillStyle=f,c.font=v;var b=e(r,g),y=i.legendHitBoxes,x=function(e,n,i){if(!(isNaN(b)||0>=b)){c.save(),c.fillStyle=h(i.fillStyle,o.defaultColor),c.lineCap=h(i.lineCap,s.borderCapStyle),c.lineDashOffset=h(i.lineDashOffset,s.borderDashOffset),c.lineJoin=h(i.lineJoin,s.borderJoinStyle),c.lineWidth=h(i.lineWidth,s.borderWidth),c.strokeStyle=h(i.strokeStyle,o.defaultColor);var r=0===h(i.lineWidth,s.borderWidth);if(c.setLineDash&&c.setLineDash(h(i.lineDash,s.borderDash)),a.labels&&a.labels.usePointStyle){var l=g*Math.SQRT2/2,u=l/Math.SQRT2,d=e+u,f=n+u;t.canvasHelpers.drawPoint(c,i.pointStyle,l,d,f)}else r||c.strokeRect(e,n,b,g),c.fillRect(e,n,b,g);c.restore()}},k=function(t,e,n,i){c.fillText(n.text,b+g/2+t,e),n.hidden&&(c.beginPath(),c.lineWidth=2,c.moveTo(b+g/2+t,e+g/2),c.lineTo(b+g/2+t+i,e+g/2),c.stroke())},_=i.isHorizontal();d=_?{x:i.left+(l-u[0])/2,y:i.top+r.padding,line:0}:{x:i.left+r.padding,y:i.top+r.padding,line:0};var w=g+r.padding;n.each(i.legendItems,function(t,e){var n=c.measureText(t.text).width,a=b+g/2+n,o=d.x,s=d.y;_?o+a>=l&&(s=d.y+=w,d.line++,o=d.x=i.left+(l-u[d.line])/2):s+w>i.bottom&&(o=d.x=o+i.columnWidths[d.line]+r.padding,s=d.y=i.top,d.line++),x(o,s,t),y[e].left=o,y[e].top=s,k(o,s,t,n),_?d.x+=a+r.padding:d.y+=w})}},handleEvent:function(t){var e=this,i=e.options,a="mouseup"===t.type?"click":t.type,r=!1;if("mousemove"===a){if(!i.onHover)return}else{if("click"!==a)return;if(!i.onClick)return}var o=n.getRelativePosition(t,e.chart.chart),s=o.x,l=o.y;if(s>=e.left&&s<=e.right&&l>=e.top&&l<=e.bottom)for(var u=e.legendHitBoxes,d=0;d<u.length;++d){var c=u[d];if(s>=c.left&&s<=c.left+c.width&&l>=c.top&&l<=c.top+c.height){if("click"===a){i.onClick.call(e,t,e.legendItems[d]),r=!0;break}if("mousemove"===a){i.onHover.call(e,t,e.legendItems[d]),r=!0;break}}}return r}}),t.plugins.register({beforeInit:function(e){var n=e.options,i=n.legend;i&&(e.legend=new t.Legend({ctx:e.chart.ctx,options:i,chart:e}),t.layoutService.addBox(e,e.legend))}})}},{}],31:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers.noop;t.plugins={_plugins:[],register:function(t){var e=this._plugins;[].concat(t).forEach(function(t){-1===e.indexOf(t)&&e.push(t)})},unregister:function(t){var e=this._plugins;[].concat(t).forEach(function(t){var n=e.indexOf(t);-1!==n&&e.splice(n,1)})},clear:function(){this._plugins=[]},count:function(){return this._plugins.length},getAll:function(){return this._plugins},notify:function(t,e){var n,i,a=this._plugins,r=a.length;for(n=0;r>n;++n)if(i=a[n],"function"==typeof i[t]&&i[t].apply(i,e||[])===!1)return!1;return!0}},t.PluginBase=t.Element.extend({beforeInit:e,afterInit:e,beforeUpdate:e,afterUpdate:e,beforeDraw:e,afterDraw:e,destroy:e}),t.pluginService=t.plugins}},{}],32:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.scale={display:!0,position:"left",gridLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1,drawBorder:!0,drawOnChartArea:!0,drawTicks:!0,tickMarkLength:10,zeroLineWidth:1,zeroLineColor:"rgba(0,0,0,0.25)",offsetGridLines:!1,borderDash:[],borderDashOffset:0},scaleLabel:{labelString:"",display:!1},ticks:{beginAtZero:!1,minRotation:0,maxRotation:50,mirror:!1,padding:10,reverse:!1,display:!0,autoSkip:!0,autoSkipPadding:0,labelOffset:0,callback:t.Ticks.formatters.values}},t.Scale=t.Element.extend({beforeUpdate:function(){e.callCallback(this.options.beforeUpdate,[this])},update:function(t,n,i){var a=this;return a.beforeUpdate(),a.maxWidth=t,a.maxHeight=n,a.margins=e.extend({left:0,right:0,top:0,bottom:0},i),a.beforeSetDimensions(),a.setDimensions(),a.afterSetDimensions(),a.beforeDataLimits(),a.determineDataLimits(),a.afterDataLimits(),a.beforeBuildTicks(),a.buildTicks(),a.afterBuildTicks(),a.beforeTickToLabelConversion(),a.convertTicksToLabels(),a.afterTickToLabelConversion(),a.beforeCalculateTickRotation(),a.calculateTickRotation(),a.afterCalculateTickRotation(),a.beforeFit(),a.fit(),a.afterFit(),a.afterUpdate(),a.minSize},afterUpdate:function(){e.callCallback(this.options.afterUpdate,[this])},beforeSetDimensions:function(){e.callCallback(this.options.beforeSetDimensions,[this])},setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0},afterSetDimensions:function(){e.callCallback(this.options.afterSetDimensions,[this])},beforeDataLimits:function(){e.callCallback(this.options.beforeDataLimits,[this])},determineDataLimits:e.noop,afterDataLimits:function(){e.callCallback(this.options.afterDataLimits,[this])},beforeBuildTicks:function(){e.callCallback(this.options.beforeBuildTicks,[this])},buildTicks:e.noop,afterBuildTicks:function(){e.callCallback(this.options.afterBuildTicks,[this])},beforeTickToLabelConversion:function(){e.callCallback(this.options.beforeTickToLabelConversion,[this])},convertTicksToLabels:function(){var t=this,e=t.options.ticks;t.ticks=t.ticks.map(e.userCallback||e.callback)},afterTickToLabelConversion:function(){e.callCallback(this.options.afterTickToLabelConversion,[this])},beforeCalculateTickRotation:function(){e.callCallback(this.options.beforeCalculateTickRotation,[this])},calculateTickRotation:function(){var n=this,i=n.ctx,a=t.defaults.global,r=n.options.ticks,o=e.getValueOrDefault(r.fontSize,a.defaultFontSize),s=e.getValueOrDefault(r.fontStyle,a.defaultFontStyle),l=e.getValueOrDefault(r.fontFamily,a.defaultFontFamily),u=e.fontString(o,s,l);i.font=u;var d,c=i.measureText(n.ticks[0]).width,h=i.measureText(n.ticks[n.ticks.length-1]).width;if(n.labelRotation=r.minRotation||0,n.paddingRight=0,n.paddingLeft=0,n.options.display&&n.isHorizontal()){n.paddingRight=h/2+3,n.paddingLeft=c/2+3,n.longestTextCache||(n.longestTextCache={});for(var f,g,m=e.longestText(i,u,n.ticks,n.longestTextCache),p=m,v=n.getPixelForTick(1)-n.getPixelForTick(0)-6;p>v&&n.labelRotation<r.maxRotation;){if(f=Math.cos(e.toRadians(n.labelRotation)),g=Math.sin(e.toRadians(n.labelRotation)),d=f*c,d+o/2>n.yLabelWidth&&(n.paddingLeft=d+o/2),n.paddingRight=o/2,g*m>n.maxHeight){n.labelRotation--;break}n.labelRotation++,p=f*m}}n.margins&&(n.paddingLeft=Math.max(n.paddingLeft-n.margins.left,0),n.paddingRight=Math.max(n.paddingRight-n.margins.right,0))},afterCalculateTickRotation:function(){e.callCallback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){e.callCallback(this.options.beforeFit,[this])},fit:function(){var n=this,i=n.minSize={width:0,height:0},a=n.options,r=t.defaults.global,o=a.ticks,s=a.scaleLabel,l=a.gridLines,u=a.display,d=n.isHorizontal(),c=e.getValueOrDefault(o.fontSize,r.defaultFontSize),h=e.getValueOrDefault(o.fontStyle,r.defaultFontStyle),f=e.getValueOrDefault(o.fontFamily,r.defaultFontFamily),g=e.fontString(c,h,f),m=e.getValueOrDefault(s.fontSize,r.defaultFontSize),p=a.gridLines.tickMarkLength;if(d?i.width=n.isFullWidth()?n.maxWidth-n.margins.left-n.margins.right:n.maxWidth:i.width=u&&l.drawTicks?p:0,d?i.height=u&&l.drawTicks?p:0:i.height=n.maxHeight,s.display&&u&&(d?i.height+=1.5*m:i.width+=1.5*m),o.display&&u){n.longestTextCache||(n.longestTextCache={});var v=e.longestText(n.ctx,g,n.ticks,n.longestTextCache),b=e.numberOfLabelLines(n.ticks),y=.5*c;if(d){n.longestLabelWidth=v;var x=Math.sin(e.toRadians(n.labelRotation))*n.longestLabelWidth+c*b+y*b;
23274i.height=Math.min(n.maxHeight,i.height+x),n.ctx.font=g;var k=n.ctx.measureText(n.ticks[0]).width,_=n.ctx.measureText(n.ticks[n.ticks.length-1]).width,w=Math.cos(e.toRadians(n.labelRotation)),S=Math.sin(e.toRadians(n.labelRotation));n.paddingLeft=0!==n.labelRotation?w*k+3:k/2+3,n.paddingRight=0!==n.labelRotation?S*(c/2)+3:_/2+3}else{var M=n.maxWidth-i.width,D=o.mirror;D?v=0:v+=n.options.ticks.padding,M>v?i.width+=v:i.width=n.maxWidth,n.paddingTop=c/2,n.paddingBottom=c/2}}n.margins&&(n.paddingLeft=Math.max(n.paddingLeft-n.margins.left,0),n.paddingTop=Math.max(n.paddingTop-n.margins.top,0),n.paddingRight=Math.max(n.paddingRight-n.margins.right,0),n.paddingBottom=Math.max(n.paddingBottom-n.margins.bottom,0)),n.width=i.width,n.height=i.height},afterFit:function(){e.callCallback(this.options.afterFit,[this])},isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){return null===t||"undefined"==typeof t?NaN:"number"!=typeof t||isFinite(t)?"object"==typeof t?t instanceof Date||t.isValid?t:this.getRightValue(this.isHorizontal()?t.x:t.y):t:NaN},getLabelForIndex:e.noop,getPixelForValue:e.noop,getValueForPixel:e.noop,getPixelForTick:function(t,e){var n=this;if(n.isHorizontal()){var i=n.width-(n.paddingLeft+n.paddingRight),a=i/Math.max(n.ticks.length-(n.options.gridLines.offsetGridLines?0:1),1),r=a*t+n.paddingLeft;e&&(r+=a/2);var o=n.left+Math.round(r);return o+=n.isFullWidth()?n.margins.left:0}var s=n.height-(n.paddingTop+n.paddingBottom);return n.top+t*(s/(n.ticks.length-1))},getPixelForDecimal:function(t){var e=this;if(e.isHorizontal()){var n=e.width-(e.paddingLeft+e.paddingRight),i=n*t+e.paddingLeft,a=e.left+Math.round(i);return a+=e.isFullWidth()?e.margins.left:0}return e.top+t*e.height},getBasePixel:function(){var t=this,e=t.min,n=t.max;return t.getPixelForValue(t.beginAtZero?0:0>e&&0>n?n:e>0&&n>0?e:0)},draw:function(n){var i=this,a=i.options;if(a.display){var r,o,s=i.ctx,l=t.defaults.global,u=a.ticks,d=a.gridLines,c=a.scaleLabel,h=0!==i.labelRotation,f=u.autoSkip,g=i.isHorizontal();u.maxTicksLimit&&(o=u.maxTicksLimit);var m=e.getValueOrDefault(u.fontColor,l.defaultFontColor),p=e.getValueOrDefault(u.fontSize,l.defaultFontSize),v=e.getValueOrDefault(u.fontStyle,l.defaultFontStyle),b=e.getValueOrDefault(u.fontFamily,l.defaultFontFamily),y=e.fontString(p,v,b),x=d.tickMarkLength,k=e.getValueOrDefault(d.borderDash,l.borderDash),_=e.getValueOrDefault(d.borderDashOffset,l.borderDashOffset),w=e.getValueOrDefault(c.fontColor,l.defaultFontColor),S=e.getValueOrDefault(c.fontSize,l.defaultFontSize),M=e.getValueOrDefault(c.fontStyle,l.defaultFontStyle),D=e.getValueOrDefault(c.fontFamily,l.defaultFontFamily),C=e.fontString(S,M,D),T=e.toRadians(i.labelRotation),P=Math.cos(T),I=i.longestLabelWidth*P;s.fillStyle=m;var F=[];if(g){if(r=!1,h&&(I/=2),(I+u.autoSkipPadding)*i.ticks.length>i.width-(i.paddingLeft+i.paddingRight)&&(r=1+Math.floor((I+u.autoSkipPadding)*i.ticks.length/(i.width-(i.paddingLeft+i.paddingRight)))),o&&i.ticks.length>o)for(;!r||i.ticks.length/(r||1)>o;)r||(r=1),r+=1;f||(r=!1)}var A="right"===a.position?i.left:i.right-x,O="right"===a.position?i.left+x:i.right,R="bottom"===a.position?i.top:i.bottom-x,L="bottom"===a.position?i.top+x:i.bottom;if(e.each(i.ticks,function(t,o){if(void 0!==t&&null!==t){var s=i.ticks.length===o+1,l=r>1&&o%r>0||o%r===0&&o+r>=i.ticks.length;if((!l||s)&&void 0!==t&&null!==t){var c,f;o===("undefined"!=typeof i.zeroLineIndex?i.zeroLineIndex:0)?(c=d.zeroLineWidth,f=d.zeroLineColor):(c=e.getValueAtIndexOrDefault(d.lineWidth,o),f=e.getValueAtIndexOrDefault(d.color,o));var m,p,v,b,y,w,S,M,D,C,P="middle",I="middle";if(g){h||(I="top"===a.position?"bottom":"top"),P=h?"right":"center";var W=i.getPixelForTick(o)+e.aliasPixel(c);D=i.getPixelForTick(o,d.offsetGridLines)+u.labelOffset,C=h?i.top+12:"top"===a.position?i.bottom-x:i.top+x,m=v=y=S=W,p=R,b=L,w=n.top,M=n.bottom}else{"left"===a.position?u.mirror?(D=i.right+u.padding,P="left"):(D=i.right-u.padding,P="right"):u.mirror?(D=i.left-u.padding,P="right"):(D=i.left+u.padding,P="left");var V=i.getPixelForTick(o);V+=e.aliasPixel(c),C=i.getPixelForTick(o,d.offsetGridLines),m=A,v=O,y=n.left,S=n.right,p=b=w=M=V}F.push({tx1:m,ty1:p,tx2:v,ty2:b,x1:y,y1:w,x2:S,y2:M,labelX:D,labelY:C,glWidth:c,glColor:f,glBorderDash:k,glBorderDashOffset:_,rotation:-1*T,label:t,textBaseline:I,textAlign:P})}}}),e.each(F,function(t){if(d.display&&(s.save(),s.lineWidth=t.glWidth,s.strokeStyle=t.glColor,s.setLineDash&&(s.setLineDash(t.glBorderDash),s.lineDashOffset=t.glBorderDashOffset),s.beginPath(),d.drawTicks&&(s.moveTo(t.tx1,t.ty1),s.lineTo(t.tx2,t.ty2)),d.drawOnChartArea&&(s.moveTo(t.x1,t.y1),s.lineTo(t.x2,t.y2)),s.stroke(),s.restore(
23274)),u.display){s.save(),s.translate(t.labelX,t.labelY),s.rotate(t.rotation),s.font=y,s.textBaseline=t.textBaseline,s.textAlign=t.textAlign;var n=t.label;if(e.isArray(n))for(var i=0,a=-(n.length-1)*p*.75;i<n.length;++i)s.fillText(""+n[i],0,a),a+=1.5*p;else s.fillText(n,0,0);s.restore()}}),c.display){var W,V,Y=0;if(g)W=i.left+(i.right-i.left)/2,V="bottom"===a.position?i.bottom-S/2:i.top+S/2;else{var B="left"===a.position;W=B?i.left+S/2:i.right-S/2,V=i.top+(i.bottom-i.top)/2,Y=B?-.5*Math.PI:.5*Math.PI}s.save(),s.translate(W,V),s.rotate(Y),s.textAlign="center",s.textBaseline="middle",s.fillStyle=w,s.font=C,s.fillText(c.labelString,0,0),s.restore()}if(d.drawBorder){s.lineWidth=e.getValueAtIndexOrDefault(d.lineWidth,0),s.strokeStyle=e.getValueAtIndexOrDefault(d.color,0);var z=i.left,N=i.right,H=i.top,E=i.bottom,U=e.aliasPixel(s.lineWidth);g?(H=E="top"===a.position?i.bottom:i.top,H+=U,E+=U):(z=N="left"===a.position?i.right:i.left,z+=U,N+=U),s.beginPath(),s.moveTo(z,H),s.lineTo(N,E),s.stroke()}}}})}},{}],33:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.scaleService={constructors:{},defaults:{},registerScaleType:function(t,n,i){this.constructors[t]=n,this.defaults[t]=e.clone(i)},getScaleConstructor:function(t){return this.constructors.hasOwnProperty(t)?this.constructors[t]:void 0},getScaleDefaults:function(n){return this.defaults.hasOwnProperty(n)?e.scaleMerge(t.defaults.scale,this.defaults[n]):{}},updateScaleDefaults:function(t,n){var i=this.defaults;i.hasOwnProperty(t)&&(i[t]=e.extend(i[t],n))},addScalesToLayout:function(n){e.each(n.scales,function(e){t.layoutService.addBox(n,e)})}}}},{}],34:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.Ticks={generators:{linear:function(t,n){var i,a=[];if(t.stepSize&&t.stepSize>0)i=t.stepSize;else{var r=e.niceNum(n.max-n.min,!1);i=e.niceNum(r/(t.maxTicks-1),!0)}var o=Math.floor(n.min/i)*i,s=Math.ceil(n.max/i)*i;if(t.min&&t.max&&t.stepSize){var l=(t.max-t.min)%t.stepSize===0;l&&(o=t.min,s=t.max)}var u=(s-o)/i;u=e.almostEquals(u,Math.round(u),i/1e3)?Math.round(u):Math.ceil(u),a.push(void 0!==t.min?t.min:o);for(var d=1;u>d;++d)a.push(o+d*i);return a.push(void 0!==t.max?t.max:s),a},logarithmic:function(t,n){for(var i=[],a=e.getValueOrDefault,r=a(t.min,Math.pow(10,Math.floor(e.log10(n.min))));r<n.max;){i.push(r);var o,s;0===r?(o=Math.floor(e.log10(n.minNotZero)),s=Math.round(n.minNotZero/Math.pow(10,o))):(o=Math.floor(e.log10(r)),s=Math.floor(r/Math.pow(10,o))+1),10===s&&(s=1,++o),r=s*Math.pow(10,o)}var l=a(t.max,r);return i.push(l),i}},formatters:{values:function(t){return e.isArray(t)?t:""+t},linear:function(t,n,i){var a=i.length>3?i[2]-i[1]:i[1]-i[0];Math.abs(a)>1&&t!==Math.floor(t)&&(a=t-Math.floor(t));var r=e.log10(Math.abs(a)),o="";if(0!==t){var s=-1*Math.floor(r);s=Math.max(Math.min(s,20),0),o=t.toFixed(s)}else o="0";return o},logarithmic:function(t,n,i){var a=t/Math.pow(10,Math.floor(e.log10(t)));return 0===t?"0":1===a||2===a||5===a||0===n||n===i.length-1?t.toExponential():""}}}}},{}],35:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.title={display:!1,position:"top",fullWidth:!0,fontStyle:"bold",padding:10,text:""};var n=e.noop;t.Title=t.Element.extend({initialize:function(n){var i=this;e.extend(i,n),i.options=e.configMerge(t.defaults.global.title,n.options),i.legendHitBoxes=[]},beforeUpdate:function(){var n=this.chart.options;n&&n.title&&(this.options=e.configMerge(t.defaults.global.title,n.title))},update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:n,beforeSetDimensions:n,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:n,beforeBuildLabels:n,buildLabels:n,afterBuildLabels:n,beforeFit:n,fit:function(){var n=this,i=e.getValueOrDefault,a=n.options,r=t.defaults.global,o=a.display,s=i(a.fontSize,r.defaultFontSize),l=n.minSize;n.isHorizontal()?(l.width=n.maxWidth,l.height=o?s+2*a.padding:0):(l.width=o?s+2*a.padding:0,l.height=n.maxHeight),n.width=l.width,n.height=l.height},afterFit:n,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var n=this,i=n.ctx,a=e.getValueOrDefault,r=n.options,o=t.defaults.global;if(r.display){var s,l,u,d=a(r.fontSize,o.defaultFontSize),c=a(r.fontStyle,o.defaultFontStyle),h=a(r.fontFamily,o.defaultFontFamily),f=e.fontString(d,c,h),g=0,m=n.top,p=n.left,v=n.bottom,b=n.right;i.fillStyle=a(r.fontColor,o.defaultFontColor),i.font=f,n.isHorizontal()?(s=p+(b-p)/2,l=m+(v-m)/2,u=b-p):(s="left"===r.position?p+d/2:b-d/2,l=m+(v-m)/2,u=v-m,g=Math.PI*("left"===r.position?-.5:.5)),i.save(),i.translate(s,l),i.rotate(g),i.textAlign="center",i.textBaseline="middle",i.fillText(r.text,0,0,u),i.restore(
23274)}}}),t.plugins.register({beforeInit:function(e){var n=e.options,i=n.title;i&&(e.titleBlock=new t.Title({ctx:e.chart.ctx,options:i,chart:e}),t.layoutService.addBox(e,e.titleBlock))}})}},{}],36:[function(t,e,n){"use strict";e.exports=function(t){function e(t,e){var n=l.color(t);return n.alpha(e*n.alpha()).rgbaString()}function n(t,e){return e&&(l.isArray(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function i(t){var e=t._xScale,n=t._yScale||t._scale,i=t._index,a=t._datasetIndex;return{xLabel:e?e.getLabelForIndex(i,a):"",yLabel:n?n.getLabelForIndex(i,a):"",index:i,datasetIndex:a,x:t._model.x,y:t._model.y}}function a(e){var n=t.defaults.global,i=l.getValueOrDefault;return{xPadding:e.xPadding,yPadding:e.yPadding,xAlign:e.xAlign,yAlign:e.yAlign,bodyFontColor:e.bodyFontColor,_bodyFontFamily:i(e.bodyFontFamily,n.defaultFontFamily),_bodyFontStyle:i(e.bodyFontStyle,n.defaultFontStyle),_bodyAlign:e.bodyAlign,bodyFontSize:i(e.bodyFontSize,n.defaultFontSize),bodySpacing:e.bodySpacing,titleFontColor:e.titleFontColor,_titleFontFamily:i(e.titleFontFamily,n.defaultFontFamily),_titleFontStyle:i(e.titleFontStyle,n.defaultFontStyle),titleFontSize:i(e.titleFontSize,n.defaultFontSize),_titleAlign:e.titleAlign,titleSpacing:e.titleSpacing,titleMarginBottom:e.titleMarginBottom,footerFontColor:e.footerFontColor,
23275    _footerFontFamily:i(e.footerFontFamily,n.defaultFontFamily),_footerFontStyle:i(e.footerFontStyle,n.defaultFontStyle),footerFontSize:i(e.footerFontSize,n.defaultFontSize),_footerAlign:e.footerAlign,footerSpacing:e.footerSpacing,footerMarginTop:e.footerMarginTop,caretSize:e.caretSize,cornerRadius:e.cornerRadius,backgroundColor:e.backgroundColor,opacity:0,legendColorBackground:e.multiKeyBackground,displayColors:e.displayColors}}function r(t,e){var n=t._chart.ctx,i=2*e.yPadding,a=0,r=e.body,o=r.reduce(function(t,e){return t+e.before.length+e.lines.length+e.after.length},0);o+=e.beforeBody.length+e.afterBody.length;var s=e.title.length,u=e.footer.length,d=e.titleFontSize,c=e.bodyFontSize,h=e.footerFontSize;i+=s*d,i+=s?(s-1)*e.titleSpacing:0,i+=s?e.titleMarginBottom:0,i+=o*c,i+=o?(o-1)*e.bodySpacing:0,i+=u?e.footerMarginTop:0,i+=u*h,i+=u?(u-1)*e.footerSpacing:0;var f=0,g=function(t){a=Math.max(a,n.measureText(t).width+f)};return n.font=l.fontString(d,e._titleFontStyle,e._titleFontFamily),l.each(e.title,g),n.font=l.fontString(c,e._bodyFontStyle,e._bodyFontFamily),l.each(e.beforeBody.concat(e.afterBody),g),f=e.displayColors?c+2:0,l.each(r,function(t){l.each(t.before,g),l.each(t.lines,g),l.each(t.after,g)}),f=0,n.font=l.fontString(h,e._footerFontStyle,e._footerFontFamily),l.each(e.footer,g),a+=2*e.xPadding,{width:a,height:i}}function o(t,e){var n=t._model,i=t._chart,a=t._chartInstance.chartArea,r="center",o="center";n.y<e.height?o="top":n.y>i.height-e.height&&(o="bottom");var s,l,u,d,c,h=(a.left+a.right)/2,f=(a.top+a.bottom)/2;"center"===o?(s=function(t){return h>=t},l=function(t){return t>h}):(s=function(t){return t<=e.width/2},l=function(t){return t>=i.width-e.width/2}),u=function(t){return t+e.width>i.width},d=function(t){return t-e.width<0},c=function(t){return f>=t?"top":"bottom"},s(n.x)?(r="left",u(n.x)&&(r="center",o=c(n.y))):l(n.x)&&(r="right",d(n.x)&&(r="center",o=c(n.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:r,yAlign:g.yAlign?g.yAlign:o}}function s(t,e,n){var i=t.x,a=t.y,r=t.caretSize,o=t.caretPadding,s=t.cornerRadius,l=n.xAlign,u=n.yAlign,d=r+o,c=s+o;return"right"===l?i-=e.width:"center"===l&&(i-=e.width/2),"top"===u?a+=d:a-="bottom"===u?e.height+d:e.height/2,"center"===u?"left"===l?i+=d:"right"===l&&(i-=d):"left"===l?i-=c:"right"===l&&(i+=c),{x:i,y:a}}var l=t.helpers;t.defaults.global.tooltips={enabled:!0,custom:null,mode:"nearest",position:"average",intersect:!0,backgroundColor:"rgba(0,0,0,0.8)",titleFontStyle:"bold",titleSpacing:2,titleMarginBottom:6,titleFontColor:"#fff",titleAlign:"left",bodySpacing:2,bodyFontColor:"#fff",bodyAlign:"left",footerFontStyle:"bold",footerSpacing:2,footerMarginTop:6,footerFontColor:"#fff",footerAlign:"left",yPadding:6,xPadding:6,caretSize:5,cornerRadius:6,multiKeyBackground:"#fff",displayColors:!0,callbacks:{beforeTitle:l.noop,title:function(t,e){var n="",i=e.labels,a=i?i.length:0;if(t.length>0){var r=t[0];r.xLabel?n=r.xLabel:a>0&&r.index<a&&(n=i[r.index])}return n},afterTitle:l.noop,beforeBody:l.noop,beforeLabel:l.noop,label:function(t,e){var n=e.datasets[t.datasetIndex].label||"";return n+": "+t.yLabel},labelColor:function(t,e){var n=e.getDatasetMeta(t.datasetIndex),i=n.data[t.index],a=i._view;return{borderColor:a.borderColor,backgroundColor:a.backgroundColor}},afterLabel:l.noop,afterBody:l.noop,beforeFooter:l.noop,footer:l.noop,afterFooter:l.noop}},t.Tooltip=t.Element.extend({initialize:function(){this._model=a(this._options)},getTitle:function(){var t=this,e=t._options,i=e.callbacks,a=i.beforeTitle.apply(t,arguments),r=i.title.apply(t,arguments),o=i.afterTitle.apply(t,arguments),s=[];return s=n(s,a),s=n(s,r),s=n(s,o)},getBeforeBody:function(){var t=this._options.callbacks.beforeBody.apply(this,arguments);return l.isArray(t)?t:void 0!==t?[t]:[]},getBody:function(t,e){var i=this,a=i._options.callbacks,r=[];return l.each(t,function(t){var o={before:[],lines:[],after:[]};n(o.before,a.beforeLabel.call(i,t,e)),n(o.lines,a.label.call(i,t,e)),n(o.after,a.afterLabel.call(i,t,e)),r.push(o)}),r},getAfterBody:function(){var t=this._options.callbacks.afterBody.apply(this,arguments);return l.isArray(t)?t:void 0!==t?[t]:[]},getFooter:function(){var t=this,e=t._options.callbacks,i=e.beforeFooter.apply(t,arguments),a=e.footer.apply(t,arguments),r=e.afterFooter.apply(t,arguments),o=[];return o=n(o,i),o=n(o,a),o=n(o,r)},update:function(e){var n,u,d=this,c=d._options,h=d._model,f=d._model=a(c),g=d._active,m=d._data,p=d._chartInstance,v={xAlign:h.xAlign,yAlign:h.yAlign},b={x:h.x,y:h.y},y={width:h.width,height:h.height},x={x:h.caretX,y:h.caretY};
23275if(g.length){f.opacity=1;var k=[];x=t.Tooltip.positioners[c.position](g,d._eventPosition);var _=[];for(n=0,u=g.length;u>n;++n)_.push(i(g[n]));c.filter&&(_=_.filter(function(t){return c.filter(t,m)})),c.itemSort&&(_=_.sort(function(t,e){return c.itemSort(t,e,m)})),l.each(_,function(t){k.push(c.callbacks.labelColor.call(d,t,p))}),f.title=d.getTitle(_,m),f.beforeBody=d.getBeforeBody(_,m),f.body=d.getBody(_,m),f.afterBody=d.getAfterBody(_,m),f.footer=d.getFooter(_,m),f.x=Math.round(x.x),f.y=Math.round(x.y),f.caretPadding=l.getValueOrDefault(x.padding,2),f.labelColors=k,f.dataPoints=_,y=r(this,f),v=o(this,y),b=s(f,y,v)}else f.opacity=0;return f.xAlign=v.xAlign,f.yAlign=v.yAlign,f.x=b.x,f.y=b.y,f.width=y.width,f.height=y.height,f.caretX=x.x,f.caretY=x.y,d._model=f,e&&c.custom&&c.custom.call(d,f),d},drawCaret:function(t,n,i){var a,r,o,s,l,u,d=this._view,c=this._chart.ctx,h=d.caretSize,f=d.cornerRadius,g=d.xAlign,m=d.yAlign,p=t.x,v=t.y,b=n.width,y=n.height;"center"===m?("left"===g?(a=p,r=a-h,o=a):(a=p+b,r=a+h,o=a),l=v+y/2,s=l-h,u=l+h):("left"===g?(a=p+f,r=a+h,o=r+h):"right"===g?(a=p+b-f,r=a-h,o=r-h):(r=p+b/2,a=r-h,o=r+h),"top"===m?(s=v,l=s-h,u=s):(s=v+y,l=s+h,u=s)),c.fillStyle=e(d.backgroundColor,i),c.beginPath(),c.moveTo(a,s),c.lineTo(r,l),c.lineTo(o,u),c.closePath(),c.fill()},drawTitle:function(t,n,i,a){var r=n.title;if(r.length){i.textAlign=n._titleAlign,i.textBaseline="top";var o=n.titleFontSize,s=n.titleSpacing;i.fillStyle=e(n.titleFontColor,a),i.font=l.fontString(o,n._titleFontStyle,n._titleFontFamily);var u,d;for(u=0,d=r.length;d>u;++u)i.fillText(r[u],t.x,t.y),t.y+=o+s,u+1===r.length&&(t.y+=n.titleMarginBottom-s)}},drawBody:function(t,n,i,a){var r=n.bodyFontSize,o=n.bodySpacing,s=n.body;i.textAlign=n._bodyAlign,i.textBaseline="top";var u=e(n.bodyFontColor,a);i.fillStyle=u,i.font=l.fontString(r,n._bodyFontStyle,n._bodyFontFamily);var d=0,c=function(e){i.fillText(e,t.x+d,t.y),t.y+=r+o};l.each(n.beforeBody,c);var h=n.displayColors;d=h?r+2:0,l.each(s,function(o,s){l.each(o.before,c),l.each(o.lines,function(o){h&&(i.fillStyle=e(n.legendColorBackground,a),i.fillRect(t.x,t.y,r,r),i.strokeStyle=e(n.labelColors[s].borderColor,a),i.strokeRect(t.x,t.y,r,r),i.fillStyle=e(n.labelColors[s].backgroundColor,a),i.fillRect(t.x+1,t.y+1,r-2,r-2),i.fillStyle=u),c(o)}),l.each(o.after,c)}),d=0,l.each(n.afterBody,c),t.y-=o},drawFooter:function(t,n,i,a){var r=n.footer;r.length&&(t.y+=n.footerMarginTop,i.textAlign=n._footerAlign,i.textBaseline="top",i.fillStyle=e(n.footerFontColor,a),i.font=l.fontString(n.footerFontSize,n._footerFontStyle,n._footerFontFamily),l.each(r,function(e){i.fillText(e,t.x,t.y),t.y+=n.footerFontSize+n.footerSpacing}))},drawBackground:function(t,n,i,a,r){i.fillStyle=e(n.backgroundColor,r),l.drawRoundedRectangle(i,t.x,t.y,a.width,a.height,n.cornerRadius),i.fill()},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var n={width:e.width,height:e.height},i={x:e.x,y:e.y},a=Math.abs(e.opacity<.001)?0:e.opacity;this._options.enabled&&(this.drawBackground(i,e,t,n,a),this.drawCaret(i,n,a),i.x+=e.xPadding,i.y+=e.yPadding,this.drawTitle(i,e,t,a),this.drawBody(i,e,t,a),this.drawFooter(i,e,t,a))}},handleEvent:function(t){var e=this,n=e._options,i=!1;if(e._lastActive=e._lastActive||[],"mouseout"===t.type?e._active=[]:e._active=e._chartInstance.getElementsAtEventForMode(t,n.mode,n),i=!l.arrayEquals(e._active,e._lastActive),e._lastActive=e._active,n.enabled||n.custom){e._eventPosition=l.getRelativePosition(t,e._chart);var a=e._model;e.update(!0),e.pivot(),i|=a.x!==e._model.x||a.y!==e._model.y}return i}}),t.Tooltip.positioners={average:function(t){if(!t.length)return!1;var e,n,i=0,a=0,r=0;for(e=0,n=t.length;n>e;++e){var o=t[e];if(o&&o.hasValue()){var s=o.tooltipPosition();i+=s.x,a+=s.y,++r}}return{x:Math.round(i/r),y:Math.round(a/r)}},nearest:function(t,e){var n,i,a,r=e.x,o=e.y,s=Number.POSITIVE_INFINITY;for(i=0,a=t.length;a>i;++i){var u=t[i];if(u&&u.hasValue()){var d=u.getCenterPoint(),c=l.distanceBetweenPoints(e,d);s>c&&(s=c,n=u)}}if(n){var h=n.tooltipPosition();r=h.x,o=h.y}return{x:r,y:o}}}}},{}],37:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n=t.defaults.global;
23275n.elements.arc={backgroundColor:n.defaultColor,borderColor:"#fff",borderWidth:2},t.elements.Arc=t.Element.extend({inLabelRange:function(t){var e=this._view;return e?Math.pow(t-e.x,2)<Math.pow(e.radius+e.hoverRadius,2):!1},inRange:function(t,n){var i=this._view;if(i){for(var a=e.getAngleFromPoint(i,{x:t,y:n}),r=a.angle,o=a.distance,s=i.startAngle,l=i.endAngle;s>l;)l+=2*Math.PI;for(;r>l;)r-=2*Math.PI;for(;s>r;)r+=2*Math.PI;var u=r>=s&&l>=r,d=o>=i.innerRadius&&o<=i.outerRadius;return u&&d}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,n=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,n=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},draw:function(){var t=this._chart.ctx,e=this._view,n=e.startAngle,i=e.endAngle;t.beginPath(),t.arc(e.x,e.y,e.outerRadius,n,i),t.arc(e.x,e.y,e.innerRadius,i,n,!0),t.closePath(),t.strokeStyle=e.borderColor,t.lineWidth=e.borderWidth,t.fillStyle=e.backgroundColor,t.fill(),t.lineJoin="bevel",e.borderWidth&&t.stroke()}})}},{}],38:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n=t.defaults.global;t.defaults.global.elements.line={tension:.4,backgroundColor:n.defaultColor,borderWidth:3,borderColor:n.defaultColor,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",capBezierPoints:!0,fill:!0},t.elements.Line=t.Element.extend({draw:function(){function t(t,e){var n=e._view;e._view.steppedLine===!0?(l.lineTo(n.x,t._view.y),l.lineTo(n.x,n.y)):0===e._view.tension?l.lineTo(n.x,n.y):l.bezierCurveTo(t._view.controlPointNextX,t._view.controlPointNextY,n.controlPointPreviousX,n.controlPointPreviousY,n.x,n.y)}var i=this,a=i._view,r=a.spanGaps,o=a.scaleZero,s=i._loop;s||("top"===a.fill?o=a.scaleTop:"bottom"===a.fill&&(o=a.scaleBottom));var l=i._chart.ctx;l.save();var u=i._children.slice(),d=-1;s&&u.length&&u.push(u[0]);var c,h,f,g;if(u.length&&a.fill){for(l.beginPath(),c=0;c<u.length;++c)h=u[c],f=e.previousItem(u,c),g=h._view,0===c?(s?l.moveTo(o.x,o.y):l.moveTo(g.x,o),g.skip||(d=c,l.lineTo(g.x,g.y))):(f=-1===d?f:u[d],g.skip?r||d!==c-1||(s?l.lineTo(o.x,o.y):l.lineTo(f._view.x,o)):(d!==c-1?r&&-1!==d?t(f,h):s?l.lineTo(g.x,g.y):(l.lineTo(g.x,o),l.lineTo(g.x,g.y)):t(f,h),d=c));s||-1===d||l.lineTo(u[d]._view.x,o),l.fillStyle=a.backgroundColor||n.defaultColor,l.closePath(),l.fill()}var m=n.elements.line;for(l.lineCap=a.borderCapStyle||m.borderCapStyle,l.setLineDash&&l.setLineDash(a.borderDash||m.borderDash),l.lineDashOffset=a.borderDashOffset||m.borderDashOffset,l.lineJoin=a.borderJoinStyle||m.borderJoinStyle,l.lineWidth=a.borderWidth||m.borderWidth,l.strokeStyle=a.borderColor||n.defaultColor,l.beginPath(),d=-1,c=0;c<u.length;++c)h=u[c],f=e.previousItem(u,c),g=h._view,0===c?g.skip||(l.moveTo(g.x,g.y),d=c):(f=-1===d?f:u[d],g.skip||(d!==c-1&&!r||-1===d?l.moveTo(g.x,g.y):t(f,h),d=c));l.stroke(),l.restore()}})}},{}],39:[function(t,e,n){"use strict";e.exports=function(t){function e(t){var e=this._view;return e?Math.pow(t-e.x,2)<Math.pow(e.radius+e.hitRadius,2):!1}function n(t){var e=this._view;return e?Math.pow(t-e.y,2)<Math.pow(e.radius+e.hitRadius,2):!1}var i=t.helpers,a=t.defaults.global,r=a.defaultColor;a.elements.point={radius:3,pointStyle:"circle",backgroundColor:r,borderWidth:1,borderColor:r,hitRadius:1,hoverRadius:4,hoverBorderWidth:1},t.elements.Point=t.Element.extend({inRange:function(t,e){var n=this._view;return n?Math.pow(t-n.x,2)+Math.pow(e-n.y,2)<Math.pow(n.hitRadius+n.radius,2):!1},inLabelRange:e,inXRange:e,inYRange:n,getCenterPoint:function(){var t=this._view;return{x:t.x,y:t.y}},getArea:function(){return Math.PI*Math.pow(this._view.radius,2)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y,padding:t.radius+t.borderWidth}},draw:function(){var e=this._view,n=this._chart.ctx,o=e.pointStyle,s=e.radius,l=e.x,u=e.y;e.skip||(n.strokeStyle=e.borderColor||r,n.lineWidth=i.getValueOrDefault(e.borderWidth,a.elements.point.borderWidth),n.fillStyle=e.backgroundColor||r,t.canvasHelpers.drawPoint(n,o,s,l,u))}})}},{}],40:[function(t,e,n){"use strict";e.exports=function(t){function e(t){return void 0!==t._view.width}function n(t){var n,i,a,r,o=t._view;if(e(t)){var s=o.width/2;n=o.x-s,i=o.x+s,a=Math.min(o.y,o.base),r=Math.max(o.y,o.base)}else{var l=o.height/2;n=Math.min(o.x,o.base),i=Math.max(o.x,o.base),a=o.y-l,r=o.y+l}return{left:n,top:a,right:i,bottom:r}}var i=t.defaults.global;i.elements.rectangle={backgroundColor:i.defaultColor,borderWidth:0,borderColor:i.defaultColor,borderSkipped:"bottom"},t.elements.Rectangle=t.Element.extend({draw:function(){function t(t){return l[(d+t)%4]}var e=this._chart.ctx,n=this._view,i=n.width/2,a=n.x-i,r=n.x+i,o=n.base-(n.base-n.y),s=n.borderWidth/2;n.borderWidth&&(a+=s,r-=s,o+=s),e.beginPath(),e.fillStyle=n.backgroundColor,e.strokeStyle=n.borderColor,e.lineWidth=n.borderWidth;var l=[[a,n.base],[a,o],[r,o],[r,n.base]],u=["bottom","left","top","right"],d=u.indexOf(n.borderSkipped,0);-1===d&&(d=0);var c=t(0);e.moveTo(c[0],c[1]);for(var h=1;4>h;h++)c=t(h),e.lineTo(c[0],c[1]);e.fill(),n.borderWidth&&e.stroke()},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){var i=!1;if(this._view){var a=n(this);i=t>=a.left&&t<=a.right&&e>=a.top&&e<=a.bottom}return i},inLabelRange:function(t,i){var a=this;if(!a._view)return!1;var r=!1,o=n(a);return r=e(a)?t>=o.left&&t<=o.right:i>=o.top&&i<=o.bottom},inXRange:function(t){var e=n(this);return t>=e.left&&t<=e.right},inYRange:function(t){var e=n(this);return t>=e.top&&t<=e.bottom},getCenterPoint:function(){var t,n,i=this._view;return e(this)?(t=i.x,n=(i.y+i.base)/2):(t=(i.x+i.base)/2,n=i.y),{x:t,y:n}},getArea:function(){var t=this._view;return t.width*Math.abs(t.y-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}})}},{}],41:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n={position:"bottom"},i=t.Scale.extend({getLabels:function(){var t=this.chart.data;return(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels},determineDataLimits:function(){var t=this,n=t.getLabels();t.minIndex=0,t.maxIndex=n.length-1;var i;void 0!==t.options.ticks.min&&(i=e.indexOf(n,t.options.ticks.min),t.minIndex=-1!==i?i:t.minIndex),void 0!==t.options.ticks.max&&(i=e.indexOf(n,t.options.ticks.max),t.max
23275Index=-1!==i?i:t.maxIndex),t.min=n[t.minIndex],t.max=n[t.maxIndex]},buildTicks:function(){var t=this,e=t.getLabels();t.ticks=0===t.minIndex&&t.maxIndex===e.length-1?e:e.slice(t.minIndex,t.maxIndex+1)},getLabelForIndex:function(t,e){var n=this,i=n.chart.data,a=n.isHorizontal();return i.xLabels&&a||i.yLabels&&!a?n.getRightValue(i.datasets[e].data[t]):n.ticks[t]},getPixelForValue:function(t,e,n,i){var a=this,r=Math.max(a.maxIndex+1-a.minIndex-(a.options.gridLines.offsetGridLines?0:1),1);if(void 0!==t&&isNaN(e)){var o=a.getLabels(),s=o.indexOf(t);e=-1!==s?s:e}if(a.isHorizontal()){var l=a.width-(a.paddingLeft+a.paddingRight),u=l/r,d=u*(e-a.minIndex)+a.paddingLeft;return(a.options.gridLines.offsetGridLines&&i||a.maxIndex===a.minIndex&&i)&&(d+=u/2),a.left+Math.round(d)}var c=a.height-(a.paddingTop+a.paddingBottom),h=c/r,f=h*(e-a.minIndex)+a.paddingTop;return a.options.gridLines.offsetGridLines&&i&&(f+=h/2),a.top+Math.round(f)},getPixelForTick:function(t,e){return this.getPixelForValue(this.ticks[t],t+this.minIndex,null,e)},getValueForPixel:function(t){var e,n=this,i=Math.max(n.ticks.length-(n.options.gridLines.offsetGridLines?0:1),1),a=n.isHorizontal(),r=a?n.width-(n.paddingLeft+n.paddingRight):n.height-(n.paddingTop+n.paddingBottom),o=r/i;return t-=a?n.left:n.top,n.options.gridLines.offsetGridLines&&(t-=o/2),t-=a?n.paddingLeft:n.paddingTop,e=0>=t?0:Math.round(t/o)},getBasePixel:function(){return this.bottom}});t.scaleService.registerScaleType("category",i,n)}},{}],42:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n={position:"left",ticks:{callback:t.Ticks.formatters.linear}},i=t.LinearScaleBase.extend({determineDataLimits:function(){function t(t){return s?t.xAxisID===n.id:t.yAxisID===n.id}var n=this,i=n.options,a=n.chart,r=a.data,o=r.datasets,s=n.isHorizontal();if(n.min=null,n.max=null,i.stacked){var l={};e.each(o,function(r,o){var s=a.getDatasetMeta(o);void 0===l[s.type]&&(l[s.type]={positiveValues:[],negativeValues:[]});var u=l[s.type].positiveValues,d=l[s.type].negativeValues;a.isDatasetVisible(o)&&t(s)&&e.each(r.data,function(t,e){var a=+n.getRightValue(t);isNaN(a)||s.data[e].hidden||(u[e]=u[e]||0,d[e]=d[e]||0,i.relativePoints?u[e]=100:0>a?d[e]+=a:u[e]+=a)})}),e.each(l,function(t){var i=t.positiveValues.concat(t.negativeValues),a=e.min(i),r=e.max(i);n.min=null===n.min?a:Math.min(n.min,a),n.max=null===n.max?r:Math.max(n.max,r)})}else e.each(o,function(i,r){var o=a.getDatasetMeta(r);a.isDatasetVisible(r)&&t(o)&&e.each(i.data,function(t,e){var i=+n.getRightValue(t);isNaN(i)||o.data[e].hidden||(null===n.min?n.min=i:i<n.min&&(n.min=i),null===n.max?n.max=i:i>n.max&&(n.max=i))})});this.handleTickRangeOptions()},getTickLimit:function(){var n,i=this,a=i.options.ticks;if(i.isHorizontal())n=Math.min(a.maxTicksLimit?a.maxTicksLimit:11,Math.ceil(i.width/50));else{var r=e.getValueOrDefault(a.fontSize,t.defaults.global.defaultFontSize);n=Math.min(a.maxTicksLimit?a.maxTicksLimit:11,Math.ceil(i.height/(2*r)))}return n},handleDirectionalChanges:function(){this.isHorizontal()||this.ticks.reverse()},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForValue:function(t){var e,n,i=this,a=i.paddingLeft,r=i.paddingBottom,o=i.start,s=+i.getRightValue(t),l=i.end-o;return i.isHorizontal()?(n=i.width-(a+i.paddingRight),e=i.left+n/l*(s-o),Math.round(e+a)):(n=i.height-(i.paddingTop+r),e=i.bottom-r-n/l*(s-o),Math.round(e))},getValueForPixel:function(t){var e=this,n=e.isHorizontal(),i=e.paddingLeft,a=e.paddingBottom,r=n?e.width-(i+e.paddingRight):e.height-(e.paddingTop+a),o=(n?t-e.left-i:e.bottom-a-t)/r;return e.start+(e.end-e.start)*o},getPixelForTick:function(t){return this.getPixelForValue(this.ticksAsNumbers[t])}});t.scaleService.registerScaleType("linear",i,n)}},{}],43:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n=e.noop;t.LinearScaleBase=t.Scale.extend({handleTickRangeOptions:function(){var t=this,n=t.options,i=n.ticks;if(i.beginAtZero){var a=e.sign(t.min),r=e.sign(t.max);0>a&&0>r?t.max=0:a>0&&r>0&&(t.min=0)}void 0!==i.min?t.min=i.min:void 0!==i.suggestedMin&&(t.min=Math.min(t.min,i.suggestedMin)),void 0!==i.max?t.max=i.max:void 0!==i.suggestedMax&&(t.max=Math.max(t.max,i.suggestedMax)),t.min===t.max&&(t.max++,i.beginAtZero||t.min--)},getTickLimit:n,handleDirectionalChanges:n,buildTicks:function(){var n=this,i=n.options,a=i.ticks,r=n.getTickLimit();r=Math.max(2,r);var o={maxTicks:r,min:a.min,max:a.max,stepSize:e.getValueOrDefault(a.fixedStepSize,a.stepSize)},s=n.ticks=t.Ticks.generators.linear(o,n);n.handleDirectionalChanges(),n.max=e.max(s),n.min=e.min(s),a.reverse?(s.reverse(),n.start=n.max,n.end=n.min):(n.start=n.min,n.end=n.max)},convertTicksToLabels:function(){var e=this;e.ticksAsNumbers=e.ticks.slice(),e.zeroLineIndex=e.ticks.indexOf(0),t.Scale.prototype.convertTicksToLabels.call(e)}})}},{}],44:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n={position:"left",ticks:{callback:t.Ticks.formatters.logarithmic}},i=t.Scale.extend({determineDataLimits:function(){function t(t){return u?t.xAxisID===n.id:t.yAxisID===n.id}var n=this,i=n.options,a=i.ticks,r=n.chart,o=r.data,s=o.datasets,l=e.getValueOrDefault,u=n.isHorizontal();if(n.min=null,n.max=null,n.minNotZero=null,i.stacked){var d={};e.each(s,function(a,o){var s=r.getDatasetMeta(o);r.isDatasetVisible(o)&&t(s)&&(void 0===d[s.type]&&(d[s.type]=[]),e.each(a.data,function(t,e){var a=d[s.type],r=+n.getRightValue(t);isNaN(r)||s.data[e].hidden||(a[e]=a[e]||0,i.relativePoints?a[e]=100:a[e]+=r)}))}),e.each(d,function(t){var i=e.min(t),a=e.max(t);n.min=null===n.min?i:Math.min(n.min,i),n.max=null===n.max?a:Math.max(n.max,a)})}else e.each(s,function(i,a){var o=r.getDatasetMeta(a);r.isDatasetVisible(a)&&t(o)&&e.each(i.data,function(t,e){var i=+n.getRightValue(t);isNaN(i)||o.data[e].hidden||(null===n.min?n.min=i:i<n.min&&(n.min=i),null===n.max?n.max=i:i>n.max&&(n.max=i),0!==i&&(null===n.minNotZero||i<n.minNotZero)&&(n.minNotZero=i))})});n.min=l(a.min,n.min),n.max=l(a.max,n.max),n.min===n.max&&(0!==n.min&&null!==n.min?(n.min=Math.pow(10,Math.floor(e.log10(n.min))-1),n.max=Math.pow(10,Math.floor(e.log10(n.max))+1)):(n.min=1,n.max=10))},buildTicks:function(){var n=this,i=n.options,a=i.ticks,r={min:a.min,max:a.max},o=n.ticks=t.Ticks.generators.logarithmic(r,n);n.isHorizontal()||o.reverse(),n.max=e.max(o),n.min=e.min(o),a.reverse?(o.reverse(),n.start=n.max,n.end=n.min):(n.start=n.min,n.end=n.max)},convertTicksToLabels:function(){this.tickValues=this.ticks.slice(),t.Scale.prototype.convertTicksToLabels.call(this)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForTick:function(t){return this.getPixelForValue(this.tickValues[t])},getPixelForValue:function(t){var n,i,a,r=this,o=r.start,s=+r.getRightValue(t),l=r.paddingTop,u=r.paddingBottom,d=r.paddingLeft,c=r.options,h=c.ticks;return r.isHorizontal()?(a=e.log10(r.end)-e.log10(o),0===s?i=r.left+d:(n=r.width-(d+r.paddingRight),i=r.left+n/a*(e.log10(s)-e.log10(o)),i+=d)):(n=r.height-(l+u),0!==o||h.reverse?0===r.end&&h.reverse?(a=e.log10(r.start)-e.log10(r.minNotZero),i=s===r.end?r.top+l:s===r.minNotZero?r.top+l+.02*n:r.top+l+.02*n+.98*n/a*(e.log10(s)-e.log10(r.minNotZero))):(a=e.log10(r.end)-e.log10(o),n=r.height-(l+u),i=r.bottom-u-n/a*(e.log10(s)-e.log10(o))):(a=e.log10(r.end)-e.log10(r.minNotZero),i=s===o?r.bottom-u:s===r.minNotZero?r.bottom-u-.02*n:r.bottom-u-.02*n-.98*n/a*(e.log10(s)-e.log10(r.minNotZero)))),i},getValueForPixel:function(t){var n,i,a=this,r=e.log10(a.end)-e.log10(a.start);return a.isHorizontal()?(i=a.width-(a.paddingLeft+a.paddingRight),n=a.start*Math.pow(10,(t-a.left-a.paddingLeft)*r/i)):(i=a.height-(a.paddingTop+a.paddingBottom),n=Math.pow(10,(a.bottom-a.paddingBottom-t)*r/i)/a.start),n}});t.scaleService.registerScaleType("logarithmic",i,n)}},{}],45:[function(t,e,n){"use strict";e.exports=function(t){var e=t.helpers,n=t.defaults.global,i={dis
23275play:!0,animate:!0,lineArc:!1,position:"chartArea",angleLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2,callback:t.Ticks.formatters.linear},pointLabels:{fontSize:10,callback:function(t){return t}}},a=t.LinearScaleBase.extend({getValueCount:function(){return this.chart.data.labels.length},setDimensions:function(){var t=this,i=t.options,a=i.ticks;t.width=t.maxWidth,t.height=t.maxHeight,t.xCenter=Math.round(t.width/2),t.yCenter=Math.round(t.height/2);var r=e.min([t.height,t.width]),o=e.getValueOrDefault(a.fontSize,n.defaultFontSize);t.drawingArea=i.display?r/2-(o/2+a.backdropPaddingY):r/2},determineDataLimits:function(){var t=this,n=t.chart;t.min=null,t.max=null,e.each(n.data.datasets,function(i,a){if(n.isDatasetVisible(a)){var r=n.getDatasetMeta(a);e.each(i.data,function(e,n){var i=+t.getRightValue(e);isNaN(i)||r.data[n].hidden||(null===t.min?t.min=i:i<t.min&&(t.min=i),null===t.max?t.max=i:i>t.max&&(t.max=i))})}}),t.handleTickRangeOptions()},getTickLimit:function(){var t=this.options.ticks,i=e.getValueOrDefault(t.fontSize,n.defaultFontSize);return Math.min(t.maxTicksLimit?t.maxTicksLimit:11,Math.ceil(this.drawingArea/(1.5*i)))},convertTicksToLabels:function(){var e=this;t.LinearScaleBase.prototype.convertTicksToLabels.call(e),e.pointLabels=e.chart.data.labels.map(e.options.pointLabels.callback,e)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){var t,i,a,r,o,s,l,u,d,c,h,f,g=this.options.pointLabels,m=e.getValueOrDefault(g.fontSize,n.defaultFontSize),p=e.getValueOrDefault(g.fontStyle,n.defaultFontStyle),v=e.getValueOrDefault(g.fontFamily,n.defaultFontFamily),b=e.fontString(m,p,v),y=e.min([this.height/2-m-5,this.width/2]),x=this.width,k=0;for(this.ctx.font=b,i=0;i<this.getValueCount();i++){t=this.getPointPosition(i,y),a=this.ctx.measureText(this.pointLabels[i]?this.pointLabels[i]:"").width+5;var _=this.getIndexAngle(i)+Math.PI/2,w=360*_/(2*Math.PI)%360;0===w||180===w?(r=a/2,t.x+r>x&&(x=t.x+r,o=i),t.x-r<k&&(k=t.x-r,l=i)):180>w?t.x+a>x&&(x=t.x+a,o=i):t.x-a<k&&(k=t.x-a,l=i)}d=k,c=Math.ceil(x-this.width),s=this.getIndexAngle(o),u=this.getIndexAngle(l),h=c/Math.sin(s+Math.PI/2),f=d/Math.sin(u+Math.PI/2),h=e.isNumber(h)?h:0,f=e.isNumber(f)?f:0,this.drawingArea=Math.round(y-(f+h)/2),this.setCenterPoint(f,h)},setCenterPoint:function(t,e){var n=this,i=n.width-e-n.drawingArea,a=t+n.drawingArea;n.xCenter=Math.round((a+i)/2+n.left),n.yCenter=Math.round(n.height/2+n.top)},getIndexAngle:function(t){var e=2*Math.PI/this.getValueCount(),n=this.chart.options&&this.chart.options.startAngle?this.chart.options.startAngle:0,i=n*Math.PI*2/360;return t*e-Math.PI/2+i},getDistanceFromCenterForValue:function(t){var e=this;if(null===t)return 0;var n=e.drawingArea/(e.max-e.min);return e.options.reverse?(e.max-t)*n:(t-e.min)*n},getPointPosition:function(t,e){var n=this,i=n.getIndexAngle(t);return{x:Math.round(Math.cos(i)*e)+n.xCenter,y:Math.round(Math.sin(i)*e)+n.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(){var t=this,e=t.min,n=t.max;return t.getPointPositionForValue(0,t.beginAtZero?0:0>e&&0>n?n:e>0&&n>0?e:0)},draw:function(){var t=this,i=t.options,a=i.gridLines,r=i.ticks,o=i.angleLines,s=i.pointLabels,l=e.getValueOrDefault;if(i.display){var u=t.ctx,d=l(r.fontSize,n.defaultFontSize),c=l(r.fontStyle,n.defaultFontStyle),h=l(r.fontFamily,n.defaultFontFamily),f=e.fontString(d,c,h);if(e.each(t.ticks,function(o,s){if(s>0||i.reverse){var c=t.getDistanceFromCenterForValue(t.ticksAsNumbers[s]),h=t.yCenter-c;if(a.display&&0!==s)if(u.strokeStyle=e.getValueAtIndexOrDefault(a.color,s-1),u.lineWidth=e.getValueAtIndexOrDefault(a.lineWidth,s-1),i.lineArc)u.beginPath(),u.arc(t.xCenter,t.yCenter,c,0,2*Math.PI),u.closePath(),u.stroke();else{u.beginPath();for(var g=0;g<t.getValueCount();g++){var m=t.getPointPosition(g,c);0===g?u.moveTo(m.x,m.y):u.lineTo(m.x,m.y)}u.closePath(),u.stroke()}if(r.display){var p=l(r.fontColor,n.defaultFontColor);if(u.font=f,r.showLabelBackdrop){var v=u.measureText(o).width;u.fillStyle=r.backdropColor,u.fillRect(t.xCenter-v/2-r.backdropPaddingX,h-d/2-r.backdropPaddingY,v+2*r.backdropPaddingX,d+2*r.backdropPaddingY)}u.textAlign="center",u.textBaseline="middle",u.fillStyle=p,u.fillText(o,t.xCenter,h)}}}),!i.lineArc){u.lineWidth=o.lineWidth,u.strokeStyle=o.color;for(var g=t.getDistanceFromCenterForValue(i.reverse?t.min:t.max),m=l(s.fontSize,n.defaultFontSize),p=l(s.fontStyle,n.defaultFontStyle),v=l(s.fontFamily,n.defaultFontFamily),b=e.fontString(m,p,v),y=t.getValueCount()-1;y>=0;y--){if(o.display){var x=t.getPointPosition(y,g);u.beginPath(),u.moveTo(t.xCenter,t.yCenter),u.lineTo(x.x,x.y),u.stroke(),u.closePath()}var k=t.getPointPosition(y,g+5),_=l(s.fontColor,n.defaultFontColor);u.font=b,u.fillStyle=_;var w=t.pointLabels,S=this.getIndexAngle(y)+Math.PI/2,M=360*S/(2*Math.PI)%360;
232750===M||180===M?u.textAlign="center":180>M?u.textAlign="left":u.textAlign="right",90===M||270===M?u.textBaseline="middle":M>270||90>M?u.textBaseline="bottom":u.textBaseline="top",u.fillText(w[y]?w[y]:"",k.x,k.y)}}}}});t.scaleService.registerScaleType("radialLinear",a,i)}},{}],46:[function(t,e,n){"use strict";var i=t(6);i="function"==typeof i?i:window.moment,e.exports=function(t){var e=t.helpers,n={units:[{name:"millisecond",steps:[1,2,5,10,20,50,100,250,500]},{name:"second",steps:[1,2,5,10,30]},{name:"minute",steps:[1,2,5,10,30]},{name:"hour",steps:[1,2,3,6,12]},{name:"day",steps:[1,2,5]},{name:"week",maxStep:4},{name:"month",maxStep:3},{name:"quarter",maxStep:4},{name:"year",maxStep:!1}]},a={position:"bottom",time:{parser:!1,format:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm:ss a",hour:"MMM D, hA",day:"ll",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"}},ticks:{autoSkip:!1}},r=t.Scale.extend({initialize:function(){if(!i)throw new Error("Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com");t.Scale.prototype.initialize.call(this)},getLabelMoment:function(t,e){return null===t||null===e?null:"undefined"!=typeof this.labelMoments[t]?this.labelMoments[t][e]:null},getLabelDiff:function(t,e){var n=this;return null===t||null===e?null:(void 0===n.labelDiffs&&n.buildLabelDiffs(),"undefined"!=typeof n.labelDiffs[t]?n.labelDiffs[t][e]:null)},getMomentStartOf:function(t){var e=this;return"week"===e.options.time.unit&&e.options.time.isoWeekday!==!1?t.clone().startOf("isoWeek").isoWeekday(e.options.time.isoWeekday):t.clone().startOf(e.tickUnit)},determineDataLimits:function(){var t=this;t.labelMoments=[];var n=[];t.chart.data.labels&&t.chart.data.labels.length>0?(e.each(t.chart.data.labels,function(e){var i=t.parseTime(e);i.isValid()&&(t.options.time.round&&i.startOf(t.options.time.round),n.push(i))},t),t.firstTick=i.min.call(t,n),t.lastTick=i.max.call(t,n)):(t.firstTick=null,t.lastTick=null),e.each(t.chart.data.datasets,function(a,r){var o=[],s=t.chart.isDatasetVisible(r);"object"==typeof a.data[0]&&null!==a.data[0]?e.each(a.data,function(e){var n=t.parseTime(t.getRightValue(e));n.isValid()&&(t.options.time.round&&n.startOf(t.options.time.round),o.push(n),s&&(t.firstTick=null!==t.firstTick?i.min(t.firstTick,n):n,t.lastTick=null!==t.lastTick?i.max(t.lastTick,n):n))},t):o=n,t.labelMoments.push(o)},t),t.options.time.min&&(t.firstTick=t.parseTime(t.options.time.min)),t.options.time.max&&(t.lastTick=t.parseTime(t.options.time.max)),t.firstTick=(t.firstTick||i()).clone(),t.lastTick=(t.lastTick||i()).clone()},buildLabelDiffs:function(){var t=this;t.labelDiffs=[];var n=[];t.chart.data.labels&&t.chart.data.labels.length>0&&e.each(t.chart.data.labels,function(e){var i=t.parseTime(e);i.isValid()&&(t.options.time.round&&i.startOf(t.options.time.round),n.push(i.diff(t.firstTick,t.tickUnit,!0)))},t),e.each(t.chart.data.datasets,function(i){var a=[];"object"==typeof i.data[0]&&null!==i.data[0]?e.each(i.data,function(e){var n=t.parseTime(t.getRightValue(e));n.isValid()&&(t.options.time.round&&n.startOf(t.options.time.round),a.push(n.diff(t.firstTick,t.tickUnit,!0)))},t):a=n,t.labelDiffs.push(a)},t)},buildTicks:function(){var i=this;i.ctx.save();var a=e.getValueOrDefault(i.options.ticks.fontSize,t.defaults.global.defaultFontSize),r=e.getValueOrDefault(i.options.ticks.fontStyle,t.defaults.global.defaultFontStyle),o=e.getValueOrDefault(i.options.ticks.fontFamily,t.defaults.global.defaultFontFamily),s=e.fontString(a,r,o);if(i.ctx.font=s,i.ticks=[],i.unitScale=1,i.scaleSizeInUnits=0,i.options.time.unit)i.tickUnit=i.options.time.unit||"day",i.displayFormat=i.options.time.displayFormats[i.tickUnit],
23276    i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0),i.unitScale=e.getValueOrDefault(i.options.time.unitStepSize,1);else{var l=i.isHorizontal()?i.width-(i.paddingLeft+i.paddingRight):i.height-(i.paddingTop+i.paddingBottom),u=i.tickFormatFunction(i.firstTick,0,[]),d=i.ctx.measureText(u).width,c=Math.cos(e.toRadians(i.options.ticks.maxRotation)),h=Math.sin(e.toRadians(i.options.ticks.maxRotation));d=d*c+a*h;var f=l/d;i.tickUnit=i.options.time.minUnit,i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0),i.displayFormat=i.options.time.displayFormats[i.tickUnit];for(var g=0,m=n.units[g];g<n.units.length;){if(i.unitScale=1,e.isArray(m.steps)&&Math.ceil(i.scaleSizeInUnits/f)<e.max(m.steps)){for(var p=0;p<m.steps.length;++p)if(m.steps[p]>=Math.ceil(i.scaleSizeInUnits/f)){i.unitScale=e.getValueOrDefault(i.options.time.unitStepSize,m.steps[p]);break}break}if(m.maxStep===!1||Math.ceil(i.scaleSizeInUnits/f)<m.maxStep){i.unitScale=e.getValueOrDefault(i.options.time.unitStepSize,Math.ceil(i.scaleSizeInUnits/f));break}++g,m=n.units[g],i.tickUnit=m.name;var v=i.firstTick.diff(i.getMomentStartOf(i.firstTick),i.tickUnit,!0),b=i.getMomentStartOf(i.lastTick.clone().add(1,i.tickUnit)).diff(i.lastTick,i.tickUnit,!0);i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0)+v+b,i.displayFormat=i.options.time.displayFormats[m.name]}}var y;if(i.options.time.min?y=i.getMomentStartOf(i.firstTick):(i.firstTick=i.getMomentStartOf(i.firstTick),y=i.firstTick),!i.options.time.max){var x=i.getMomentStartOf(i.lastTick),k=x.diff(i.lastTick,i.tickUnit,!0);0>k?i.lastTick=i.getMomentStartOf(i.lastTick.add(1,i.tickUnit)):k>=0&&(i.lastTick=x),i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0)}i.options.time.displayFormat&&(i.displayFormat=i.options.time.displayFormat),i.ticks.push(i.firstTick.clone());for(var _=1;_<=i.scaleSizeInUnits;++_){var w=y.clone().add(_,i.tickUnit);if(i.options.time.max&&w.diff(i.lastTick,i.tickUnit,!0)>=0)break;_%i.unitScale===0&&i.ticks.push(w)}var S=i.ticks[i.ticks.length-1].diff(i.lastTick,i.tickUnit);(0!==S||0===i.scaleSizeInUnits)&&(i.options.time.max?(i.ticks.push(i.lastTick.clone()),i.scaleSizeInUnits=i.lastTick.diff(i.ticks[0],i.tickUnit,!0)):(i.ticks.push(i.lastTick.clone()),i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0))),i.ctx.restore(
23276),i.labelDiffs=void 0},getLabelForIndex:function(t,e){var n=this,i=n.chart.data.labels&&t<n.chart.data.labels.length?n.chart.data.labels[t]:"";return"object"==typeof n.chart.data.datasets[e].data[0]&&(i=n.getRightValue(n.chart.data.datasets[e].data[t])),n.options.time.tooltipFormat&&(i=n.parseTime(i).format(n.options.time.tooltipFormat)),i},tickFormatFunction:function(t,n,i){var a=t.format(this.displayFormat),r=this.options.ticks,o=e.getValueOrDefault(r.callback,r.userCallback);return o?o(a,n,i):a},convertTicksToLabels:function(){var t=this;t.tickMoments=t.ticks,t.ticks=t.ticks.map(t.tickFormatFunction,t)},getPixelForValue:function(t,e,n){var i=this,a=null;if(void 0!==e&&void 0!==n&&(a=i.getLabelDiff(n,e)),null===a&&(t&&t.isValid||(t=i.parseTime(i.getRightValue(t))),t&&t.isValid&&t.isValid()&&(a=t.diff(i.firstTick,i.tickUnit,!0))),null!==a){var r=0!==a?a/i.scaleSizeInUnits:a;if(i.isHorizontal()){var o=i.width-(i.paddingLeft+i.paddingRight),s=o*r+i.paddingLeft;return i.left+Math.round(s)}var l=i.height-(i.paddingTop+i.paddingBottom),u=l*r+i.paddingTop;return i.top+Math.round(u)}},getPixelForTick:function(t){return this.getPixelForValue(this.tickMoments[t],null,null)},getValueForPixel:function(t){var e=this,n=e.isHorizontal()?e.width-(e.paddingLeft+e.paddingRight):e.height-(e.paddingTop+e.paddingBottom),a=(t-(e.isHorizontal()?e.left+e.paddingLeft:e.top+e.paddingTop))/n;return a*=e.scaleSizeInUnits,e.firstTick.clone().add(i.duration(a,e.tickUnit).asSeconds(),"seconds")},parseTime:function(t){var e=this;return"string"==typeof e.options.time.parser?i(t,e.options.time.parser):"function"==typeof e.options.time.parser?e.options.time.parser(t):"function"==typeof t.getMonth||"number"==typeof t?i(t):t.isValid&&t.isValid()?t:"string"!=typeof e.options.time.format&&e.options.time.format.call?(console.warn("options.time.format is deprecated and replaced by options.time.parser. See http://nnnick.github.io/Chart.js/docs-v2/#scales-time-scale"),e.options.time.format(t)):i(t,e.options.time.format)}});t.scaleService.registerScaleType("time",r,a)}},{6:6}]},{},[7])(7)});
23277(function ($) {
23278  'use strict';
23279
23280  //<editor-fold desc="Shims">
23281  if (!String.prototype.includes) {
23282    (function () {
23283      'use strict'; // needed to support `apply`/`call` with `undefined`/`null`
23284      var toString = {}.toString;
23285      var defineProperty = (function () {
23286        // IE 8 only supports `Object.defineProperty` on DOM elements
23287        try {
23288          var object = {};
23289          var $defineProperty = Object.defineProperty;
23290          var result = $defineProperty(object, object, object) && $defineProperty;
23291        } catch (error) {
23292        }
23293        return result;
23294      }());
23295      var indexOf = ''.indexOf;
23296      var includes = function (search) {
23297        if (this == null) {
23298          throw new TypeError();
23299        }
23300        var string = String(this);
23301        if (search && toString.call(search) == '[object RegExp]') {
23302          throw new TypeError();
23303        }
23304        var stringLength = string.length;
23305        var searchString = String(search);
23306        var searchLength = searchString.length;
23307        var position = arguments.length > 1 ? arguments[1] : undefined;
23308        // `ToInteger`
23309        var pos = position ? Number(position) : 0;
23310        if (pos != pos) { // better `isNaN`
23311          pos = 0;
23312        }
23313        var start = Math.min(Math.max(pos, 0), stringLength);
23314        // Avoid the `indexOf` call if no match is possible
23315        if (searchLength + start > stringLength) {
23316          return false;
23317        }
23318        return indexOf.call(string, searchString, pos) != -1;
23319      };
23320      if (defineProperty) {
23321        defineProperty(String.prototype, 'includes', {
23322          'value': includes,
23323          'configurable': true,
23324          'writable': true
23325        });
23326      } else {
23327        String.prototype.includes = includes;
23328      }
23329    }());
23330  }
23331
23332  if (!String.prototype.startsWith) {
23333    (function () {
23334      'use strict'; // needed to support `apply`/`call` with `undefined`/`null`
23335      var defineProperty = (function () {
23336        // IE 8 only supports `Object.defineProperty` on DOM elements
23337        try {
23338          var object = {};
23339          var $defineProperty = Object.defineProperty;
23340          var result = $defineProperty(object, object, object) && $defineProperty;
23341        } catch (error) {
23342        }
23343        return result;
23344      }());
23345      var toString = {}.toString;
23346      var startsWith = function (search) {
23347        if (this == null) {
23348          throw new TypeError();
23349        }
23350        var string = String(this);
23351        if (search && toString.call(search) == '[object RegExp]') {
23352          throw new TypeError();
23353        }
23354        var stringLength = string.length;
23355        var searchString = String(search);
23356        var searchLength = searchString.length;
23357        var position = arguments.length > 1 ? arguments[1] : undefined;
23358        // `ToInteger`
23359        var pos = position ? Number(position) : 0;
23360        if (pos != pos) { // better `isNaN`
23361          pos = 0;
23362        }
23363        var start = Math.min(Math.max(pos, 0), stringLength);
23364        // Avoid the `indexOf` call if no match is possible
23365        if (searchLength + start > stringLength) {
23366          return false;
23367        }
23368        var index = -1;
23369        while (++index < searchLength) {
23370          if (string.charCodeAt(start + index) != searchString.charCodeAt(index)) {
23371            return false;
23372          }
23373        }
23374        return true;
23375      };
23376      if (defineProperty) {
23377        defineProperty(String.prototype, 'startsWith', {
23378          'value': startsWith,
23379          'configurable': true,
23380          'writable': true
23381        });
23382      } else {
23383        String.prototype.startsWith = startsWith;
23384      }
23385    }());
23386  }
23387
23388  if (!Object.keys) {
23389    Object.keys = function (
23390      o, // object
23391      k, // key
23392      r  // result array
23393      ){
23394      // initialize object and result
23395      r=[];
23396      // iterate over object keys
23397      for (k in o)
23398          // fill result array with non-prototypical keys
23399        r.hasOwnProperty.call(o, k) && r.push(k);
23400      // return result
23401      return r;
23402    };
23403  }
23404
23405  // set data-selected on select element if the value has been programmatically selected
23406  // prior to initialization of bootstrap-select
23407  // * consider removing or replacing an alternative method *
23408  var valHooks = {
23409    useDefault: false,
23410    _set: $.valHooks.select.set
23411  };
23412
23413  $.valHooks.select.set = function(elem, value) {
23414    if (value && !valHooks.useDefault) $(elem).data('selected', true);
23415
23416    return valHooks._set.apply(this, arguments);
23417  };
23418
23419  var changed_arguments = null;
23420
23421  var EventIsSupported = (function() {
23422    try {
23423      new Event('change');
23424      return true;
23425    } catch (e) {
23426      return false;
23427    }
23428  })();
23429
23430  $.fn.triggerNative = function (eventName) {
23431    var el = this[0],
23432        event;
23433
23434    if (el.dispatchEvent) { // for modern browsers & IE9+
23435      if (EventIsSupported) {
23436        // For modern browsers
23437        event = new Event(eventName, {
23438          bubbles: true
23439        });
23440      } else {
23441        // For IE since it doesn't support Event constructor
23442        event = document.createEvent('Event');
23443        event.initEvent(eventName, true, false);
23444      }
23445
23446      el.dispatchEvent(event);
23447    } else if (el.fireEvent) { // for IE8
23448      event = document.createEventObject();
23449      event.eventType = eventName;
23450      el.fireEvent('on' + eventName, event);
23451    } else {
23452      // fall back to jQuery.trigger
23453      this.trigger(eventName);
23454    }
23455  };
23456  //</editor-fold>
23457
23458  // Case insensitive contains search
23459  $.expr.pseudos.icontains = function (obj, index, meta) {
23460    var $obj = $(obj).find('a');
23461    var haystack = ($obj.data('tokens') || $obj.text()).toString().toUpperCase();
23462    return haystack.includes(meta[3].toUpperCase());
23463  };
23464
23465  // Case insensitive begins search
23466  $.expr.pseudos.ibegins = function (obj, index, meta) {
23467    var $obj = $(obj).find('a');
23468    var haystack = ($obj.data('tokens') || $obj.text()).toString().toUpperCase();
23469    return haystack.startsWith(meta[3].toUpperCase());
23470  };
23471
23472  // Case and accent insensitive contains search
23473  $.expr.pseudos.aicontains = function (obj, index, meta) {
23474    var $obj = $(obj).find('a');
23475    var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toString().toUpperCase();
23476    return haystack.includes(meta[3].toUpperCase());
23477  };
23478
23479  // Case and accent insensitive begins search
23480  $.expr.pseudos.aibegins = function (obj, index, meta) {
23481    var $obj = $(obj).find('a');
23482    var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toString().toUpperCase();
23483    return haystack.startsWith(meta[3].toUpperCase());
23484  };
23485
23486  /**
23487   * Remove all diatrics from the given text.
23488   * @access private
23489   * @param {String} text
23490   * @returns {String}
23491   */
23492  function normalizeToBase(text) {
23493    var rExps = [
23494      {re: /[\xC0-\xC6]/g, ch: "A"},
23495      {re: /[\xE0-\xE6]/g, ch: "a"},
23496      {re: /[\xC8-\xCB]/g, ch: "E"},
23497      {re: /[\xE8-\xEB]/g, ch: "e"},
23498      {re: /[\xCC-\xCF]/g, ch: "I"},
23499      {re: /[\xEC-\xEF]/g, ch: "i"},
23500      {re: /[\xD2-\xD6]/g, ch: "O"},
23501      {re: /[\xF2-\xF6]/g, ch: "o"},
23502      {re: /[\xD9-\xDC]/g, ch: "U"},
23503      {re: /[\xF9-\xFC]/g, ch: "u"},
23504      {re: /[\xC7-\xE7]/g, ch: "c"},
23505      {re: /[\xD1]/g, ch: "N"},
23506      {re: /[\xF1]/g, ch: "n"}
23507    ];
23508    $.each(rExps, function () {
23509      text = text ? text.replace(this.re, this.ch) : '';
23510    });
23511    return text;
23512  }
23513
23514
23515  // List of HTML entities for escaping.
23516  var escapeMap = {
23517    '&': '&amp;',
23518    '<': '&lt;',
23519    '>': '&gt;',
23520    '"': '&quot;',
23521    "'": '&#x27;',
23522    '`': '&#x60;'
23523  };
23524  
23525  var unescapeMap = {
23526    '&amp;': '&',
23527    '&lt;': '<',
23528    '&gt;': '>',
23529    '&quot;': '"',
23530    '&#x27;': "'",
23531    '&#x60;': '`'
23532  };
23533
23534  // Functions for escaping and unescaping strings to/from HTML interpolation.
23535  var createEscaper = function(map) {
23536    var escaper = function(match) {
23537      return map[match];
23538    };
23539    // Regexes for identifying a key that needs to be escaped.
23540    var source = '(?:' + Object.keys(map).join('|') + ')';
23541    var testRegexp = RegExp(source);
23542    var replaceRegexp = RegExp(source, 'g');
23543    return function(string) {
23544      string = string == null ? '' : '' + string;
23545      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
23546    };
23547  };
23548
23549  var htmlEscape = createEscaper(escapeMap);
23550  var htmlUnescape = createEscaper(unescapeMap);
23551
23552  var Selectpicker = function (element, options) {
23553    // bootstrap-select has been initialized - revert valHooks.select.set back to its original function
23554    if (!valHooks.useDefault) {
23555      $.valHooks.select.set = valHooks._set;
23556      valHooks.useDefault = true;
23557    }
23558
23559    this.$element = $(element);
23560    this.$newElement = null;
23561    this.$button = null;
23562    this.$menu = null;
23563    this.$lis = null;
23564    this.options = options;
23565
23566    // If we have no title yet, try to pull it from the html title attribute (jQuery doesnt' pick it up as it's not a
23567    // data-attribute)
23568    if (this.options.title === null) {
23569      this.options.title = this.$element.attr('title');
23570    }
23571
23572    // Format window padding
23573    var winPad = this.options.windowPadding;
23574    if (typeof winPad === 'number') {
23575      this.options.windowPadding = [winPad, winPad, winPad, winPad];
23576    }
23577
23578    //Expose public methods
23579    this.val = Selectpicker.prototype.val;
23580    this.render = Selectpicker.prototype.render;
23581    this.refresh = Selectpicker.prototype.refresh;
23582    this.setStyle = Selectpicker.prototype.setStyle;
23583    this.selectAll = Selectpicker.prototype.selectAll;
23584    this.deselectAll = Selectpicker.prototype.deselectAll;
23585    this.destroy = Selectpicker.prototype.destroy;
23586    this.remove = Selectpicker.prototype.remove;
23587    this.show = Selectpicker.prototype.show;
23588    this.hide = Selectpicker.prototype.hide;
23589
23590    this.init();
23591  };
23592
23593  Selectpicker.VERSION = '1.12.4';
23594
23595  // part of this is duplicated in i18n/defaults-en_US.js. Make sure to update both.
23596  Selectpicker.DEFAULTS = {
23597    noneSelectedText: 'Nothing selected',
23598    noneResultsText: 'No results matched {0}',
23599    countSelectedText: function (numSelected, numTotal) {
23600      return (numSelected == 1) ? "{0} item selected" : "{0} items selected";
23601    },
23602    maxOptionsText: function (numAll, numGroup) {
23603      return [
23604        (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)',
23605        (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)'
23606      ];
23607    },
23608    selectAllText: 'Select All',
23609    deselectAllText: 'Deselect All',
23610    doneButton: false,
23611    doneButtonText: 'Close',
23612    multipleSeparator: ', ',
23613    styleBase: 'btn',
23614    style: 'btn-default',
23615    size: 'auto',
23616    title: null,
23617    selectedTextFormat: 'values',
23618    width: false,
23619    container: false,
23620    hideDisabled: false,
23621    showSubtext: false,
23622    showIcon: true,
23623    showContent: true,
23624    dropupAuto: true,
23625    header: false,
23626    liveSearch: false,
23627    liveSearchPlaceholder: null,
23628    liveSearchNormalize: false,
23629    liveSearchStyle: 'contains',
23630    actionsBox: false,
23631    iconBase: 'glyphicon',
23632    tickIcon: 'glyphicon-ok',
23633    showTick: false,
23634    template: {
23635      caret: '<span class="caret"></span>'
23636    },
23637    maxOptions: false,
23638    mobile: false,
23639    selectOnTab: false,
23640    dropdownAlignRight: false,
23641    windowPadding: 0
23642  };
23643
23644  Selectpicker.prototype = {
23645
23646    constructor: Selectpicker,
23647
23648    init: function () {
23649      var that = this,
23650          id = this.$element.attr('id');
23651
23652      this.$element.addClass('bs-select-hidden');
23653
23654      // store originalIndex (key) and newIndex (value) in this.liObj for fast accessibility
23655      // allows us to do this.$lis.eq(that.liObj[index]) instead of this.$lis.filter('[data-original-index="' + index + '"]')
23656      this.liObj = {};
23657      this.multiple = this.$element.prop('multiple');
23658      this.autofocus = this.$element.prop('autofocus');
23659      this.$newElement = this.createView();
23660      this.$element
23661        .after(this.$newElement)
23662        .appendTo(this.$newElement);
23663      this.$button = this.$newElement.children('button');
23664      this.$menu = this.$newElement.children('.dropdown-menu');
23665      this.$menuInner = this.$menu.children('.inner');
23666      this.$searchbox = this.$menu.find('input');
23667
23668      this.$element.removeClass('bs-select-hidden');
23669
23670      if (this.options.dropdownAlignRight === true) this.$menu.addClass('dropdown-menu-right');
23671
23672      if (typeof id !== 'undefined') {
23673        this.$button.attr('data-id', id);
23674        $('label[for="' + id + '"]').click(function (e) {
23675          e.preventDefault();
23676          that.$button.focus();
23677        });
23678      }
23679
23680      this.checkDisabled();
23681      this.clickListener();
23682      if (this.options.liveSearch) this.liveSearchListener();
23683      this.render();
23684      this.setStyle();
23685      this.setWidth();
23686      if (this.options.container) this.selectPosition();
23687      this.$menu.data('this', this);
23688      this.$newElement.data('this', this);
23689      if (this.options.mobile) this.mobile();
23690
23691      this.$newElement.on({
23692        'hide.bs.dropdown': function (e) {
23693          that.$menuInner.attr('aria-expanded', false);
23694          that.$element.trigger('hide.bs.select', e);
23695        },
23696        'hidden.bs.dropdown': function (e) {
23697          that.$element.trigger('hidden.bs.select', e);
23698        },
23699        'show.bs.dropdown': function (e) {
23700          that.$menuInner.attr('aria-expanded', true);
23701          that.$element.trigger('show.bs.select', e);
23702        },
23703        'shown.bs.dropdown': function (e) {
23704          that.$element.trigger('shown.bs.select', e);
23705        }
23706      });
23707
23708      if (that.$element[0].hasAttribute('required')) {
23709        this.$element.on('invalid', function () {
23710          that.$button.addClass('bs-invalid');
23711
23712          that.$element.on({
23713            'focus.bs.select': function () {
23714              that.$button.focus();
23715              that.$element.off('focus.bs.select');
23716            },
23717            'shown.bs.select': function () {
23718              that.$element
23719                .val(that.$element.val()) // set the value to hide the validation message in Chrome when menu is opened
23720                .off('shown.bs.select');
23721            },
23722            'rendered.bs.select': function () {
23723              // if select is no longer invalid, remove the bs-invalid class
23724              if (this.validity.valid) that.$button.removeClass('bs-invalid');
23725              that.$element.off('rendered.bs.select');
23726            }
23727          });
23728
23729          that.$button.on('blur.bs.select', function() {
23730            that.$element.focus().blur();
23731            that.$button.off('blur.bs.select');
23732          });
23733        });
23734      }
23735
23736      setTimeout(function () {
23737        that.$element.trigger('loaded.bs.select');
23738      });
23739    },
23740
23741    createDropdown: function () {
23742      // Options
23743      // If we are multiple or showTick option is set, then add the show-tick class
23744      var showTick = (this.multiple || this.options.showTick) ? ' show-tick' : '',
23745          inputGroup = this.$element.parent().hasClass('input-group') ? ' input-group-btn' : '',
23746          autofocus = this.autofocus ? ' autofocus' : '';
23747      // Elements
23748      var header = this.options.header ? '<div class="popover-title"><button type="button" class="close" aria-hidden="true">&times;</button>' + this.options.header + '</div>' : '';
23749      var searchbox = this.options.liveSearch ?
23750      '<div class="bs-searchbox">' +
23751      '<input type="text" class="form-control" autocomplete="off"' +
23752      (null === this.options.liveSearchPlaceholder ? '' : ' placeholder="' + htmlEscape(this.options.liveSearchPlaceholder) + '"') + ' role="textbox" aria-label="Search">' +
23753      '</div>'
23754          : '';
23755      var actionsbox = this.multiple && this.options.actionsBox ?
23756      '<div class="bs-actionsbox">' +
23757      '<div class="btn-group btn-group-sm btn-block">' +
23758      '<button type="button" class="actions-btn bs-select-all btn btn-default">' +
23759      this.options.selectAllText +
23760      '</button>' +
23761      '<button type="button" class="actions-btn bs-deselect-all btn btn-default">' +
23762      this.options.deselectAllText +
23763      '</button>' +
23764      '</div>' +
23765      '</div>'
23766          : '';
23767      var donebutton = this.multiple && this.options.doneButton ?
23768      '<div class="bs-donebutton">' +
23769      '<div class="btn-group btn-block">' +
23770      '<button type="button" class="btn btn-sm btn-default">' +
23771      this.options.doneButtonText +
23772      '</button>' +
23773      '</div>' +
23774      '</div>'
23775          : '';
23776      var drop =
23777          '<div class="btn-group bootstrap-select' + showTick + inputGroup + '">' +
23778          '<button type="button" class="' + this.options.styleBase + ' dropdown-toggle" data-toggle="dropdown"' + autofocus + ' role="button">' +
23779          '<span class="filter-option pull-left"></span>&nbsp;' +
23780          '<span class="bs-caret">' +
23781          this.options.template.caret +
23782          '</span>' +
23783          '</button>' +
23784          '<div class="dropdown-menu open" role="combobox">' +
23785          header +
23786          searchbox +
23787          actionsbox +
23788          '<ul class="dropdown-menu inner" role="listbox" aria-expanded="false">' +
23789          '</ul>' +
23790          donebutton +
23791          '</div>' +
23792          '</div>';
23793
23794      return $(drop);
23795    },
23796
23797    createView: function () {
23798      var $drop = this.createDropdown(),
23799          li = this.createLi();
23800
23801      $drop.find('ul')[0].innerHTML = li;
23802      return $drop;
23803    },
23804
23805    reloadLi: function () {
23806      // rebuild
23807      var li = this.createLi();
23808      this.$menuInner[0].innerHTML = li;
23809    },
23810
23811    createLi: function () {
23812      var that = this,
23813          _li = [],
23814          optID = 0,
23815          titleOption = document.createElement('option'),
23816          liIndex = -1; // increment liIndex whenever a new <li> element is created to ensure liObj is correct
23817
23818      // Helper functions
23819      /**
23820       * @param content
23821       * @param [index]
23822       * @param [classes]
23823       * @param [optgroup]
23824       * @returns {string}
23825       */
23826      var generateLI = function (content, index, classes, optgroup) {
23827        return '<li' +
23828            ((typeof classes !== 'undefined' && '' !== classes) ? ' class="' + classes + '"' : '') +
23829            ((typeof index !== 'undefined' && null !== index) ? ' data-original-index="' + index + '"' : '') +
23830            ((typeof optgroup !== 'undefined' && null !== optgroup) ? 'data-optgroup="' + optgroup + '"' : '') +
23831            '>' + content + '</li>';
23832      };
23833
23834      /**
23835       * @param text
23836       * @param [classes]
23837       * @param [inline]
23838       * @param [tokens]
23839       * @returns {string}
23840       */
23841      var generateA = function (text, classes, inline, tokens) {
23842        return '<a tabindex="0"' +
23843            (typeof classes !== 'undefined' ? ' class="' + classes + '"' : '') +
23844            (inline ? ' style="' + inline + '"' : '') +
23845            (that.options.liveSearchNormalize ? ' data-normalized-text="' + normalizeToBase(htmlEscape($(text).html())) + '"' : '') +
23846            (typeof tokens !== 'undefined' || tokens !== null ? ' data-tokens="' + tokens + '"' : '') +
23847            ' role="option">
23847' + text +
23848            '<span class="' + that.options.iconBase + ' ' + that.options.tickIcon + ' check-mark"></span>' +
23849            '</a>';
23850      };
23851
23852      if (this.options.title && !this.multiple) {
23853        // this option doesn't create a new <li> element, but does add a new option, so liIndex is decreased
23854        // since liObj is recalculated on every refresh, liIndex needs to be decreased even if the titleOption is already appended
23855        liIndex--;
23856
23857        if (!this.$element.find('.bs-title-option').length) {
23858          // Use native JS to prepend option (faster)
23859          var element = this.$element[0];
23860          titleOption.className = 'bs-title-option';
23861          titleOption.innerHTML = this.options.title;
23862          titleOption.value = '';
23863          element.insertBefore(titleOption, element.firstChild);
23864          // Check if selected or data-selected attribute is already set on an option. If not, select the titleOption option.
23865          // the selected item may have been changed by user or programmatically before the bootstrap select plugin runs,
23866          // if so, the select will have the data-selected attribute
23867          var $opt = $(element.options[element.selectedIndex]);
23868          if ($opt.attr('selected') === undefined && this.$element.data('selected') === undefined) {
23869            titleOption.selected = true;
23870          }
23871        }
23872      }
23873
23874      var $selectOptions = this.$element.find('option');
23875
23876      $selectOptions.each(function (index) {
23877        var $this = $(this);
23878
23879        liIndex++;
23880
23881        if ($this.hasClass('bs-title-option')) return;
23882
23883        // Get the class and text for the option
23884        var optionClass = this.className || '',
23885            inline = htmlEscape(this.style.cssText),
23886            text = $this.data('content') ? $this.data('content') : $this.html(),
23887            tokens = $this.data('tokens') ? $this.data('tokens') : null,
23888            subtext = typeof $this.data('subtext') !== 'undefined' ? '<small class="text-muted">' + $this.data('subtext') + '</small>' : '',
23889            icon = typeof $this.data('icon') !== 'undefined' ? '<span class="' + that.options.iconBase + ' ' + $this.data('icon') + '"></span> ' : '',
23890            $parent = $this.parent(),
23891            isOptgroup = $parent[0].tagName === 'OPTGROUP',
23892            isOptgroupDisabled = isOptgroup && $parent[0].disabled,
23893            isDisabled = this.disabled || isOptgroupDisabled,
23894            prevHiddenIndex;
23895
23896        if (icon !== '' && isDisabled) {
23897          icon = '<span>' + icon + '</span>';
23898        }
23899
23900        if (that.options.hideDisabled && (isDisabled && !isOptgroup || isOptgroupDisabled)) {
23901          // set prevHiddenIndex - the index of the first hidden option in a group of hidden options
23902          // used to determine whether or not a divider should be placed after an optgroup if there are
23903          // hidden options between the optgroup and the first visible option
23904          prevHiddenIndex = $this.data('prevHiddenIndex');
23905          $this.next().data('prevHiddenIndex', (prevHiddenIndex !== undefined ? prevHiddenIndex : index));
23906
23907          liIndex--;
23908          return;
23909        }
23910
23911        if (!$this.data('content')) {
23912          // Prepend any icon and append any subtext to the main text.
23913          text = icon + '<span class="text">' + text + subtext + '</span>';
23914        }
23915
23916        if (isOptgroup && $this.data('divider') !== true) {
23917          if (that.options.hideDisabled && isDisabled) {
23918            if ($parent.data('allOptionsDisabled') === undefined) {
23919              var $options = $parent.children();
23920              $parent.data('allOptionsDisabled', $options.filter(':disabled').length === $options.length);
23921            }
23922
23923            if ($parent.data('allOptionsDisabled')) {
23924              liIndex--;
23925              return;
23926            }
23927          }
23928
23929          var optGroupClass = ' ' + $parent[0].className || '';
23930
23931          if ($this.index() === 0) { // Is it the first option of the optgroup?
23932            optID += 1;
23933
23934            // Get the opt group label
23935            var label = $parent[0].label,
23936                labelSubtext = typeof $parent.data('subtext') !== 'undefined' ? '<small class="text-muted">' + $parent.data('subtext') + '</small>' : '',
23937                labelIcon = $parent.data('icon') ? '<span class="' + that.options.iconBase + ' ' + $parent.data('icon') + '"></span> ' : '';
23938
23939            label = labelIcon + '<span class="text">' + htmlEscape(label) + labelSubtext + '</span>';
23940
23941            if (index !== 0 && _li.length > 0) { // Is it NOT the first option of the select && are there elements in the dropdown?
23942              liIndex++;
23943              _li.push(generateLI('', null, 'divider', optID + 'div'));
23944            }
23945            liIndex++;
23946            _li.push(generateLI(label, null, 'dropdown-header' + optGroupClass, optID));
23947          }
23948
23949          if (that.options.hideDisabled && isDisabled) {
23950            liIndex--;
23951            return;
23952          }
23953
23954          _li.push(generateLI(generateA(text, 'opt ' + optionClass + optGroupClass, inline, tokens), index, '', optID));
23955        } else if ($this.data('divider') === true) {
23956          _li.push(generateLI('', index, 'divider'));
23957        } else if ($this.data('hidden') === true) {
23958          // set prevHiddenIndex - the index of the first hidden option in a group of hidden options
23959          // used to determine whether or not a divider should be placed after an optgroup if there are
23960          // hidden options between the optgroup and the first visible option
23961          prevHiddenIndex = $this.data('prevHiddenIndex');
23962          $this.next().data('prevHiddenIndex', (prevHiddenIndex !== undefined ? prevHiddenIndex : index));
23963
23964          _li.push(generateLI(generateA(text, optionClass, inline, tokens), index, 'hidden is-hidden'));
23965        } else {
23966          var showDivider = this.previousElementSibling && this.previousElementSibling.tagName === 'OPTGROUP';
23967
23968          // if previous element is not an optgroup and hideDisabled is true
23969          if (!showDivider && that.options.hideDisabled) {
23970            prevHiddenIndex = $this.data('prevHiddenIndex');
23971
23972            if (prevHiddenIndex !== undefined) {
23973              // select the element **before** the first hidden element in the group
23974              var prevHidden = $selectOptions.eq(prevHiddenIndex)[0].previousElementSibling;
23975              
23976              if (prevHidden && prevHidden.tagName === 'OPTGROUP' && !prevHidden.disabled) {
23977                showDivider = true;
23978              }
23979            }
23980          }
23981
23982          if (showDivider) {
23983            liIndex++;
23984            _li.push(generateLI('', null, 'divider', optID + 'div'));
23985          }
23986          _li.push(generateLI(generateA(text, optionClass, inline, tokens), index));
23987        }
23988
23989        that.liObj[index] = liIndex;
23990      });
23991
23992      //If we are not multiple, we don't have a selected item, and we don't have a title, select the first element so something is set in the button
23993      if (!this.multiple && this.$element.find('option:selected').length === 0 && !this.options.title) {
23994        this.$element.find('option').eq(0).prop('selected', true).attr('selected', 'selected');
23995      }
23996
23997      return _li.join('');
23998    },
23999
24000    findLis: function () {
24001      if (this.$lis == null) this.$lis = this.$menu.find('li');
24002      return this.$lis;
24003    },
24004
24005    /**
24006     * @param [updateLi] defaults to true
24007     */
24008    render: function (updateLi) {
24009      var that = this,
24010          notDisabled,
24011          $selectOptions = this.$element.find('option');
24012
24013      //Update the LI to match the SELECT
24014      if (updateLi !== false) {
24015        $selectOptions.each(function (index) {
24016          var $lis = that.findLis().eq(that.liObj[index]);
24017
24018          that.setDisabled(index, this.disabled || this.parentNode.tagName === 'OPTGROUP' && this.parentNode.disabled, $lis);
24019          that.setSelected(index, this.selected, $lis);
24020        });
24021      }
24022
24023      this.togglePlaceholder();
24024
24025      this.tabIndex();
24026
24027      var selectedItems = $selectOptions.map(function () {
24028        if (this.selected) {
24029          if (that.options.hideDisabled && (this.disabled || this.parentNode.tagName === 'OPTGROUP' && this.parentNode.disabled)) return;
24030
24031          var $this = $(this),
24032              icon = $this.data('icon') && that.options.showIcon ? '<i class="' + that.options.iconBase + ' ' + $this.data('icon') + '"></i> ' : '',
24033              subtext;
24034
24035          if (that.options.showSubtext && $this.data('subtext') && !that.multiple) {
24036            subtext = ' <small class="text-muted">' + $this.data('subtext') + '</small>';
24037          } else {
24038            subtext = '';
24039          }
24040          if (typeof $this.attr('title') !== 'undefined') {
24041            return $this.attr('title');
24042          } else if ($this.data('content') && that.options.showContent) {
24043            return $this.data('content').toString();
24044          } else {
24045            return icon + $this.html() + subtext;
24046          }
24047        }
24048      }).toArray();
24049
24050      //Fixes issue in IE10 occurring when no default option is selected and at least one option is disabled
24051      //Convert all the values into a comma delimited string
24052      var title = !this.multiple ? selectedItems[0] : selectedItems.join(this.options.multipleSeparator);
24053
24054      //If this is multi select, and the selectText type is count, the show 1 of 2 selected etc..
24055      if (this.multiple && this.options.selectedTextFormat.indexOf('count') > -1) {
24056        var max = this.options.selectedTextFormat.split('>');
24057        if ((max.length > 1 && selectedItems.length > max[1]) || (max.length == 1 && selectedItems.length >= 2)) {
24058          notDisabled = this.options.hideDisabled ? ', [disabled]' : '';
24059          var totalCount = $selectOptions.not('[data-divider="true"], [data-hidden="true"]' + notDisabled).length,
24060              tr8nText = (typeof this.options.countSelectedText === 'function') ? this.options.countSelectedText(selectedItems.length, totalCount) : this.options.countSelectedText;
24061          title = tr8nText.replace('{0}', selectedItems.length.toString()).replace('{1}', totalCount.toString());
24062        }
24063      }
24064
24065      if (this.options.title == undefined) {
24066        this.options.title = this.$element.attr('title');
24067      }
24068
24069      if (this.options.selectedTextFormat == 'static') {
24070        title = this.options.title;
24071      }
24072
24073      //If we dont have a title, then use the default, or if nothing is set at all, use the not selected text
24074      if (!title) {
24075        title = typeof this.options.title !== 'undefined' ? this.options.title : this.options.noneSelectedText;
24076      }
24077
24078      //strip all HTML tags and trim the result, then unescape any escaped tags
24079      this.$button.attr('title', htmlUnescape($.trim(title.replace(/<[^>]*>?/g, ''))));
24080      this.$button.children('.filter-option').html(title);
24081
24082      this.$element.trigger('rendered.bs.select');
24083    },
24084
24085    /**
24086     * @param [style]
24087     * @param [status]
24088     */
24089    setStyle: function (style, status) {
24090      if (this.$element.attr('class')) {
24091        this.$newElement.addClass(this.$element.attr('class').replace(/selectpicker|mobile-device|bs-select-hidden|validate\[.*\]/gi, ''));
24092      }
24093
24094      var buttonClass = style ? style : this.options.style;
24095
24096      if (status == 'add') {
24097        this.$button.addClass(buttonClass);
24098      } else if (status == 'remove') {
24099        this.$button.removeClass(buttonClass);
24100      } else {
24101        this.$button.removeClass(this.options.style);
24102        this.$button.addClass(buttonClass);
24103      }
24104    },
24105
24106    liHeight: function (refresh) {
24107      if (!refresh && (this.options.size === false || this.sizeInfo)) return;
24108
24109      var newElement = document.createElement('div'),
24110          menu = document.createElement('div'),
24111          menuInner = document.createElement('ul'),
24112          divider = document.createElement('li'),
24113          li = document.createElement('li'),
24114          a = document.createElement('a'),
24115          text = document.createElement('span'),
24116          header = this.options.header && this.$menu.find('.popover-title').length > 0 ? this.$menu.find('.popover-title')[0].cloneNode(true) : null,
24117          search = this.options.liveSearch ? document.createElement('div') : null,
24118          actions = this.options.actionsBox && this.multiple && this.$menu.find('.bs-actionsbox').length > 0 ? this.$menu.find('.bs-actionsbox')[0].cloneNode(true) : null,
24119          doneButton = this.options.doneButton && this.multiple && this.$menu.find('.bs-donebutton').length > 0 ? this.$menu.find('.bs-donebutton')[0].cloneNode(true) : null;
24120
24121      text.className = 'text';
24122      newElement.className = this.$menu[0].parentNode.className + ' open';
24123      menu.className = 'dropdown-menu open';
24124      menuInner.className = 'dropdown-menu inner';
24125      divider.className = 'divider';
24126
24127      text.appendChild(document.createTextNode('Inner text'));
24128      a.appendChild(text);
24129      li.appendChild(a);
24130      menuInner.appendChild(li);
24131      menuInner.appendChild(divider);
24132      if (header) menu.appendChild(header);
24133      if (search) {
24134        var input = document.createElement('input');
24135        search.className = 'bs-searchbox';
24136        input.className = 'form-control';
24137        search.appendChild(input);
24138        menu.appendChild(search);
24139      }
24140      if (actions) menu.appendChild(actions);
24141      menu.appendChild(menuInner);
24142      if (doneButton) menu.appendChild(doneButton);
24143      newElement.appendChild(menu);
24144
24145      document.body.appendChild(newElement);
24146
24147      var liHeight = a.offsetHeight,
24148          headerHeight = header ? header.offsetHeight : 0,
24149          searchHeight = search ? search.offsetHeight : 0,
24150          actionsHeight = actions ? actions.offsetHeight : 0,
24151          doneButtonHeight = doneButton ? doneButton.offsetHeight : 0,
24152          dividerHeight = $(divider).outerHeight(true),
24153          // fall back to jQuery if getComputedStyle is not supported
24154          menuStyle = typeof getComputedStyle === 'function' ? getComputedStyle(menu) : false,
24155          $menu = menuStyle ? null : $(menu),
24156          menuPadding = {
24157            vert: parseInt(menuStyle ? menuStyle.paddingTop : $menu.css('paddingTop')) +
24158                  parseInt(menuStyle ? menuStyle.paddingBottom : $menu.css('paddingBottom')) +
24159                  parseInt(menuStyle ? menuStyle.borderTopWidth : $menu.css('borderTopWidth')) +
24160                  parseInt(menuStyle ? menuStyle.borderBottomWidth : $menu.css('borderBottomWidth')),
24161            horiz: parseInt(menuStyle ? menuStyle.paddingLeft : $menu.css('paddingLeft')) +
24162                  parseInt(menuStyle ? menuStyle.paddingRight : $menu.css('paddingRight')) +
24163                  parseInt(menuStyle ? menuStyle.borderLeftWidth : $menu.css('borderLeftWidth')) +
24164                  parseInt(menuStyle ? menuStyle.borderRightWidth : $menu.css('borderRightWidth'))
24165          },
24166          menuExtras =  {
24167            vert: menuPadding.vert +
24168                  parseInt(menuStyle ? menuStyle.marginTop : $menu.css('marginTop')) +
24169                  parseInt(menuStyle ? menuStyle.marginBottom : $menu.css('marginBottom')) + 2,
24170            horiz: menuPadding.horiz +
24171                  parseInt(menuStyle ? menuStyle.marginLeft : $menu.css('marginLeft')) +
24172                  parseInt(menuStyle ? menuStyle.marginRight : $menu.css('marginRight')) + 2
24173          }
24174
24175      document.body.removeChild(newElement);
24176
24177      this.sizeInfo = {
24178        liHeight: liHeight,
24179        headerHeight: headerHeight,
24180        searchHeight: searchHeight,
24181        actionsHeight: actionsHeight,
24182        doneButtonHeight: doneButtonHeight,
24183        dividerHeight: dividerHeight,
24184        menuPadding: menuPadding,
24185        menuExtras: menuExtras
24186      };
24187    },
24188
24189    setSize: function () {
24190      this.findLis();
24191      this.liHeight();
24192
24193      if (this.options.header) this.$menu.css('padding-top', 0);
24194      if (this.options.size === false) return;
24195
24196      var that = this,
24197          $menu = this.$menu,
24198          $menuInner = this.$menuInner,
24199          $window = $(window),
24200          selectHeight = this.$newElement[0].offsetHeight,
24201          selectWidth = this.$newElement[0].offsetWidth,
24202          liHeight = this.sizeInfo['liHeight'],
24203          headerHeight = this.sizeInfo['headerHeight'],
24204          searchHeight = this.sizeInfo['searchHeight'],
24205          actionsHeight = this.sizeInfo['actionsHeight'],
24206          doneButtonHeight = this.sizeInfo['doneButtonHeight'],
24207          divHeight = this.sizeInfo['dividerHeight'],
24208          menuPadding = this.sizeInfo['menuPadding'],
24209          menuExtras = this.sizeInfo['menuExtras'],
24210          notDisabled = this.options.hideDisabled ? '.disabled' : '',
24211          menuHeight,
24212          menuWidth,
24213          getHeight,
24214          getWidth,
24215          selectOffsetTop,
24216          selectOffsetBot,
24217          selectOffsetLeft,
24218          selectOffsetRight,
24219          getPos = function() {
24220            var pos = that.$newElement.offset(),
24221                $container = $(that.options.container),
24222                containerPos;
24223
24224            if (that.options.container && !$container.is('body')) {
24225              containerPos = $container.offset();
24226              containerPos.top += parseInt($container.css('borderTopWidth'));
24227              containerPos.left += parseInt($container.css('borderLeftWidth'));
24228            } else {
24229              containerPos = { top: 0, left: 0 };
24230            }
24231
24232            var winPad = that.options.windowPadding;
24233            selectOffsetTop = pos.top - containerPos.top - $window.scrollTop();
24234            selectOffsetBot = $window.height() - selectOffsetTop - selectHeight - containerPos.top - winPad[2];
24235            selectOffsetLeft = pos.left - containerPos.left - $window.scrollLeft();
24236            selectOffsetRight = $window.width() - selectOffsetLeft - selectWidth - containerPos.left - winPad[1];
24237            selectOffsetTop -= winPad[0];
24238            selectOffsetLeft -= winPad[3];
24239          };
24240
24241      getPos();
24242
24243      if (this.options.size === 'auto') {
24244        var getSize = function () {
24245          var minHeight,
24246              hasClass = function (className, include) {
24247                return function (element) {
24248                    if (include) {
24249                        return (element.classList ? element.classList.contains(className) : $(element).hasClass(className));
24250                    } else {
24251                        return !(element.classList ? element.classList.contains(className) : $(element).hasClass(className));
24252                    }
24253                };
24254              },
24255              lis = that.$menuInner[0].getElementsByTagName('li'),
24256              lisVisible = Array.prototype.filter ? Array.prototype.filter.call(lis, hasClass('hidden', false)) : that.$lis.not('.hidden'),
24257              optGroup = Array.prototype.filter ? Array.prototype.filter.call(lisVisible, hasClass('dropdown-header', true)) : lisVisible.filter('.dropdown-header');
24258
24259          getPos();
24260          menuHeight = selectOffsetBot - menuExtras.vert;
24261          menuWidth = selectOffsetRight - menuExtras.horiz;
24262
24263          if (that.options.container) {
24264            if (!$menu.data('height')) $menu.data('height', $menu.height());
24265            getHeight = $menu.data('height');
24266
24267            if (!$menu.data('width')) $menu.data('width', $menu.width());
24268            getWidth = $menu.data('width');
24269          } else {
24270            getHeight = $menu.height();
24271            getWidth = $menu.width();
24272          }
24273
24274          if (that.options.dropupAuto) {
24275            that.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras.vert) < getHeight);
24276          }
24277
24278          if (that.$newElement.hasClass('dropup')) {
24279            menuHeight = selectOffsetTop - menuExtras.vert;
24280          }
24281
24282          if (that.options.dropdownAlignRight === 'auto') {
24283            $menu.toggleClass('dropdown-menu-right', selectOffsetLeft > selectOffsetRight && (menuWidth - menuExtras.horiz) < (getWidth - selectWidth));
24284          }
24285
24286          if ((lisVisible.length + optGroup.length) > 3) {
24287            minHeight = liHeight * 3 + menuExtras.vert - 2;
24288          } else {
24289            minHeight = 0;
24290          }
24291
24292          $menu.css({
24293            'max-height': menuHeight + 'px',
24294            'overflow': 'hidden',
24295            'min-height': minHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px'
24296          });
24297          $menuInner.css({
24298            'max-height': menuHeight - headerHeight - searchHeight - actionsHeight - doneButtonHeight - menuPadding.vert + 'px',
24299            'overflow-y': 'auto',
24300            'min-height': Math.max(minHeight - menuPadding.vert, 0) + 'px'
24301          });
24302        };
24303        getSize();
24304        this.$searchbox.off('input.getSize propertychange.getSize').on('input.getSize propertychange.getSize', getSize);
24305        $window.off('resize.getSize scroll.getSize').on('resize.getSize scroll.getSize', getSize);
24306      } else if (this.options.size && this.options.size != 'auto' && this.$lis.not(notDisabled).length > this.options.size) {
24307        var optIndex = this.$lis.not('.divider').not(notDisabled).children().slice(0, this.options.size).last().parent().index(),
24308            divLength = this.$lis.slice(0, optIndex + 1).filter('.divider').length;
24309        menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding.vert;
24310
24311        if (that.options.container) {
24312          if (!$menu.data('height')) $menu.data('height', $menu.height());
24313          getHeight = $menu.data('height');
24314        } else {
24315          getHeight = $menu.height();
24316        }
24317
24318        if (that.options.dropupAuto) {
24319          //noinspection JSUnusedAssignment
24320          this.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras.vert) < getHeight);
24321        }
24322        $menu.css({
24323          'max-height': menuHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px',
24324          'overflow': 'hidden',
24325          'min-height': ''
24326        });
24327        $menuInner.css({
24328          'max-height': menuHeight - menuPadding.vert + 'px',
24329          'overflow-y': 'auto',
24330          'min-height': ''
24331        });
24332      }
24333    },
24334
24335    setWidth: function () {
24336      if (this.options.width === 'auto') {
24337        this.$menu.css('min-width', '0');
24338
24339        // Get correct width if element is hidden
24340        var $selectClone = this.$menu.parent().clone().appendTo('body'),
24341            $selectClone2 = this.options.container ? this.$newElement.clone().appendTo('body') : $selectClone,
24342            ulWidth = $selectClone.children('.dropdown-menu').outerWidth(),
24343            btnWidth = $selectClone2.css('width', 'auto').children('button').outerWidth();
24344
24345        $selectClone.remove();
24346        $selectClone2.remove();
24347
24348        // Set width to whatever's larger, button title or longest option
24349        this.$newElement.css('width', Math.max(ulWidth, btnWidth) + 'px');
24350      } else if (this.options.width === 'fit') {
24351        // Remove inline min-width so width can be changed from 'auto'
24352        this.$menu.css('min-width', '');
24353        this.$newElement.css('width', '').addClass('fit-width');
24354      } else if (this.options.width) {
24355        // Remove inline min-width so width can be changed from 'auto'
24356        this.$menu.css('min-width', '');
24357        this.$newElement.css('width', this.options.width);
24358      } else {
24359        // Remove inline min-width/width so width can be changed
24360        this.$menu.css('min-width', '');
24361        this.$newElement.css('width', '');
24362      }
24363      // Remove fit-width class if width is changed programmatically
24364      if (this.$newElement.hasClass('fit-width') && this.options.width !== 'fit') {
24365        this.$newElement.removeClass('fit-width');
24366      }
24367    },
24368
24369    selectPosition: function () {
24370      this.$bsContainer = $('<div class="bs-container" />');
24371
24372      var that = this,
24373          $container = $(this.options.container),
24374          pos,
24375          containerPos,
24376          actualHeight,
24377          getPlacement = function ($element) {
24378            that.$bsContainer.addClass($element.attr('class').replace(/form-control|fit-width/gi, '')).toggleClass('dropup', $element.hasClass('dropup'));
24379            pos = $element.offset();
24380
24381            if (!$container.is('body')) {
24382              containerPos = $container.offset();
24383              containerPos.top += parseInt($container.css('borderTopWidth')) - $container.scrollTop();
24384              containerPos.left += parseInt($container.css('borderLeftWidth')) - $container.scrollLeft();
24385            } else {
24386              containerPos = { top: 0, left: 0 };
24387            }
24388
24389            actualHeight = $element.hasClass('dropup') ? 0 : $element[0].offsetHeight;
24390
24391            that.$bsContainer.css({
24392              'top': pos.top - containerPos.top + actualHeight,
24393              'left': pos.left - containerPos.left,
24394              'width': $element[0].offsetWidth
24395            });
24396          };
24397
24398      this.$button.on('click', function () {
24399        var $this = $(this);
24400
24401        if (that.isDisabled()) {
24402          return;
24403        }
24404
24405        getPlacement(that.$newElement);
24406
24407        that.$bsContainer
24408          .appendTo(that.options.container)
24409          .toggleClass('open', !$this.hasClass('open'))
24410          .append(that.$menu);
24411      });
24412
24413      $(window).on('resize scroll', function () {
24414        getPlacement(that.$newElement);
24415      });
24416
24417      this.$element.on('hide.bs.select', function () {
24418        that.$menu.data('height', that.$menu.height());
24419        that.$bsContainer.detach();
24420      });
24421    },
24422
24423    /**
24424     * @param {number} index - the index of the option that is being changed
24425     * @param {boolean} selected - true if the option is being selected, false if being deselected
24426     * @param {JQuery} $lis - the 'li' element that is being modified
24427     */
24428    setSelected: function (index, selected, $lis) {
24429      if (!$lis) {
24430        this.togglePlaceholder(); // check if setSelected is being called by changing the value of the select
24431        $lis = this.findLis().eq(this.liObj[index]);
24432      }
24433
24434      $lis.toggleClass('selected', selected).find('a').attr('aria-selected', selected);
24435    },
24436
24437    /**
24438     * @param {number} index - the index of the option that is being disabled
24439     * @param {boolean} disabled - true if the option is being disabled, false if being enabled
24440     * @param {JQuery} $lis - the 'li' element that is being modified
24441     */
24442    setDisabled: function (index, disabled, $lis) {
24443      if (!$lis) {
24444        $lis = this.findLis().eq(this.liObj[index]);
24445      }
24446
24447      if (disabled) {
24448        $lis.addClass('disabled').children('a').attr('href', '#').attr('tabindex', -1).attr('aria-disabled', true);
24449      } else {
24450        $lis.removeClass('disabled').children('a').removeAttr('href').attr('tabindex', 0).attr('aria-disabled', false);
24451      }
24452    },
24453
24454    isDisabled: function () {
24455      return this.$element[0].disabled;
24456    },
24457
24458    checkDisabled: function () {
24459      var that = this;
24460
24461      if (this.isDisabled()) {
24462        this.$newElement.addClass('disabled');
24463        this.$button.addClass('disabled').attr('tabindex', -1).attr('aria-disabled', true);
24464      } else {
24465        if (this.$button.hasClass('disabled')) {
24466          this.$newElement.removeClass('disabled');
24467          this.$button.removeClass('disabled').attr('aria-disabled', false);
24468        }
24469
24470        if (this.$button.attr('tabindex') == -1 && !this.$element.data('tabindex')) {
24471          this.$button.removeAttr('tabindex');
24472        }
24473      }
24474
24475      this.$button.click(function () {
24476        return !that.isDisabled();
24477      });
24478    },
24479
24480    togglePlaceholder: function () {
24481      var value = this.$element.val();
24482      this.$button.toggleClass('bs-placeholder', value === null || value === '' || (value.constructor === Array && value.length === 0));
24483    },
24484
24485    tabIndex: function () {
24486      if (this.$element.data('tabindex') !== this.$element.attr('tabindex') && 
24487        (this.$element.attr('tabindex') !== -98 && this.$element.attr('tabindex') !== '-98')) {
24488        this.$element.data('tabindex', this.$element.attr('tabindex'));
24489        this.$button.attr('tabindex', this.$element.data('tabindex'));
24490      }
24491
24492      this.$element.attr('tabindex', -98);
24493    },
24494
24495    clickListener: function () {
24496      var that = this,
24497          $document = $(document);
24498
24499      $document.data('spaceSelect', false);
24500
24501      this.$button.on('keyup', function (e) {
24502        if (/(32)/.test(e.keyCode.toString(10)) && $document.data('spaceSelect')) {
24503            e.preventDefault();
24504            $document.data('spaceSelect', false);
24505        }
24506      });
24507
24508      this.$button.on('click', function () {
24509        that.setSize();
24510      });
24511
24512      this.$element.on('shown.bs.select', function () {
24513        if (!that.options.liveSearch && !that.multiple) {
24514          that.$menuInner.find('.selected a').focus();
24515        } else if (!that.multiple) {
24516          var selectedIndex = that.liObj[that.$element[0].selectedIndex];
24517
24518          if (typeof selectedIndex !== 'number' || that.options.size === false) return;
24519
24520          // scroll to selected option
24521          var offset = that.$lis.eq(selectedIndex)[0].offsetTop - that.$menuInner[0].offsetTop;
24522          offset = offset - that.$menuInner[0].offsetHeight/2 + that.sizeInfo.liHeight/2;
24523          that.$menuInner[0].scrollTop = offset;
24524        }
24525      });
24526
24527      this.$menuInner.on('click', 'li a', function (e) {
24528        var $this = $(this),
24529            clickedIndex = $this.parent().data('originalIndex'),
24530            prevValue = that.$element.val(),
24531            prevIndex = that.$element.prop('selectedIndex'),
24532            triggerChange = true;
24533
24534        // Don't close on multi choice menu
24535        if (that.multiple && that.options.maxOptions !== 1) {
24536          e.stopPropagation();
24537        }
24538
24539        e.preventDefault();
24540
24541        //Don't run if we have been disabled
24542        if (!that.isDisabled() && !$this.parent().hasClass('disabled')) {
24543          var $options = that.$element.find('option'),
24544              $option = $options.eq(clickedIndex),
24545              state = $option.prop('selected'),
24546              $optgroup = $option.parent('optgroup'),
24547              maxOptions = that.options.maxOptions,
24548              maxOptionsGrp = $optgroup.data('maxOptions') || false;
24549
24550          if (!that.multiple) { // Deselect all others if not multi select box
24551            $options.prop('selected', false);
24552            $option.prop('selected', true);
24553            that.$menuInner.find('.selected').removeClass('selected').find('a').attr('aria-selected', false);
24554            that.setSelected(clickedIndex, true);
24555          } else { // Toggle the one we have chosen if we are multi select.
24556            $option.prop('selected', !state);
24557            that.setSelected(clickedIndex, !state);
24558            $this.blur();
24559
24560            if (maxOptions !== false || maxOptionsGrp !== false) {
24561              var maxReached = maxOptions < $options.filter(':selected').length,
24562                  maxReachedGrp = maxOptionsGrp < $optgroup.find('option:selected').length;
24563
24564              if ((maxOptions && maxReached) || (maxOptionsGrp && maxReachedGrp)) {
24565                if (maxOptions && maxOptions == 1) {
24566                  $options.prop('selected', false);
24567                  $option.prop('selected', true);
24568                  that.$menuInner.find('.selected').removeClass('selected');
24569                  that.setSelected(clickedIndex, true);
24570                } else if (maxOptionsGrp && maxOptionsGrp == 1) {
24571                  $optgroup.find('option:selected').prop('selected', false);
24572                  $option.prop('selected', true);
24573                  var optgroupID = $this.parent().data('optgroup');
24574                  that.$menuInner.find('[data-optgroup="' + optgroupID + '"]').removeClass('selected');
24575                  that.setSelected(clickedIndex, true);
24576                } else {
24577                  var maxOptionsText = typeof that.options.maxOptionsText === 'string' ? [that.options.maxOptionsText, that.options.maxOptionsText] : that.options.maxOptionsText,
24578                      maxOptionsArr = typeof maxOptionsText === 'function' ? maxOptionsText(maxOptions, maxOptionsGrp) : maxOptionsText,
24579                      maxTxt = maxOptionsArr[0].replace('{n}', maxOptions),
24580                      maxTxtGrp = maxOptionsArr[1].replace('{n}', maxOptionsGrp),
24581                      $notify = $('<div class="notify"></div>');
24582                  // If {var} is set in array, replace it
24583                  /** @deprecated */
24584                  if (maxOptionsArr[2]) {
24585                    maxTxt = maxTxt.replace('{var}', maxOptionsArr[2][maxOptions > 1 ? 0 : 1]);
24586                    maxTxtGrp = maxTxtGrp.replace('{var}', maxOptionsArr[2][maxOptionsGrp > 1 ? 0 : 1]);
24587                  }
24588
24589                  $option.prop('selected', false);
24590
24591                  that.$menu.append($notify);
24592
24593                  if (maxOptions && maxReached) {
24594                    $notify.append($('<div>' + maxTxt + '</div>'));
24595                    triggerChange = false;
24596                    that.$element.trigger('maxReached.bs.select');
24597                  }
24598
24599                  if (maxOptionsGrp && maxReachedGrp) {
24600                    $notify.append($('<div>' + maxTxtGrp + '</div>'));
24601                    triggerChange = false;
24602                    that.$element.trigger('maxReachedGrp.bs.select');
24603                  }
24604
24605                  setTimeout(function () {
24606                    that.setSelected(clickedIndex, false);
24607                  }, 10);
24608
24609                  $notify.delay(750).fadeOut(300, function () {
24610                    $(this).remove();
24611                  });
24612                }
24613              }
24614            }
24615          }
24616
24617          if (!that.multiple || (that.multiple && that.options.maxOptions === 1)) {
24618            that.$button.focus();
24619          } else if (that.options.liveSearch) {
24620            that.$searchbox.focus();
24621          }
24622
24623          // Trigger select 'change'
24624          if (triggerChange) {
24625            if ((prevValue != that.$element.val() && that.multiple) || (prevIndex != that.$element.prop('selectedIndex') && !that.multiple)) {
24626              // $option.prop('selected') is current option state (selected/unselected). state is previous option state.
24627              changed_arguments = [clickedIndex, $option.prop('selected'), state];
24628              that.$element
24629                .triggerNative('change');
24630            }
24631          }
24632        }
24633      });
24634
24635      this.$menu.on('click', 'li.disabled a, .popover-title, .popover-title :not(.close)', function (e) {
24636        if (e.currentTarget == this) {
24637          e.preventDefault();
24638          e.stopPropagation();
24639          if (that.options.liveSearch && !$(e.target).hasClass('close')) {
24640            that.$searchbox.focus();
24641          } else {
24642            that.$button.focus();
24643          }
24644        }
24645      });
24646
24647      this.$menuInner.on('click', '.divider, .dropdown-header', function (e) {
24648        e.preventDefault();
24649        e.stopPropagation();
24650        if (that.options.liveSearch) {
24651          that.$searchbox.focus();
24652        } else {
24653          that.$button.focus();
24654        }
24655      });
24656
24657      this.$menu.on('click', '.popover-title .close', function () {
24658        that.$button.click();
24659      });
24660
24661      this.$searchbox.on('click', function (e) {
24662        e.stopPropagation();
24663      });
24664
24665      this.$menu.on('click', '.actions-btn', function (e) {
24666        if (that.options.liveSearch) {
24667          that.$searchbox.focus();
24668        } else {
24669          that.$button.focus();
24670        }
24671
24672        e.preventDefault();
24673        e.stopPropagation();
24674
24675        if ($(this).hasClass('bs-select-all')) {
24676          that.selectAll();
24677        } else {
24678          that.deselectAll();
24679        }
24680      });
24681
24682      this.$element.change(function () {
24683        that.render(false);
24684        that.$element.trigger('changed.bs.select', changed_arguments);
24685        changed_arguments = null;
24686      });
24687    },
24688
24689    liveSearchListener: function () {
24690      var that = this,
24691          $no_results = $('<li class="no-results"></li>');
24692
24693      this.$button.on('click.dropdown.data-api', function () {
24694        that.$menuInner.find('.active').removeClass('active');
24695        if (!!that.$searchbox.val()) {
24696          that.$searchbox.val('');
24697          that.$lis.not('.is-hidden').removeClass('hidden');
24698          if (!!$no_results.parent().length) $no_results.remove();
24699        }
24700        if (!that.multiple) that.$menuInner.find('.selected').addClass('active');
24701        setTimeout(function () {
24702          that.$searchbox.focus();
24703        }, 10);
24704      });
24705
24706      this.$searchbox.on('click.dropdown.data-api focus.dropdown.data-api touchend.dropdown.data-api', function (e) {
24707        e.stopPropagation();
24708      });
24709
24710      this.$searchbox.on('input propertychange', function () {
24711        that.$lis.not('.is-hidden').removeClass('hidden');
24712        that.$lis.filter('.active').removeClass('active');
24713        $no_results.remove();
24714
24715        if (that.$searchbox.val()) {
24716          var $searchBase = that.$lis.not('.is-hidden, .divider, .dropdown-header'),
24717              $hideItems;
24718          if (that.options.liveSearchNormalize) {
24719            $hideItems = $searchBase.not(':a' + that._searchStyle() + '("' + normalizeToBase(that.$searchbox.val()) + '")');
24720          } else {
24721            $hideItems = $searchBase.not(':' + that._searchStyle() + '("' + that.$searchbox.val() + '")');
24722          }
24723
24724          if ($hideItems.length === $searchBase.length) {
24725            $no_results.html(that.options.noneResultsText.replace('{0}', '"' + htmlEscape(that.$searchbox.val()) + '"'));
24726            that.$menuInner.append($no_results);
24727            that.$lis.addClass('hidden');
24728          } else {
24729            $hideItems.addClass('hidden');
24730
24731            var $lisVisible = that.$lis.not('.hidden'),
24732                $foundDiv;
24733
24734            // hide divider if first or last visible, or if followed by another divider
24735            $lisVisible.each(function (index) {
24736              var $this = $(this);
24737
24738              if ($this.hasClass('divider')) {
24739                if ($foundDiv === undefined) {
24740                  $this.addClass('hidden');
24741                } else {
24742                  if ($foundDiv) $foundDiv.addClass('hidden');
24743                  $foundDiv = $this;
24744                }
24745              } else if ($this.hasClass('dropdown-header') && $lisVisible.eq(index + 1).data('optgroup') !== $this.data('optgroup')) {
24746                $this.addClass('hidden');
24747              } else {
24748                $foundDiv = null;
24749              }
24750            });
24751            if ($foundDiv) $foundDiv.addClass('hidden');
24752
24753            $searchBase.not('.hidden').first().addClass('active');
24754            that.$menuInner.scrollTop(0);
24755          }
24756        }
24757      });
24758    },
24759
24760    _searchStyle: function () {
24761      var styles = {
24762        begins: 'ibegins',
24763        startsWith: 'ibegins'
24764      };
24765
24766      return styles[this.options.liveSearchStyle] || 'icontains';
24767    },
24768
24769    val: function (value) {
24770      if (typeof value !== 'undefined') {
24771        this.$element.val(value);
24772        this.render();
24773
24774        return this.$element;
24775      } else {
24776        return this.$element.val();
24777      }
24778    },
24779
24780    changeAll: function (status) {
24781      if (!this.multiple) return;
24782      if (typeof status === 'undefined') status = true;
24783
24784      this.findLis();
24785
24786      var $options = this.$element.find('option'),
24787          $lisVisible = this.$lis.not('.divider, .dropdown-header, .disabled, .hidden'),
24788          lisVisLen = $lisVisible.length,
24789          selectedOptions = [];
24790          
24791      if (status) {
24792        if ($lisVisible.filter('.selected').length === $lisVisible.length) return;
24793      } else {
24794        if ($lisVisible.filter('.selected').length === 0) return;
24795      }
24796          
24797      $lisVisible.toggleClass('selected', status);
24798
24799      for (var 
24799i = 0; i < lisVisLen; i++) {
24800        var origIndex = $lisVisible[i].getAttribute('data-original-index');
24801        selectedOptions[selectedOptions.length] = $options.eq(origIndex)[0];
24802      }
24803
24804      $(selectedOptions).prop('selected', status);
24805
24806      this.render(false);
24807
24808      this.togglePlaceholder();
24809
24810      this.$element
24811        .triggerNative('change');
24812    },
24813
24814    selectAll: function () {
24815      return this.changeAll(true);
24816    },
24817
24818    deselectAll: function () {
24819      return this.changeAll(false);
24820    },
24821
24822    toggle: function (e) {
24823      e = e || window.event;
24824
24825      if (e) e.stopPropagation();
24826
24827      this.$button.trigger('click');
24828    },
24829
24830    keydown: function (e) {
24831      var $this = $(this),
24832          $parent = $this.is('input') ? $this.parent().parent() : $this.parent(),
24833          $items,
24834          that = $parent.data('this'),
24835          index,
24836          prevIndex,
24837          isActive,
24838          selector = ':not(.disabled, .hidden, .dropdown-header, .divider)',
24839          keyCodeMap = {
24840            32: ' ',
24841            48: '0',
24842            49: '1',
24843            50: '2',
24844            51: '3',
24845            52: '4',
24846            53: '5',
24847            54: '6',
24848            55: '7',
24849            56: '8',
24850            57: '9',
24851            59: ';',
24852            65: 'a',
24853            66: 'b',
24854            67: 'c',
24855            68: 'd',
24856            69: 'e',
24857            70: 'f',
24858            71: 'g',
24859            72: 'h',
24860            73: 'i',
24861            74: 'j',
24862            75: 'k',
24863            76: 'l',
24864            77: 'm',
24865            78: 'n',
24866            79: 'o',
24867            80: 'p',
24868            81: 'q',
24869            82: 'r',
24870            83: 's',
24871            84: 't',
24872            85: 'u',
24873            86: 'v',
24874            87: 'w',
24875            88: 'x',
24876            89: 'y',
24877            90: 'z',
24878            96: '0',
24879            97: '1',
24880            98: '2',
24881            99: '3',
24882            100: '4',
24883            101: '5',
24884            102: '6',
24885            103: '7',
24886            104: '8',
24887            105: '9'
24888          };
24889
24890
24891      isActive = that.$newElement.hasClass('open');
24892
24893      if (!isActive && (e.keyCode >= 48 && e.keyCode <= 57 || e.keyCode >= 96 && e.keyCode <= 105 || e.keyCode >= 65 && e.keyCode <= 90)) {
24894        if (!that.options.container) {
24895          that.setSize();
24896          that.$menu.parent().addClass('open');
24897          isActive = true;
24898        } else {
24899          that.$button.trigger('click');
24900        }
24901        that.$searchbox.focus();
24902        return;
24903      }
24904
24905      if (that.options.liveSearch) {
24906        if (/(^9$|27)/.test(e.keyCode.toString(10)) && isActive) {
24907          e.preventDefault();
24908          e.stopPropagation();
24909          that.$menuInner.click();
24910          that.$button.focus();
24911        }
24912      }
24913
24914      if (/(38|40)/.test(e.keyCode.toString(10))) {
24915        $items = that.$lis.filter(selector);
24916        if (!$items.length) return;
24917
24918        if (!that.options.liveSearch) {
24919          index = $items.index($items.find('a').filter(':focus').parent());
24920	    } else {
24921          index = $items.index($items.filter('.active'));
24922        }
24923
24924        prevIndex = that.$menuInner.data('prevIndex');
24925
24926        if (e.keyCode == 38) {
24927          if ((that.options.liveSearch || index == prevIndex) && index != -1) index--;
24928          if (index < 0) index += $items.length;
24929        } else if (e.keyCode == 40) {
24930          if (that.options.liveSearch || index == prevIndex) index++;
24931          index = index % $items.length;
24932        }
24933
24934        that.$menuInner.data('prevIndex', index);
24935
24936        if (!that.options.liveSearch) {
24937          $items.eq(index).children('a').focus();
24938        } else {
24939          e.preventDefault();
24940          if (!$this.hasClass('dropdown-toggle')) {
24941            $items.removeClass('active').eq(index).addClass('active').children('a').focus();
24942            $this.focus();
24943          }
24944        }
24945
24946      } else if (!$this.is('input')) {
24947        var keyIndex = [],
24948            count,
24949            prevKey;
24950
24951        $items = that.$lis.filter(selector);
24952        $items.each(function (i) {
24953          if ($.trim($(this).children('a').text().toLowerCase()).substring(0, 1) == keyCodeMap[e.keyCode]) {
24954            keyIndex.push(i);
24955          }
24956        });
24957
24958        count = $(document).data('keycount');
24959        count++;
24960        $(document).data('keycount', count);
24961
24962        prevKey = $.trim($(':focus').text().toLowerCase()).substring(0, 1);
24963
24964        if (prevKey != keyCodeMap[e.keyCode]) {
24965          count = 1;
24966          $(document).data('keycount', count);
24967        } else if (count >= keyIndex.length) {
24968          $(document).data('keycount', 0);
24969          if (count > keyIndex.length) count = 1;
24970        }
24971
24972        $items.eq(keyIndex[count - 1]).children('a').focus();
24973      }
24974
24975      // Select focused option if "Enter", "Spacebar" or "Tab" (when selectOnTab is true) are pressed inside the menu.
24976      if ((/(13|32)/.test(e.keyCode.toString(10)) || (/(^9$)/.test(e.keyCode.toString(10)) && that.options.selectOnTab)) && isActive) {
24977        if (!/(32)/.test(e.keyCode.toString(10))) e.preventDefault();
24978        if (!that.options.liveSearch) {
24979          var elem = $(':focus');
24980          elem.click();
24981          // Bring back focus for multiselects
24982          elem.focus();
24983          // Prevent screen from scrolling if the user hit the spacebar
24984          e.preventDefault();
24985          // Fixes spacebar selection of dropdown items in FF & IE
24986          $(document).data('spaceSelect', true);
24987        } else if (!/(32)/.test(e.keyCode.toString(10))) {
24988          that.$menuInner.find('.active a').click();
24989          $this.focus();
24990        }
24991        $(document).data('keycount', 0);
24992      }
24993
24994      if ((/(^9$|27)/.test(e.keyCode.toString(10)) && isActive && (that.multiple || that.options.liveSearch)) || (/(27)/.test(e.keyCode.toString(10)) && !isActive)) {
24995        that.$menu.parent().removeClass('open');
24996        if (that.options.container) that.$newElement.removeClass('open');
24997        that.$button.focus();
24998      }
24999    },
25000
25001    mobile: function () {
25002      this.$element.addClass('mobile-device');
25003    },
25004
25005    refresh: function () {
25006      this.$lis = null;
25007      this.liObj = {};
25008      this.reloadLi();
25009      this.render();
25010      this.checkDisabled();
25011      this.liHeight(true);
25012      this.setStyle();
25013      this.setWidth();
25014      if (this.$lis) this.$searchbox.trigger('propertychange');
25015
25016      this.$element.trigger('refreshed.bs.select');
25017    },
25018
25019    hide: function () {
25020      this.$newElement.hide();
25021    },
25022
25023    show: function () {
25024      this.$newElement.show();
25025    },
25026
25027    remove: function () {
25028      this.$newElement.remove();
25029      this.$element.remove();
25030    },
25031
25032    destroy: function () {
25033      this.$newElement.before(this.$element).remove();
25034
25035      if (this.$bsContainer) {
25036        this.$bsContainer.remove();
25037      } else {
25038        this.$menu.remove();
25039      }
25040
25041      this.$element
25042        .off('.bs.select')
25043        .removeData('selectpicker')
25044        .removeClass('bs-select-hidden selectpicker');
25045    }
25046  };
25047
25048  // SELECTPICKER PLUGIN DEFINITION
25049  // ==============================
25050  function Plugin(option) {
25051    // get the args of the outer function..
25052    var args = arguments;
25053    // The arguments of the function are explicitly re-defined from the argument list, because the shift causes them
25054    // to get lost/corrupted in android 2.3 and IE9 #715 #775
25055    var _option = option;
25056
25057    [].shift.apply(args);
25058
25059    var value;
25060    var chain = this.each(function () {
25061      var $this = $(this);
25062      if ($this.is('select')) {
25063        var data = $this.data('selectpicker'),
25064            options = typeof _option == 'object' && _option;
25065
25066        if (!data) {
25067          var config = $.extend({}, Selectpicker.DEFAULTS, $.fn.selectpicker.defaults || {}, $this.data(), options);
25068          config.template = $.extend({}, Selectpicker.DEFAULTS.template, ($.fn.selectpicker.defaults ? $.fn.selectpicker.defaults.template : {}), $this.data().template, options.template);
25069          $this.data('selectpicker', (data = new Selectpicker(this, config)));
25070        } else if (options) {
25071          for (var i in options) {
25072            if (options.hasOwnProperty(i)) {
25073              data.options[i] = options[i];
25074            }
25075          }
25076        }
25077
25078        if (typeof _option == 'string') {
25079          if (data[_option] instanceof Function) {
25080            value = data[_option].apply(data, args);
25081          } else {
25082            value = data.options[_option];
25083          }
25084        }
25085      }
25086    });
25087
25088    if (typeof value !== 'undefined') {
25089      //noinspection JSUnusedAssignment
25090      return value;
25091    } else {
25092      return chain;
25093    }
25094  }
25095
25096  var old = $.fn.selectpicker;
25097  $.fn.selectpicker = Plugin;
25098  $.fn.selectpicker.Constructor = Selectpicker;
25099
25100  // SELECTPICKER NO CONFLICT
25101  // ========================
25102  $.fn.selectpicker.noConflict = function () {
25103    $.fn.selectpicker = old;
25104    return this;
25105  };
25106
25107  $(document)
25108      .data('keycount', 0)
25109      .on('keydown.bs.select', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role="listbox"], .bs-searchbox input', Selectpicker.prototype.keydown)
25110      .on('focusin.modal', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role="listbox"], .bs-searchbox input', function (e) {
25111        e.stopPropagation();
25112      });
25113
25114  // SELECTPICKER DATA-API
25115  // =====================
25116  $(window).on('load.bs.select.data-api', function () {
25117    $('.selectpicker').each(function () {
25118      var $selectpicker = $(this);
25119      Plugin.call($selectpicker, $selectpicker.data());
25120    })
25121  });
25122})(jQuery);
25123
25124//# sourceMappingURL=../maps/libs.js.map

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