PageSourceSearch

https://www.amtrak.com/etc.clientlibs/amtrak-b2c/components/core/clientlib-base.js

js amtrak.com collected 2026-09-24 08:27:16 UTC 833,831 bytes, 24,362 lines download raw bytes

1/*
2 * ADOBE CONFIDENTIAL
3 *
4 * Copyright 2012 Adobe Systems Incorporated
5 * All Rights Reserved.
6 *
7 * NOTICE:  All information contained herein is, and remains
8 * the property of Adobe Systems Incorporated and its suppliers,
9 * if any.  The intellectual and technical concepts contained
10 * herein are proprietary to Adobe Systems Incorporated and its
11 * suppliers and may be covered by U.S. and Foreign Patents,
12 * patents in process, and are protected by trade secret or copyright law.
13 * Dissemination of this information or reproduction of this material
14 * is strictly forbidden unless prior written permission is obtained
15 * from Adobe Systems Incorporated.
16 *
17 */
18
19/**
20 * The <code>_g</code> library contains all Granite component classes and utilities.
21 * @static
22 * @granite-class _g
23 */
24window._g = window._g || {};
25
26// namespace
27_g.shared = {};
28
29// debug console
30if (window.console === undefined) {
31    window.console = {log:function(m){}};
32}
33
34/*
35 * ADOBE CONFIDENTIAL
36 *
37 * Copyright 2012 Adobe Systems Incorporated
38 * All Rights Reserved.
39 *
40 * NOTICE:  All information contained herein is, and remains
41 * the property of Adobe Systems Incorporated and its suppliers,
42 * if any.  The intellectual and technical concepts contained
43 * herein are proprietary to Adobe Systems Incorporated and its
44 * suppliers and may be covered by U.S. and Foreign Patents,
45 * patents in process, and are protected by trade secret or copyright law.
46 * Dissemination of this information or reproduction of this material
47 * is strictly forbidden unless prior written permission is obtained
48 * from Adobe Systems Incorporated.
49 *
50 */
51
52/**
53 * A helper class providing a set of HTTP-related utilities.
54 * @static
55 * @singleton
56 * @class CQ.shared.HTTP
57 * @deprecated use Granite.HTTP and Granite.$#ajax instead
58 */
59_g.shared.HTTP = new function() {
60    /**
61     * Creates an empty response object.
62     * @private
63     * @static
64     * @return {Object} The response object
65     */
66    var createResponse = function() {
67        var response = new Object();
68        response.headers = new Object();
69        response.body = new Object();
70        return response;
71    };
72
73    var getResponseFromXhr = function(request) {
74        if (!request) return null;
75        var response = createResponse();
76        response.body = request.responseText;
77        response.headers[_g.HTTP.HEADER_STATUS] = request.status;
78        // set properties for backward compatibility (pre 5.3)
79        response.responseText = request.responseText;
80        response.status = request.status;
81        return response;
82    };
83
84    return {
85        /**
86         * The extension for HTML files.
87         * @static
88         * @final
89         * @type String
90         */
91        EXTENSION_HTML: ".html",
92
93        /**
94         * The extension for JSON files.
95         * @static
96         * @final
97         * @type String
98         */
99        EXTENSION_JSON: ".json",
100
101        /**
102         * The extension for resources.
103         * @private
104         * @static
105         * @final
106         * @type String
107         */
108        EXTENSION_RES: ".res",
109
110        /**
111         * The Status header.
112         * @static
113         * @final
114         * @type String
115         */
116        HEADER_STATUS: "Status",
117
118        /**
119         * The Message header.
120         * @static
121         * @final
122         * @type String
123         */
124        HEADER_MESSAGE: "Message",
125
126        /**
127         * The Location header.
128         * @static
129         * @final
130         * @type String
131         */
132        HEADER_LOCATION: "Location",
133
134        /**
135         * The Path header.
136         * @static
137         * @final
138         * @type String
139         */
140        HEADER_PATH: "Path",
141
142        /**
143         * The parameter name for no caching.
144         * @static
145         * @final
146         * @type String
147         */
148        PARAM_NO_CACHE: "cq_ck",
149
150        /**
151         * Requests the specified URL from the server using GET. The request
152         * will be synchronous, unless a callback function is specified.
153         * @static
154         * @param {String} url The URL to request
155         * @param {Function} callback (optional) The callback function which is
156         *        called regardless of success or failure and is passed the following
157         *        parameters:<ul>
158         *        <li><b>options</b> : Object<div class="sub-desc">The parameter to the request call.</div></li>
159         *        <li><b>success</b> : Boolean<div class="sub-desc">True if the request succeeded.</div></li>
160         *        <li><b>response</b> : Object<div class="sub-desc">The response object.</div></li>
161         *        </ul>
162         * @param {Object} scope The scope for the callback (optional)
163         * @param {Boolean} suppressForbiddenCheck Suppress the check if the session has timed out (optional)
164         * @return {Mixed} The response object or, if the
165         *         request is asynchronous, the transaction ID
166         */
167        get: function(url, callback, scope, suppressForbiddenCheck) {
168            url = _g.HTTP.getXhrHookedURL(_g.HTTP.externalize(url, true));
169
170            if (callback != undefined) {
171                return _g.$.ajax({
172                    type: "GET",
173                    url: url,
174                    externalize: false,
175                    encodePath: false,
176                    hook: false,
177                    complete: function(request, textStatus) {
178                        var response = getResponseFromXhr(request);
179                        if (!suppressForbiddenCheck) _g.HTTP.handleForbidden(response);
180                        callback.call(scope || this,
181                                this,
182                                textStatus == "success",
183                                response);
184                    }
185                });
186            } else {
187                try {
188                    var request = _g.$.ajax({
189                        type: "GET",
190                        url: url,
191                        async: false,
192                        externalize: false,
193                        encodePath: false,
194                        hook: false
195                    });
196                    var response = getResponseFromXhr(request);
197                    if (!suppressForbiddenCheck) _g.HTTP.handleForbidden(response);
198                    return response;
199                } catch (e) {
200                    return null;
201                }
202            }
203        },
204
205        /**
206         * Requests the specified URL from the server using POST. The request
207         * will be synchronous, unless a callback function is specified.
208         * The returned response object looks like this:
209         * <pre><code>{ headers: { "Status": 200, ... } }</code></pre>
210         * See constants above for all supported headers.
211         * @static
212         * @param {String} url The URL to request
213         * @param {Function} callback (optional) The callback function which is
214         *        called regardless of success or failure and is passed the following
215         *        parameters:<ul>
216         *        <li><b>options</b> : Object<div class="sub-desc">The parameter to the request call.</div></li>
217         *        <li><b>success</b> : Boolean<div class="sub-desc">True if the request succeeded.</div></li>
218         *        <li><b>xhr</b> : Object<div class="sub-desc">The XMLHttpRequest object containing the response data.
219         *        See <a href="http://www.w3.org/TR/XMLHttpRequest/">http://www.w3.org/TR/XMLHttpRequest/</a> for details about
220         *        accessing elements of the response.</div></li>
221         *        <li><b>response</b> : Object<div class="sub-desc">The response object.<br>
222         *        <i>Added in CQ 5.3</i></div></li>
223         *        </ul>
224         * @param {Object} params The parameters
225         * @param {Object} scope The scope for the callback
226         * @param {Boolean} suppressErrorMsg Suppress the error msg notification
227         * @param {Boolean} suppressForbiddenCheck Suppress the check if the session has timed out (optional)
228         * @return {Mixed} The response object or, if the request is
229         *         asynchronous, the transaction ID
230         */
231        post: function(url, callback, params, scope, suppressErrorMsg, suppressForbiddenCheck) {
232            url = _g.HTTP.externalize(url, true);
233
234            var hook = _g.HTTP.getXhrHook(url, "POST", params);
235            if (hook) {
236                url = hook.url;
237                params = hook.params;
238            }
239
240            if (callback != undefined) {
241                return _g.$.ajax({
242                    type: "POST",
243                    url: url,
244                    data: params,
245                    externalize: false,
246                    encodePath: false,
247                    hook: false,
248                    complete: function(request, textStatus) {
249                        var response = _g.HTTP.buildPostResponseFromHTML(request.responseText);
250                        if (!suppressForbiddenCheck) _g.HTTP.handleForbidden(request);
251                        callback.call(scope || this,
252                                this,
253                                textStatus == "success",
254                                response);
255                    }
256                });
257            } else {
258                try {
259                    var request = _g.$.ajax({
260                        type: "POST",
261                        url: url,
262                        data: params,
263                        async: false,
264                        externalize: false,
265                        encodePath: false,
266                        hook: false
267                    });
268                    var response = _g.HTTP.buildPostResponseFromHTML(request.responseText);
269                    if (!suppressForbiddenCheck) _g.HTTP.handleForbidden(request);
270                    return response;
271                } catch (e) {
272                    return null;
273                }
274            }
275        },
276
277        /**
278         * Returns the value of the parameter with the specified name
279         * in the URL. Only the first value will be considered.
280         * Values will be URL-decoded.
281         * @static
282         * @param {String} url The URL
283         * @param {String} name The name of the parameter
284         * @return {String} The value
285         */
286        getParameter: function(url, name) {
287            var params = _g.HTTP.getParameters(url, name);
288            return params != null ? params[0] : null;
289        },
290
291        /**
292         * Returns the values of the parameters with the specified name
293         * in the URL. Values will be URL-decoded.
294         * @static
295         * @param {String} url The URL
296         * @param {String} name The name of the parameter
297         * @return {String[]} The values
298         */
299        getParameters: function(url, name) {
300            var values = [];
301            if (!name) {
302                return null;
303            }
304            name = encodeURIComponent(name);
305            if (url.indexOf("?") == -1) {
306                return null;
307            }
308            if (url.indexOf("#") != -1) {
309                url = url.substring(0, url.indexOf("#"));
310            }
311            var query = url.substring(url.indexOf("?") + 1);
312            if (query.indexOf(name) == -1) {
313                return null;
314            }
315            var queryPts = query.split("&");
316            for (var i = 0; i < queryPts.length; i++) {
317                var paramPts = queryPts[i].split("=");
318                if (paramPts[0] == name) {
319                    values.push(paramPts.length > 1 ? decodeURIComponent(paramPts[1]) : "");
320                }
321            }
322            return values.length > 0 ? values : null;
323        },
324
325        /**
326         * Adds a parameter to the specified URL. The parameter name and
327         * value will be URL-endcoded.
328         * @static
329         * @param {String} url The URL
330         * @param {String} name The name of the parameter
331         * @param {String/String[]} value The value of the parameter.
332         *        Since 5.3, an array of strings can be passed
333         * @return {String} The URL with the new parameter
334         */
335        addParameter: function(url, name, value) {
336            if (value && value instanceof Array) {
337                for (var i = 0; i < value.length; i++) {
338                    url = _g.HTTP.addParameter(url, name, value[i]);
339                }
340                return url;
341            }
342            var separator = url.indexOf("?") == -1 ? "?" : "&";
343            var hashIdx = url.indexOf("#");
344            if (hashIdx < 0) {
345                return url + separator + encodeURIComponent(name) + "=" + encodeURIComponent(value);
346            } else {
347                var hash = url.substring(hashIdx);
348                url = url.substring(0, hashIdx);
349                return url + separator + encodeURIComponent(name) + "=" + encodeURIComponent(value) + hash;
350            }
351        },
352
353        /**
354         * Overwrites a parameter in the specified URL. The parameter name
355         * and value will be URL-endcoded.
356         * @static
357         * @param {String} url The URL
358         * @param {String} name The name of the parameter
359         * @param {String} value The value of the parameter
360         * @return {String} The URL with the new parameter
361         */
362        setParameter: function(url, name, value) {
363            url = _g.HTTP.removeParameter(url, name);
364            return _g.HTTP.addParameter(url, name, value);
365        },
366
367        /**
368         * Removes a parameter from the specified URL.
369         * @static
370         * @param {String} url The URL
371         * @param {String} name The name of the parameter to remove
372         * @return {String} The URL without the parameter
373         */
374        removeParameter: function(url, name) {
375            var pattern0 = "?" + encodeURIComponent(name) + "=";
376            var pattern1 = "&" + encodeURIComponent(name) + "=";
377            var pattern;
378            if (url.indexOf(pattern0) != -1) {
379                pattern = pattern0;
380            }
381            else if (url.indexOf(pattern1) != -1) {
382                pattern = pattern1;
383            }
384            else {
385                return url;
386            }
387
388            var indexCutStart = url.indexOf(pattern);
389            var begin = url.substring(0, indexCutStart);
390
391            var indexCutEnd = url.indexOf("&", indexCutStart + 1);
392            var end = "";
393            if (indexCutEnd != -1) {
394                end = url.substring(indexCutEnd);
395                if (end.indexOf("&") == 0) {
396                    end = end.replace("&", "?");
397                }
398            }
399            return begin + end;
400        },
401
402        /**
403         * Removes all parameter from the specified URL.
404         * @static
405         * @param {String} url The URL
406         * @return {String} The URL without parameters
407         */
408        removeParameters: Granite.HTTP.removeParameters,
409
410        /**
411         * Adds the specified selector to an URL.
412         * @param {String} url The URL. The URL must contain a extension and
413         *                 must not contain a suffix (x.json/a/b). Anchor and
414         *                 request parameters are supported.
415         * @param {String} selector The name of the selector to insert
416         * @param {Number} index (optional) The index of the selector. If it is "-1"
417         *                 or bigger than the number of the existing selectors
418         *                 the selector will be appended. Defaults to "0".
419         * @return {String} The updated URL
420         * @since 5.3
421         */
422        addSelector: function(url, selector, index) {
423            if (!index) index = 0;
424
425            // url:  /x/y.z.json?a=1#b
426            // post: ?a=1#b
427            // path: /x
428            // main: y.z.json
429            var post = ""; // string of parameters and anchor
430            var pIndex = url.indexOf("?");
431            if (pIndex == -1) pIndex = url.indexOf("#");
432            if (pIndex != -1) {
433                post = url.substring(pIndex);
434                url = url.substring(0, pIndex);
435            }
436            var sIndex = url.lastIndexOf("/");
437            var main = url.substring(sIndex); // name, selectors and extension
438            if (main.indexOf("." + selector + ".") == -1) {
439                var path = url.substring(0, sIndex);
440                var obj = main.split(".");
441                var newMain = "";
442                var delim = "";
443                if (index > obj.length - 2 || index == -1) {
444                    // insert at last position
445                    index = obj.length - 2;
446                }
447                for (var i = 0; i < obj.length; i++) {
448                    newMain += delim + obj[i];
449                    delim = ".";
450                    if (index == i) {
451                        newMain += delim + selector;
452                    }
453                }
454                return path + newMain + post;
455            }
456            else {
457                return url;
458            }
459        },
460
461        /**
462         * Replaces the selector at the given index position. If no selector exists
463         * at the index position, no change is made to the URL.
464         *
465         * @param {String} url The URL.
466         * @param {String} selector The value with which to replace the selector.
467         * @param {Number} index The index of the selector to set/replace.
468         * @return {String} The URL with the selector replaced.
469         * @since 5.4
470         */
471        setSelector: function(url, selector, index) {
472
473            var post = "";
474            var pIndex = url.indexOf("?");
475            if (pIndex == -1) pIndex = url.indexOf("#");
476            if (pIndex != -1) {
477                post = url.substring(pIndex);
478                url = url.substring(0, pIndex);
479            }
480
481            var selectors = _g.HTTP.getSelectors(url);
482            var ext = url.substring(url.lastIndexOf("."));
483            // cut extension
484            url = url.substring(0, url.lastIndexOf("."));
485            // cut selectors
486            var fragment = (selectors.length > 0) ? url.replace("." + selectors.join("."), "") : url;
487
488            if (selectors.length > 0) {
489                for (var i = 0; i < selectors.length; i++) {
490                    if (index == i) {
491                        fragment += "." + selector;
492                    } else {
493                        fragment += "." + selectors[i]
494                    }
495                }
496            } else {
497                fragment += "." + selector;
498            }
499
500            return fragment + ext + post;
501        },
502
503        /**
504         * Adds the specified selectors to an URL.
505         * @param {String} url The URL. The URL must contain a extension and
506         *                 must not contain a suffix (x.json/a/b). Anchor and
507         *                 request parameters are supported.
508         * @param {String[]} selectors The name of the selectors to insert
509         * @return {String} The updated URL
510         * @since 5.5
511         */
512        addSelectors: function(url, selectors) {
513            var res = url;
514            if( url && selectors && selectors.length) {
515                for(var i=0;i< selectors.length;i++) {
516                    res = _g.HTTP.addSelector(res, selectors[i], i);
517                }
518            }
519            return res;
520        },
521
522        /**
523         * Returns the anchor part of the URL.
524         * @static
525         * @param {String} url The URL
526         * @return {String} The anchor
527         */
528        getAnchor: function(url) {
529            if (url.indexOf("#") != -1) {
530                return url.substring(url.indexOf("#") + 1);
531            }
532            return "";
533        },
534
535        /**
536         * Sets the anchor of the specified URL.
537         * @static
538         * @param {String} url The URL
539         * @param {String} anchor The anchor
540         * @return {String} The URL with anchor
541         */
542        setAnchor: function(url, anchor) {
543            return _g.HTTP.removeAnchor(url) + "#" + anchor;
544        },
545
546        /**
547         * Removes the anchor from the specified URL.
548         * @static
549         * @param {String} url The URL
550         * @return {String} The URL without anchor
551         */
552        removeAnchor: Granite.HTTP.removeAnchor,
553
554        /**
555         * Prevents caching by adding a timestamp to the specified URL.
556         * @static
557         * @param {String} url The URL
558         * @return {String} The URL with timestamp
559         */
560        noCaching: function(url) {
561            return _g.HTTP.setParameter(url, _g.HTTP.PARAM_NO_CACHE, new Date().valueOf());
562        },
563
564        /**
565         * Builds a response object using the specified node and its child nodes.
566         * The content of each node with an ID will be set as a response header.
567         * @private
568         * @static
569         * @param {Node} node The content document or the node to parse
570         * @param {Object} response The response object to use (optional)
571         * @return {Object} The response object
572         */
573        buildPostResponseFromNode: function(node, response) {
574            if (!node) {
575                return null;
576            }
577            if (response == undefined) {
578                response = createResponse();
579            }
580
581            for (var i = 0; i < node.childNodes.length; i++) {
582                var child = node.childNodes[i];
583                if (child.tagName) {
584                    if (child.id) {
585                        if (child.href) {
586                            response.headers[child.id] = child.href;
587                        }
588                        else {
589                            response.headers[child.id] = child.innerHTML;
590                        }
591                    }
592                    response = _g.HTTP.buildPostResponseFromNode(child, response);
593                }
594            }
595            return response;
596        },
597
598        /**
599         * Builds a response object using the specified HTML string. The
600         * content of each node with an ID will be set as a response header.
601         * @private
602         * @static
603         * @param {String} html The HTML string
604         * @return {Object} The response object
605         */
606        buildPostResponseFromHTML: function(html) {
607            var response = createResponse();
608            try {
609                if (html.responseText != undefined) {
610                    html = html.responseText;
611                } else if (typeof html != "string") {
612                    html = html.toString();
613                }
614                var div = document.createElement("div");
615                div.innerHTML = html;
616                response = _g.HTTP.buildPostResponseFromNode(div, response);
617                div = null;
618            } catch (e) {
619            }
620            return response;
621        },
622
623        /**
624         * Returns the value of the cookie with the specified name.
625         * @static
626         * @param {String} name The name of the cookie
627         * @return {String} The value of the cookie
628         */
629        getCookie: function(name) {
630            var cname = encodeURIComponent(name) + "=";
631            var dc = document.cookie;
632            if (dc.length > 0) {
633                var begin = dc.indexOf(cname);
634                if (begin != -1) {
635                    begin += cname.length;
636                    var end = dc.indexOf(";", begin);
637                    if (end == -1) end = dc.length;
638                    return decodeURIComponent(dc.substring(begin, end));
639                }
640            }
641            return null;
642        },
643
644        /**
645         * Sets the value of the cookie with the specified name.
646         * @static
647         * @param {String} name The name of the cookie
648         * @param {String} value The value of the cookie
649         * @param {String} path (optional) The server path the cookie applies to
650         * @param {Number} days (optional) The number of days the cookie will live
651         * @param {String} domain (optional) The server domain
652         * @param {Boolean} secure (optional) True if the
653         *        connection is secure
654         * @return {String} The value of the cookie
655         */
656        setCookie: function(name, value, path, days, domain, secure) {
657            if (typeof(days) != "number") days = 7;
658            var date;
659            if (days > 0) {
660                date = new Date();
661                date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
662            } else {
663                date = new Date(0);
664            }
665            document.cookie = encodeURIComponent(name) + "=" +
666                    encodeURIComponent(value) + "; " +
667                    (days != 0 ? "expires=" + date.toGMTString() + "; " : "") +
668                    (domain ? "domain=" + domain + "; " : "") +
669                    (path ? "path=" + path : "") +
670                    (secure ? "; secure" : "");
671            return value;
672        },
673
674        /**
675         * Clears the cookie with the specified name.
676         * @static
677         * @param {String} name The name of the cookie
678         * @param {String} path (optional) The server path the cookie applies to
679         * @param {String} domain (optional) The server domain
680         * @param {Boolean} secure (optional) True if the
681         *        connection is secure
682         */
683        clearCookie : function(name, path, domain, secure) {
684            _g.HTTP.setCookie(name, "null", path || "", -1, domain || "", secure || "");
685        },
686
687        /**
688         * Returns the scheme and authority (user, hostname, port) part of
689         * the specified URL or an empty string if the URL does not include
690         * that part.
691         * @static
692         * @param {String} url The URL
693         * @return {String} The scheme and authority part
694         */
695        getSchemeAndAuthority: Granite.HTTP.getSchemeAndAuthority,
696
697        /**
698         * Returns the context path used on the server.
699         * @static
700         * @return {String} The context path
701         * @since 5.3
702         */
703        getContextPath: Granite.HTTP.getContextPath,
704
705        /**
706         * Makes sure the specified relative URL starts with the context path
707         * used on the server. If an absolute URL is passed, it will be returned
708         * as-is.
709         * @static
710         * @param {String} url The URL
711         * @param {boolean} encode true to encode the path of the URL (optional)
712         * @return {String} The externalized URL
713         * @since 5.3
714         */
715        externalize: function(url, encode) {
716            // check if URL is already XHR_HOOKED and assume that the externalization has
717            // already been applied if so (externalizing an already hooked URL will break
718            // it in several/most cases!)
719            if ((typeof G_IS_HOOKED != "undefined") && G_IS_HOOKED(url)) {
720                return url;
721            }
722            if (encode) url = _g.HTTP.encodePathOfURI(url);
723
724            // Granite.HTTP.externalize does nor hooked check nor encoding
725            url = Granite.HTTP.externalize(url);
726
727            return url;
728        },
729
730        /**
731         * Removes scheme, authority and context path from the specified
732         * absolute URL if it has the same scheme and authority as the
733         * specified document (or the current one).
734         * @static
735         * @param {String} url The URL
736         * @param {String} doc (optional) The document
737         * @return {String} The internalized URL
738         */
739        internalize: Granite.HTTP.internalize,
740
741        /**
742         * Removes all parts but the path from the specified URL.
743         * <p>Examples:<pre><code>
744         /x/y.sel.html?param=abc => /x/y
745         </code></pre>
746         * <pre><code>
747         http://www.day.com/foo/bar.html => /foo/bar
748         </code></pre><p>
749         * @static
750         * @param {String} url The URL, may be empty. If empty <code>window.location.href</code> is taken.
751         * @return {String} The path
752         * @since 5.3
753         */
754        getPath: Granite.HTTP.getPath,
755
756        /**
757         * Returns the current request suffix as provided by CQURLInfo.suffix.
758         *
759         * @static
760         * @return {String} The suffix
761         *
762         * @since 5.5
763         */
764        getSuffix: function() {
765            if (window.CQURLInfo && CQURLInfo.suffix) {
766                return CQURLInfo.suffix;
767            }
768            return null;
769        },
770
771        /**
772         * Returns an array with the selectors present in the given url.
773         * If no selectors are present, an empty array is returned.
774         * @static
775         * @param {String} url The URL, optional. If no url is provided, the
776         *                     selectors as provided by CQURLInfo.selectors
777         *                     are taken, with a fallback to window.location.href.
778         * @return {Array} An array containing the selectors or an empty
779         *                 array if none were found.
780         * @since 5.4
781         */
782        getSelectors: function(url) {
783
784            if (!url && window.CQURLInfo) {
785                if (CQURLInfo.selectors) {
786                    return CQURLInfo.selectors;
787                }
788            }
789
790            var selectors = [];
791
792            url = url || window.location.href;
793
794            url = _g.HTTP.removeParameters(url);
795            url = _g.HTTP.removeAnchor(url);
796
797            var fragment = url.substring(url.lastIndexOf("/"));
798            if (fragment) {
799                var split = fragment.split(".");
800                if (split.length > 2) {
801                    for (var i = 0; i < split.length; i++) {
802                        // don't add node name and extension as selectors
803                        if (i > 0 && i < split.length - 1) {
804                            selectors.push(split[i]);
805                        }
806                    }
807                }
808            }
809
810            return selectors;
811        },
812
813        /**
814         * Returns the extension of an URL. This is the string
815         * after the last dot until the end of the url without
816         * any request parameters, anchors or suffix, for
817         * example "html".
818         *
819         * @param {String} url The URL
820         * @return {String} The URL extension (without the dot)
821         *                  or an empty string if no was found.
822         * @since 5.4
823         */
824        getExtension: function(url) {
825
826            if (!url && window.CQURLInfo) {
827                if (CQURLInfo.extension) {
828                    return CQURLInfo.extension;
829                }
830            }
831
832            url = url || window.location.href;
833
834            // strip things from the end
835            url = _g.HTTP.removeParameters(url);
836            url = _g.HTTP.removeAnchor(url);
837
838            // extension is everything after the last dot
839            var pos = url.lastIndexOf(".");
840            if (pos < 0) {
841                return "";
842            }
843
844            // do not include the dot
845            url = url.substring(pos + 1);
846
847            // remove suffix if present
848            pos = url.indexOf("/");
849            if (pos < 0) {
850                return url;
851            }
852
853            return url.substring(0, pos);
854        },
855
856        /**
857         * Encodes the path of the specified URL if it is not already encoded.
858         * Path means the part of the URL before the first question mark or
859         * hash sign.<br>
860         * See {@link #encodePath} for details about the encoding.<br>
861         * Sample:<br>
862         * <code>/x/y+z.png?path=/x/y+z >> /x/y%2Bz.png?path=x/y+z</code><br>
863         * Note that the sample would not work because the "+" in the request
864         * parameter would be interpreted as a space. Parameters must be encoded
865         * separately.
866         * @param {String} url The URL to encoded
867         * @return {String} The encoded URL
868         * @since 5.3
869         */
870        encodePathOfURI: Granite.HTTP.encodePathOfURI,
871
872        /**
873         * Encodes the specified path using encodeURI. Additionally <code>+</code>,
874         * <code>#</code> and <code>?</code> are encoded.<br>
875         * The following characters are not encoded:<br>
876         * <code>0-9 a-z A-Z</code><br>
877         * <code>- _ . ! ~ * ( )</code><br>
878         * <code>/ : @ & =</code><br>
879         * @param {String} path The path to encode
880         * @return {String} The encoded path
881         * @since 5.3
882         */
883        encodePath: Granite.HTTP.encodePath,
884
885        /**
886         * Evaluates and returns the body of the specified response object.
887         * Alternatively, a URL can be specified, in which case it will be
888         * requested using a synchornous {@link #get} in order to acquire
889         * the response object.
890         * @static
891         * @param {Object/String} response The response object or URL
892         * @return {Object} The evaluated response body
893         * @since 5.3
894         */
895        eval: Granite.HTTP.eval,
896
897        /**
898         * Checks whether the specified status code is OK.
899         * @static
900         * @param {Number} status The status code
901         * @return {Boolean} True if the status is OK, else false
902         */
903        isOkStatus: function(status) {
904            try {
905                return (new String(status).indexOf("2") == 0);
906            } catch (e) {
907                return false;
908            }
909        },
910
911        /**
912         * Checks if the specified response is OK.
913         * The response object is expected to look like this:
914         * <pre><code>{ headers: { "Status": 200, ... } }</code></pre>
915         * See constants above for all supported headers.
916         * @static
917         * @param {Object} response The response object
918         * @return {Boolean} True if the response is OK, else false
919         */
920        isOk: function(response) {
921            try {
922                return _g.HTTP.isOkStatus(
923                        response.headers[_g.HTTP.HEADER_STATUS]);
924            } catch (e) {
925                return false;
926            }
927        },
928
929        /**
930         * <p>Returns if the specified response is of status 403/forbidden. If the
931         * status is 403 and <code>suppressLogin</code> is undefined the document
932         * is redirected to the login page.</p>
933         * <p>The status is expected to be found in the "status" property of the
934         * response: <code>{ "status": 403 }</code></p>
935         * @param {Object} response The response
936         * @param {Boolean} suppressLogin <code>true</code> to not redirect to the login page
937         * @return {Boolean} <code>true</code> if the status is 403
938         */
939        handleForbidden: function(response, suppressLogin) {
940            try {
941                if (response[_g.HTTP.HEADER_STATUS.toLowerCase()] == 403) {
942                    Granite.HTTP.handleLoginRedirect();
943                    return true;
944                }
945                return false;
946            } catch (e) {
947                return false;
948            }
949        },
950
951        /**
952         * Gets the XHR hooked URL if called in a portlet context
953         * @param {String} url The URL to get
954         * @param {String} method The method to use to retrieve the XHR hooked URL
955         * @param {Object} params The parameters
956         * @return {String} The XHR hooked URL if available, the provided URL otherwise
957         */
958        getXhrHook: Granite.HTTP.getXhrHook,
959
960        /**
961         * Gets the XHR hooked URL if called in a portlet context
962         * @param {String} url The URL to get
963         * @param {String} method The method to use to retrieve the XHR hooked URL
964         * @param {Object} params The parameters
965         * @return {String} The XHR hooked URL if available, the provided URL otherwise
966         */
967        getXhrHookedURL: function(url, method, params) {
968            var hook = _g.HTTP.getXhrHook(url, method, params);
969            if (hook) {
970                return hook.url;
971            }
972            return url;
973        },
974
975        /**
976         * Reloads the XHR hook (portlet context)
977         * @static
978         * @param {String} url The URL
979         * @return {String} Updated URL if reload hook function exists
980         */
981        reloadHook: function(url) {
982            if (typeof G_RELOAD_HOOK != "undefined" && _g.$.isFunction(G_RELOAD_HOOK)) {
983                if (CQURLInfo.selectorString != "") {
984                    url = _g.HTTP.addSelector(url, CQURLInfo.selectorString);
985                }
986                url = G_RELOAD_HOOK(url) || url;
987            }
988            return url;
989        }
990
991    }
992};
993
994// shortcut
995_g.HTTP = _g.shared.HTTP;
996
997/*
998 * ADOBE CONFIDENTIAL
999 *
1000 * Copyright 2012 Adobe Systems Incorporated
1001 * All Rights Reserved.
1002 *
1003 * NOTICE:  All information contained herein is, and remains
1004 * the property of Adobe Systems Incorporated and its suppliers,
1005 * if any.  The intellectual and technical concepts contained
1006 * herein are proprietary to Adobe Systems Incorporated and its
1007 * suppliers and may be covered by U.S. and Foreign Patents,
1008 * patents in process, and are protected by trade secret or copyright law.
1009 * Dissemination of this information or reproduction of this material
1010 * is strictly forbidden unless prior written permission is obtained
1011 * from Adobe Systems Incorporated.
1012 *
1013 */
1014
1015/**
1016 * A helper class providing a set of general utilities.
1017 * @static
1018 * @singleton
1019 * @class CQ.shared.Util
1020 * @granite-class _g.Util
1021 * @deprecated
1022 */
1023_g.shared.Util = new function() {
1024    return {
1025        /**
1026         * Reloads the window or replaces its location with the specified URL.
1027         * If no window is specified, the current window will be used.
1028         * @static
1029         * @param {Window} win (optional) The window to reload
1030         * @param {String} url (optional) The URL
1031         * @param {String} preventHistory (optional) Prevent history
1032         */
1033        reload: function(win, url, preventHistory) {
1034            if (!win) win = window;
1035            if (!url) {
1036                url = _g.HTTP.noCaching(win.location.href);
1037            }
1038            url = _g.HTTP.reloadHook(url);
1039
1040            if (preventHistory) {
1041                win.location.replace(url);
1042            } else {
1043                win.location.href = url;
1044            }
1045        },
1046
1047        /**
1048         * Loads the specified URL in the current window.
1049         * @static
1050         * @param {String} url The URL
1051         * @param {String} preventHistory (optional) Prevent history
1052         */
1053        load: function(url, preventHistory) {
1054            _g.Util.reload(window, url, preventHistory);
1055        },
1056
1057        /**
1058         * Opens a new window with the specified URL.
1059         * If no window is specified, the current window will be used.
1060         * @static
1061         * @param {String} url The URL
1062         * @param {Window} win (optional) The window to reload
1063         * @param {String} name (optional) New window name
1064         * @param {String} options (optional) New window options
1065         * @return {Object} New window
1066         */
1067        open: function(url, win, name, options) {
1068            if (!win) win = window;
1069            if (!url) {
1070                return;
1071            }
1072            url = _g.HTTP.reloadHook(url);
1073
1074            if (!name) {
1075                name = "";
1076            }
1077            if (!options) {
1078                options = "";
1079            }
1080
1081            return win.open(url, name, options);
1082        },
1083
1084        /**
1085         * Converts certain characters (&, <, >, and ") to their HTML character equivalents for literal display in web pages.
1086         * @param {String} value The string to encode
1087         * @return {String} The encoded text
1088         */
1089        htmlEncode : function(value) {
1090            return !value ? value : String(value).replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;").replace(/"/g, "&quot;");
1091        },
1092
1093        /**
1094         * Converts certain characters (&, <, >, and ") from their HTML character equivalents.
1095         * @param {String} value The string to decode
1096         * @return {String} The decoded text
1097         */
1098        htmlDecode : function(value) {
1099            return !value ? value : String(value).replace(/&gt;/g, ">").replace(/&lt;/g, "<").replace(/&quot;/g, '"').replace(/&amp;/g, "&");
1100        },
1101
1102        /**
1103         * Truncates a string and add an ellipsis ('...') to the end if it exceeds the specified length
1104         * @param {String}  value  The string to truncate
1105         * @param {Number}  length The maximum length to allow before truncating
1106         * @param {Boolean} word   True to try to find a common work break
1107         * @return {String} The converted text
1108         */
1109        ellipsis : function(value, length, word) {
1110            if (value && value.length > length) {
1111                if (word) {
1112                    var vs = value.substr(0, length - 2);
1113                    var index = Math.max(vs.lastIndexOf(' '), vs.lastIndexOf('.'), vs.lastIndexOf('!'), vs.lastIndexOf('?'), vs.lastIndexOf(';'));
1114                    if (index == -1 || index < (length - 15)) {
1115                        return value.substr(0, length - 3) + "...";
1116                    } else {
1117                        return vs.substr(0, index) + "...";
1118                    }
1119                } else {
1120                    return value.substr(0, length - 3) + "...";
1121                }
1122            }
1123            return value;
1124        },
1125
1126                /**
1127         * Replaces occurrences of <code>{n}</code> in the specified text with
1128         * the texts from the snippets.
1129         * <p>Example 1 (single snippet):<pre><code>
1130var text = CQ.shared.Util.patchText("{0} has signed in.", "Jack");
1131           </code></pre>Result 1:<pre><code>
1132Jack has signed in.
1133           </code></pre></p>
1134         * <p>Example 2 (multiple snippets):<pre><code>
1135var text = "{0} {1} has signed in from {2}.";
1136text = CQ.shared.Util.patchText(text, ["Jack", "McFarland", "10.0.0.99"]);
1137           </code></pre>Result 2:<pre><code>
1138Jack McFarland has signed in from 10.0.0.99.
1139           </code></pre></p>
1140         * @static
1141         * @param {String} text The text
1142         * @param {String/String[]} snippets The text(s) replacing
1143         *        <code>{n}</code>
1144         * @return {String} The patched text
1145         */
1146        patchText: Granite.Util.patchText,
1147
1148        /**
1149         * Evaluates and returns the response text of the specified response
1150         * object.
1151         * @static
1152         * @param {Object} response The response object
1153         * @return {Object} The evaluated object
1154         * @deprecated Use {@link CQ.shared.HTTP#eval} instead
1155         */
1156        eval: function(response) {
1157            return _g.HTTP.eval(response);
1158        },
1159
1160        /**
1161         * Returns the top most accessible window.
1162         * @static
1163         * @return {Window} The top window
1164         * @since 5.5
1165         */
1166        getTopWindow: Granite.Util.getTopWindow,
1167        
1168        /**
1169         * Allows to define if Granite.Util is running in an iFrame and parent window is in another domain
1170         * (and optionally define what would be the top window in that case.
1171         * This is necessary to use {@link getTopWindow} in a iFrame on WebKit based browsers because
1172         * {@link getTopWindow} iterates on parent windows to find the top one which triggers a security exception
1173         * if one parent window is in a different domain. Exception cannot be caught but is not breaking the JS
1174         * execution.
1175         * @param {Object} topWindow (optional) The iFrame top window. Must be running on the same host to avoid
1176         * security exception. Defaults to window.
1177         */
1178         setIFrameMode: Granite.Util.setIFrameMode
1179    }
1180
1181};
1182
1183// shortcut
1184_g.Util = _g.shared.Util;
1185
1186/*
1187 * ADOBE CONFIDENTIAL
1188 *
1189 * Copyright 2012 Adobe Systems Incorporated
1190 * All Rights Reserved.
1191 *
1192 * NOTICE:  All information contained herein is, and remains
1193 * the property of Adobe Systems Incorporated and its suppliers,
1194 * if any.  The intellectual and technical concepts contained
1195 * herein are proprietary to Adobe Systems Incorporated and its
1196 * suppliers and may be covered by U.S. and Foreign Patents,
1197 * patents in process, and are protected by trade secret or copyright law.
1198 * Dissemination of this information or reproduction of this material
1199 * is strictly forbidden unless prior written permission is obtained
1200 * from Adobe Systems Incorporated.
1201 *
1202 */
1203
1204/**
1205 * A helper class providing a set of Sling-related utilities.
1206 * @static
1207 * @singleton
1208 * @class CQ.Sling
1209 * @deprecated use Granite.Sling instead
1210 */
1211_g.shared.Sling = function() {
1212
1213    return {
1214
1215        /**
1216         * The selector for infinite hierarchy depth when retrieving
1217         * repository content.
1218         * @static
1219         * @final
1220         * @type String
1221         */
1222        SELECTOR_INFINITY: Granite.Sling.SELECTOR_INFINITY,
1223
1224        /**
1225         * The parameter name for the used character set.
1226         * @static
1227         * @final
1228         * @type String
1229         */
1230        CHARSET: Granite.Sling.CHARSET,
1231
1232        /**
1233         * The parameter name for the status.
1234         * @static
1235         * @final
1236         * @type String
1237         */
1238        STATUS: Granite.Sling.STATUS,
1239
1240        /**
1241         * The parameter value for the status type "browser".
1242         * @static
1243         * @final
1244         * @type String
1245         */
1246        STATUS_BROWSER: Granite.Sling.STATUS_BROWSER,
1247
1248        /**
1249         * The parameter name for the operation.
1250         * @static
1251         * @final
1252         * @type String
1253         */
1254        OPERATION: Granite.Sling.OPERATION,
1255
1256        /**
1257         * The parameter value for the delete operation.
1258         * @static
1259         * @final
1260         * @type String
1261         */
1262        OPERATION_DELETE: Granite.Sling.OPERATION_DELETE,
1263
1264        /**
1265         * The parameter value for the move operation.
1266         * @static
1267         * @final
1268         * @type String
1269         */
1270        OPERATION_MOVE: Granite.Sling.OPERATION_MOVE,
1271
1272        /**
1273         * The parameter name suffix for deleting.
1274         * @static
1275         * @final
1276         * @type String
1277         */
1278        DELETE_SUFFIX: Granite.Sling.DELETE_SUFFIX,
1279
1280        /**
1281         * The parameter name suffix for setting a type hint.
1282         * @static
1283         * @final
1284         * @type String
1285         */
1286        TYPEHINT_SUFFIX: Granite.Sling.TYPEHINT_SUFFIX,
1287
1288        /**
1289         * The parameter name suffix for copying.
1290         * @static
1291         * @final
1292         * @type String
1293         */
1294        COPY_SUFFIX: Granite.Sling.COPY_SUFFIX,
1295
1296        /**
1297         * The parameter name suffix for moving.
1298         * @static
1299         * @final
1300         * @type String
1301         */
1302        MOVE_SUFFIX: Granite.Sling.MOVE_SUFFIX,
1303
1304        /**
1305         * The parameter name for the ordering.
1306         * @static
1307         * @final
1308         * @type String
1309         */
1310        ORDER: Granite.Sling.ORDER,
1311
1312        /**
1313         * The parameter name for the replace flag.
1314         * @static
1315         * @final
1316         * @type String
1317         */
1318        REPLACE: Granite.Sling.REPLACE,
1319
1320        /**
1321         * The parameter name for the destination flag.
1322         * @static
1323         * @final
1324         * @type String
1325         */
1326        DESTINATION: Granite.Sling.DESTINATION,
1327
1328        /**
1329         * The parameter name for the save parameter prefix.
1330         * @static
1331         * @final
1332         * @type String
1333         */
1334        SAVE_PARAM_PREFIX: Granite.Sling.SAVE_PARAM_PREFIX,
1335
1336        /**
1337         * The parameter name for input fields that should
1338         * be ignored by Sling.
1339         * @static
1340         * @final
1341         * @type String
1342         */
1343        IGNORE_PARAM: Granite.Sling.IGNORE_PARAM,
1344
1345        /**
1346         * The parameter name for login requests.
1347         * @static
1348         * @final
1349         * @type String
1350         */
1351        REQUEST_LOGIN_PARAM: Granite.Sling.REQUEST_LOGIN_PARAM,
1352
1353        /**
1354         * Login URL
1355         * @static
1356         * @final
1357         * @type String
1358         */
1359        LOGIN_URL: Granite.Sling.LOGIN_URL,
1360
1361        /**
1362         * Logout URL
1363         * @static
1364         * @final
1365         * @type String
1366         */
1367        LOGOUT_URL: Granite.Sling.LOGOUT_URL,
1368
1369        /**
1370         * Detects and processes binary repository data returned by Sling
1371         * and does some preparsing on it for more easy data handling.
1372         * @static
1373         * @param {Object} value The repository data to check
1374         * @return {Object} The processed repository data
1375         */
1376        processBinaryData: function(value) {
1377            if (value && value[":jcr:data"] != undefined) {
1378                // value is a binary
1379                var o = new Object();
1380                o.size = value[":jcr:data"];
1381                o.type = value["jcr:mimeType"];
1382                o.date = value["jcr:lastModified"];
1383                value = o;
1384            }
1385            return value;
1386        },
1387
1388        /**
1389         * Returns the content path for the data.
1390         * @static
1391         * @param {String} relPath The relative path to resolve
1392         * @param {String} absPath The absolute path to resovle against
1393         * @param {Boolean} allowParentPaths Indicates parent paths (../) should be processed at the start of the
1394         * relative path
1395         * @return {String} The absolute path path
1396         */
1397        getContentPath: function(relPath, absPath, allowParentPaths) {
1398            var path = absPath;
1399            if (path.lastIndexOf(".") > path.lastIndexOf("/")) {
1400                // remove selectors and extension from absPath:
1401                // /content/foo.bar.html >> /content/foo
1402                path = path.substr(0, path.indexOf(".", path.lastIndexOf("/")));
1403            }
1404            if (relPath) {
1405                if (relPath.indexOf("/") == 0) {
1406                    path = relPath;
1407                } else {
1408                    if (allowParentPaths) {
1409                        while (relPath.indexOf("../") == 0) {
1410                            relPath = relPath.substring(3);
1411                            path = path.substring(0, path.lastIndexOf("/"));
1412                        }
1413                    }
1414                    relPath = relPath.replace("./", "");
1415                    path = path + "/" + relPath;
1416                }
1417            }
1418            return path;
1419        }
1420    };
1421
1422}();
1423
1424// shortcut
1425_g.Sling = _g.shared.Sling;
1426
1427/*
1428 * ADOBE CONFIDENTIAL
1429 *
1430 * Copyright 2012 Adobe Systems Incorporated
1431 * All Rights Reserved.
1432 *
1433 * NOTICE:  All information contained herein is, and remains
1434 * the property of Adobe Systems Incorporated and its suppliers,
1435 * if any.  The intellectual and technical concepts contained
1436 * herein are proprietary to Adobe Systems Incorporated and its
1437 * suppliers and may be covered by U.S. and Foreign Patents,
1438 * patents in process, and are protected by trade secret or copyright law.
1439 * Dissemination of this information or reproduction of this material
1440 * is strictly forbidden unless prior written permission is obtained
1441 * from Adobe Systems Incorporated.
1442 *
1443 */
1444
1445/**
1446 * Provides static utilities for XSS management.
1447 * @static
1448 * @singleton
1449 * @since 5.4
1450 * @class CQ.shared.XSS
1451 * @granite-class _g.XSS
1452 * @deprecated
1453 */
1454_g.shared.XSS = new function() {
1455    return {
1456        /**
1457         * Get XSS property name from a provided property name
1458         *
1459         * @static
1460         * @param  {String} propertyName Property name
1461         * @return {String} XSS property name
1462         */
1463        getXSSPropertyName: function(propertyName) {
1464            if (!propertyName) {
1465                return '';
1466            }
1467            if (_g.XSS.KEY_REGEXP.test(propertyName)) {
1468                return propertyName;
1469            }
1470            return propertyName += _g.XSS.KEY_SUFFIX;
1471        },
1472
1473        /**
1474         * Get XSS property value from provided property name and json record
1475         *
1476         * @static
1477         * @param  {Object} rec          Object containing the properties and their values
1478         * @param  {String} propertyName Property name
1479         * @param  {Number} ellipsisLimit Maximum number of characters
1480         * @return {String} XSS property value
1481         */
1482        getXSSRecordPropertyValue: function(rec, propertyName, ellipsisLimit) {
1483            var value = '';
1484            if (rec && propertyName) {
1485                var xssPropValue = rec.get(this.getXSSPropertyName(propertyName));
1486                if (xssPropValue) {
1487                    value = xssPropValue;
1488                } else {
1489                    value = this.getXSSValue(rec.get(propertyName));
1490                }
1491
1492                if (ellipsisLimit && !isNaN(ellipsisLimit)) {
1493                    value = _g.Util.ellipsis(value, ellipsisLimit, true);
1494                }
1495            }
1496            return value;
1497        },
1498
1499        /**
1500         * Get XSS property value from provided property name and table
1501         *
1502         * @static
1503         * @param  {Object} table         Object containing the properties and their values
1504         * @param  {String} propertyName  Property name
1505         * @param  {Number} ellipsisLimit Maximum number of characters
1506         * @return {String} XSS property value
1507         */
1508        getXSSTablePropertyValue: function(table, propertyName, ellipsisLimit) {
1509            var value = '';
1510            if (table && propertyName) {
1511                var xssPropValue = table[this.getXSSPropertyName(propertyName)];
1512                if (xssPropValue) {
1513                    value = xssPropValue;
1514                } else {
1515                    value = this.getXSSValue(table[propertyName]);
1516                }
1517
1518                if (ellipsisLimit && !isNaN(ellipsisLimit)) {
1519                    value = _g.Util.ellipsis(value, ellipsisLimit, true);
1520                }
1521            }
1522            return value;
1523        },
1524
1525        /**
1526         * XSS value renderer
1527         *
1528         * @static
1529         * @param  {String} val  Value to protect
1530         * @return {String} XSS protected value
1531         */
1532        getXSSValue: function(val) {
1533            if (val) {
1534                // There is a value to display, which we encode
1535                return _g.Util.htmlEncode(val);
1536            } else {
1537                // There was no value to display
1538                return '';
1539            }
1540        },
1541
1542        /**
1543         * Update configuration object's property name if XSS is enabled for it
1544         *
1545         * @static
1546         * @param {Object}  cfg          Configuration object
1547         * @param {String}  propertyName Property name of the provided configuration object
1548         */
1549        updatePropertyName: function(cfg, propertyName) {
1550            if (!cfg || !propertyName || !cfg[propertyName]) {
1551                return;
1552            }
1553            if (cfg['xssProtect'] && !cfg['xssKeepPropName']) {
1554                cfg[propertyName] = this.getXSSPropertyName(cfg[propertyName]);
1555            }
1556        },
1557
1558        /**
1559         * XSS property renderer
1560         *
1561         * @static
1562         * @param  {String} val  Value to display if XSS would not have been requested or is not available
1563         * @param  {Object} meta Field metadata
1564         * @param  {Object} cfg  Field configuration
1565         * @param  {Object} rec  Record containing information
1566         * @return {String} XSS property value
1567         */
1568        xssPropertyRenderer: function(val, meta, rec, cfg) {
1569            if (cfg && cfg['dataIndex'] && rec && rec.data && rec.data[this.getXSSPropertyName(cfg['dataIndex'])]) {
1570                // The record contains the XSS property equivalent
1571                val = rec.data[this.getXSSPropertyName(cfg['dataIndex'])];
1572                if (cfg['ellipsisLimit'] && !isNaN(cfg['ellipsisLimit'])) {
1573                    val = _g.Util.ellipsis(val, cfg['ellipsisLimit'], true);
1574                }
1575                return val;
1576            } else if (val) {
1577                // The record does not contain the XSS property equivalent
1578                return val;
1579            } else {
1580                // There was no value to display
1581                return '';
1582            }
1583        }
1584    }
1585};
1586
1587// shortcut
1588_g.XSS = _g.shared.XSS;
1589
1590/**
1591 * Key suffix for XSS property name
1592 * @static
1593 * @final
1594 * @type String
1595 */
1596_g.XSS.KEY_SUFFIX = "_xss";
1597
1598/**
1599 * Key regular expression to test if a property name already ends with XSS suffix
1600 * @private
1601 * @static
1602 * @final
1603 * @type Object
1604 */
1605_g.XSS.KEY_REGEXP = new RegExp(_g.XSS.KEY_SUFFIX + "$");
1606
1607/*
1608 * ADOBE CONFIDENTIAL
1609 *
1610 * Copyright 2012 Adobe Systems Incorporated
1611 * All Rights Reserved.
1612 *
1613 * NOTICE:  All information contained herein is, and remains
1614 * the property of Adobe Systems Incorporated and its suppliers,
1615 * if any.  The intellectual and technical concepts contained
1616 * herein are proprietary to Adobe Systems Incorporated and its
1617 * suppliers and may be covered by U.S. and Foreign Patents,
1618 * patents in process, and are protected by trade secret or copyright law.
1619 * Dissemination of this information or reproduction of this material
1620 * is strictly forbidden unless prior written permission is obtained
1621 * from Adobe Systems Incorporated.
1622 *
1623 */
1624
1625/**
1626 * A helper class providing a set of utilities related to internationalization
1627 * (i18n). Note: for cq localization, make sure to use CQ.I18n.get().
1628 * @static
1629 * @singleton
1630 * @class CQ.I18n
1631 * @granite-class _g.I18n
1632 * @deprecated use Granite.I18n instead
1633 */
1634_g.shared.I18n = Granite.I18n;//function() {
1635
1636// shortcut
1637_g.I18n = _g.shared.I18n;
1638
1639_g.shared.I18n.getMessage = Granite.I18n.get;
1640_g.shared.I18n.getVarMessage = Granite.I18n.getVar;
1641
1642/*
1643 * ADOBE CONFIDENTIAL
1644 *
1645 * Copyright 2012 Adobe Systems Incorporated
1646 * All Rights Reserved.
1647 *
1648 * NOTICE:  All information contained herein is, and remains
1649 * the property of Adobe Systems Incorporated and its suppliers,
1650 * if any.  The intellectual and technical concepts contained
1651 * herein are proprietary to Adobe Systems Incorporated and its
1652 * suppliers and may be covered by U.S. and Foreign Patents,
1653 * patents in process, and are protected by trade secret or copyright law.
1654 * Dissemination of this information or reproduction of this material
1655 * is strictly forbidden unless prior written permission is obtained
1656 * from Adobe Systems Incorporated.
1657 *
1658 */
1659
1660/**
1661 * A helper class providing a set of String related utilities.
1662 * @static
1663 * @singleton
1664 * @since 5.5
1665 * @class CQ.shared.String
1666 * @granite-class _g.String
1667 * @deprecated
1668 */
1669_g.shared.String = new function() {
1670
1671    return {
1672
1673        /**
1674         * Check to see if the the str starts with the prefix.
1675         * The comparison is case sensitive.
1676         * @static
1677         * @param {String} str The string to check.
1678         * @param {String} prefix The prefix to find.
1679         * @return {Boolean} if the str starts with the prefix
1680         * return true, otherwise false.
1681         */
1682        startsWith: function( str, prefix ) {
1683            if (str == null || prefix == null) {
1684                return str == null && prefix == null;
1685            }
1686
1687            if (prefix.length > str.length) {
1688                return false;
1689            }
1690
1691            // ensure we are dealing with the string form of this object
1692            var sMatch = str.toString();
1693            var sSearch	= prefix.toString();
1694
1695            return (sMatch.indexOf(sSearch) == 0);
1696        },
1697
1698        /**
1699         * Check to see if the the str ends with the suffix.
1700         * The comparison is case sensitive.
1701         * @static
1702         * @param {String} str The string to check.
1703         * @param {String} suffix The suffix to find.
1704         * @return {Boolean} if the str ends with the suffix
1705         * return true, otherwise false.
1706         */
1707        endsWith: function( str, suffix ) {
1708
1709            if (str == null || suffix == null) {
1710                return str == null && suffix == null;
1711            }
1712
1713            if (suffix.length > str.length) {
1714                return false;
1715            }
1716
1717            // ensure we are dealing with the string form of this object
1718            str = str.toString();
1719            suffix	= suffix.toString();
1720
1721            return (str.lastIndexOf(suffix) == (str.length - suffix.length));
1722        },
1723
1724        /**
1725         * Check to see if the the str contains the searchStr.
1726         * The comparison is case sensitive.
1727         * @static
1728         * @param {String} str The string to check.
1729         * @param {String} searchStr The prefix to find.
1730         * @return {Boolean} if the str ends with the suffix
1731         * return true, otherwise false.
1732         */
1733        contains: function( str, searchStr ) {
1734
1735            if (str == null || searchStr == null) {
1736                return false;
1737            }
1738
1739            // ensure we are dealing with the string form of this object
1740            str = str.toString();
1741            searchStr = searchStr.toString();
1742
1743            return (str.indexOf(searchStr) >= 0);
1744        }
1745    }
1746};
1747
1748// shortcut
1749_g.String = _g.shared.String;
1750
1751/*
1752 * ADOBE CONFIDENTIAL
1753 *
1754 * Copyright 2012 Adobe Systems Incorporated
1755 * All Rights Reserved.
1756 *
1757 * NOTICE:  All information contained herein is, and remains
1758 * the property of Adobe Systems Incorporated and its suppliers,
1759 * if any.  The intellectual and technical concepts contained
1760 * herein are proprietary to Adobe Systems Incorporated and its
1761 * suppliers and may be covered by U.S. and Foreign Patents,
1762 * patents in process, and are protected by trade secret or copyright law.
1763 * Dissemination of this information or reproduction of this material
1764 * is strictly forbidden unless prior written permission is obtained
1765 * from Adobe Systems Incorporated.
1766 *
1767 */
1768
1769/**
1770 * @class _g.shared.ClientSidePersistence
1771 * The _g.shared.ClientSidePersistence is a class providing method to persist a map of pairs (key/value).
1772 * @constructor
1773 * Creates a new ClientSidePersistence object.
1774 */
1775_g.shared.ClientSidePersistence = function(cfg) {
1776    var session = {
1777        /**
1778         * @cfg {String} PERSISTENCE_NAME
1779         * Persistence global key name
1780         * @final
1781         * @private
1782         */
1783        PERSISTENCE_NAME: _g.shared.ClientSidePersistence.decoratePersistenceName("ClientSidePersistence"),
1784
1785        /**
1786         * @cfg {Object} config
1787         * Default configuration of ClientSidePersistence
1788         */
1789        config: {},
1790
1791        /**
1792         * @property {Object} cache
1793         * Client side persistence cache object
1794         * @private
1795         */
1796        cache: null,
1797
1798        /**
1799         * Returns current ClientSidePersistence mode
1800         * @return {Object} Current ClientSidePersistence mode (see {@link #config})
1801         */
1802        getMode: function() {
1803            return this.config.mode;
1804        },
1805
1806        /**
1807         * Returns window object used by ClientSidePersistence
1808         * @return {Object} window object used by ClientSidePersistence
1809         */
1810        getWindow: function() {
1811            return this.config['window'] || _g.shared.Util.getTopWindow();
1812        },
1813
1814        /**
1815         * Prints actual ClientSidePersistence content restricted to specified container name (if specified) and to used mode
1816         * @private
1817         * @return
1818         */
1819        debug: function() {
1820            if (console) {
1821                var map = this.getMap();
1822                var debugInfo = "[ClientSidePersistence -> mode=" + this.getMode().name + ", container=" + (this.config.container || '') + "]\n";
1823                var count = 0;
1824                var containerRE = new RegExp('^' + this.config.container + '/');
1825
1826                for (var idx = 0, keys = Object.keys(map).sort(), last = null; idx < keys.length; idx++) {
1827                    var key = keys[idx];
1828
1829                    if (this.config.container && (typeof(key) == 'string') && !key.match(containerRE)) {
1830                        continue;
1831                    }
1832
1833                    var value = map[key];
1834                    debugInfo += "-[" + ++count + "]->
1834 '" + key.replace(containerRE, '') + "' = '" + decodeURIComponent(value) + "'\n";
1835                }
1836
1837                if (!count) {
1838                    debugInfo += "(container is empty)";
1839                }
1840
1841                console.log(debugInfo);
1842            }
1843        },
1844
1845        /**
1846         * Returns user provided key with container name (if it's specified)
1847         * @param {String} key
1848         * @private
1849         * @return {String} user provided key with container name
1850         */
1851        keyName: function(key) {
1852            return (this.config.container ? (this.config.container + '/') : '') + key;
1853        },
1854
1855        /**
1856         * Returns the list of all the keys contained into the persistence
1857         * @return {String[]} list of the keys
1858         */
1859        getKeys: function() {
1860            var map = this.getMap();
1861            var keys = [];
1862            if( map ) {
1863                for ( var k in map ) {
1864                    if ( this.config.container ) {
1865                        if (k.indexOf(this.config.container + '/') == 0 ) {
1866                            var key = k.substring( this.config.container.length + 1 );
1867                            keys.push(key);
1868                        }
1869                    } else {
1870                        keys.push(k);
1871                    }
1872                }
1873
1874            }
1875            return keys;
1876        },
1877
1878        /**
1879         * Returns the value of the given key.
1880         * @param {String} key
1881         * @return {String} value of a given key
1882         */
1883        get: function(key) {
1884            var value = this.getMap()[this.keyName(key)];
1885            return value ? decodeURIComponent(value) : value;
1886        },
1887
1888        /**
1889         * Sets the value of the given key.
1890         * @param {String} key
1891         * @param {String} value
1892         */
1893        set: function(key, value) {
1894            key = (typeof key === 'string') ? key.replace(/:=/g, '') : '';
1895            var eventData = {'key' : key};
1896            key = this.keyName(key);
1897
1898            if (!key.length) {
1899                return;
1900            }
1901
1902            var result = [];
1903            var map = this.getMap();
1904            eventData.action = map[key] ? "update": "set";
1905
1906            if (value) {
1907                map[key] = encodeURIComponent(value);
1908            } else {
1909                eventData.action = "remove";
1910                delete map[key];
1911            }
1912
1913            for (var entry in map) {
1914                result.push(entry + ':=' + map[entry]);
1915            }
1916
1917            this.cache = map;
1918            this.write(result.join('|'));
1919
1920            _g.$.extend(eventData, {
1921                'value': value,
1922                'mode': this.getMode().name,
1923                'container': this.config.container
1924            });
1925
1926            _g.$(_g.shared.ClientSidePersistence).trigger(_g.shared.ClientSidePersistence.EVENT_NAME, eventData);
1927        },
1928
1929        /**
1930         * Returns object containing a map of key/value pairs
1931         * @private
1932         * @return {Object} map of key/value pairs
1933         */
1934        getMap: function() {
1935            if (!this.cache || !this.config.useCache) {
1936                var data = this.read().split('|');
1937                var result = {};
1938
1939                for (var idx = 0; idx < data.length; idx++) {
1940                    var chunks = data[idx].split(':=');
1941                    var key = chunks[0];
1942
1943                    if (key && key.length) {
1944                        result[key] = chunks[1] || '';
1945                    }
1946                }
1947
1948                this.cache = result;
1949            }
1950
1951            return this.cache;
1952        },
1953
1954        /**
1955         * Removes key from the persistence
1956         * @param {String} key
1957         * @return
1958         */
1959        remove: function(key) {
1960            this.set(key);
1961        },
1962
1963        /**
1964         * Clears the whole content of persistence object
1965         * @return
1966         */
1967        clearMap: function() {
1968            this.write();
1969        },
1970
1971        /**
1972         * Reads the whole content of persistence object
1973         * @private
1974         * @return {String} content of persistence object
1975         */
1976        read: function() {
1977            return this.config.mode.read(this) || '';
1978        },
1979
1980        /**
1981         * Stores user provided data in persistence object
1982         * @param {String} data
1983         * @private
1984         * @return
1985         */
1986        write: function(data) {
1987            this.config.mode.write(this, data || '');
1988        }
1989    };
1990
1991    /* applies user provided config on top of default configuration */
1992    _g.$.extend(session.config, _g.shared.ClientSidePersistence.getDefaultConfig(), cfg);
1993
1994    if (session.config.useContainer === false) {
1995        session.config.container = null;
1996    }
1997
1998    /* check if sessionStorage is supported and switch to localStorage otherwise */
1999    var useFallback;
2000    var testItem = 'test-' + Math.random();
2001
2002    if (session.config.mode === _g.shared.ClientSidePersistence.MODE_SESSION) {
2003        useFallback = false;
2004
2005        try {
2006            window.sessionStorage.setItem(testItem, testItem);
2007            window.sessionStorage.removeItem(testItem);
2008        } catch (error) {
2009            useFallback = true;
2010        }
2011
2012        if (useFallback) {
2013            session.config.mode = _g.shared.ClientSidePersistence.MODE_LOCAL;
2014        }
2015    }
2016
2017    /* check if localStorage is supported and switch to window.name otherwise */
2018    if (session.config.mode === _g.shared.ClientSidePersistence.MODE_LOCAL) {
2019        useFallback = false;
2020
2021        try {
2022            window.localStorage.setItem(testItem, testItem);
2023            window.localStorage.removeItem(testItem);
2024        } catch (error) {
2025            useFallback = true;
2026        }
2027
2028        if (useFallback) {
2029            session.config.mode = _g.shared.ClientSidePersistence.MODE_WINDOW;
2030        }
2031    }
2032
2033    return session;
2034};
2035
2036/**
2037 * @cfg {String} EVENT_NAME
2038 * Event name triggered while setting/updating key in ClientSidePersistence
2039 * @final
2040 * @private
2041 */
2042_g.shared.ClientSidePersistence.EVENT_NAME = 'ClientSidePersistence';
2043
2044/**
2045 * window.sessionStorage implementation for ClientSidePersistence
2046 */
2047_g.shared.ClientSidePersistence.MODE_SESSION = {
2048    /**
2049     * @property {String} name
2050     * Name of MODE_SESSION storage implementation
2051     */
2052    name: 'session',
2053
2054    /**
2055     * Reads the whole content of persistence object (using window.sessionStorage)
2056     * @param {ClientSidePersistence} self
2057     * @return content of persistence object
2058     */
2059    read: function(self) {
2060        return self.getWindow().sessionStorage.getItem(self.PERSISTENCE_NAME);
2061    },
2062
2063    /**
2064     * Stores user provided data in persistence object (using window.sessionStorage)
2065     * @param {ClientSidePersistence} self
2066     * @param {String} value
2067     * @return
2068     */
2069    write: function(self, value) {
2070        if (Granite.OptOutUtil.isOptedOut()) return;
2071        try {
2072            self.getWindow().sessionStorage.setItem(self.PERSISTENCE_NAME, value);
2073        } catch(error) {
2074            //could not deal with the setItem
2075            return;
2076        }
2077    }
2078};
2079
2080/**
2081 * window.localStorage implementation for ClientSidePersistence
2082 */
2083_g.shared.ClientSidePersistence.MODE_LOCAL = {
2084    /**
2085     * @property {String} name
2086     * Name of MODE_LOCAL storage implementation
2087     */
2088    name: 'local',
2089
2090    /**
2091     * Reads the whole content of persistence object (using window.localStorage)
2092     * @param {ClientSidePersistence} self
2093     * @return content of persistence object
2094     */
2095    read: function(self) {
2096        return self.getWindow().localStorage.getItem(self.PERSISTENCE_NAME);
2097    },
2098
2099    /**
2100     * Stores user provided data in persistence object (using window.localStorage)
2101     * @param {ClientSidePersistence} self
2102     * @param {String} value
2103     * @return
2104     */
2105    write: function(self, value) {
2106        if (Granite.OptOutUtil.isOptedOut()) return;
2107        try {
2108            self.getWindow().localStorage.setItem(self.PERSISTENCE_NAME, value);
2109        } catch(error) {
2110            //could not deal with the setItem
2111            return;
2112        }
2113    }
2114};
2115
2116_g.shared.ClientSidePersistence.decoratePersistenceName = function(name) {
2117    return name;
2118};
2119
2120/**
2121 * window.name implementation for ClientSidePersistence
2122 */
2123_g.shared.ClientSidePersistence.MODE_WINDOW = {
2124    /**
2125     * @property {String} name
2126     * Name of MODE_WINDOW storage implementation
2127     */
2128    'name': 'window',
2129
2130    /**
2131     * Reads the whole content of persistence object (using window.name)
2132     * @param {ClientSidePersistence} self
2133     * @return content of persistence object
2134     */
2135    read: function(self) {
2136        return self.getWindow().name;
2137    },
2138
2139    /**
2140     * Stores user provided data in persistence object (using window.name)
2141     * @param {ClientSidePersistence} self
2142     * @param {String} value
2143     * @return
2144     */
2145    write: function(self, value) {
2146        if (Granite.OptOutUtil.isOptedOut()) return;
2147        self.getWindow().name = value;
2148    }
2149};
2150
2151/**
2152 * document.cookie implementation for ClientSidePersistence
2153 */
2154_g.shared.ClientSidePersistence.MODE_COOKIE = {
2155    /**
2156     * @property {String} COOKIE_NAME
2157     * Cookie key name used by MODE_COOKIE persistence mode
2158     */
2159    COOKIE_NAME: _g.shared.ClientSidePersistence.decoratePersistenceName("SessionPersistence"),
2160
2161    /**
2162     * @property {String} name
2163     * Name of MODE_COOKIE storage implementation
2164     */
2165    name: 'cookie',
2166
2167    /**
2168     * Reads the whole content of persistence object (using document.cookie)
2169     * @param {ClientSidePersistence} self
2170     * @return content of persistence object
2171     */
2172    read: function(self) {
2173        return _g.shared.ClientSidePersistence.CookieHelper.read(this.COOKIE_NAME);
2174    },
2175
2176    /**
2177     * Stores or clears user provided data in persistence object (using document.cookie)
2178     * @param {ClientSidePersistence} self
2179     * @param {String} value (optional)
2180     * @return
2181     */
2182    write: function(self, value) {
2183        if (Granite.OptOutUtil.isOptedOut() && !Granite.OptOutUtil.maySetCookie(this.COOKIE_NAME)) return;
2184        if (!value) {
2185            _g.shared.ClientSidePersistence.CookieHelper.erase(this.COOKIE_NAME);
2186        } else {
2187            _g.shared.ClientSidePersistence.CookieHelper.set(this.COOKIE_NAME, value, 365 /* days */);
2188        }
2189    }
2190};
2191
2192/*
2193 * ClientSidePersistence default config
2194 */
2195_g.shared.ClientSidePersistence.getDefaultConfig = function() {
2196    return {
2197        /**
2198         * @property {Object} window
2199         * Defines which window object should be used by ClientSidePersistence
2200         */
2201        window: _g.shared.Util.getTopWindow(),
2202
2203        /**
2204         * @property {Boolean} useCache
2205         * Determines if ClientSidePersistence should use internal 
2205cache
2206         */
2207        useCache: false,
2208
2209        /**
2210         * @property {String} container
2211         * Container name where key/values will be stored (by default it's null)
2212         */
2213        container: null,
2214
2215        /**
2216         * @property {Object} mode
2217         * Defines which mode should be used (available modes are {@link _g.shared.ClientSidePersistence.MODE_SESSION MODE_SESSION},
2218         * {@link _g.shared.ClientSidePersistence.MODE_LOCAL MODE_LOCAL}, {@link _g.shared.ClientSidePersistence.MODE_WINDOW MODE_WINDOW}
2219         * and {@link _g.shared.ClientSidePersistence.MODE_COOKIE MODE_COOKIE})
2220         */
2221        mode: _g.shared.ClientSidePersistence.MODE_LOCAL
2222    };
2223};
2224
2225/**
2226 * Cookie helper class.
2227 * @class _g.shared.ClientSidePersistence.CookieHelper
2228 * @singleton
2229 */
2230_g.shared.ClientSidePersistence.CookieHelper = {
2231    /**
2232     * Sets a cookie.
2233     * @param {String} name
2234     * @param {String} value
2235     * @param {Number} days
2236     */
2237    set: function(name, value, days) {
2238        var expires = "";
2239        if (days) {
2240            var date = new Date();
2241            date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
2242            expires = "; expires=" + date.toGMTString();
2243        }
2244        if (value) {
2245            value = encodeURIComponent(value);
2246        }
2247        document.cookie = name + "=" + value + expires + "; path=/";
2248    },
2249
2250    /**
2251     * Returns the value of the cookie of the given name.
2252     * @param {String} name
2253     * @return {String} value of a given name (can be null)
2254     */
2255    read: function(name) {
2256        var nameEQ = name + "=";
2257        var ca = document.cookie.split(';');
2258        for (var i = 0; i < ca.length; i++) {
2259            var c = ca[i];
2260            while (c.charAt(0) == ' ') c = c.substring(1, c.length);
2261            if (c.indexOf(nameEQ) == 0) {
2262                var value = c.substring(nameEQ.length, c.length);
2263                return value ? decodeURIComponent(value) : null;
2264            }
2265        }
2266        return null;
2267    },
2268
2269    /**
2270     * Removes the cookie of the given name.
2271     * @param {String} name
2272     */
2273    erase: function(name) {
2274        _g.shared.ClientSidePersistence.CookieHelper.set(name, "", -1);
2275    }
2276};
2277
2278/*
2279 * Clears client side persistence using all implemented modes
2280 */
2281_g.shared.ClientSidePersistence.clearAllMaps = function() {
2282    var modes = [
2283        _g.shared.ClientSidePersistence.MODE_COOKIE,
2284        _g.shared.ClientSidePersistence.MODE_LOCAL,
2285        _g.shared.ClientSidePersistence.MODE_SESSION,
2286        _g.shared.ClientSidePersistence.MODE_WINDOW
2287    ];
2288
2289    _g.$.each(modes, function(id, mode) {
2290        var persistence = new _g.shared.ClientSidePersistence({'mode': mode});
2291        persistence.clearMap();
2292    });
2293};
2294
2295/*
2296 * ADOBE CONFIDENTIAL
2297 *
2298 * Copyright 2012 Adobe Systems Incorporated
2299 * All Rights Reserved.
2300 *
2301 * NOTICE:  All information contained herein is, and remains
2302 * the property of Adobe Systems Incorporated and its suppliers,
2303 * if any.  The intellectual and technical concepts contained
2304 * herein are proprietary to Adobe Systems Incorporated and its
2305 * suppliers and may be covered by U.S. and Foreign Patents,
2306 * patents in process, and are protected by trade secret or copyright law.
2307 * Dissemination of this information or reproduction of this material
2308 * is strictly forbidden unless prior written permission is obtained
2309 * from Adobe Systems Incorporated.
2310 *
2311 */
2312
2313//------------------------------------------------------------------------------
2314// Initialize the Granite shared library
2315
2316//todo: user language (not yet available)
2317//_g.I18n.init({locale: _g.User.getLanguage()});
2318_g.I18n.init();
2319
2320/*
2321 * Copyright 1997-2010 Day Management AG
2322 * Barfuesserplatz 6, 4001 Basel, Switzerland
2323 * All Rights Reserved.
2324 *
2325 * This software is the confidential and proprietary information of
2326 * Day Management AG, ("Confidential Information"). You shall not
2327 * disclose such Confidential Information and shall use it only in
2328 * accordance with the terms of the license agreement you entered into
2329 * with Day.
2330 */
2331
2332
2333/*
2334 * Copyright 1997-2010 Day Management AG
2335 * Barfuesserplatz 6, 4001 Basel, Switzerland
2336 * All Rights Reserved.
2337 *
2338 * This software is the confidential and proprietary information of
2339 * Day Management AG, ("Confidential Information"). You shall not
2340 * disclose such Confidential Information and shall use it only in
2341 * accordance with the terms of the license agreement you entered into
2342 * with Day.
2343 */
2344
2345/**
2346 * The <code>CQ</code> library contains all CQ component classes and utilities.
2347 * @static
2348 */
2349window.CQ = window.CQ || {};
2350
2351// map CQ.shared to Granite shared
2352CQ.shared = _g.shared;
2353
2354// shortcuts
2355CQ.Sling = CQ.shared.Sling;
2356CQ.I18n = CQ.shared.I18n;
2357
2358// map constants for portlet support
2359G_XHR_HOOK = typeof CQ_XHR_HOOK != "undefined" ? CQ_XHR_HOOK : undefined;
2360G_RELOAD_HOOK = typeof CQ_RELOAD_HOOK != "undefined" ? CQ_RELOAD_HOOK : undefined;
2361G_IS_HOOKED = typeof CQ_IS_HOOKED != "undefined" ? CQ_IS_HOOKED : undefined;
2362G_CONTENT_PATH = typeof CQ_CONTENT_PATH != "undefined" ? CQ_CONTENT_PATH : undefined;
2363
2364/**
2365 * ADOBE CONFIDENTIAL
2366 *
2367 * Copyright 2011 Adobe Systems Incorporated
2368 * All Rights Reserved.
2369 *
2370 * NOTICE:  All information contained herein is, and remains
2371 * the property of Adobe Systems Incorporated and its suppliers,
2372 * if any.  The intellectual and technical concepts contained
2373 * herein are proprietary to Adobe Systems Incorporated and its
2374 * suppliers and may be covered by U.S. and Foreign Patents,
2375 * patents in process, and are protected by trade secret or copyright law.
2376 * Dissemination of this information or reproduction of this material
2377 * is strictly forbidden unless prior written permission is obtained
2378 * from Adobe Systems Incorporated.
2379 *
2380 */
2381
2382/**
2383 * A helper class providing a set of form related utilities.
2384 * @static
2385 * @singleton
2386 * @class CQ.shared.Form
2387 */
2388CQ.shared.Form = function() {
2389
2390    /**
2391     * Returns an associative array mapping ids to label nodes.
2392     * @private
2393     * @return {Object} For instance:
2394     *      {
2395     *          id1: labelNode1,
2396     *          id2: labelNode2,
2397     *          ...
2398     *      }
2399     */
2400    var getDocumentLabelMap = function() {
2401        var contentFrame = parent.frames["ContentFrame"],
2402        doc = contentFrame !== undefined ? contentFrame.contentDocument : document;
2403
2404        var labelMap = new Object();
2405        var labelNodes = doc.getElementsByTagName("label");
2406        for (var i = 0; i < labelNodes.length; i++) {
2407            var forId = labelNodes[i].htmlFor;  // buggy IE can't handle getAttribute("for")
2408            if (forId) {
2409                labelMap[forId] = labelNodes[i];
2410            }
2411        }
2412        return labelMap;
2413    };
2414
2415    /**
2416     * Given a <label> node (perhaps one containing <input> or <select> children), return the text
2417     * content (excluding any <input> or <select> content).
2418     * @private
2419     * @return {String} The text content of all non-<input> and non-<select> descendants.
2420     */
2421    var getLabelNodeTextContent = function(node) {
2422        var text = "";
2423        var walkTree = function(node) {
2424            if (node.nodeType == 3) { // text node
2425                text += node.nodeValue;
2426            }
2427            if (node.nodeName.toLowerCase() == "select"
2428                || node.nodeName.toLowerCase() == "input"
2429                || node.nodeName.toLowerCase() == "textarea"
2430                || node.nodeName.toLowerCase() == "button") {
2431                // don't walk into fields if they're children of the label
2432                return;
2433            }
2434            for (var i = 0; node.childNodes && i < node.childNodes.length; i++) {
2435                walkTree(node.childNodes[i]);
2436            }
2437        };
2438        walkTree(node);
2439        return text;
2440    };
2441
2442    /**
2443     * Given an indexed id, return the id for the parent section (the id with the index stripped off).
2444     * @private
2445     */
2446    var getSectionIdForIndexedId = function(id) {
2447        return id.replace(/-\d+$/, "");
2448    };
2449
2450    /**
2451     * <p>Return the label text (as a <code>String</code>) for a particular <code>id</code>.  When a label
2452     * can't be found, return the id itself as a fall-back.</p>
2453     * <p>Note: Public callers can ignore the <code>documentLabelMap</code> parameter (it's used internally
2454     * as a caching mechanism).</p>
2455     * @param {String} id The id which the target <code>&lt;label&gt;</code> refers to.
2456     * @return {String} The label text.
2457     */
2458    var getLabelForId = function(id, documentLabelMap) {
2459        if (!documentLabelMap) {
2460            documentLabelMap = getDocumentLabelMap();
2461        }
2462
2463        if (documentLabelMap[id]) {
2464            return getLabelNodeTextContent(documentLabelMap[id]);
2465        }
2466        return null;
2467    };
2468
2469    /**
2470     * Locate the default values for the given node. Supported nodes
2471     * include, <code>input</code>, <code>textarea</code>, <code>option</code>.
2472     *
2473     * @private
2474     * @param {HTMLElement} node The element which to locate the default value for.
2475     * @return {String} the default value for the given node.
2476     */
2477    var getDefaultValue = function(node) {
2478        var defaultValue;
2479        var nodeName = node.nodeName.toLowerCase();
2480        var nodeType = hasAttribute(node, "type") ? node.getAttribute("type") : undefined;
2481
2482        if (nodeName == "input") {
2483            if (nodeType == "radio" || nodeType == "checkbox") {
2484                if (hasAttribute(node, "checked")) {
2485                    defaultValue = node.getAttribute("value");
2486                }
2487            } else if (node.type == "text") {
2488                defaultValue = node.defaultValue;
2489                // support elements like hidden, reset, submit
2490            } else {
2491                defaultValue = node.value;
2492            }
2493        } else if (nodeName == "textarea") {
2494            defaultValue = node.value;
2495        } else if (nodeName == "option" && hasAttribute(node, "selected")) {
2496            defaultValue = node.getAttribute("value");
2497        }
2498
2499        return defaultValue;
2500    };
2501
2502    /**
2503     * Helper function to get around IE7 not supporting hasAttribute.
2504     * @private
2505     * @param {HTMLElement} el the html element
2506     * @param {String} attr the attribute to test for.
2507     */
2508    var hasAttribute = function(el, attr) {
2509        if (el == null) {
2510            return false;
2511        }
2512
2513        // IE8 issue with attributes being not null but empty string
2514        return ($CQ(el).attr(attr) != undefined);
2515    };
2516
2517    return {
2518
2519        /**
2520         * Searches an array for an object with a particular property of a particular value.
2521         * @return {Object} the first object which matches, or null if no objects match.
2522         */
2523        searchArray: function(arr, testProperty, testValue) {
2524            for (var i = 0; i < arr.length; i++) {
2525                if (arr[i][testProperty] && arr[i][testProperty] == testValue) {
2526                    return arr[i];
2527                }
2528            }
2529            return null;
2530        },
2531
2532        /**
2533         * <p>Return the label text for an <code>&lt;input&gt;</code> or <code>&lt;select&gt;</code>.  When a
2534         * label can't be found, the element's name attribute is used as a fall-back.</p>
2535         * <p>Note: Public callers can ignore the <code>documentLabelMap</code> parameter (it's used internally
2536         * as a caching mechanism).</p>
2537         * @param {HTMLElement} fieldNode The <code>&lt;input&gt;</code>, <code>&lt;select&gt;</code> or
2538         * <code>&lt;textArea&gt;</code> node.
2539         * @return {String} The label text.
2540         */
2541        getLabelForField: function(fieldNode, documentLabelMap) {
2542            if (!documentLabelMap) {
2543                documentLabelMap = getDocumentLabelMap();
2544            }
2545
2546            var id = fieldNode.getAttribute("id");
2547            if (id && documentLabelMap[id]) {
2548                return getLabelNodeTextContent(documentLabelMap[id]);
2549            }
2550
2551            var parent = fieldNode.parentNode;
2552            while (parent) {
2553                if (parent.nodeName.toLowerCase() == "label") {
2554                    return getLabelNodeTextContent(parent);
2555                }
2556                parent = parent.parentNode;
2557            }
2558
2559            // No label found; we'll have to live with the name:
2560            return fieldNode.getAttribute("name");
2561        },
2562
2563        /**
2564         * Get a list of fields in the document.
2565         * @return {Array} Each object in the array represents a field.  Each field contains:
2566         * <div class="mdetail-params"><ul)
2567         *   <li><code>text</code> : String<div class="sub-desc">The label to display (usually the field's caption).</div></li>
2568         *   <li><code>value</code> : String<div class="sub-desc">The name of the field.</div></li>
2569         *   <li><code>enumeration</code> : Array|null<div class="sub-desc">For enumerated fields, a nested array of text/value pairs.</div></li>
2570         * </ul></div>
2571         */
2572        getFields: function() {
2573            var contentFrame = parent.frames["ContentFrame"],
2574                doc = contentFrame !== undefined ? contentFrame.contentDocument : document,
2575                documentLabelMap = getDocumentLabelMap();
2576
2577            var fields = [];
2578
2579            var visitNamedNode = function(node, inLocalNode, selector) {
2580                var name = node.getAttribute("name");
2581                var nodeType = node.nodeName.toLowerCase();
2582                var field;
2583
2584                if (nodeType == "input" || nodeType == "textarea") {
2585                    var controlType = hasAttribute(node, "type") ? node.getAttribute("type").toLowerCase() : "text";
2586                    if (controlType == "button" || controlType == "submit" || controlType == "reset") {
2587                        return;
2588                    }
2589
2590                    // Fetch (or create) the field record:
2591                    //
2592                    field = CQ.shared.Form.searchArray(fields, "value", name);
2593                    if (!field) {
2594                        fields.push({
2595                            "text": CQ.shared.Form.getLabelForField(node, documentLabelMap),
2596                            "value": name,      // for Selection.setOptions()
2597                            "name": name,       // for everyone else
2598                            "enumeration": undefined,
2599                            "local": inLocalNode,
2600                            "selector": selector,
2601                            "type": nodeType,
2602                            "defaultValue": getDefaultValue(node),
2603                            "node": node
2604                        });
2605                        field = fields[fields.length-1];
2606                    }
2607
2608                    // See if we're an enumeration.  Note that Sidekick-authored checkboxes are always
2609                    // enumerations, even when they appear singly.
2610                    //
2611                    if (controlType == "radio" || (field.local && controlType == "checkbox")) {
2612                        if (!field.enumeration) {
2613                            // This is the first one we've found of this group; promote the label to the
2614                            // section label
2615                            var inputId = node.getAttribute("id");
2616                            if (inputId) {
2617                                var sectionId = getSectionIdForIndexedId(inputId);
2618                                var sectionLabel = getLabelForId(sectionId, documentLabelMap);
2619                                field.text = (sectionLabel ? sectionLabel : name);
2620                            } else {
2621                                field.text = name;
2622                            }
2623                            field.enumeration = [];
2624                        }
2625                        field.enumeration.push({
2626                            "text": CQ.shared.Form.getLabelForField(node, documentLabelMap),
2627                            "value": node.getAttribute("value"),
2628                            "defaultValue": getDefaultValue(node),
2629                            "node": node
2630                        });
2631                    }
2632                } else if (nodeType == "select") {
2633                    // Create the field record:
2634                    //
2635                    fields.push({
2636                        "text": CQ.shared.Form.getLabelForField(node, documentLabelMap),
2637                        "value": name,              // for Selection.setOptions()
2638                        "name": name,               // for everyone else
2639                        "enumeration": [],
2640                        "local": inLocalNode,
2641                        "type": nodeType,
2642                        "selector": selector,
2643                        "defaultValue": undefined,  // defaultValues are on the options, not select element
2644                        "node": node
2645                    });
2646                    field = fields[fields.length-1];
2647
2648                    // Add the options to the field's enumeration:
2649                    //
2650                    var optionNodes = node.getElementsByTagName("option");
2651                    for (var i = 0; i < optionNodes.length; i++) {
2652                        field.enumeration.push({
2653                            "text": optionNodes[i].innerHTML,
2654                            "value": optionNodes[i].getAttribute("value"),
2655                            "defaultValue": getDefaultValue(optionNodes[i]),
2656                            "node": optionNodes[i]
2657                        });
2658                    }
2659                }
2660            };
2661
2662            var walkTree = function(node, inLocalNode, selector) {
2663                if (node.nodeName.toLowerCase() == "div" && $CQ(node).children('.form_row').length > 0) {
2664                    inLocalNode = true;
2665                    selector = $CQ(node).attr('class').replace(/\s/g,'\.');
2666                }
2667
2668                if (node.getAttribute && node.getAttribute("name")) {
2669                    visitNamedNode(node, inLocalNode, selector);
2670                }
2671
2672                for (var i = 0; node.childNodes && i < node.childNodes.length; i++) {
2673                    var child = node.childNodes[i];
2674                    if (child.nodeType == 1) { // if element
2675                        walkTree(child, inLocalNode, selector);
2676                    }
2677                }
2678            };
2679
2680            walkTree(doc, false, undefined);
2681            return fields;
2682        }
2683    }
2684}();
2685
2686/*
2687 * Copyright 1997-2009 Day Management AG
2688 * Barfuesserplatz 6, 4001 Basel, Switzerland
2689 * All Rights Reserved.
2690 *
2691 * This software is the confidential and proprietary information of
2692 * Day Management AG, ("Confidential Information"). You shall not
2693 * disclose such Confidential Information and shall use it only in
2694 * accordance with the terms of the license agreement you entered into
2695 * with Day.
2696 */
2697
2698/**
2699 * A helper class providing information about a CQ user.
2700 * @class CQ.shared.User
2701 * @singleton
2702 */
2703CQ.shared.User = function(infoData) {
2704    return  {
2705        /**
2706         * @property {Object} data
2707         * The user data.
2708         * @private
2709         */
2710        data: null,
2711
2712        /**
2713         * @property {String} language
2714         * Resolved language read from preferences
2715         * @private
2716         */
2717        language: null,
2718
2719        /**
2720         * @property {String} userPropsPath
2721         * The path where user properties may be requested from.
2722         * @private
2723         */
2724        userPropsPath: null,
2725
2726        /**
2727         * Assembles the url to request the user properties from.
2728         * Apply default if no path has been set.
2729         * @private
2730         */
2731        getUserPropsUrl: function() {
2732            if(!this.userPropsPath) {
2733                this.userPropsPath = CQ.shared.User.PROXY_URI;
2734            }
2735            return this.userPropsPath;
2736        },
2737
2738        /**
2739         * Loads the data.
2740         * @private
2741         */
2742        load: function() {
2743            var url = this.getUserPropsUrl();
2744            url = CQ.shared.HTTP.noCaching(url);
2745            var response = CQ.shared.HTTP.get(url);
2746            if (CQ.shared.HTTP.isOk(response)) {
2747                this.data = CQ.shared.Util.eval(response);
2748            }
2749        },
2750
2751        /**
2752         * Instantly initializes the user via a request to server or the provided infoData if it has not already been initialized.
2753         * @param {Object} infoData (optional) Data to initialize the user with
2754         * @param {Boolean} force  (otpional) True to force initialization (in case of second initialization)
2755         * @return {Object} The initialization data
2756         */
2757        init: function(infoData, force) {
2758            if( !this.initialized || force) {
2759                if (infoData) {
2760                    // this is not used yet
2761                    this.data = infoData;
2762                } else {
2763                    this.load();
2764                }
2765                this.initialized = true;
2766            }
2767            return this.data;
2768        },
2769
2770        /**
2771         * Initializes the user via a request to server only when user is used for the first time.
2772         */
2773        lazyInit: function() {
2774            this.lazyLoad = function() {
2775                this.load();
2776                this.initialized = true;
2777            }
2778        },
2779
2780        /**
2781         * Returns if the user has been initialized.
2782         * @return {Boolean} True if initialized, false otherwise.
2783         */
2784        isInitialized: function() {
2785            return this.initialized;
2786        },
2787
2788        /**
2789         * Returns the language selected by the user.
2790         * @return {String} The language
2791         */
2792        getLanguage: function() {
2793            if( !this.isInitialized() && this.lazyLoad ) {
2794                this.lazyLoad.call(this);
2795            }
2796
2797            this.language = this.data &&
2798                this.data["preferences"] &&
2799                this.data["preferences"]["language"] ?
2800                this.data["preferences"]["language"] :
2801                "en";
2802            return this.language;
2803        }
2804
2805    }
2806
2807}();
2808
2809/**
2810 * The URI to retrieve the user info from (defaults to <code>"/libs/cq/security/userinfo.json"</code>).
2811 * @static
2812 * @final
vendor: 4,711 bytes, lines 2813-2926
2813 * @type String
2814 */
2815CQ.shared.User.PROXY_URI = CQ.shared.HTTP.externalize("/libs/cq/security/userinfo" + CQ.shared.HTTP.EXTENSION_JSON);
2816/*
2817 * Copyright 1997-2010 Day Management AG
2818 * Barfuesserplatz 6, 4001 Basel, Switzerland
2819 * All Rights Reserved.
2820 *
2821 * This software is the confidential and proprietary information of
2822 * Day Management AG, ("Confidential Information"). You shall not
2823 * disclose such Confidential Information and shall use it only in
2824 * accordance with the terms of the license agreement you entered into
2825 * with Day.
2826 */
2827//------------------------------------------------------------------------------
2828// Initialize the CQ shared library
2829
2830CQ.shared.User.lazyInit();
2831
2832CQ.shared.I18n.init({
2833    locale: function() { return document.documentElement.lang || CQ.shared.User.getLanguage();},
2834    urlPrefix: "/libs/cq/i18n/dict."
2835});
2836
2837(function (global, factory) {
2838  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
2839  typeof define === 'function' && define.amd ? define('underscore', factory) :
2840  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, (function () {
2841    var current = global._;
2842    var exports = global._ = factory();
2843    exports.noConflict = function () { global._ = current; return exports; };
2844  }()));
2845}(this, (function () {
2846  //     Underscore.js 1.13.5
2847  //     https://underscorejs.org
2848  //     (c) 2009-2022 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors
2849  //     Underscore may be freely distributed under the MIT license.
2850
2851  // Current version.
2852  var VERSION = '1.13.5';
2853
2854  // Establish the root object, `window` (`self`) in the browser, `global`
2855  // on the server, or `this` in some virtual machines. We use `self`
2856  // instead of `window` for `WebWorker` support.
2857  var root = (typeof self == 'object' && self.self === self && self) ||
2858            (typeof global == 'object' && global.global === global && global) ||
2859            Function('return this')() ||
2860            {};
2861
2862  // Save bytes in the minified (but not gzipped) version:
2863  var ArrayProto = Array.prototype, ObjProto = Object.prototype;
2864  var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null;
2865
2866  // Create quick reference variables for speed access to core prototypes.
2867  var push = ArrayProto.push,
2868      slice = ArrayProto.slice,
2869      toString = ObjProto.toString,
2870      hasOwnProperty = ObjProto.hasOwnProperty;
2871
2872  // Modern feature detection.
2873  var supportsArrayBuffer = typeof ArrayBuffer !== 'undefined',
2874      supportsDataView = typeof DataView !== 'undefined';
2875
2876  // All **ECMAScript 5+** native function implementations that we hope to use
2877  // are declared here.
2878  var nativeIsArray = Array.isArray,
2879      nativeKeys = Object.keys,
2880      nativeCreate = Object.create,
2881      nativeIsView = supportsArrayBuffer && ArrayBuffer.isView;
2882
2883  // Create references to these builtin functions because we override them.
2884  var _isNaN = isNaN,
2885      _isFinite = isFinite;
2886
2887  // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
2888  var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');
2889  var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
2890    'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
2891
2892  // The largest integer that can be represented exactly.
2893  var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
2894
2895  // Some functions take a variable number of arguments, or a few expected
2896  // arguments at the beginning and then a variable number of values to operate
2897  // on. This helper accumulates all remaining arguments past the function’s
2898  // argument length (or an explicit `startIndex`), into an array that becomes
2899  // the last argument. Similar to ES6’s "rest parameter".
2900  function restArguments(func, startIndex) {
2901    startIndex = startIndex == null ? func.length - 1 : +startIndex;
2902    return function() {
2903      var length = Math.max(arguments.length - startIndex, 0),
2904          rest = Array(length),
2905          index = 0;
2906      for (; index < length; index++) {
2907        rest[index] = arguments[index + startIndex];
2908      }
2909      switch (startIndex) {
2910        case 0: return func.call(this, rest);
2911        case 1: return func.call(this, arguments[0], rest);
2912        case 2: return func.call(this, arguments[0], arguments[1], rest);
2913      }
2914      var args = Array(startIndex + 1);
2915      for (index = 0; index < startIndex; index++) {
2916        args[index] = arguments[index];
2917      }
2918      args[startIndex] = rest;
2919      return func.apply(this, args);
2920    };
2921  }
2922
2923  // Is a given variable an object?
2924  function isObject(obj) {
2925    var type = typeof obj;
2926    return type === 'function' || (type === 'object' && !!obj)
vendor: 5,142 bytes, lines 2926-3088
2926;
2927  }
2928
2929  // Is a given value equal to null?
2930  function isNull(obj) {
2931    return obj === null;
2932  }
2933
2934  // Is a given variable undefined?
2935  function isUndefined(obj) {
2936    return obj === void 0;
2937  }
2938
2939  // Is a given value a boolean?
2940  function isBoolean(obj) {
2941    return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
2942  }
2943
2944  // Is a given value a DOM element?
2945  function isElement(obj) {
2946    return !!(obj && obj.nodeType === 1);
2947  }
2948
2949  // Internal function for creating a `toString`-based type tester.
2950  function tagTester(name) {
2951    var tag = '[object ' + name + ']';
2952    return function(obj) {
2953      return toString.call(obj) === tag;
2954    };
2955  }
2956
2957  var isString = tagTester('String');
2958
2959  var isNumber = tagTester('Number');
2960
2961  var isDate = tagTester('Date');
2962
2963  var isRegExp = tagTester('RegExp');
2964
2965  var isError = tagTester('Error');
2966
2967  var isSymbol = tagTester('Symbol');
2968
2969  var isArrayBuffer = tagTester('ArrayBuffer');
2970
2971  var isFunction = tagTester('Function');
2972
2973  // Optimize `isFunction` if appropriate. Work around some `typeof` bugs in old
2974  // v8, IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236).
2975  var nodelist = root.document && root.document.childNodes;
2976  if (typeof /./ != 'function' && typeof Int8Array != 'object' && typeof nodelist != 'function') {
2977    isFunction = function(obj) {
2978      return typeof obj == 'function' || false;
2979    };
2980  }
2981
2982  var isFunction$1 = isFunction;
2983
2984  var hasObjectTag = tagTester('Object');
2985
2986  // In IE 10 - Edge 13, `DataView` has string tag `'[object Object]'`.
2987  // In IE 11, the most common among them, this problem also applies to
2988  // `Map`, `WeakMap` and `Set`.
2989  var hasStringTagBug = (
2990        supportsDataView && hasObjectTag(new DataView(new ArrayBuffer(8)))
2991      ),
2992      isIE11 = (typeof Map !== 'undefined' && hasObjectTag(new Map));
2993
2994  var isDataView = tagTester('DataView');
2995
2996  // In IE 10 - Edge 13, we need a different heuristic
2997  // to determine whether an object is a `DataView`.
2998  function ie10IsDataView(obj) {
2999    return obj != null && isFunction$1(obj.getInt8) && isArrayBuffer(obj.buffer);
3000  }
3001
3002  var isDataView$1 = (hasStringTagBug ? ie10IsDataView : isDataView);
3003
3004  // Is a given value an array?
3005  // Delegates to ECMA5's native `Array.isArray`.
3006  var isArray = nativeIsArray || tagTester('Array');
3007
3008  // Internal function to check whether `key` is an own property name of `obj`.
3009  function has$1(obj, key) {
3010    return obj != null && hasOwnProperty.call(obj, key);
3011  }
3012
3013  var isArguments = tagTester('Arguments');
3014
3015  // Define a fallback version of the method in browsers (ahem, IE < 9), where
3016  // there isn't any inspectable "Arguments" type.
3017  (function() {
3018    if (!isArguments(arguments)) {
3019      isArguments = function(obj) {
3020        return has$1(obj, 'callee');
3021      };
3022    }
3023  }());
3024
3025  var isArguments$1 = isArguments;
3026
3027  // Is a given object a finite number?
3028  function isFinite$1(obj) {
3029    return !isSymbol(obj) && _isFinite(obj) && !isNaN(parseFloat(obj));
3030  }
3031
3032  // Is the given value `NaN`?
3033  function isNaN$1(obj) {
3034    return isNumber(obj) && _isNaN(obj);
3035  }
3036
3037  // Predicate-generating function. Often useful outside of Underscore.
3038  function constant(value) {
3039    return function() {
3040      return value;
3041    };
3042  }
3043
3044  // Common internal logic for `isArrayLike` and `isBufferLike`.
3045  function createSizePropertyCheck(getSizeProperty) {
3046    return function(collection) {
3047      var sizeProperty = getSizeProperty(collection);
3048      return typeof sizeProperty == 'number' && sizeProperty >= 0 && sizeProperty <= MAX_ARRAY_INDEX;
3049    }
3050  }
3051
3052  // Internal helper to generate a function to obtain property `key` from `obj`.
3053  function shallowProperty(key) {
3054    return function(obj) {
3055      return obj == null ? void 0 : obj[key];
3056    };
3057  }
3058
3059  // Internal helper to obtain the `byteLength` property of an object.
3060  var getByteLength = shallowProperty('byteLength');
3061
3062  // Internal helper to determine whether we should spend extensive checks against
3063  // `ArrayBuffer` et al.
3064  var isBufferLike = createSizePropertyCheck(getByteLength);
3065
3066  // Is a given value a typed array?
3067  var typedArrayPattern = /\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/;
3068  function isTypedArray(obj) {
3069    // `ArrayBuffer.isView` is the most future-proof, so use it when available.
3070    // Otherwise, fall back on the above regular expression.
3071    return nativeIsView ? (nativeIsView(obj) && !isDataView$1(obj)) :
3072                  isBufferLike(obj) && typedArrayPattern.test(toString.call(obj));
3073  }
3074
3075  var isTypedArray$1 = supportsArrayBuffer ? isTypedArray : constant(false);
3076
3077  // Internal helper to obtain the `length` property of an object.
3078  var getLength = shallowProperty('length');
3079
3080  // Internal helper to create a simple lookup structure.
3081  // `collectNonEnumProps` used to depend on `_.contains`, but this led to
3082  // circular imports. `emulatedSet` is a one-off solution that only works for
3083  // arrays of strings.
3084  function emulatedSet(keys) {
3085    var hash = {};
3086    for (var l = keys.length, i = 0; i < l; ++i) hash[keys[i]] = true;
3087    return {
3088      contains: function(key) { return hash[key]
3088 === true; },
3089      push: function(key) {
3090        hash[key] = true;
3091        return keys.push(key);
3092      }
3093    };
3094  }
3095
3096  // Internal helper. Checks `keys` for the presence of keys in IE < 9 that won't
3097  // be iterated by `for key in ...` and thus missed. Extends `keys` in place if
3098  // needed.
3099  function collectNonEnumProps(obj, keys) {
3100    keys = emulatedSet(keys);
3101    var nonEnumIdx = nonEnumerableProps.length;
3102    var constructor = obj.constructor;
3103    var proto = (isFunction$1(constructor) && constructor.prototype)
vendor: 40,901 bytes, lines 3103-4279
3103 || ObjProto;
3104
3105    // Constructor is a special case.
3106    var prop = 'constructor';
3107    if (has$1(obj, prop) && !keys.contains(prop)) keys.push(prop);
3108
3109    while (nonEnumIdx--) {
3110      prop = nonEnumerableProps[nonEnumIdx];
3111      if (prop in obj && obj[prop] !== proto[prop] && !keys.contains(prop)) {
3112        keys.push(prop);
3113      }
3114    }
3115  }
3116
3117  // Retrieve the names of an object's own properties.
3118  // Delegates to **ECMAScript 5**'s native `Object.keys`.
3119  function keys(obj) {
3120    if (!isObject(obj)) return [];
3121    if (nativeKeys) return nativeKeys(obj);
3122    var keys = [];
3123    for (var key in obj) if (has$1(obj, key)) keys.push(key);
3124    // Ahem, IE < 9.
3125    if (hasEnumBug) collectNonEnumProps(obj, keys);
3126    return keys;
3127  }
3128
3129  // Is a given array, string, or object empty?
3130  // An "empty" object has no enumerable own-properties.
3131  function isEmpty(obj) {
3132    if (obj == null) return true;
3133    // Skip the more expensive `toString`-based type checks if `obj` has no
3134    // `.length`.
3135    var length = getLength(obj);
3136    if (typeof length == 'number' && (
3137      isArray(obj) || isString(obj) || isArguments$1(obj)
3138    )) return length === 0;
3139    return getLength(keys(obj)) === 0;
3140  }
3141
3142  // Returns whether an object has a given set of `key:value` pairs.
3143  function isMatch(object, attrs) {
3144    var _keys = keys(attrs), length = _keys.length;
3145    if (object == null) return !length;
3146    var obj = Object(object);
3147    for (var i = 0; i < length; i++) {
3148      var key = _keys[i];
3149      if (attrs[key] !== obj[key] || !(key in obj)) return false;
3150    }
3151    return true;
3152  }
3153
3154  // If Underscore is called as a function, it returns a wrapped object that can
3155  // be used OO-style. This wrapper holds altered versions of all functions added
3156  // through `_.mixin`. Wrapped objects may be chained.
3157  function _$1(obj) {
3158    if (obj instanceof _$1) return obj;
3159    if (!(this instanceof _$1)) return new _$1(obj);
3160    this._wrapped = obj;
3161  }
3162
3163  _$1.VERSION = VERSION;
3164
3165  // Extracts the result from a wrapped and chained object.
3166  _$1.prototype.value = function() {
3167    return this._wrapped;
3168  };
3169
3170  // Provide unwrapping proxies for some methods used in engine operations
3171  // such as arithmetic and JSON stringification.
3172  _$1.prototype.valueOf = _$1.prototype.toJSON = _$1.prototype.value;
3173
3174  _$1.prototype.toString = function() {
3175    return String(this._wrapped);
3176  };
3177
3178  // Internal function to wrap or shallow-copy an ArrayBuffer,
3179  // typed array or DataView to a new view, reusing the buffer.
3180  function toBufferView(bufferSource) {
3181    return new Uint8Array(
3182      bufferSource.buffer || bufferSource,
3183      bufferSource.byteOffset || 0,
3184      getByteLength(bufferSource)
3185    );
3186  }
3187
3188  // We use this string twice, so give it a name for minification.
3189  var tagDataView = '[object DataView]';
3190
3191  // Internal recursive comparison function for `_.isEqual`.
3192  function eq(a, b, aStack, bStack) {
3193    // Identical objects are equal. `0 === -0`, but they aren't identical.
3194    // See the [Harmony `egal` proposal](https://wiki.ecmascript.org/doku.php?id=harmony:egal).
3195    if (a === b) return a !== 0 || 1 / a === 1 / b;
3196    // `null` or `undefined` only equal to itself (strict comparison).
3197    if (a == null || b == null) return false;
3198    // `NaN`s are equivalent, but non-reflexive.
3199    if (a !== a) return b !== b;
3200    // Exhaust primitive checks
3201    var type = typeof a;
3202    if (type !== 'function' && type !== 'object' && typeof b != 'object') return false;
3203    return deepEq(a, b, aStack, bStack);
3204  }
3205
3206  // Internal recursive comparison function for `_.isEqual`.
3207  function deepEq(a, b, aStack, bStack) {
3208    // Unwrap any wrapped objects.
3209    if (a instanceof _$1) a = a._wrapped;
3210    if (b instanceof _$1) b = b._wrapped;
3211    // Compare `[[Class]]` names.
3212    var className = toString.call(a);
3213    if (className !== toString.call(b)) return false;
3214    // Work around a bug in IE 10 - Edge 13.
3215    if (hasStringTagBug && className == '[object Object]' && isDataView$1(a)) {
3216      if (!isDataView$1(b)) return false;
3217      className = tagDataView;
3218    }
3219    switch (className) {
3220      // These types are compared by value.
3221      case '[object RegExp]':
3222        // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
3223      case '[object String]':
3224        // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
3225        // equivalent to `new String("5")`.
3226        return '' + a === '' + b;
3227      case '[object Number]':
3228        // `NaN`s are equivalent, but non-reflexive.
3229        // Object(NaN) is equivalent to NaN.
3230        if (+a !== +a) return +b !== +b;
3231        // An `egal` comparison is performed for other numeric values.
3232        return +a === 0 ? 1 / +a === 1 / b : +a === +b;
3233      case '[object Date]':
3234      case '[object Boolean]':
3235        // Coerce dates and booleans to numeric primitive values. Dates are compared by their
3236        // millisecond representations. Note that invalid dates with millisecond representations
3237        // of `NaN` are not equivalent.
3238        return +a === +b;
3239      case '[object Symbol]':
3240        return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b);
3241      case '[object ArrayBuffer]':
3242      case tagDataView:
3243        // Coerce to typed array so we can fall through.
3244        return deepEq(toBufferView(a), toBufferView(b), aStack, bStack);
3245    }
3246
3247    var areArrays = className === '[object Array]';
3248    if (!areArrays && isTypedArray$1(a)) {
3249        var byteLength = getByteLength(a);
3250        if (byteLength !== getByteLength(b)) return false;
3251        if (a.buffer === b.buffer && a.byteOffset === b.byteOffset) return true;
3252        areArrays = true;
3253    }
3254    if (!areArrays) {
3255      if (typeof a != 'object' || typeof b != 'object') return false;
3256
3257      // Objects with different constructors are not equivalent, but `Object`s or `Array`s
3258      // from different frames are.
3259      var aCtor = a.constructor, bCtor = b.constructor;
3260      if (aCtor !== bCtor && !(isFunction$1(aCtor) && aCtor instanceof aCtor &&
3261                               isFunction$1(bCtor) && bCtor instanceof bCtor)
3262                          && ('constructor' in a && 'constructor' in b)) {
3263        return false;
3264      }
3265    }
3266    // Assume equality for cyclic structures. The algorithm for detecting cyclic
3267    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
3268
3269    // Initializing stack of traversed objects.
3270    // It's done here since we only need them for objects and arrays comparison.
3271    aStack = aStack || [];
3272    bStack = bStack || [];
3273    var length = aStack.length;
3274    while (length--) {
3275      // Linear search. Performance is inversely proportional to the number of
3276      // unique nested structures.
3277      if (aStack[length] === a) return bStack[length] === b;
3278    }
3279
3280    // Add the first object to the stack of traversed objects.
3281    aStack.push(a);
3282    bStack.push(b);
3283
3284    // Recursively compare objects and arrays.
3285    if (areArrays) {
3286      // Compare array lengths to determine if a deep comparison is necessary.
3287      length = a.length;
3288      if (length !== b.length) return false;
3289      // Deep compare the contents, ignoring non-numeric properties.
3290      while (length--) {
3291        if (!eq(a[length], b[length], aStack, bStack)) return false;
3292      }
3293    } else {
3294      // Deep compare objects.
3295      var _keys = keys(a), key;
3296      length = _keys.length;
3297      // Ensure that both objects contain the same number of properties before comparing deep equality.
3298      if (keys(b).length !== length) return false;
3299      while (length--) {
3300        // Deep compare each member
3301        key = _keys[length];
3302        if (!(has$1(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
3303      }
3304    }
3305    // Remove the first object from the stack of traversed objects.
3306    aStack.pop();
3307    bStack.pop();
3308    return true;
3309  }
3310
3311  // Perform a deep comparison to check if two objects are equal.
3312  function isEqual(a, b) {
3313    return eq(a, b);
3314  }
3315
3316  // Retrieve all the enumerable property names of an object.
3317  function allKeys(obj) {
3318    if (!isObject(obj)) return [];
3319    var keys = [];
3320    for (var key in obj) keys.push(key);
3321    // Ahem, IE < 9.
3322    if (hasEnumBug) collectNonEnumProps(obj, keys);
3323    return keys;
3324  }
3325
3326  // Since the regular `Object.prototype.toString` type tests don't work for
3327  // some types in IE 11, we use a fingerprinting heuristic instead, based
3328  // on the methods. It's not great, but it's the best we got.
3329  // The fingerprint method lists are defined below.
3330  function ie11fingerprint(methods) {
3331    var length = getLength(methods);
3332    return function(obj) {
3333      if (obj == null) return false;
3334      // `Map`, `WeakMap` and `Set` have no enumerable keys.
3335      var keys = allKeys(obj);
3336      if (getLength(keys)) return false;
3337      for (var i = 0; i < length; i++) {
3338        if (!isFunction$1(obj[methods[i]])) return false;
3339      }
3340      // If we are testing against `WeakMap`, we need to ensure that
3341      // `obj` doesn't have a `forEach` method in order to distinguish
3342      // it from a regular `Map`.
3343      return methods !== weakMapMethods || !isFunction$1(obj[forEachName]);
3344    };
3345  }
3346
3347  // In the interest of compact minification, we write
3348  // each string in the fingerprints only once.
3349  var forEachName = 'forEach',
3350      hasName = 'has',
3351      commonInit = ['clear', 'delete'],
3352      mapTail = ['get', hasName, 'set'];
3353
3354  // `Map`, `WeakMap` and `Set` each have slightly different
3355  // combinations of the above sublists.
3356  var mapMethods = commonInit.concat(forEachName, mapTail),
3357      weakMapMethods = commonInit.concat(mapTail),
3358      setMethods = ['add'].concat(commonInit, forEachName, hasName);
3359
3360  var isMap = isIE11 ? ie11fingerprint(mapMethods) : tagTester('Map');
3361
3362  var isWeakMap = isIE11 ? ie11fingerprint(weakMapMethods) : tagTester('WeakMap');
3363
3364  var isSet = isIE11 ? ie11fingerprint(setMethods) : tagTester('Set');
3365
3366  var isWeakSet = tagTester('WeakSet');
3367
3368  // Retrieve the values of an object's properties.
3369  function values(obj) {
3370    var _keys = keys(obj);
3371    var length = _keys.length;
3372    var values = Array(length);
3373    for (var i = 0; i < length; i++) {
3374      values[i] = obj[_keys[i]];
3375    }
3376    return values;
3377  }
3378
3379  // Convert an object into a list of `[key, value]` pairs.
3380  // The opposite of `_.object` with one argument.
3381  function pairs(obj) {
3382    var _keys = keys(obj);
3383    var length = _keys.length;
3384    var pairs = Array(length);
3385    for (var i = 0; i < length; i++) {
3386      pairs[i] = [_keys[i], obj[_keys[i]]];
3387    }
3388    return pairs;
3389  }
3390
3391  // Invert the keys and values of an object. The values must be serializable.
3392  function invert(obj) {
3393    var result = {};
3394    var _keys = keys(obj);
3395    for (var i = 0, length = _keys.length; i < length; i++) {
3396      result[obj[_keys[i]]] = _keys[i];
3397    }
3398    return result;
3399  }
3400
3401  // Return a sorted list of the function names available on the object.
3402  function functions(obj) {
3403    var names = [];
3404    for (var key in obj) {
3405      if (isFunction$1(obj[key])) names.push(key);
3406    }
3407    return names.sort();
3408  }
3409
3410  // An internal function for creating assigner functions.
3411  function createAssigner(keysFunc, defaults) {
3412    return function(obj) {
3413      var length = arguments.length;
3414      if (defaults) obj = Object(obj);
3415      if (length < 2 || obj == null) return obj;
3416      for (var index = 1; index < length; index++) {
3417        var source = arguments[index],
3418            keys = keysFunc(source),
3419            l = keys.length;
3420        for (var i = 0; i < l; i++) {
3421          var key = keys[i];
3422          if (!defaults || obj[key] === void 0) obj[key] = source[key];
3423        }
3424      }
3425      return obj;
3426    };
3427  }
3428
3429  // Extend a given object with all the properties in passed-in object(s).
3430  var extend = createAssigner(allKeys);
3431
3432  // Assigns a given object with all the own properties in the passed-in
3433  // object(s).
3434  // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
3435  var extendOwn = createAssigner(keys);
3436
3437  // Fill in a given object with default properties.
3438  var defaults = createAssigner(allKeys, true);
3439
3440  // Create a naked function reference for surrogate-prototype-swapping.
3441  function ctor() {
3442    return function(){};
3443  }
3444
3445  // An internal function for creating a new object that inherits from another.
3446  function baseCreate(prototype) {
3447    if (!isObject(prototype)) return {};
3448    if (nativeCreate) return nativeCreate(prototype);
3449    var Ctor = ctor();
3450    Ctor.prototype = prototype;
3451    var result = new Ctor;
3452    Ctor.prototype = null;
3453    return result;
3454  }
3455
3456  // Creates an object that inherits from the given prototype object.
3457  // If additional properties are provided then they will be added to the
3458  // created object.
3459  function create(prototype, props) {
3460    var result = baseCreate(prototype);
3461    if (props) extendOwn(result, props);
3462    return result;
3463  }
3464
3465  // Create a (shallow-cloned) duplicate of an object.
3466  function clone(obj) {
3467    if (!isObject(obj)) return obj;
3468    return isArray(obj) ? obj.slice() : extend({}, obj);
3469  }
3470
3471  // Invokes `interceptor` with the `obj` and then returns `obj`.
3472  // The primary purpose of this method is to "tap into" a method chain, in
3473  // order to perform operations on intermediate results within the chain.
3474  function tap(obj, interceptor) {
3475    interceptor(obj);
3476    return obj;
3477  }
3478
3479  // Normalize a (deep) property `path` to array.
3480  // Like `_.iteratee`, this function can be customized.
3481  function toPath$1(path) {
3482    return isArray(path) ? path : [path];
3483  }
3484  _$1.toPath = toPath$1;
3485
3486  // Internal wrapper for `_.toPath` to enable minification.
3487  // Similar to `cb` for `_.iteratee`.
3488  function toPath(path) {
3489    return _$1.toPath(path);
3490  }
3491
3492  // Internal function to obtain a nested property in `obj` along `path`.
3493  function deepGet(obj, path) {
3494    var length = path.length;
3495    for (var i = 0; i < length; i++) {
3496      if (obj == null) return void 0;
3497      obj = obj[path[i]];
3498    }
3499    return length ? obj : void 0;
3500  }
3501
3502  // Get the value of the (deep) property on `path` from `object`.
3503  // If any property in `path` does not exist or if the value is
3504  // `undefined`, return `defaultValue` instead.
3505  // The `path` is normalized through `_.toPath`.
3506  function get(object, path, defaultValue) {
3507    var value = deepGet(object, toPath(path));
3508    return isUndefined(value) ? defaultValue : value;
3509  }
3510
3511  // Shortcut function for checking if an object has a given property directly on
3512  // itself (in other words, not on a prototype). Unlike the internal `has`
3513  // function, this public version can also traverse nested properties.
3514  function has(obj, path) {
3515    path = toPath(path);
3516    var length = path.length;
3517    for (var i = 0; i < length; i++) {
3518      var key = path[i];
3519      if (!has$1(obj, key)) return false;
3520      obj = obj[key];
3521    }
3522    return !!length;
3523  }
3524
3525  // Keep the identity function around for default iteratees.
3526  function identity(value) {
3527    return value;
3528  }
3529
3530  // Returns a predicate for checking whether an object has a given set of
3531  // `key:value` pairs.
3532  function matcher(attrs) {
3533    attrs = extendOwn({}, attrs);
3534    return function(obj) {
3535      return isMatch(obj, attrs);
3536    };
3537  }
3538
3539  // Creates a function that, when passed an object, will traverse that object’s
3540  // properties down the given `path`, specified as an array of keys or indices.
3541  function property(path) {
3542    path = toPath(path);
3543    return function(obj) {
3544      return deepGet(obj, path);
3545    };
3546  }
3547
3548  // Internal function that returns an efficient (for current engines) version
3549  // of the passed-in callback, to be repeatedly applied in other Underscore
3550  // functions.
3551  function optimizeCb(func, context, argCount) {
3552    if (context === void 0) return func;
3553    switch (argCount == null ? 3 : argCount) {
3554      case 1: return function(value) {
3555        return func.call(context, value);
3556      };
3557      // The 2-argument case is omitted because we’re not using it.
3558      case 3: return function(value, index, collection) {
3559        return func.call(context, value, index, collection);
3560      };
3561      case 4: return function(accumulator, value, index, collection) {
3562        return func.call(context, accumulator, value, index, collection);
3563      };
3564    }
3565    return function() {
3566      return func.apply(context, arguments);
3567    };
3568  }
3569
3570  // An internal function to generate callbacks that can be applied to each
3571  // element in a collection, returning the desired result — either `_.identity`,
3572  // an arbitrary callback, a property matcher, or a property accessor.
3573  function baseIteratee(value, context, argCount) {
3574    if (value == null) return identity;
3575    if (isFunction$1(value)) return optimizeCb(value, context, argCount);
3576    if (isObject(value) && !isArray(value)) return matcher(value);
3577    return property(value);
3578  }
3579
3580  // External wrapper for our callback generator. Users may customize
3581  // `_.iteratee` if they want additional predicate/iteratee shorthand styles.
3582  // This abstraction hides the internal-only `argCount` argument.
3583  function iteratee(value, context) {
3584    return baseIteratee(value, context, Infinity);
3585  }
3586  _$1.iteratee = iteratee;
3587
3588  // The function we call internally to generate a callback. It invokes
3589  // `_.iteratee` if overridden, otherwise `baseIteratee`.
3590  function cb(value, context, argCount) {
3591    if (_$1.iteratee !== iteratee) return _$1.iteratee(value, context);
3592    return baseIteratee(value, context, argCount);
3593  }
3594
3595  // Returns the results of applying the `iteratee` to each element of `obj`.
3596  // In contrast to `_.map` it returns an object.
3597  function mapObject(obj, iteratee, context) {
3598    iteratee = cb(iteratee, context);
3599    var _keys = keys(obj),
3600        length = _keys.length,
3601        results = {};
3602    for (var index = 0; index < length; index++) {
3603      var currentKey = _keys[index];
3604      results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
3605    }
3606    return results;
3607  }
3608
3609  // Predicate-generating function. Often useful outside of Underscore.
3610  function noop(){}
3611
3612  // Generates a function for a given object that returns a given property.
3613  function propertyOf(obj) {
3614    if (obj == null) return noop;
3615    return function(path) {
3616      return get(obj, path);
3617    };
3618  }
3619
3620  // Run a function **n** times.
3621  function times(n, iteratee, context) {
3622    var accum = Array(Math.max(0, n));
3623    iteratee = optimizeCb(iteratee, context, 1);
3624    for (var i = 0; i < n; i++) accum[i] = iteratee(i);
3625    return accum;
3626  }
3627
3628  // Return a random integer between `min` and `max` (inclusive).
3629  function random(min, max) {
3630    if (max == null) {
3631      max = min;
3632      min = 0;
3633    }
3634    return min + Math.floor(Math.random() * (max - min + 1));
3635  }
3636
3637  // A (possibly faster) way to get the current timestamp as an integer.
3638  var now = Date.now || function() {
3639    return new Date().getTime();
3640  };
3641
3642  // Internal helper to generate functions for escaping and unescaping strings
3643  // to/from HTML interpolation.
3644  function createEscaper(map) {
3645    var escaper = function(match) {
3646      return map[match];
3647    };
3648    // Regexes for identifying a key that needs to be escaped.
3649    var source = '(?:' + keys(map).join('|') + ')';
3650    var testRegexp = RegExp(source);
3651    var replaceRegexp = RegExp(source, 'g');
3652    return function(string) {
3653      string = string == null ? '' : '' + string;
3654      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
3655    };
3656  }
3657
3658  // Internal list of HTML entities for escaping.
3659  var escapeMap = {
3660    '&': '&amp;',
3661    '<': '&lt;',
3662    '>': '&gt;',
3663    '"': '&quot;',
3664    "'": '&#x27;',
3665    '`': '&#x60;'
3666  };
3667
3668  // Function for escaping strings to HTML interpolation.
3669  var _escape = createEscaper(escapeMap);
3670
3671  // Internal list of HTML entities for unescaping.
3672  var unescapeMap = invert(escapeMap);
3673
3674  // Function for unescaping strings from HTML interpolation.
3675  var _unescape = createEscaper(unescapeMap);
3676
3677  // By default, Underscore uses ERB-style template delimiters. Change the
3678  // following template settings to use alternative delimiters.
3679  var templateSettings = _$1.templateSettings = {
3680    evaluate: /<%([\s\S]+?)%>/g,
3681    interpolate: /<%=([\s\S]+?)%>/g,
3682    escape: /<%-([\s\S]+?)%>/g
3683  };
3684
3685  // When customizing `_.templateSettings`, if you don't want to define an
3686  // interpolation, evaluation or escaping regex, we need one that is
3687  // guaranteed not to match.
3688  var noMatch = /(.)^/;
3689
3690  // Certain characters need to be escaped so that they can be put into a
3691  // string literal.
3692  var escapes = {
3693    "'": "'",
3694    '\\': '\\',
3695    '\r': 'r',
3696    '\n': 'n',
3697    '\u2028': 'u2028',
3698    '\u2029': 'u2029'
3699  };
3700
3701  var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g;
3702
3703  function escapeChar(match) {
3704    return '\\' + escapes[match];
3705  }
3706
3707  // In order to prevent third-party code injection through
3708  // `_.templateSettings.variable`, we test it against the following regular
3709  // expression. It is intentionally a bit more liberal than just matching valid
3710  // identifiers, but still prevents possible loopholes through defaults or
3711  // destructuring assignment.
3712  var bareIdentifier = /^\s*(\w|\$)+\s*$/;
3713
3714  // JavaScript micro-templating, similar to John Resig's implementation.
3715  // Underscore templating handles arbitrary delimiters, preserves whitespace,
3716  // and correctly escapes quotes within interpolated code.
3717  // NB: `oldSettings` only exists for backwards compatibility.
3718  function template(text, settings, oldSettings) {
3719    if (!settings && oldSettings) settings = oldSettings;
3720    settings = defaults({}, settings, _$1.templateSettings);
3721
3722    // Combine delimiters into one regular expression via alternation.
3723    var matcher = RegExp([
3724      (settings.escape || noMatch).source,
3725      (settings.interpolate || noMatch).source,
3726      (settings.evaluate || noMatch).source
3727    ].join('|') + '|$', 'g');
3728
3729    // Compile the template source, escaping string literals appropriately.
3730    var index = 0;
3731    var source = "__p+='";
3732    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
3733      source += text.slice(index, offset).replace(escapeRegExp, escapeChar);
3734      index = offset + match.length;
3735
3736      if (escape) {
3737        source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
3738      } else if (interpolate) {
3739        source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
3740      } else if (evaluate) {
3741        source += "';\n" + evaluate + "\n__p+='";
3742      }
3743
3744      // Adobe VMs need the match returned to produce the correct offset.
3745      return match;
3746    });
3747    source += "';\n";
3748
3749    var argument = settings.variable;
3750    if (argument) {
3751      // Insure against third-party code injection. (CVE-2021-23358)
3752      if (!bareIdentifier.test(argument)) throw new Error(
3753        'variable is not a bare identifier: ' + argument
3754      );
3755    } else {
3756      // If a variable is not specified, place data values in local scope.
3757      source = 'with(obj||{}){\n' + source + '}\n';
3758      argument = 'obj';
3759    }
3760
3761    source = "var __t,__p='',__j=Array.prototype.join," +
3762      "print=function(){__p+=__j.call(arguments,'');};\n" +
3763      source + 'return __p;\n';
3764
3765    var render;
3766    try {
3767      render = new Function(argument, '_', source);
3768    } catch (e) {
3769      e.source = source;
3770      throw e;
3771    }
3772
3773    var template = function(data) {
3774      return render.call(this, data, _$1);
3775    };
3776
3777    // Provide the compiled source as a convenience for precompilation.
3778    template.source = 'function(' + argument + '){\n' + source + '}';
3779
3780    return template;
3781  }
3782
3783  // Traverses the children of `obj` along `path`. If a child is a function, it
3784  // is invoked with its parent as context. Returns the value of the final
3785  // child, or `fallback` if any child is undefined.
3786  function result(obj, path, fallback) {
3787    path = toPath(path);
3788    var length = path.length;
3789    if (!length) {
3790      return isFunction$1(fallback) ? fallback.call(obj) : fallback;
3791    }
3792    for (var i = 0; i < length; i++) {
3793      var prop = obj == null ? void 0 : obj[path[i]];
3794      if (prop === void 0) {
3795        prop = fallback;
3796        i = length; // Ensure we don't continue iterating.
3797      }
3798      obj = isFunction$1(prop) ? prop.call(obj) : prop;
3799    }
3800    return obj;
3801  }
3802
3803  // Generate a unique integer id (unique within the entire client session).
3804  // Useful for temporary DOM ids.
3805  var idCounter = 0;
3806  function uniqueId(prefix) {
3807    var id = ++idCounter + '';
3808    return prefix ? prefix + id : id;
3809  }
3810
3811  // Start chaining a wrapped Underscore object.
3812  function chain(obj) {
3813    var instance = _$1(obj);
3814    instance._chain = true;
3815    return instance;
3816  }
3817
3818  // Internal function to execute `sourceFunc` bound to `context` with optional
3819  // `args`. Determines whether to execute a function as a constructor or as a
3820  // normal function.
3821  function executeBound(sourceFunc, boundFunc, context, callingContext, args) {
3822    if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
3823    var self = baseCreate(sourceFunc.prototype);
3824    var result = sourceFunc.apply(self, args);
3825    if (isObject(result)) return result;
3826    return self;
3827  }
3828
3829  // Partially apply a function by creating a version that has had some of its
3830  // arguments pre-filled, without changing its dynamic `this` context. `_` acts
3831  // as a placeholder by default, allowing any combination of arguments to be
3832  // pre-filled. Set `_.partial.placeholder` for a custom placeholder argument.
3833  var partial = restArguments(function(func, boundArgs) {
3834    var placeholder = partial.placeholder;
3835    var bound = function() {
3836      var position = 0, length = boundArgs.length;
3837      var args = Array(length);
3838      for (var i = 0; i < length; i++) {
3839        args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i];
3840      }
3841      while (position < arguments.length) args.push(arguments[position++]);
3842      return executeBound(func, bound, this, this, args);
3843    };
3844    return bound;
3845  });
3846
3847  partial.placeholder = _$1;
3848
3849  // Create a function bound to a given object (assigning `this`, and arguments,
3850  // optionally).
3851  var bind = restArguments(function(func, context, args) {
3852    if (!isFunction$1(func)) throw new TypeError('Bind must be called on a function');
3853    var bound = restArguments(function(callArgs) {
3854      return executeBound(func, bound, context, this, args.concat(callArgs));
3855    });
3856    return bound;
3857  });
3858
3859  // Internal helper for collection methods to determine whether a collection
3860  // should be iterated as an array or as an object.
3861  // Related: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
3862  // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
3863  var isArrayLike = createSizePropertyCheck(getLength);
3864
3865  // Internal implementation of a recursive `flatten` function.
3866  function flatten$1(input, depth, strict, output) {
3867    output = output || [];
3868    if (!depth && depth !== 0) {
3869      depth = Infinity;
3870    } else if (depth <= 0) {
3871      return output.concat(input);
3872    }
3873    var idx = output.length;
3874    for (var i = 0, length = getLength(input); i < length; i++) {
3875      var value = input[i];
3876      if (isArrayLike(value) && (isArray(value) || isArguments$1(value))) {
3877        // Flatten current level of array or arguments object.
3878        if (depth > 1) {
3879          flatten$1(value, depth - 1, strict, output);
3880          idx = output.length;
3881        } else {
3882          var j = 0, len = value.length;
3883          while (j < len) output[idx++] = value[j++];
3884        }
3885      } else if (!strict) {
3886        output[idx++] = value;
3887      }
3888    }
3889    return output;
3890  }
3891
3892  // Bind a number of an object's methods to that object. Remaining arguments
3893  // are the method names to be bound. Useful for ensuring that all callbacks
3894  // defined on an object belong to it.
3895  var bindAll = restArguments(function(obj, keys) {
3896    keys = flatten$1(keys, false, false);
3897    var index = keys.length;
3898    if (index < 1) throw new Error('bindAll must be passed function names');
3899    while (index--) {
3900      var key = keys[index];
3901      obj[key] = bind(obj[key], obj);
3902    }
3903    return obj;
3904  });
3905
3906  // Memoize an expensive function by storing its results.
3907  function memoize(func, hasher) {
3908    var memoize = function(key) {
3909      var cache = memoize.cache;
3910      var address = '' + (hasher ? hasher.apply(this, arguments) : key);
3911      if (!has$1(cache, address)) cache[address] = func.apply(this, arguments);
3912      return cache[address];
3913    };
3914    memoize.cache = {};
3915    return memoize;
3916  }
3917
3918  // Delays a function for the given number of milliseconds, and then calls
3919  // it with the arguments supplied.
3920  var delay = restArguments(function(func, wait, args) {
3921    return setTimeout(function() {
3922      return func.apply(null, args);
3923    }, wait);
3924  });
3925
3926  // Defers a function, scheduling it to run after the current call stack has
3927  // cleared.
3928  var defer = partial(delay, _$1, 1);
3929
3930  // Returns a function, that, when invoked, will only be triggered at most once
3931  // during a given window of time. Normally, the throttled function will run
3932  // as much as it can, without ever going more than once per `wait` duration;
3933  // but if you'd like to disable the execution on the leading edge, pass
3934  // `{leading: false}`. To disable execution on the trailing edge, ditto.
3935  function throttle(func, wait, options) {
3936    var timeout, context, args, result;
3937    var previous = 0;
3938    if (!options) options = {};
3939
3940    var later = function() {
3941      previous = options.leading === false ? 0 : now();
3942      timeout = null;
3943      result = func.apply(context, args);
3944      if (!timeout) context = args = null;
3945    };
3946
3947    var throttled = function() {
3948      var _now = now();
3949      if (!previous && options.leading === false) previous = _now;
3950      var remaining = wait - (_now - previous);
3951      context = this;
3952      args = arguments;
3953      if (remaining <= 0 || remaining > wait) {
3954        if (timeout) {
3955          clearTimeout(timeout);
3956          timeout = null;
3957        }
3958        previous = _now;
3959        result = func.apply(context, args);
3960        if (!timeout) context = args = null;
3961      } else if (!timeout && options.trailing !== false) {
3962        timeout = setTimeout(later, remaining);
3963      }
3964      return result;
3965    };
3966
3967    throttled.cancel = function() {
3968      clearTimeout(timeout);
3969      previous = 0;
3970      timeout = context = args = null;
3971    };
3972
3973    return throttled;
3974  }
3975
3976  // When a sequence of calls of the returned function ends, the argument
3977  // function is triggered. The end of a sequence is defined by the `wait`
3978  // parameter. If `immediate` is passed, the argument function will be
3979  // triggered at the beginning of the sequence instead of at the end.
3980  function debounce(func, wait, immediate) {
3981    var timeout, previous, args, result, context;
3982
3983    var later = function() {
3984      var passed = now() - previous;
3985      if (wait > passed) {
3986        timeout = setTimeout(later, wait - passed);
3987      } else {
3988        timeout = null;
3989        if (!immediate) result = func.apply(context, args);
3990        // This check is needed because `func` can recursively invoke `debounced`.
3991        if (!timeout) args = context = null;
3992      }
3993    };
3994
3995    var debounced = restArguments(function(_args) {
3996      context = this;
3997      args = _args;
3998      previous = now();
3999      if (!timeout) {
4000        timeout = setTimeout(later, wait);
4001        if (immediate) result = func.apply(context, args);
4002      }
4003      return result;
4004    });
4005
4006    debounced.cancel = function() {
4007      clearTimeout(timeout);
4008      timeout = args = context = null;
4009    };
4010
4011    return debounced;
4012  }
4013
4014  // Returns the first function passed as an argument to the second,
4015  // allowing you to adjust arguments, run code before and after, and
4016  // conditionally execute the original function.
4017  function wrap(func, wrapper) {
4018    return partial(wrapper, func);
4019  }
4020
4021  // Returns a negated version of the passed-in predicate.
4022  function negate(predicate) {
4023    return function() {
4024      return !predicate.apply(this, arguments);
4025    };
4026  }
4027
4028  // Returns a function that is the composition of a list of functions, each
4029  // consuming the return value of the function that follows.
4030  function compose() {
4031    var args = arguments;
4032    var start = args.length - 1;
4033    return function() {
4034      var i = start;
4035      var result = args[start].apply(this, arguments);
4036      while (i--) result = args[i].call(this, result);
4037      return result;
4038    };
4039  }
4040
4041  // Returns a function that will only be executed on and after the Nth call.
4042  function after(times, func) {
4043    return function() {
4044      if (--times < 1) {
4045        return func.apply(this, arguments);
4046      }
4047    };
4048  }
4049
4050  // Returns a function that will only be executed up to (but not including) the
4051  // Nth call.
4052  function before(times, func) {
4053    var memo;
4054    return function() {
4055      if (--times > 0) {
4056        memo = func.apply(this, arguments);
4057      }
4058      if (times <= 1) func = null;
4059      return memo;
4060    };
4061  }
4062
4063  // Returns a function that will be executed at most one time, no matter how
4064  // often you call it. Useful for lazy initialization.
4065  var once = partial(before, 2);
4066
4067  // Returns the first key on an object that passes a truth test.
4068  function findKey(obj, predicate, context) {
4069    predicate = cb(predicate, context);
4070    var _keys = keys(obj), key;
4071    for (var i = 0, length = _keys.length; i < length; i++) {
4072      key = _keys[i];
4073      if (predicate(obj[key], key, obj)) return key;
4074    }
4075  }
4076
4077  // Internal function to generate `_.findIndex` and `_.findLastIndex`.
4078  function createPredicateIndexFinder(dir) {
4079    return function(array, predicate, context) {
4080      predicate = cb(predicate, context);
4081      var length = getLength(array);
4082      var index = dir > 0 ? 0 : length - 1;
4083      for (; index >= 0 && index < length; index += dir) {
4084        if (predicate(array[index], index, array)) return index;
4085      }
4086      return -1;
4087    };
4088  }
4089
4090  // Returns the first index on an array-like that passes a truth test.
4091  var findIndex = createPredicateIndexFinder(1);
4092
4093  // Returns the last index on an array-like that passes a truth test.
4094  var findLastIndex = createPredicateIndexFinder(-1);
4095
4096  // Use a comparator function to figure out the smallest index at which
4097  // an object should be inserted so as to maintain order. Uses binary search.
4098  function sortedIndex(array, obj, iteratee, context) {
4099    iteratee = cb(iteratee, context, 1);
4100    var value = iteratee(obj);
4101    var low = 0, high = getLength(array);
4102    while (low < high) {
4103      var mid = Math.floor((low + high) / 2);
4104      if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
4105    }
4106    return low;
4107  }
4108
4109  // Internal function to generate the `_.indexOf` and `_.lastIndexOf` functions.
4110  function createIndexFinder(dir, predicateFind, sortedIndex) {
4111    return function(array, item, idx) {
4112      var i = 0, length = getLength(array);
4113      if (typeof idx == 'number') {
4114        if (dir > 0) {
4115          i = idx >= 0 ? idx : Math.max(idx + length, i);
4116        } else {
4117          length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;
4118        }
4119      } else if (sortedIndex && idx && length) {
4120        idx = sortedIndex(array, item);
4121        return array[idx] === item ? idx : -1;
4122      }
4123      if (item !== item) {
4124        idx = predicateFind(slice.call(array, i, length), isNaN$1);
4125        return idx >= 0 ? idx + i : -1;
4126      }
4127      for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {
4128        if (array[idx] === item) return idx;
4129      }
4130      return -1;
4131    };
4132  }
4133
4134  // Return the position of the first occurrence of an item in an array,
4135  // or -1 if the item is not included in the array.
4136  // If the array is large and already in sort order, pass `true`
4137  // for **isSorted** to use binary search.
4138  var indexOf = createIndexFinder(1, findIndex, sortedIndex);
4139
4140  // Return the position of the last occurrence of an item in an array,
4141  // or -1 if the item is not included in the array.
4142  var lastIndexOf = createIndexFinder(-1, findLastIndex);
4143
4144  // Return the first value which passes a truth test.
4145  function find(obj, predicate, context) {
4146    var keyFinder = isArrayLike(obj) ? findIndex : findKey;
4147    var key = keyFinder(obj, predicate, context);
4148    if (key !== void 0 && key !== -1) return obj[key];
4149  }
4150
4151  // Convenience version of a common use case of `_.find`: getting the first
4152  // object containing specific `key:value` pairs.
4153  function findWhere(obj, attrs) {
4154    return find(obj, matcher(attrs));
4155  }
4156
4157  // The cornerstone for collection functions, an `each`
4158  // implementation, aka `forEach`.
4159  // Handles raw objects in addition to array-likes. Treats all
4160  // sparse array-likes as if they were dense.
4161  function each(obj, iteratee, context) {
4162    iteratee = optimizeCb(iteratee, context);
4163    var i, length;
4164    if (isArrayLike(obj)) {
4165      for (i = 0, length = obj.length; i < length; i++) {
4166        iteratee(obj[i], i, obj);
4167      }
4168    } else {
4169      var _keys = keys(obj);
4170      for (i = 0, length = _keys.length; i < length; i++) {
4171        iteratee(obj[_keys[i]], _keys[i], obj);
4172      }
4173    }
4174    return obj;
4175  }
4176
4177  // Return the results of applying the iteratee to each element.
4178  function map(obj, iteratee, context) {
4179    iteratee = cb(iteratee, context);
4180    var _keys = !isArrayLike(obj) && keys(obj),
4181        length = (_keys || obj).length,
4182        results = Array(length);
4183    for (var index = 0; index < length; index++) {
4184      var currentKey = _keys ? _keys[index] : index;
4185      results[index] = iteratee(obj[currentKey], currentKey, obj);
4186    }
4187    return results;
4188  }
4189
4190  // Internal helper to create a reducing function, iterating left or right.
4191  function createReduce(dir) {
4192    // Wrap code that reassigns argument variables in a separate function than
4193    // the one that accesses `arguments.length` to avoid a perf hit. (#1991)
4194    var reducer = function(obj, iteratee, memo, initial) {
4195      var _keys = !isArrayLike(obj) && keys(obj),
4196          length = (_keys || obj).length,
4197          index = dir > 0 ? 0 : length - 1;
4198      if (!initial) {
4199        memo = obj[_keys ? _keys[index] : index];
4200        index += dir;
4201      }
4202      for (; index >= 0 && index < length; index += dir) {
4203        var currentKey = _keys ? _keys[index] : index;
4204        memo = iteratee(memo, obj[currentKey], currentKey, obj);
4205      }
4206      return memo;
4207    };
4208
4209    return function(obj, iteratee, memo, context) {
4210      var initial = arguments.length >= 3;
4211      return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial);
4212    };
4213  }
4214
4215  // **Reduce** builds up a single result from a list of values, aka `inject`,
4216  // or `foldl`.
4217  var reduce = createReduce(1);
4218
4219  // The right-associative version of reduce, also known as `foldr`.
4220  var reduceRight = createReduce(-1);
4221
4222  // Return all the elements that pass a truth test.
4223  function filter(obj, predicate, context) {
4224    var results = [];
4225    predicate = cb(predicate, context);
4226    each(obj, function(value, index, list) {
4227      if (predicate(value, index, list)) results.push(value);
4228    });
4229    return results;
4230  }
4231
4232  // Return all the elements for which a truth test fails.
4233  function reject(obj, predicate, context) {
4234    return filter(obj, negate(cb(predicate)), context);
4235  }
4236
4237  // Determine whether all of the elements pass a truth test.
4238  function every(obj, predicate, context) {
4239    predicate = cb(predicate, context);
4240    var _keys = !isArrayLike(obj) && keys(obj),
4241        length = (_keys || obj).length;
4242    for (var index = 0; index < length; index++) {
4243      var currentKey = _keys ? _keys[index] : index;
4244      if (!predicate(obj[currentKey], currentKey, obj)) return false;
4245    }
4246    return true;
4247  }
4248
4249  // Determine if at least one element in the object passes a truth test.
4250  function some(obj, predicate, context) {
4251    predicate = cb(predicate, context);
4252    var _keys = !isArrayLike(obj) && keys(obj),
4253        length = (_keys || obj).length;
4254    for (var index = 0; index < length; index++) {
4255      var currentKey = _keys ? _keys[index] : index;
4256      if (predicate(obj[currentKey], currentKey, obj)) return true;
4257    }
4258    return false;
4259  }
4260
4261  // Determine if the array or object contains a given item (using `===`).
4262  function contains(obj, item, fromIndex, guard) {
4263    if (!isArrayLike(obj)) obj = values(obj);
4264    if (typeof fromIndex != 'number' || guard) fromIndex = 0;
4265    return indexOf(obj, item, fromIndex) >= 0;
4266  }
4267
4268  // Invoke a method (with arguments) on every item in a collection.
4269  var invoke = restArguments(function(obj, path, args) {
4270    var contextPath, func;
4271    if (isFunction$1(path)) {
4272      func = path;
4273    } else {
4274      path = toPath(path);
4275      contextPath = path.slice(0, -1);
4276      path = path[path.length - 1];
4277    }
4278    return map(obj, function(context) {
4279      var method = func;
vendor: 17,988 bytes, lines 4280-4878
4280      if (!method) {
4281        if (contextPath && contextPath.length) {
4282          context = deepGet(context, contextPath);
4283        }
4284        if (context == null) return void 0;
4285        method = context[path];
4286      }
4287      return method == null ? method : method.apply(context, args);
4288    });
4289  });
4290
4291  // Convenience version of a common use case of `_.map`: fetching a property.
4292  function pluck(obj, key) {
4293    return map(obj, property(key));
4294  }
4295
4296  // Convenience version of a common use case of `_.filter`: selecting only
4297  // objects containing specific `key:value` pairs.
4298  function where(obj, attrs) {
4299    return filter(obj, matcher(attrs));
4300  }
4301
4302  // Return the maximum element (or element-based computation).
4303  function max(obj, iteratee, context) {
4304    var result = -Infinity, lastComputed = -Infinity,
4305        value, computed;
4306    if (iteratee == null || (typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null)) {
4307      obj = isArrayLike(obj) ? obj : values(obj);
4308      for (var i = 0, length = obj.length; i < length; i++) {
4309        value = obj[i];
4310        if (value != null && value > result) {
4311          result = value;
4312        }
4313      }
4314    } else {
4315      iteratee = cb(iteratee, context);
4316      each(obj, function(v, index, list) {
4317        computed = iteratee(v, index, list);
4318        if (computed > lastComputed || (computed === -Infinity && result === -Infinity)) {
4319          result = v;
4320          lastComputed = computed;
4321        }
4322      });
4323    }
4324    return result;
4325  }
4326
4327  // Return the minimum element (or element-based computation).
4328  function min(obj, iteratee, context) {
4329    var result = Infinity, lastComputed = Infinity,
4330        value, computed;
4331    if (iteratee == null || (typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null)) {
4332      obj = isArrayLike(obj) ? obj : values(obj);
4333      for (var i = 0, length = obj.length; i < length; i++) {
4334        value = obj[i];
4335        if (value != null && value < result) {
4336          result = value;
4337        }
4338      }
4339    } else {
4340      iteratee = cb(iteratee, context);
4341      each(obj, function(v, index, list) {
4342        computed = iteratee(v, index, list);
4343        if (computed < lastComputed || (computed === Infinity && result === Infinity)) {
4344          result = v;
4345          lastComputed = computed;
4346        }
4347      });
4348    }
4349    return result;
4350  }
4351
4352  // Safely create a real, live array from anything iterable.
4353  var reStrSymbol = /[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g;
4354  function toArray(obj) {
4355    if (!obj) return [];
4356    if (isArray(obj)) return slice.call(obj);
4357    if (isString(obj)) {
4358      // Keep surrogate pair characters together.
4359      return obj.match(reStrSymbol);
4360    }
4361    if (isArrayLike(obj)) return map(obj, identity);
4362    return values(obj);
4363  }
4364
4365  // Sample **n** random values from a collection using the modern version of the
4366  // [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
4367  // If **n** is not specified, returns a single random element.
4368  // The internal `guard` argument allows it to work with `_.map`.
4369  function sample(obj, n, guard) {
4370    if (n == null || guard) {
4371      if (!isArrayLike(obj)) obj = values(obj);
4372      return obj[random(obj.length - 1)];
4373    }
4374    var sample = toArray(obj);
4375    var length = getLength(sample);
4376    n = Math.max(Math.min(n, length), 0);
4377    var last = length - 1;
4378    for (var index = 0; index < n; index++) {
4379      var rand = random(index, last);
4380      var temp = sample[index];
4381      sample[index] = sample[rand];
4382      sample[rand] = temp;
4383    }
4384    return sample.slice(0, n);
4385  }
4386
4387  // Shuffle a collection.
4388  function shuffle(obj) {
4389    return sample(obj, Infinity);
4390  }
4391
4392  // Sort the object's values by a criterion produced by an iteratee.
4393  function sortBy(obj, iteratee, context) {
4394    var index = 0;
4395    iteratee = cb(iteratee, context);
4396    return pluck(map(obj, function(value, key, list) {
4397      return {
4398        value: value,
4399        index: index++,
4400        criteria: iteratee(value, key, list)
4401      };
4402    }).sort(function(left, right) {
4403      var a = left.criteria;
4404      var b = right.criteria;
4405      if (a !== b) {
4406        if (a > b || a === void 0) return 1;
4407        if (a < b || b === void 0) return -1;
4408      }
4409      return left.index - right.index;
4410    }), 'value');
4411  }
4412
4413  // An internal function used for aggregate "group by" operations.
4414  function group(behavior, partition) {
4415    return function(obj, iteratee, context) {
4416      var result = partition ? [[], []] : {};
4417      iteratee = cb(iteratee, context);
4418      each(obj, function(value, index) {
4419        var key = iteratee(value, index, obj);
4420        behavior(result, value, key);
4421      });
4422      return result;
4423    };
4424  }
4425
4426  // Groups the object's values by a criterion. Pass either a string attribute
4427  // to group by, or a function that returns the criterion.
4428  var groupBy = group(function(result, value, key) {
4429    if (has$1(result, key)) result[key].push(value); else result[key] = [value];
4430  });
4431
4432  // Indexes the object's values by a criterion, similar to `_.groupBy`, but for
4433  // when you know that your index values will be unique.
4434  var indexBy = group(function(result, value, key) {
4435    result[key] = value;
4436  });
4437
4438  // Counts instances of an object that group by a certain criterion. Pass
4439  // either a string attribute to count by, or a function that returns the
4440  // criterion.
4441  var countBy = group(function(result, value, key) {
4442    if (has$1(result, key)) result[key]++; else result[key] = 1;
4443  });
4444
4445  // Split a collection into two arrays: one whose elements all pass the given
4446  // truth test, and one whose elements all do not pass the truth test.
4447  var partition = group(function(result, value, pass) {
4448    result[pass ? 0 : 1].push(value);
4449  }, true);
4450
4451  // Return the number of elements in a collection.
4452  function size(obj) {
4453    if (obj == null) return 0;
4454    return isArrayLike(obj) ? obj.length : keys(obj).length;
4455  }
4456
4457  // Internal `_.pick` helper function to determine whether `key` is an enumerable
4458  // property name of `obj`.
4459  function keyInObj(value, key, obj) {
4460    return key in obj;
4461  }
4462
4463  // Return a copy of the object only containing the allowed properties.
4464  var pick = restArguments(function(obj, keys) {
4465    var result = {}, iteratee = keys[0];
4466    if (obj == null) return result;
4467    if (isFunction$1(iteratee)) {
4468      if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]);
4469      keys = allKeys(obj);
4470    } else {
4471      iteratee = keyInObj;
4472      keys = flatten$1(keys, false, false);
4473      obj = Object(obj);
4474    }
4475    for (var i = 0, length = keys.length; i < length; i++) {
4476      var key = keys[i];
4477      var value = obj[key];
4478      if (iteratee(value, key, obj)) result[key] = value;
4479    }
4480    return result;
4481  });
4482
4483  // Return a copy of the object without the disallowed properties.
4484  var omit = restArguments(function(obj, keys) {
4485    var iteratee = keys[0], context;
4486    if (isFunction$1(iteratee)) {
4487      iteratee = negate(iteratee);
4488      if (keys.length > 1) context = keys[1];
4489    } else {
4490      keys = map(flatten$1(keys, false, false), String);
4491      iteratee = function(value, key) {
4492        return !contains(keys, key);
4493      };
4494    }
4495    return pick(obj, iteratee, context);
4496  });
4497
4498  // Returns everything but the last entry of the array. Especially useful on
4499  // the arguments object. Passing **n** will return all the values in
4500  // the array, excluding the last N.
4501  function initial(array, n, guard) {
4502    return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
4503  }
4504
4505  // Get the first element of an array. Passing **n** will return the first N
4506  // values in the array. The **guard** check allows it to work with `_.map`.
4507  function first(array, n, guard) {
4508    if (array == null || array.length < 1) return n == null || guard ? void 0 : [];
4509    if (n == null || guard) return array[0];
4510    return initial(array, array.length - n);
4511  }
4512
4513  // Returns everything but the first entry of the `array`. Especially useful on
4514  // the `arguments` object. Passing an **n** will return the rest N values in the
4515  // `array`.
4516  function rest(array, n, guard) {
4517    return slice.call(array, n == null || guard ? 1 : n);
4518  }
4519
4520  // Get the last element of an array. Passing **n** will return the last N
4521  // values in the array.
4522  function last(array, n, guard) {
4523    if (array == null || array.length < 1) return n == null || guard ? void 0 : [];
4524    if (n == null || guard) return array[array.length - 1];
4525    return rest(array, Math.max(0, array.length - n));
4526  }
4527
4528  // Trim out all falsy values from an array.
4529  function compact(array) {
4530    return filter(array, Boolean);
4531  }
4532
4533  // Flatten out an array, either recursively (by default), or up to `depth`.
4534  // Passing `true` or `false` as `depth` means `1` or `Infinity`, respectively.
4535  function flatten(array, depth) {
4536    return flatten$1(array, depth, false);
4537  }
4538
4539  // Take the difference between one array and a number of other arrays.
4540  // Only the elements present in just the first array will remain.
4541  var difference = restArguments(function(array, rest) {
4542    rest = flatten$1(rest, true, true);
4543    return filter(array, function(value){
4544      return !contains(rest, value);
4545    });
4546  });
4547
4548  // Return a version of the array that does not contain the specified value(s).
4549  var without = restArguments(function(array, otherArrays) {
4550    return difference(array, otherArrays);
4551  });
4552
4553  // Produce a duplicate-free version of the array. If the array has already
4554  // been sorted, you have the option of using a faster algorithm.
4555  // The faster algorithm will not work with an iteratee if the iteratee
4556  // is not a one-to-one function, so providing an iteratee will disable
4557  // the faster algorithm.
4558  function uniq(array, isSorted, iteratee, context) {
4559    if (!isBoolean(isSorted)) {
4560      context = iteratee;
4561      iteratee = isSorted;
4562      isSorted = false;
4563    }
4564    if (iteratee != null) iteratee = cb(iteratee, context);
4565    var result = [];
4566    var seen = [];
4567    for (var i = 0, length = getLength(array); i < length; i++) {
4568      var value = array[i],
4569          computed = iteratee ? iteratee(value, i, array) : value;
4570      if (isSorted && !iteratee) {
4571        if (!i || seen !== computed) result.push(value);
4572        seen = computed;
4573      } else if (iteratee) {
4574        if (!contains(seen, computed)) {
4575          seen.push(computed);
4576          result.push(value);
4577        }
4578      } else if (!contains(result, value)) {
4579        result.push(value);
4580      }
4581    }
4582    return result;
4583  }
4584
4585  // Produce an array that contains the union: each distinct element from all of
4586  // the passed-in arrays.
4587  var union = restArguments(function(arrays) {
4588    return uniq(flatten$1(arrays, true, true));
4589  });
4590
4591  // Produce an array that contains every item shared between all the
4592  // passed-in arrays.
4593  function intersection(array) {
4594    var result = [];
4595    var argsLength = arguments.length;
4596    for (var i = 0, length = getLength(array); i < length; i++) {
4597      var item = array[i];
4598      if (contains(result, item)) continue;
4599      var j;
4600      for (j = 1; j < argsLength; j++) {
4601        if (!contains(arguments[j], item)) break;
4602      }
4603      if (j === argsLength) result.push(item);
4604    }
4605    return result;
4606  }
4607
4608  // Complement of zip. Unzip accepts an array of arrays and groups
4609  // each array's elements on shared indices.
4610  function unzip(array) {
4611    var length = (array && max(array, getLength).length) || 0;
4612    var result = Array(length);
4613
4614    for (var index = 0; index < length; index++) {
4615      result[index] = pluck(array, index);
4616    }
4617    return result;
4618  }
4619
4620  // Zip together multiple lists into a single array -- elements that share
4621  // an index go together.
4622  var zip = restArguments(unzip);
4623
4624  // Converts lists into objects. Pass either a single array of `[key, value]`
4625  // pairs, or two parallel arrays of the same length -- one of keys, and one of
4626  // the corresponding values. Passing by pairs is the reverse of `_.pairs`.
4627  function object(list, values) {
4628    var result = {};
4629    for (var i = 0, length = getLength(list); i < length; i++) {
4630      if (values) {
4631        result[list[i]] = values[i];
4632      } else {
4633        result[list[i][0]] = list[i][1];
4634      }
4635    }
4636    return result;
4637  }
4638
4639  // Generate an integer Array containing an arithmetic progression. A port of
4640  // the native Python `range()` function. See
4641  // [the Python documentation](https://docs.python.org/library/functions.html#range).
4642  function range(start, stop, step) {
4643    if (stop == null) {
4644      stop = start || 0;
4645      start = 0;
4646    }
4647    if (!step) {
4648      step = stop < start ? -1 : 1;
4649    }
4650
4651    var length = Math.max(Math.ceil((stop - start) / step), 0);
4652    var range = Array(length);
4653
4654    for (var idx = 0; idx < length; idx++, start += step) {
4655      range[idx] = start;
4656    }
4657
4658    return range;
4659  }
4660
4661  // Chunk a single array into multiple arrays, each containing `count` or fewer
4662  // items.
4663  function chunk(array, count) {
4664    if (count == null || count < 1) return [];
4665    var result = [];
4666    var i = 0, length = array.length;
4667    while (i < length) {
4668      result.push(slice.call(array, i, i += count));
4669    }
4670    return result;
4671  }
4672
4673  // Helper function to continue chaining intermediate results.
4674  function chainResult(instance, obj) {
4675    return instance._chain ? _$1(obj).chain() : obj;
4676  }
4677
4678  // Add your own custom functions to the Underscore object.
4679  function mixin(obj) {
4680    each(functions(obj), function(name) {
4681      var func = _$1[name] = obj[name];
4682      _$1.prototype[name] = function() {
4683        var args = [this._wrapped];
4684        push.apply(args, arguments);
4685        return chainResult(this, func.apply(_$1, args));
4686      };
4687    });
4688    return _$1;
4689  }
4690
4691  // Add all mutator `Array` functions to the wrapper.
4692  each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
4693    var method = ArrayProto[name];
4694    _$1.prototype[name] = function() {
4695      var obj = this._wrapped;
4696      if (obj != null) {
4697        method.apply(obj, arguments);
4698        if ((name === 'shift' || name === 'splice') && obj.length === 0) {
4699          delete obj[0];
4700        }
4701      }
4702      return chainResult(this, obj);
4703    };
4704  });
4705
4706  // Add all accessor `Array` functions to the wrapper.
4707  each(['concat', 'join', 'slice'], function(name) {
4708    var method = ArrayProto[name];
4709    _$1.prototype[name] = function() {
4710      var obj = this._wrapped;
4711      if (obj != null) obj = method.apply(obj, arguments);
4712      return chainResult(this, obj);
4713    };
4714  });
4715
4716  // Named Exports
4717
4718  var allExports = {
4719    __proto__: null,
4720    VERSION: VERSION,
4721    restArguments: restArguments,
4722    isObject: isObject,
4723    isNull: isNull,
4724    isUndefined: isUndefined,
4725    isBoolean: isBoolean,
4726    isElement: isElement,
4727    isString: isString,
4728    isNumber: isNumber,
4729    isDate: isDate,
4730    isRegExp: isRegExp,
4731    isError: isError,
4732    isSymbol: isSymbol,
4733    isArrayBuffer: isArrayBuffer,
4734    isDataView: isDataView$1,
4735    isArray: isArray,
4736    isFunction: isFunction$1,
4737    isArguments: isArguments$1,
4738    isFinite: isFinite$1,
4739    isNaN: isNaN$1,
4740    isTypedArray: isTypedArray$1,
4741    isEmpty: isEmpty,
4742    isMatch: isMatch,
4743    isEqual: isEqual,
4744    isMap: isMap,
4745    isWeakMap: isWeakMap,
4746    isSet: isSet,
4747    isWeakSet: isWeakSet,
4748    keys: keys,
4749    allKeys: allKeys,
4750    values: values,
4751    pairs: pairs,
4752    invert: invert,
4753    functions: functions,
4754    methods: functions,
4755    extend: extend,
4756    extendOwn: extendOwn,
4757    assign: extendOwn,
4758    defaults: defaults,
4759    create: create,
4760    clone: clone,
4761    tap: tap,
4762    get: get,
4763    has: has,
4764    mapObject: mapObject,
4765    identity: identity,
4766    constant: constant,
4767    noop: noop,
4768    toPath: toPath$1,
4769    property: property,
4770    propertyOf: propertyOf,
4771    matcher: matcher,
4772    matches: matcher,
4773    times: times,
4774    random: random,
4775    now: now,
4776    escape: _escape,
4777    unescape: _unescape,
4778    templateSettings: templateSettings,
4779    template: template,
4780    result: result,
4781    uniqueId: uniqueId,
4782    chain: chain,
4783    iteratee: iteratee,
4784    partial: partial,
4785    bind: bind,
4786    bindAll: bindAll,
4787    memoize: memoize,
4788    delay: delay,
4789    defer: defer,
4790    throttle: throttle,
4791    debounce: debounce,
4792    wrap: wrap,
4793    negate: negate,
4794    compose: compose,
4795    after: after,
4796    before: before,
4797    once: once,
4798    findKey: findKey,
4799    findIndex: findIndex,
4800    findLastIndex: findLastIndex,
4801    sortedIndex: sortedIndex,
4802    indexOf: indexOf,
4803    lastIndexOf: lastIndexOf,
4804    find: find,
4805    detect: find,
4806    findWhere: findWhere,
4807    each: each,
4808    forEach: each,
4809    map: map,
4810    collect: map,
4811    reduce: reduce,
4812    foldl: reduce,
4813    inject: reduce,
4814    reduceRight: reduceRight,
4815    foldr: reduceRight,
4816    filter: filter,
4817    select: filter,
4818    reject: reject,
4819    every: every,
4820    all: every,
4821    some: some,
4822    any: some,
4823    contains: contains,
4824    includes: contains,
4825    include: contains,
4826    invoke: invoke,
4827    pluck: pluck,
4828    where: where,
4829    max: max,
4830    min: min,
4831    shuffle: shuffle,
4832    sample: sample,
4833    sortBy: sortBy,
4834    groupBy: groupBy,
4835    indexBy: indexBy,
4836    countBy: countBy,
4837    partition: partition,
4838    toArray: toArray,
4839    size: size,
4840    pick: pick,
4841    omit: omit,
4842    first: first,
4843    head: first,
4844    take: first,
4845    initial: initial,
4846    last: last,
4847    rest: rest,
4848    tail: rest,
4849    drop: rest,
4850    compact: compact,
4851    flatten: flatten,
4852    without: without,
4853    uniq: uniq,
4854    unique: uniq,
4855    union: union,
4856    intersection: intersection,
4857    difference: difference,
4858    unzip: unzip,
4859    transpose: unzip,
4860    zip: zip,
4861    object: object,
4862    range: range,
4863    chunk: chunk,
4864    mixin: mixin,
4865    'default': _$1
4866  };
4867
4868  // Default Export
4869
4870  // Add all of the Underscore functions to the wrapper object.
4871  var _ = mixin(allExports);
4872  // Legacy Node.js API.
4873  _._ = _;
4874
4875  return _;
4876
4877})));
4878//# sourceMappingURL=underscore-umd.js.map
vendor: 18,145 bytes, lines 4879-5536
4879/**!
4880
4881 @license
4882 handlebars v4.7.8
4883
4884Copyright (C) 2011-2019 by Yehuda Katz
4885
4886Permission is hereby granted, free of charge, to any person obtaining a copy
4887of this software and associated documentation files (the "Software"), to deal
4888in the Software without restriction, including without limitation the rights
4889to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
4890copies of the Software, and to permit persons to whom the Software is
4891furnished to do so, subject to the following conditions:
4892
4893The above copyright notice and this permission notice shall be included in
4894all copies or substantial portions of the Software.
4895
4896THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4897IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4898FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
4899AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4900LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
4901OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
4902THE SOFTWARE.
4903
4904*/
4905(function webpackUniversalModuleDefinition(root, factory) {
4906	if(typeof exports === 'object' && typeof module === 'object')
4907		module.exports = factory();
4908	else if(typeof define === 'function' && define.amd)
4909		define([], factory);
4910	else if(typeof exports === 'object')
4911		exports["Handlebars"] = factory();
4912	else
4913		root["Handlebars"] = factory();
4914})(this, function() {
4915return /******/ (function(modules) { // webpackBootstrap
4916/******/ 	// The module cache
4917/******/ 	var installedModules = {};
4918
4919/******/ 	// The require function
4920/******/ 	function __webpack_require__(moduleId) {
4921
4922/******/ 		// Check if module is in cache
4923/******/ 		if(installedModules[moduleId])
4924/******/ 			return installedModules[moduleId].exports;
4925
4926/******/ 		// Create a new module (and put it into the cache)
4927/******/ 		var module = installedModules[moduleId] = {
4928/******/ 			exports: {},
4929/******/ 			id: moduleId,
4930/******/ 			loaded: false
4931/******/ 		};
4932
4933/******/ 		// Execute the module function
4934/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
4935
4936/******/ 		// Flag the module as loaded
4937/******/ 		module.loaded = true;
4938
4939/******/ 		// Return the exports of the module
4940/******/ 		return module.exports;
4941/******/ 	}
4942
4943
4944/******/ 	// expose the modules object (__webpack_modules__)
4945/******/ 	__webpack_require__.m = modules;
4946
4947/******/ 	// expose the module cache
4948/******/ 	__webpack_require__.c = installedModules;
4949
4950/******/ 	// __webpack_public_path__
4951/******/ 	__webpack_require__.p = "";
4952
4953/******/ 	// Load entry module and return exports
4954/******/ 	return __webpack_require__(0);
4955/******/ })
4956/************************************************************************/
4957/******/ ([
4958/* 0 */
4959/***/ (function(module, exports, __webpack_require__) {
4960
4961	'use strict';
4962
4963	var _interopRequireDefault = __webpack_require__(1)['default'];
4964
4965	exports.__esModule = true;
4966
4967	var _handlebarsRuntime = __webpack_require__(2);
4968
4969	var _handlebarsRuntime2 = _interopRequireDefault(_handlebarsRuntime);
4970
4971	// Compiler imports
4972
4973	var _handlebarsCompilerAst = __webpack_require__(84);
4974
4975	var _handlebarsCompilerAst2 = _interopRequireDefault(_handlebarsCompilerAst);
4976
4977	var _handlebarsCompilerBase = __webpack_require__(85);
4978
4979	var _handlebarsCompilerCompiler = __webpack_require__(90);
4980
4981	var _handlebarsCompilerJavascriptCompiler = __webpack_require__(91);
4982
4983	var _handlebarsCompilerJavascriptCompiler2 = _interopRequireDefault(_handlebarsCompilerJavascriptCompiler);
4984
4985	var _handlebarsCompilerVisitor = __webpack_require__(88);
4986
4987	var _handlebarsCompilerVisitor2 = _interopRequireDefault(_handlebarsCompilerVisitor);
4988
4989	var _handlebarsNoConflict = __webpack_require__(83);
4990
4991	var _handlebarsNoConflict2 = _interopRequireDefault(_handlebarsNoConflict);
4992
4993	var _create = _handlebarsRuntime2['default'].create;
4994	function create() {
4995	  var hb = _create();
4996
4997	  hb.compile = function (input, options) {
4998	    return _handlebarsCompilerCompiler.compile(input, options, hb);
4999	  };
5000	  hb.precompile = function (input, options) {
5001	    return _handlebarsCompilerCompiler.precompile(input, options, hb);
5002	  };
5003
5004	  hb.AST = _handlebarsCompilerAst2['default'];
5005	  hb.Compiler = _handlebarsCompilerCompiler.Compiler;
5006	  hb.JavaScriptCompiler = _handlebarsCompilerJavascriptCompiler2['default'];
5007	  hb.Parser = _handlebarsCompilerBase.parser;
5008	  hb.parse = _handlebarsCompilerBase.parse;
5009	  hb.parseWithoutProcessing = _handlebarsCompilerBase.parseWithoutProcessing;
5010
5011	  return hb;
5012	}
5013
5014	var inst = create();
5015	inst.create = create;
5016
5017	_handlebarsNoConflict2['default'](inst);
5018
5019	inst.Visitor = _handlebarsCompilerVisitor2['default'];
5020
5021	inst['default'] = inst;
5022
5023	exports['default'] = inst;
5024	module.exports = exports['default'];
5025
5026/***/ }),
5027/* 1 */
5028/***/ (function(module, exports) {
5029
5030	"use strict";
5031
5032	exports["default"] = function (obj) {
5033	  return obj && obj.__esModule ? obj : {
5034	    "default": obj
5035	  };
5036	};
5037
5038	exports.__esModule = true;
5039
5040/***/ }),
5041/* 2 */
5042/***/ (function(module, exports, __webpack_require__) {
5043
5044	'use strict';
5045
5046	var _interopRequireWildcard = __webpack_require__(3)['default'];
5047
5048	var _interopRequireDefault = __webpack_require__(1)['default'];
5049
5050	exports.__esModule = true;
5051
5052	var _handlebarsBase = __webpack_require__(4);
5053
5054	var base = _interopRequireWildcard(_handlebarsBase);
5055
5056	// Each of these augment the Handlebars object. No need to setup here.
5057	// (This is done to easily share code between commonjs and browse envs)
5058
5059	var _handlebarsSafeString = __webpack_require__(77);
5060
5061	var _handlebarsSafeString2 = _interopRequireDefault(_handlebarsSafeString);
5062
5063	var _handlebarsException = __webpack_require__(6);
5064
5065	var _handlebarsException2 = _interopRequireDefault(_handlebarsException);
5066
5067	var _handlebarsUtils = __webpack_require__(5);
5068
5069	var Utils = _interopRequireWildcard(_handlebarsUtils);
5070
5071	var _handlebarsRuntime = __webpack_require__(78);
5072
5073	var runtime = _interopRequireWildcard(_handlebarsRuntime);
5074
5075	var _handlebarsNoConflict = __webpack_require__(83);
5076
5077	var _handlebarsNoConflict2 = _interopRequireDefault(_handlebarsNoConflict);
5078
5079	// For compatibility and usage outside of module systems, make the Handlebars object a namespace
5080	function create() {
5081	  var hb = new base.HandlebarsEnvironment();
5082
5083	  Utils.extend(hb, base);
5084	  hb.SafeString = _handlebarsSafeString2['default'];
5085	  hb.Exception = _handlebarsException2['default'];
5086	  hb.Utils = Utils;
5087	  hb.escapeExpression = Utils.escapeExpression;
5088
5089	  hb.VM = runtime;
5090	  hb.template = function (spec) {
5091	    return runtime.template(spec, hb);
5092	  };
5093
5094	  return hb;
5095	}
5096
5097	var inst = create();
5098	inst.create = create;
5099
5100	_handlebarsNoConflict2['default'](inst);
5101
5102	inst['default'] = inst;
5103
5104	exports['default'] = inst;
5105	module.exports = exports['default'];
5106
5107/***/ }),
5108/* 3 */
5109/***/ (function(module, exports) {
5110
5111	"use strict";
5112
5113	exports["default"] = function (obj) {
5114	  if (obj && obj.__esModule) {
5115	    return obj;
5116	  } else {
5117	    var newObj = {};
5118
5119	    if (obj != null) {
5120	      for (var key in obj) {
5121	        if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];
5122	      }
5123	    }
5124
5125	    newObj["default"] = obj;
5126	    return newObj;
5127	  }
5128	};
5129
5130	exports.__esModule = true;
5131
5132/***/ }),
5133/* 4 */
5134/***/ (function(module, exports, __webpack_require__) {
5135
5136	'use strict';
5137
5138	var _interopRequireDefault = __webpack_require__(1)['default'];
5139
5140	exports.__esModule = true;
5141	exports.HandlebarsEnvironment = HandlebarsEnvironment;
5142
5143	var _utils = __webpack_require__(5);
5144
5145	var _exception = __webpack_require__(6);
5146
5147	var _exception2 = _interopRequireDefault(_exception);
5148
5149	var _helpers = __webpack_require__(10);
5150
5151	var _decorators = __webpack_require__(70);
5152
5153	var _logger = __webpack_require__(72);
5154
5155	var _logger2 = _interopRequireDefault(_logger);
5156
5157	var _internalProtoAccess = __webpack_require__(73);
5158
5159	var VERSION = '4.7.8';
5160	exports.VERSION = VERSION;
5161	var COMPILER_REVISION = 8;
5162	exports.COMPILER_REVISION = COMPILER_REVISION;
5163	var LAST_COMPATIBLE_COMPILER_REVISION = 7;
5164
5165	exports.LAST_COMPATIBLE_COMPILER_REVISION = LAST_COMPATIBLE_COMPILER_REVISION;
5166	var REVISION_CHANGES = {
5167	  1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
5168	  2: '== 1.0.0-rc.3',
5169	  3: '== 1.0.0-rc.4',
5170	  4: '== 1.x.x',
5171	  5: '== 2.0.0-alpha.x',
5172	  6: '>= 2.0.0-beta.1',
5173	  7: '>= 4.0.0 <4.3.0',
5174	  8: '>= 4.3.0'
5175	};
5176
5177	exports.REVISION_CHANGES = REVISION_CHANGES;
5178	var objectType = '[object Object]';
5179
5180	function HandlebarsEnvironment(helpers, partials, decorators) {
5181	  this.helpers = helpers || {};
5182	  this.partials = partials || {};
5183	  this.decorators = decorators || {};
5184
5185	  _helpers.registerDefaultHelpers(this);
5186	  _decorators.registerDefaultDecorators(this);
5187	}
5188
5189	HandlebarsEnvironment.prototype = {
5190	  constructor: HandlebarsEnvironment,
5191
5192	  logger: _logger2['default'],
5193	  log: _logger2['default'].log,
5194
5195	  registerHelper: function registerHelper(name, fn) {
5196	    if (_utils.toString.call(name) === objectType) {
5197	      if (fn) {
5198	        throw new _exception2['default']('Arg not supported with multiple helpers');
5199	      }
5200	      _utils.extend(this.helpers, name);
5201	    } else {
5202	      this.helpers[name] = fn;
5203	    }
5204	  },
5205	  unregisterHelper: function unregisterHelper(name) {
5206	    delete this.helpers[name];
5207	  },
5208
5209	  registerPartial: function registerPartial(name, partial) {
5210	    if (_utils.toString.call(name) === objectType) {
5211	      _utils.extend(this.partials, name);
5212	    } else {
5213	      if (typeof partial === 'undefined') {
5214	        throw new _exception2['default']('Attempting to register a partial called "' + name + '" as undefined');
5215	      }
5216	      this.partials[name] = partial;
5217	    }
5218	  },
5219	  unregisterPartial: function unregisterPartial(name) {
5220	    delete this.partials[name];
5221	  },
5222
5223	  registerDecorator: function registerDecorator(name, fn) {
5224	    if (_utils.toString.call(name) === objectType) {
5225	      if (fn) {
5226	        throw new _exception2['default']('Arg not supported with multiple decorators');
5227	      }
5228	      _utils.extend(this.decorators, name);
5229	    } else {
5230	      this.decorators[name] = fn;
5231	    }
5232	  },
5233	  unregisterDecorator: function unregisterDecorator(name) {
5234	    delete this.decorators[name];
5235	  },
5236	  /**
5237	   * Reset the memory of illegal property accesses that have already been logged.
5238	   * @deprecated should only be used in handlebars test-cases
5239	   */
5240	  resetLoggedPropertyAccesses: function resetLoggedPropertyAccesses() {
5241	    _internalProtoAccess.resetLoggedProperties();
5242	  }
5243	};
5244
5245	var log = _logger2['default'].log;
5246
5247	exports.log = log;
5248	exports.createFrame = _utils.createFrame;
5249	exports.logger = _logger2['default'];
5250
5251/***/ }),
5252/* 5 */
5253/***/ (function(module, exports) {
5254
5255	'use strict';
5256
5257	exports.__esModule = true;
5258	exports.extend = extend;
5259	exports.indexOf = indexOf;
5260	exports.escapeExpression = escapeExpression;
5261	exports.isEmpty = isEmpty;
5262	exports.createFrame = createFrame;
5263	exports.blockParams = blockParams;
5264	exports.appendContextPath = appendContextPath;
5265	var escape = {
5266	  '&': '&amp;',
5267	  '<': '&lt;',
5268	  '>': '&gt;',
5269	  '"': '&quot;',
5270	  "'": '&#x27;',
5271	  '`': '&#x60;',
5272	  '=': '&#x3D;'
5273	};
5274
5275	var badChars = /[&<>"'`=]/g,
5276	    possible = /[&<>"'`=]/;
5277
5278	function escapeChar(chr) {
5279	  return escape[chr];
5280	}
5281
5282	function extend(obj /* , ...source */) {
5283	  for (var i = 1; i < arguments.length; i++) {
5284	    for (var key in arguments[i]) {
5285	      if (Object.prototype.hasOwnProperty.call(arguments[i], key)) {
5286	        obj[key] = arguments[i][key];
5287	      }
5288	    }
5289	  }
5290
5291	  return obj;
5292	}
5293
5294	var toString = Object.prototype.toString;
5295
5296	exports.toString = toString;
5297	// Sourced from lodash
5298	// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
5299	/* eslint-disable func-style */
5300	var isFunction = function isFunction(value) {
5301	  return typeof value === 'function';
5302	};
5303	// fallback for older versions of Chrome and Safari
5304	/* istanbul ignore next */
5305	if (isFunction(/x/)) {
5306	  exports.isFunction = isFunction = function (value) {
5307	    return typeof value === 'function' && toString.call(value) === '[object Function]';
5308	  };
5309	}
5310	exports.isFunction = isFunction;
5311
5312	/* eslint-enable func-style */
5313
5314	/* istanbul ignore next */
5315	var isArray = Array.isArray || function (value) {
5316	  return value && typeof value === 'object' ? toString.call(value) === '[object Array]' : false;
5317	};
5318
5319	exports.isArray = isArray;
5320	// Older IE versions do not directly support indexOf so we must implement our own, sadly.
5321
5322	function indexOf(array, value) {
5323	  for (var i = 0, len = array.length; i < len; i++) {
5324	    if (array[i] === value) {
5325	      return i;
5326	    }
5327	  }
5328	  return -1;
5329	}
5330
5331	function escapeExpression(string) {
5332	  if (typeof string !== 'string') {
5333	    // don't escape SafeStrings, since they're already safe
5334	    if (string && string.toHTML) {
5335	      return string.toHTML();
5336	    } else if (string == null) {
5337	      return '';
5338	    } else if (!string) {
5339	      return string + '';
5340	    }
5341
5342	    // Force a string conversion as this will be done by the append regardless and
5343	    // the regex test will do this transparently behind the scenes, causing issues if
5344	    // an object's to string has escaped characters in it.
5345	    string = '' + string;
5346	  }
5347
5348	  if (!possible.test(string)) {
5349	    return string;
5350	  }
5351	  return string.replace(badChars, escapeChar);
5352	}
5353
5354	function isEmpty(value) {
5355	  if (!value && value !== 0) {
5356	    return true;
5357	  } else if (isArray(value) && value.length === 0) {
5358	    return true;
5359	  } else {
5360	    return false;
5361	  }
5362	}
5363
5364	function createFrame(object) {
5365	  var frame = extend({}, object);
5366	  frame._parent = object;
5367	  return frame;
5368	}
5369
5370	function blockParams(params, ids) {
5371	  params.path = ids;
5372	  return params;
5373	}
5374
5375	function appendContextPath(contextPath, id) {
5376	  return (contextPath ? contextPath + '.' : '') + id;
5377	}
5378
5379/***/ }),
5380/* 6 */
5381/***/ (function(module, exports, __webpack_require__) {
5382
5383	'use strict';
5384
5385	var _Object$defineProperty = __webpack_require__(7)['default'];
5386
5387	exports.__esModule = true;
5388	var errorProps = ['description', 'fileName', 'lineNumber', 'endLineNumber', 'message', 'name', 'number', 'stack'];
5389
5390	function Exception(message, node) {
5391	  var loc = node && node.loc,
5392	      line = undefined,
5393	      endLineNumber = undefined,
5394	      column = undefined,
5395	      endColumn = undefined;
5396
5397	  if (loc) {
5398	    line = loc.start.line;
5399	    endLineNumber = loc.end.line;
5400	    column = loc.start.column;
5401	    endColumn = loc.end.column;
5402
5403	    message += ' - ' + line + ':' + column;
5404	  }
5405
5406	  var tmp = Error.prototype.constructor.call(this, message);
5407
5408	  // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
5409	  for (var idx = 0; idx < errorProps.length; idx++) {
5410	    this[errorProps[idx]] = tmp[errorProps[idx]];
5411	  }
5412
5413	  /* istanbul ignore else */
5414	  if (Error.captureStackTrace) {
5415	    Error.captureStackTrace(this, Exception);
5416	  }
5417
5418	  try {
5419	    if (loc) {
5420	      this.lineNumber = line;
5421	      this.endLineNumber = endLineNumber;
5422
5423	      // Work around issue under safari where we can't directly set the column value
5424	      /* istanbul ignore next */
5425	      if (_Object$defineProperty) {
5426	        Object.defineProperty(this, 'column', {
5427	          value: column,
5428	          enumerable: true
5429	        });
5430	        Object.defineProperty(this, 'endColumn', {
5431	          value: endColumn,
5432	          enumerable: true
5433	        });
5434	      } else {
5435	        this.column = column;
5436	        this.endColumn = endColumn;
5437	      }
5438	    }
5439	  } catch (nop) {
5440	    /* Ignore if the browser is very particular */
5441	  }
5442	}
5443
5444	Exception.prototype = new Error();
5445
5446	exports['default'] = Exception;
5447	module.exports = exports['default'];
5448
5449/***/ }),
5450/* 7 */
5451/***/ (function(module, exports, __webpack_require__) {
5452
5453	module.exports = { "default": __webpack_require__(8), __esModule: true };
5454
5455/***/ }),
5456/* 8 */
5457/***/ (function(module, exports, __webpack_require__) {
5458
5459	var $ = __webpack_require__(9);
5460	module.exports = function defineProperty(it, key, desc){
5461	  return $.setDesc(it, key, desc);
5462	};
5463
5464/***/ }),
5465/* 9 */
5466/***/ (function(module, exports) {
5467
5468	var $Object = Object;
5469	module.exports = {
5470	  create:     $Object.create,
5471	  getProto:   $Object.getPrototypeOf,
5472	  isEnum:     {}.propertyIsEnumerable,
5473	  getDesc:    $Object.getOwnPropertyDescriptor,
5474	  setDesc:    $Object.defineProperty,
5475	  setDescs:   $Object.defineProperties,
5476	  getKeys:    $Object.keys,
5477	  getNames:   $Object.getOwnPropertyNames,
5478	  getSymbols: $Object.getOwnPropertySymbols,
5479	  each:       [].forEach
5480	};
5481
5482/***/ }),
5483/* 10 */
5484/***/ (function(module, exports, __webpack_require__) {
5485
5486	'use strict';
5487
5488	var _interopRequireDefault = __webpack_require__(1)['default'];
5489
5490	exports.__esModule = true;
5491	exports.registerDefaultHelpers = registerDefaultHelpers;
5492	exports.moveHelperToHooks = moveHelperToHooks;
5493
5494	var _helpersBlockHelperMissing = __webpack_require__(11);
5495
5496	var _helpersBlockHelperMissing2 = _interopRequireDefault(_helpersBlockHelperMissing);
5497
5498	var _helpersEach = __webpack_require__(12);
5499
5500	var _helpersEach2 = _interopRequireDefault(_helpersEach);
5501
5502	var _helpersHelperMissing = __webpack_require__(65);
5503
5504	var _helpersHelperMissing2 = _interopRequireDefault(_helpersHelperMissing);
5505
5506	var _helpersIf = __webpack_require__(66);
5507
5508	var _helpersIf2 = _interopRequireDefault(_helpersIf);
5509
5510	var _helpersLog = __webpack_require__(67);
5511
5512	var _helpersLog2 = _interopRequireDefault(_helpersLog);
5513
5514	var _helpersLookup = __webpack_require__(68);
5515
5516	var _helpersLookup2 = _interopRequireDefault(_helpersLookup);
5517
5518	var _helpersWith = __webpack_require__(69);
5519
5520	var _helpersWith2 = _interopRequireDefault(_helpersWith);
5521
5522	function registerDefaultHelpers(instance) {
5523	  _helpersBlockHelperMissing2['default'](instance);
5524	  _helpersEach2['default'](instance);
5525	  _helpersHelperMissing2['default'](instance);
5526	  _helpersIf2['default'](instance);
5527	  _helpersLog2['default'](instance);
5528	  _helpersLookup2['default'](instance);
5529	  _helpersWith2['default'](instance);
5530	}
5531
5532	function moveHelperToHooks(instance, helperName, keepHelper) {
5533	  if (instance.helpers[helperName]) {
5534	    instance.hooks[helperName] = instance.helpers[helperName];
5535	    if (!keepHelper) {
5536	      delete instance.helpers[helperName]
vendor: 39,427 bytes, lines 5536-6922
5536;
5537	    }
5538	  }
5539	}
5540
5541/***/ }),
5542/* 11 */
5543/***/ (function(module, exports, __webpack_require__) {
5544
5545	'use strict';
5546
5547	exports.__esModule = true;
5548
5549	var _utils = __webpack_require__(5);
5550
5551	exports['default'] = function (instance) {
5552	  instance.registerHelper('blockHelperMissing', function (context, options) {
5553	    var inverse = options.inverse,
5554	        fn = options.fn;
5555
5556	    if (context === true) {
5557	      return fn(this);
5558	    } else if (context === false || context == null) {
5559	      return inverse(this);
5560	    } else if (_utils.isArray(context)) {
5561	      if (context.length > 0) {
5562	        if (options.ids) {
5563	          options.ids = [options.name];
5564	        }
5565
5566	        return instance.helpers.each(context, options);
5567	      } else {
5568	        return inverse(this);
5569	      }
5570	    } else {
5571	      if (options.data && options.ids) {
5572	        var data = _utils.createFrame(options.data);
5573	        data.contextPath = _utils.appendContextPath(options.data.contextPath, options.name);
5574	        options = { data: data };
5575	      }
5576
5577	      return fn(context, options);
5578	    }
5579	  });
5580	};
5581
5582	module.exports = exports['default'];
5583
5584/***/ }),
5585/* 12 */
5586/***/ (function(module, exports, __webpack_require__) {
5587
5588	'use strict';
5589
5590	var _Symbol = __webpack_require__(13)['default'];
5591
5592	var _Symbol$iterator = __webpack_require__(43)['default'];
5593
5594	var _getIterator = __webpack_require__(55)['default'];
5595
5596	var _Object$keys = __webpack_require__(60)['default'];
5597
5598	var _interopRequireDefault = __webpack_require__(1)['default'];
5599
5600	exports.__esModule = true;
5601
5602	var _utils = __webpack_require__(5);
5603
5604	var _exception = __webpack_require__(6);
5605
5606	var _exception2 = _interopRequireDefault(_exception);
5607
5608	exports['default'] = function (instance) {
5609	  instance.registerHelper('each', function (context, options) {
5610	    if (!options) {
5611	      throw new _exception2['default']('Must pass iterator to #each');
5612	    }
5613
5614	    var fn = options.fn,
5615	        inverse = options.inverse,
5616	        i = 0,
5617	        ret = '',
5618	        data = undefined,
5619	        contextPath = undefined;
5620
5621	    if (options.data && options.ids) {
5622	      contextPath = _utils.appendContextPath(options.data.contextPath, options.ids[0]) + '.';
5623	    }
5624
5625	    if (_utils.isFunction(context)) {
5626	      context = context.call(this);
5627	    }
5628
5629	    if (options.data) {
5630	      data = _utils.createFrame(options.data);
5631	    }
5632
5633	    function execIteration(field, index, last) {
5634	      if (data) {
5635	        data.key = field;
5636	        data.index = index;
5637	        data.first = index === 0;
5638	        data.last = !!last;
5639
5640	        if (contextPath) {
5641	          data.contextPath = contextPath + field;
5642	        }
5643	      }
5644
5645	      ret = ret + fn(context[field], {
5646	        data: data,
5647	        blockParams: _utils.blockParams([context[field], field], [contextPath + field, null])
5648	      });
5649	    }
5650
5651	    if (context && typeof context === 'object') {
5652	      if (_utils.isArray(context)) {
5653	        for (var j = context.length; i < j; i++) {
5654	          if (i in context) {
5655	            execIteration(i, i, i === context.length - 1);
5656	          }
5657	        }
5658	      } else if (typeof _Symbol === 'function' && context[_Symbol$iterator]) {
5659	        var newContext = [];
5660	        var iterator = _getIterator(context);
5661	        for (var it = iterator.next(); !it.done; it = iterator.next()) {
5662	          newContext.push(it.value);
5663	        }
5664	        context = newContext;
5665	        for (var j = context.length; i < j; i++) {
5666	          execIteration(i, i, i === context.length - 1);
5667	        }
5668	      } else {
5669	        (function () {
5670	          var priorKey = undefined;
5671
5672	          _Object$keys(context).forEach(function (key) {
5673	            // We're running the iterations one step out of sync so we can detect
5674	            // the last iteration without have to scan the object twice and create
5675	            // an itermediate keys array.
5676	            if (priorKey !== undefined) {
5677	              execIteration(priorKey, i - 1);
5678	            }
5679	            priorKey = key;
5680	            i++;
5681	          });
5682	          if (priorKey !== undefined) {
5683	            execIteration(priorKey, i - 1, true);
5684	          }
5685	        })();
5686	      }
5687	    }
5688
5689	    if (i === 0) {
5690	      ret = inverse(this);
5691	    }
5692
5693	    return ret;
5694	  });
5695	};
5696
5697	module.exports = exports['default'];
5698
5699/***/ }),
5700/* 13 */
5701/***/ (function(module, exports, __webpack_require__) {
5702
5703	module.exports = { "default": __webpack_require__(14), __esModule: true };
5704
5705/***/ }),
5706/* 14 */
5707/***/ (function(module, exports, __webpack_require__) {
5708
5709	__webpack_require__(15);
5710	__webpack_require__(42);
5711	module.exports = __webpack_require__(21).Symbol;
5712
5713/***/ }),
5714/* 15 */
5715/***/ (function(module, exports, __webpack_require__) {
5716
5717	'use strict';
5718	// ECMAScript 6 symbols shim
5719	var $              = __webpack_require__(9)
5720	  , global         = __webpack_require__(16)
5721	  , has            = __webpack_require__(17)
5722	  , DESCRIPTORS    = __webpack_require__(18)
5723	  , $export        = __webpack_require__(20)
5724	  , redefine       = __webpack_require__(24)
5725	  , $fails         = __webpack_require__(19)
5726	  , shared         = __webpack_require__(27)
5727	  , setToStringTag = __webpack_require__(28)
5728	  , uid            = __webpack_require__(30)
5729	  , wks            = __webpack_require__(29)
5730	  , keyOf          = __webpack_require__(31)
5731	  , $names         = __webpack_require__(36)
5732	  , enumKeys       = __webpack_require__(37)
5733	  , isArray        = __webpack_require__(38)
5734	  , anObject       = __webpack_require__(39)
5735	  , toIObject      = __webpack_require__(32)
5736	  , createDesc     = __webpack_require__(26)
5737	  , getDesc        = $.getDesc
5738	  , setDesc        = $.setDesc
5739	  , _create        = $.create
5740	  , getNames       = $names.get
5741	  , $Symbol        = global.Symbol
5742	  , $JSON          = global.JSON
5743	  , _stringify     = $JSON && $JSON.stringify
5744	  , setter         = false
5745	  , HIDDEN         = wks('_hidden')
5746	  , isEnum         = $.isEnum
5747	  , SymbolRegistry = shared('symbol-registry')
5748	  , AllSymbols     = shared('symbols')
5749	  , useNative      = typeof $Symbol == 'function'
5750	  , ObjectProto    = Object.prototype;
5751
5752	// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687
5753	var setSymbolDesc = DESCRIPTORS && $fails(function(){
5754	  return _create(setDesc({}, 'a', {
5755	    get: function(){ return setDesc(this, 'a', {value: 7}).a; }
5756	  })).a != 7;
5757	}) ? function(it, key, D){
5758	  var protoDesc = getDesc(ObjectProto, key);
5759	  if(protoDesc)delete ObjectProto[key];
5760	  setDesc(it, key, D);
5761	  if(protoDesc && it !== ObjectProto)setDesc(ObjectProto, key, protoDesc);
5762	} : setDesc;
5763
5764	var wrap = function(tag){
5765	  var sym = AllSymbols[tag] = _create($Symbol.prototype);
5766	  sym._k = tag;
5767	  DESCRIPTORS && setter && setSymbolDesc(ObjectProto, tag, {
5768	    configurable: true,
5769	    set: function(value){
5770	      if(has(this, HIDDEN) && has(this[HIDDEN], tag))this[HIDDEN][tag] = false;
5771	      setSymbolDesc(this, tag, createDesc(1, value));
5772	    }
5773	  });
5774	  return sym;
5775	};
5776
5777	var isSymbol = function(it){
5778	  return typeof it == 'symbol';
5779	};
5780
5781	var $defineProperty = function defineProperty(it, key, D){
5782	  if(D && has(AllSymbols, key)){
5783	    if(!D.enumerable){
5784	      if(!has(it, HIDDEN))setDesc(it, HIDDEN, createDesc(1, {}));
5785	      it[HIDDEN][key] = true;
5786	    } else {
5787	      if(has(it, HIDDEN) && it[HIDDEN][key])it[HIDDEN][key] = false;
5788	      D = _create(D, {enumerable: createDesc(0, false)});
5789	    } return setSymbolDesc(it, key, D);
5790	  } return setDesc(it, key, D);
5791	};
5792	var $defineProperties = function defineProperties(it, P){
5793	  anObject(it);
5794	  var keys = enumKeys(P = toIObject(P))
5795	    , i    = 0
5796	    , l = keys.length
5797	    , key;
5798	  while(l > i)$defineProperty(it, key = keys[i++], P[key]);
5799	  return it;
5800	};
5801	var $create = function create(it, P){
5802	  return P === undefined ? _create(it) : $defineProperties(_create(it), P);
5803	};
5804	var $propertyIsEnumerable = function propertyIsEnumerable(key){
5805	  var E = isEnum.call(this, key);
5806	  return E || !has(this, key) || !has(AllSymbols, key) || has(this, HIDDEN) && this[HIDDEN][key]
5807	    ? E : true;
5808	};
5809	var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key){
5810	  var D = getDesc(it = toIObject(it), key);
5811	  if(D && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key]))D.enumerable = true;
5812	  return D;
5813	};
5814	var $getOwnPropertyNames = function getOwnPropertyNames(it){
5815	  var names  = getNames(toIObject(it))
5816	    , result = []
5817	    , i      = 0
5818	    , key;
5819	  while(names.length > i)if(!has(AllSymbols, key = names[i++]) && key != HIDDEN)result.push(key);
5820	  return result;
5821	};
5822	var $getOwnPropertySymbols = function getOwnPropertySymbols(it){
5823	  var names  = getNames(toIObject(it))
5824	    , result = []
5825	    , i      = 0
5826	    , key;
5827	  while(names.length > i)if(has(AllSymbols, key = names[i++]))result.push(AllSymbols[key]);
5828	  return result;
5829	};
5830	var $stringify = function stringify(it){
5831	  if(it === undefined || isSymbol(it))return; // IE8 returns string on undefined
5832	  var args = [it]
5833	    , i    = 1
5834	    , $$   = arguments
5835	    , replacer, $replacer;
5836	  while($$.length > i)args.push($$[i++]);
5837	  replacer = args[1];
5838	  if(typeof replacer == 'function')$replacer = replacer;
5839	  if($replacer || !isArray(replacer))replacer = function(key, value){
5840	    if($replacer)value = $replacer.call(this, key, value);
5841	    if(!isSymbol(value))return value;
5842	  };
5843	  args[1] = replacer;
5844	  return _stringify.apply($JSON, args);
5845	};
5846	var buggyJSON = $fails(function(){
5847	  var S = $Symbol();
5848	  // MS Edge converts symbol values to JSON as {}
5849	  // WebKit converts symbol values to JSON as null
5850	  // V8 throws on boxed symbols
5851	  return _stringify([S]) != '[null]' || _stringify({a: S}) != '{}' || _stringify(Object(S)) != '{}';
5852	});
5853
5854	// 19.4.1.1 Symbol([description])
5855	if(!useNative){
5856	  $Symbol = function Symbol(){
5857	    if(isSymbol(this))throw TypeError('Symbol is not a constructor');
5858	    return wrap(uid(arguments.length > 0 ? arguments[0] : undefined));
5859	  };
5860	  redefine($Symbol.prototype, 'toString', function toString(){
5861	    return this._k;
5862	  });
5863
5864	  isSymbol = function(it){
5865	    return it instanceof $Symbol;
5866	  };
5867
5868	  $.create     = $create;
5869	  $.isEnum     = $propertyIsEnumerable;
5870	  $.getDesc    = $getOwnPropertyDescriptor;
5871	  $.setDesc    = $defineProperty;
5872	  $.setDescs   = $defineProperties;
5873	  $.getNames   = $names.get = $getOwnPropertyNames;
5874	  $.getSymbols = $getOwnPropertySymbols;
5875
5876	  if(DESCRIPTORS && !__webpack_require__(41)){
5877	    redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true);
5878	  }
5879	}
5880
5881	var symbolStatics = {
5882	  // 19.4.2.1 Symbol.for(key)
5883	  'for': function(key){
5884	    return has(SymbolRegistry, key += '')
5885	      ? SymbolRegistry[key]
5886	      : SymbolRegistry[key] = $Symbol(key);
5887	  },
5888	  // 19.4.2.5 Symbol.keyFor(sym)
5889	  keyFor: function keyFor(key){
5890	    return keyOf(SymbolRegistry, key);
5891	  },
5892	  useSetter: function(){ setter = true; },
5893	  useSimple: function(){ setter = false; }
5894	};
5895	// 19.4.2.2 Symbol.hasInstance
5896	// 19.4.2.3 Symbol.isConcatSpreadable
5897	// 19.4.2.4 Symbol.iterator
5898	// 19.4.2.6 Symbol.match
5899	// 19.4.2.8 Symbol.replace
5900	// 19.4.2.9 Symbol.search
5901	// 19.4.2.10 Symbol.species
5902	// 19.4.2.11 Symbol.split
5903	// 19.4.2.12 Symbol.toPrimitive
5904	// 19.4.2.13 Symbol.toStringTag
5905	// 19.4.2.14 Symbol.unscopables
5906	$.each.call((
5907	  'hasInstance,isConcatSpreadable,iterator,match,replace,search,' +
5908	  'species,split,toPrimitive,toStringTag,unscopables'
5909	).split(','), function(it){
5910	  var sym = wks(it);
5911	  symbolStatics[it] = useNative ? sym : wrap(sym);
5912	});
5913
5914	setter = true;
5915
5916	$export($export.G + $export.W, {Symbol: $Symbol});
5917
5918	$export($export.S, 'Symbol', symbolStatics);
5919
5920	$export($export.S + $export.F * !useNative, 'Object', {
5921	  // 19.1.2.2 Object.create(O [, Properties])
5922	  create: $create,
5923	  // 19.1.2.4 Object.defineProperty(O, P, Attributes)
5924	  defineProperty: $defineProperty,
5925	  // 19.1.2.3 Object.defineProperties(O, Properties)
5926	  defineProperties: $defineProperties,
5927	  // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)
5928	  getOwnPropertyDescriptor: $getOwnPropertyDescriptor,
5929	  // 19.1.2.7 Object.getOwnPropertyNames(O)
5930	  getOwnPropertyNames: $getOwnPropertyNames,
5931	  // 19.1.2.8 Object.getOwnPropertySymbols(O)
5932	  getOwnPropertySymbols: $getOwnPropertySymbols
5933	});
5934
5935	// 24.3.2 JSON.stringify(value [, replacer [, space]])
5936	$JSON && $export($export.S + $export.F * (!useNative || buggyJSON), 'JSON', {stringify: $stringify});
5937
5938	// 19.4.3.5 Symbol.prototype[@@toStringTag]
5939	setToStringTag($Symbol, 'Symbol');
5940	// 20.2.1.9 Math[@@toStringTag]
5941	setToStringTag(Math, 'Math', true);
5942	// 24.3.3 JSON[@@toStringTag]
5943	setToStringTag(global.JSON, 'JSON', true);
5944
5945/***/ }),
5946/* 16 */
5947/***/ (function(module, exports) {
5948
5949	// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
5950	var global = module.exports = typeof window != 'undefined' && window.Math == Math
5951	  ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')();
5952	if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef
5953
5954/***/ }),
5955/* 17 */
5956/***/ (function(module, exports) {
5957
5958	var hasOwnProperty = {}.hasOwnProperty;
5959	module.exports = function(it, key){
5960	  return hasOwnProperty.call(it, key);
5961	};
5962
5963/***/ }),
5964/* 18 */
5965/***/ (function(module, exports, __webpack_require__) {
5966
5967	// Thank's IE8 for his funny defineProperty
5968	module.exports = !__webpack_require__(19)(function(){
5969	  return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7;
5970	});
5971
5972/***/ }),
5973/* 19 */
5974/***/ (function(module, exports) {
5975
5976	module.exports = function(exec){
5977	  try {
5978	    return !!exec();
5979	  } catch(e){
5980	    return true;
5981	  }
5982	};
5983
5984/***/ }),
5985/* 20 */
5986/***/ (function(module, exports, __webpack_require__) {
5987
5988	var global    = __webpack_require__(16)
5989	  , core      = __webpack_require__(21)
5990	  , ctx       = __webpack_require__(22)
5991	  , PROTOTYPE = 'prototype';
5992
5993	var $export = function(type, name, source){
5994	  var IS_FORCED = type & $export.F
5995	    , IS_GLOBAL = type & $export.G
5996	    , IS_STATIC = type & $export.S
5997	    , IS_PROTO  = type & $export.P
5998	    , IS_BIND   = type & $export.B
5999	    , IS_WRAP   = type & $export.W
6000	    , exports   = IS_GLOBAL ? core : core[name] || (core[name] = {})
6001	    , target    = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE]
6002	    , key, own, out;
6003	  if(IS_GLOBAL)source = name;
6004	  for(key in source){
6005	    // contains in native
6006	    own = !IS_FORCED && target && key in target;
6007	    if(own && key in exports)continue;
6008	    // export native or passed
6009	    out = own ? target[key] : source[key];
6010	    // prevent global pollution for namespaces
6011	    exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key]
6012	    // bind timers to global for call from export context
6013	    : IS_BIND && own ? ctx(out, global)
6014	    // wrap global constructors for prevent change them in library
6015	    : IS_WRAP && target[key] == out ? (function(C){
6016	      var F = function(param){
6017	        return this instanceof C ? new C(param) : C(param);
6018	      };
6019	      F[PROTOTYPE] = C[PROTOTYPE];
6020	      return F;
6021	    // make static versions for prototype methods
6022	    })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;
6023	    if(IS_PROTO)(exports[PROTOTYPE] || (exports[PROTOTYPE] = {}))[key] = out;
6024	  }
6025	};
6026	// type bitmap
6027	$export.F = 1;  // forced
6028	$export.G = 2;  // global
6029	$export.S = 4;  // static
6030	$export.P = 8;  // proto
6031	$export.B = 16; // bind
6032	$export.W = 32; // wrap
6033	module.exports = $export;
6034
6035/***/ }),
6036/* 21 */
6037/***/ (function(module, exports) {
6038
6039	var core = module.exports = {version: '1.2.6'};
6040	if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef
6041
6042/***/ }),
6043/* 22 */
6044/***/ (function(module, exports, __webpack_require__) {
6045
6046	// optional / simple context binding
6047	var aFunction = __webpack_require__(23);
6048	module.exports = function(fn, that, length){
6049	  aFunction(fn);
6050	  if(that === undefined)return fn;
6051	  switch(length){
6052	    case 1: return function(a){
6053	      return fn.call(that, a);
6054	    };
6055	    case 2: return function(a, b){
6056	      return fn.call(that, a, b);
6057	    };
6058	    case 3: return function(a, b, c){
6059	      return fn.call(that, a, b, c);
6060	    };
6061	  }
6062	  return function(/* ...args */){
6063	    return fn.apply(that, arguments);
6064	  };
6065	};
6066
6067/***/ }),
6068/* 23 */
6069/***/ (function(module, exports) {
6070
6071	module.exports = function(it){
6072	  if(typeof it != 'function')throw TypeError(it + ' is not a function!');
6073	  return it;
6074	};
6075
6076/***/ }),
6077/* 24 */
6078/***/ (function(module, exports, __webpack_require__) {
6079
6080	module.exports = __webpack_require__(25);
6081
6082/***/ }),
6083/* 25 */
6084/***/ (function(module, exports, __webpack_require__) {
6085
6086	var $          = __webpack_require__(9)
6087	  , createDesc = __webpack_require__(26);
6088	module.exports = __webpack_require__(18) ? function(object, key, value){
6089	  return $.setDesc(object, key, createDesc(1, value));
6090	} : function(object, key, value){
6091	  object[key] = value;
6092	  return object;
6093	};
6094
6095/***/ }),
6096/* 26 */
6097/***/ (function(module, exports) {
6098
6099	module.exports = function(bitmap, value){
6100	  return {
6101	    enumerable  : !(bitmap & 1),
6102	    configurable: !(bitmap & 2),
6103	    writable    : !(bitmap & 4),
6104	    value       : value
6105	  };
6106	};
6107
6108/***/ }),
6109/* 27 */
6110/***/ (function(module, exports, __webpack_require__) {
6111
6112	var global = __webpack_require__(16)
6113	  , SHARED = '__core-js_shared__'
6114	  , store  = global[SHARED] || (global[SHARED] = {});
6115	module.exports = function(key){
6116	  return store[key] || (store[key] = {});
6117	};
6118
6119/***/ }),
6120/* 28 */
6121/***/ (function(module, exports, __webpack_require__) {
6122
6123	var def = __webpack_require__(9).setDesc
6124	  , has = __webpack_require__(17)
6125	  , TAG = __webpack_require__(29)('toStringTag');
6126
6127	module.exports = function(it, tag, stat){
6128	  if(it && !has(it = stat ? it : it.prototype, TAG))def(it, TAG, {configurable: true, value: tag});
6129	};
6130
6131/***/ }),
6132/* 29 */
6133/***/ (function(module, exports, __webpack_require__) {
6134
6135	var store  = __webpack_require__(27)('wks')
6136	  , uid    = __webpack_require__(30)
6137	  , Symbol = __webpack_require__(16).Symbol;
6138	module.exports = function(name){
6139	  return store[name] || (store[name] =
6140	    Symbol && Symbol[name] || (Symbol || uid)('Symbol.' + name));
6141	};
6142
6143/***/ }),
6144/* 30 */
6145/***/ (function(module, exports) {
6146
6147	var id = 0
6148	  , px = Math.random();
6149	module.exports = function(key){
6150	  return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));
6151	};
6152
6153/***/ }),
6154/* 31 */
6155/***/ (function(module, exports, __webpack_require__) {
6156
6157	var $         = __webpack_require__(9)
6158	  , toIObject = __webpack_require__(32);
6159	module.exports = function(object, el){
6160	  var O      = toIObject(object)
6161	    , keys   = $.getKeys(O)
6162	    , length = keys.length
6163	    , index  = 0
6164	    , key;
6165	  while(length > index)if(O[key = keys[index++]] === el)return key;
6166	};
6167
6168/***/ }),
6169/* 32 */
6170/***/ (function(module, exports, __webpack_require__) {
6171
6172	// to indexed object, toObject with fallback for non-array-like ES3 strings
6173	var IObject = __webpack_require__(33)
6174	  , defined = __webpack_require__(35);
6175	module.exports = function(it){
6176	  return IObject(defined(it));
6177	};
6178
6179/***/ }),
6180/* 33 */
6181/***/ (function(module, exports, __webpack_require__) {
6182
6183	// fallback for non-array-like ES3 and non-enumerable old V8 strings
6184	var cof = __webpack_require__(34);
6185	module.exports = Object('z').propertyIsEnumerable(0) ? Object : function(it){
6186	  return cof(it) == 'String' ? it.split('') : Object(it);
6187	};
6188
6189/***/ }),
6190/* 34 */
6191/***/ (function(module, exports) {
6192
6193	var toString = {}.toString;
6194
6195	module.exports = function(it){
6196	  return toString.call(it).slice(8, -1);
6197	};
6198
6199/***/ }),
6200/* 35 */
6201/***/ (function(module, exports) {
6202
6203	// 7.2.1 RequireObjectCoercible(argument)
6204	module.exports = function(it){
6205	  if(it == undefined)throw TypeError("Can't call method on  " + it);
6206	  return it;
6207	};
6208
6209/***/ }),
6210/* 36 */
6211/***/ (function(module, exports, __webpack_require__) {
6212
6213	// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window
6214	var toIObject = __webpack_require__(32)
6215	  , getNames  = __webpack_require__(9).getNames
6216	  , toString  = {}.toString;
6217
6218	var windowNames = typeof window == 'object' && Object.getOwnPropertyNames
6219	  ? Object.getOwnPropertyNames(window) : [];
6220
6221	var getWindowNames = function(it){
6222	  try {
6223	    return getNames(it);
6224	  } catch(e){
6225	    return windowNames.slice();
6226	  }
6227	};
6228
6229	module.exports.get = function getOwnPropertyNames(it){
6230	  if(windowNames && toString.call(it) == '[object Window]')return getWindowNames(it);
6231	  return getNames(toIObject(it));
6232	};
6233
6234/***/ }),
6235/* 37 */
6236/***/ (function(module, exports, __webpack_require__) {
6237
6238	// all enumerable object keys, includes symbols
6239	var $ = __webpack_require__(9);
6240	module.exports = function(it){
6241	  var keys       = $.getKeys(it)
6242	    , getSymbols = $.getSymbols;
6243	  if(getSymbols){
6244	    var symbols = getSymbols(it)
6245	      , isEnum  = $.isEnum
6246	      , i       = 0
6247	      , key;
6248	    while(symbols.length > i)if(isEnum.call(it, key = symbols[i++]))keys.push(key);
6249	  }
6250	  return keys;
6251	};
6252
6253/***/ }),
6254/* 38 */
6255/***/ (function(module, exports, __webpack_require__) {
6256
6257	// 7.2.2 IsArray(argument)
6258	var cof = __webpack_require__(34);
6259	module.exports = Array.isArray || function(arg){
6260	  return cof(arg) == 'Array';
6261	};
6262
6263/***/ }),
6264/* 39 */
6265/***/ (function(module, exports, __webpack_require__) {
6266
6267	var isObject = __webpack_require__(40);
6268	module.exports = function(it){
6269	  if(!isObject(it))throw TypeError(it + ' is not an object!');
6270	  return it;
6271	};
6272
6273/***/ }),
6274/* 40 */
6275/***/ (function(module, exports) {
6276
6277	module.exports = function(it){
6278	  return typeof it === 'object' ? it !== null : typeof it === 'function';
6279	};
6280
6281/***/ }),
6282/* 41 */
6283/***/ (function(module, exports) {
6284
6285	module.exports = true;
6286
6287/***/ }),
6288/* 42 */
6289/***/ (function(module, exports) {
6290
6291
6292
6293/***/ }),
6294/* 43 */
6295/***/ (function(module, exports, __webpack_require__) {
6296
6297	module.exports = { "default": __webpack_require__(44), __esModule: true };
6298
6299/***/ }),
6300/* 44 */
6301/***/ (function(module, exports, __webpack_require__) {
6302
6303	__webpack_require__(45);
6304	__webpack_require__(51);
6305	module.exports = __webpack_require__(29)('iterator');
6306
6307/***/ }),
6308/* 45 */
6309/***/ (function(module, exports, __webpack_require__) {
6310
6311	'use strict';
6312	var $at  = __webpack_require__(46)(true);
6313
6314	// 21.1.3.27 String.prototype[@@iterator]()
6315	__webpack_require__(48)(String, 'String', function(iterated){
6316	  this._t = String(iterated); // target
6317	  this._i = 0;                // next index
6318	// 21.1.5.2.1 %StringIteratorPrototype%.next()
6319	}, function(){
6320	  var O     = this._t
6321	    , index = this._i
6322	    , point;
6323	  if(index >= O.length)return {value: undefined, done: true};
6324	  point = $at(O, index);
6325	  this._i += point.length;
6326	  return {value: point, done: false};
6327	});
6328
6329/***/ }),
6330/* 46 */
6331/***/ (function(module, exports, __webpack_require__) {
6332
6333	var toInteger = __webpack_require__(47)
6334	  , defined   = __webpack_require__(35);
6335	// true  -> String#at
6336	// false -> String#codePointAt
6337	module.exports = function(TO_STRING){
6338	  return function(that, pos){
6339	    var s = String(defined(that))
6340	      , i = toInteger(pos)
6341	      , l = s.length
6342	      , a, b;
6343	    if(i < 0 || i >= l)return TO_STRING ? '' : undefined;
6344	    a = s.charCodeAt(i);
6345	    return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff
6346	      ? TO_STRING ? s.charAt(i) : a
6347	      : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;
6348	  };
6349	};
6350
6351/***/ }),
6352/* 47 */
6353/***/ (function(module, exports) {
6354
6355	// 7.1.4 ToInteger
6356	var ceil  = Math.ceil
6357	  , floor = Math.floor;
6358	module.exports = function(it){
6359	  return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
6360	};
6361
6362/***/ }),
6363/* 48 */
6364/***/ (function(module, exports, __webpack_require__) {
6365
6366	'use strict';
6367	var LIBRARY        = __webpack_require__(41)
6368	  , $export        = __webpack_require__(20)
6369	  , redefine       = __webpack_require__(24)
6370	  , hide           = __webpack_require__(25)
6371	  , has            = __webpack_require__(17)
6372	  , Iterators      = __webpack_require__(49)
6373	  , $iterCreate    = __webpack_require__(50)
6374	  , setToStringTag = __webpack_require__(28)
6375	  , getProto       = __webpack_require__(9).getProto
6376	  , ITERATOR       = __webpack_require__(29)('iterator')
6377	  , BUGGY          = !([].keys && 'next' in [].keys()) // Safari has buggy iterators w/o `next`
6378	  , FF_ITERATOR    = '@@iterator'
6379	  , KEYS           = 'keys'
6380	  , VALUES         = 'values';
6381
6382	var returnThis = function(){ return this; };
6383
6384	module.exports = function(Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED){
6385	  $iterCreate(Constructor, NAME, next);
6386	  var getMethod = function(kind){
6387	    if(!BUGGY && kind in proto)return proto[kind];
6388	    switch(kind){
6389	      case KEYS: return function keys(){ return new Constructor(this, kind); };
6390	      case VALUES: return function values(){ return new Constructor(this, kind); };
6391	    } return function entries(){ return new Constructor(this, kind); };
6392	  };
6393	  var TAG        = NAME + ' Iterator'
6394	    , DEF_VALUES = DEFAULT == VALUES
6395	    , VALUES_BUG = false
6396	    , proto      = Base.prototype
6397	    , $native    = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT]
6398	    , $default   = $native || getMethod(DEFAULT)
6399	    , methods, key;
6400	  // Fix native
6401	  if($native){
6402	    var IteratorPrototype = getProto($default.call(new Base));
6403	    // Set @@toStringTag to native iterators
6404	    setToStringTag(IteratorPrototype, TAG, true);
6405	    // FF fix
6406	    if(!LIBRARY && has(proto, FF_ITERATOR))hide(IteratorPrototype, ITERATOR, returnThis);
6407	    // fix Array#{values, @@iterator}.name in V8 / FF
6408	    if(DEF_VALUES && $native.name !== VALUES){
6409	      VALUES_BUG = true;
6410	      $default = function values(){ return $native.call(this); };
6411	    }
6412	  }
6413	  // Define iterator
6414	  if((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])){
6415	    hide(proto, ITERATOR, $default);
6416	  }
6417	  // Plug for library
6418	  Iterators[NAME] = $default;
6419	  Iterators[TAG]  = returnThis;
6420	  if(DEFAULT){
6421	    methods = {
6422	      values:  DEF_VALUES  ? $default : getMethod(VALUES),
6423	      keys:    IS_SET      ? $default : getMethod(KEYS),
6424	      entries: !DEF_VALUES ? $default : getMethod('entries')
6425	    };
6426	    if(FORCED)for(key in methods){
6427	      if(!(key in proto))redefine(proto, key, methods[key]);
6428	    } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods);
6429	  }
6430	  return methods;
6431	};
6432
6433/***/ }),
6434/* 49 */
6435/***/ (function(module, exports) {
6436
6437	module.exports = {};
6438
6439/***/ }),
6440/* 50 */
6441/***/ (function(module, exports, __webpack_require__) {
6442
6443	'use strict';
6444	var $              = __webpack_require__(9)
6445	  , descriptor     = __webpack_require__(26)
6446	  , setToStringTag = __webpack_require__(28)
6447	  , IteratorPrototype = {};
6448
6449	// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
6450	__webpack_require__(25)(IteratorPrototype, __webpack_require__(29)('iterator'), function(){ return this; });
6451
6452	module.exports = function(Constructor, NAME, next){
6453	  Constructor.prototype = $.create(IteratorPrototype, {next: descriptor(1, next)});
6454	  setToStringTag(Constructor, NAME + ' Iterator');
6455	};
6456
6457/***/ }),
6458/* 51 */
6459/***/ (function(module, exports, __webpack_require__) {
6460
6461	__webpack_require__(52);
6462	var Iterators = __webpack_require__(49);
6463	Iterators.NodeList = Iterators.HTMLCollection = Iterators.Array;
6464
6465/***/ }),
6466/* 52 */
6467/***/ (function(module, exports, __webpack_require__) {
6468
6469	'use strict';
6470	var addToUnscopables = __webpack_require__(53)
6471	  , step             = __webpack_require__(54)
6472	  , Iterators        = __webpack_require__(49)
6473	  , toIObject        = __webpack_require__(32);
6474
6475	// 22.1.3.4 Array.prototype.entries()
6476	// 22.1.3.13 Array.prototype.keys()
6477	// 22.1.3.29 Array.prototype.values()
6478	// 22.1.3.30 Array.prototype[@@iterator]()
6479	module.exports = __webpack_require__(48)(Array, 'Array', function(iterated, kind){
6480	  this._t = toIObject(iterated); // target
6481	  this._i = 0;                   // next index
6482	  this._k = kind;                // kind
6483	// 22.1.5.2.1 %ArrayIteratorPrototype%.next()
6484	}, function(){
6485	  var O     = this._t
6486	    , kind  = this._k
6487	    , index = this._i++;
6488	  if(!O || index >= O.length){
6489	    this._t = undefined;
6490	    return step(1);
6491	  }
6492	  if(kind == 'keys'  )return step(0, index);
6493	  if(kind == 'values')return step(0, O[index]);
6494	  return step(0, [index, O[index]]);
6495	}, 'values');
6496
6497	// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)
6498	Iterators.Arguments = Iterators.Array;
6499
6500	addToUnscopables('keys');
6501	addToUnscopables('values');
6502	addToUnscopables('entries');
6503
6504/***/ }),
6505/* 53 */
6506/***/ (function(module, exports) {
6507
6508	module.exports = function(){ /* empty */ };
6509
6510/***/ }),
6511/* 54 */
6512/***/ (function(module, exports) {
6513
6514	module.exports = function(done, value){
6515	  return {value: value, done: !!done};
6516	};
6517
6518/***/ }),
6519/* 55 */
6520/***/ (function(module, exports, __webpack_require__) {
6521
6522	module.exports = { "default": __webpack_require__(56), __esModule: true };
6523
6524/***/ }),
6525/* 56 */
6526/***/ (function(module, exports, __webpack_require__) {
6527
6528	__webpack_require__(51);
6529	__webpack_require__(45);
6530	module.exports = __webpack_require__(57);
6531
6532/***/ }),
6533/* 57 */
6534/***/ (function(module, exports, __webpack_require__) {
6535
6536	var anObject = __webpack_require__(39)
6537	  , get      = __webpack_require__(58);
6538	module.exports = __webpack_require__(21).getIterator = function(it){
6539	  var iterFn = get(it);
6540	  if(typeof iterFn != 'function')throw TypeError(it + ' is not iterable!');
6541	  return anObject(iterFn.call(it));
6542	};
6543
6544/***/ }),
6545/* 58 */
6546/***/ (function(module, exports, __webpack_require__) {
6547
6548	var classof   = __webpack_require__(59)
6549	  , ITERATOR  = __webpack_require__(29)('iterator')
6550	  , Iterators = __webpack_require__(49);
6551	module.exports = __webpack_require__(21).getIteratorMethod = function(it){
6552	  if(it != undefined)return it[ITERATOR]
6553	    || it['@@iterator']
6554	    || Iterators[classof(it)];
6555	};
6556
6557/***/ }),
6558/* 59 */
6559/***/ (function(module, exports, __webpack_require__) {
6560
6561	// getting tag from 19.1.3.6 Object.prototype.toString()
6562	var cof = __webpack_require__(34)
6563	  , TAG = __webpack_require__(29)('toStringTag')
6564	  // ES3 wrong here
6565	  , ARG = cof(function(){ return arguments; }()) == 'Arguments';
6566
6567	module.exports = function(it){
6568	  var O, T, B;
6569	  return it === undefined ? 'Undefined' : it === null ? 'Null'
6570	    // @@toStringTag case
6571	    : typeof (T = (O = Object(it))[TAG]) == 'string' ? T
6572	    // builtinTag case
6573	    : ARG ? cof(O)
6574	    // ES3 arguments fallback
6575	    : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;
6576	};
6577
6578/***/ }),
6579/* 60 */
6580/***/ (function(module, exports, __webpack_require__) {
6581
6582	module.exports = { "default": __webpack_require__(61), __esModule: true };
6583
6584/***/ }),
6585/* 61 */
6586/***/ (function(module, exports, __webpack_require__) {
6587
6588	__webpack_require__(62);
6589	module.exports = __webpack_require__(21).Object.keys;
6590
6591/***/ }),
6592/* 62 */
6593/***/ (function(module, exports, __webpack_require__) {
6594
6595	// 19.1.2.14 Object.keys(O)
6596	var toObject = __webpack_require__(63);
6597
6598	__webpack_require__(64)('keys', function($keys){
6599	  return function keys(it){
6600	    return $keys(toObject(it));
6601	  };
6602	});
6603
6604/***/ }),
6605/* 63 */
6606/***/ (function(module, exports, __webpack_require__) {
6607
6608	// 7.1.13 ToObject(argument)
6609	var defined = __webpack_require__(35);
6610	module.exports = function(it){
6611	  return Object(defined(it));
6612	};
6613
6614/***/ }),
6615/* 64 */
6616/***/ (function(module, exports, __webpack_require__) {
6617
6618	// most Object methods by ES6 should accept primitives
6619	var $export = __webpack_require__(20)
6620	  , core    = __webpack_require__(21)
6621	  , fails   = __webpack_require__(19);
6622	module.exports = function(KEY, exec){
6623	  var fn  = (core.Object || {})[KEY] || Object[KEY]
6624	    , exp = {};
6625	  exp[KEY] = exec(fn);
6626	  $export($export.S + $export.F * fails(function(){ fn(1); }), 'Object', exp);
6627	};
6628
6629/***/ }),
6630/* 65 */
6631/***/ (function(module, exports, __webpack_require__) {
6632
6633	'use strict';
6634
6635	var _interopRequireDefault = __webpack_require__(1)['default'];
6636
6637	exports.__esModule = true;
6638
6639	var _exception = __webpack_require__(6);
6640
6641	var _exception2 = _interopRequireDefault(_exception);
6642
6643	exports['default'] = function (instance) {
6644	  instance.registerHelper('helperMissing', function () /* [args, ]options */{
6645	    if (arguments.length === 1) {
6646	      // A missing field in a {{foo}} construct.
6647	      return undefined;
6648	    } else {
6649	      // Someone is actually trying to call something, blow up.
6650	      throw new _exception2['default']('Missing helper: "' + arguments[arguments.length - 1].name + '"');
6651	    }
6652	  });
6653	};
6654
6655	module.exports = exports['default'];
6656
6657/***/ }),
6658/* 66 */
6659/***/ (function(module, exports, __webpack_require__) {
6660
6661	'use strict';
6662
6663	var _interopRequireDefault = __webpack_require__(1)['default'];
6664
6665	exports.__esModule = true;
6666
6667	var _utils = __webpack_require__(5);
6668
6669	var _exception = __webpack_require__(6);
6670
6671	var _exception2 = _interopRequireDefault(_exception);
6672
6673	exports['default'] = function (instance) {
6674	  instance.registerHelper('if', function (conditional, options) {
6675	    if (arguments.length != 2) {
6676	      throw new _exception2['default']('#if requires exactly one argument');
6677	    }
6678	    if (_utils.isFunction(conditional)) {
6679	      conditional = conditional.call(this);
6680	    }
6681
6682	    // Default behavior is to render the positive path if the value is truthy and not empty.
6683	    // The `includeZero` option may be set to treat the condtional as purely not empty based on the
6684	    // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
6685	    if (!options.hash.includeZero && !conditional || _utils.isEmpty(conditional)) {
6686	      return options.inverse(this);
6687	    } else {
6688	      return options.fn(this);
6689	    }
6690	  });
6691
6692	  instance.registerHelper('unless', function (conditional, options) {
6693	    if (arguments.length != 2) {
6694	      throw new _exception2['default']('#unless requires exactly one argument');
6695	    }
6696	    return instance.helpers['if'].call(this, conditional, {
6697	      fn: options.inverse,
6698	      inverse: options.fn,
6699	      hash: options.hash
6700	    });
6701	  });
6702	};
6703
6704	module.exports = exports['default'];
6705
6706/***/ }),
6707/* 67 */
6708/***/ (function(module, exports) {
6709
6710	'use strict';
6711
6712	exports.__esModule = true;
6713
6714	exports['default'] = function (instance) {
6715	  instance.registerHelper('log', function () /* message, options */{
6716	    var args = [undefined],
6717	        options = arguments[arguments.length - 1];
6718	    for (var i = 0; i < arguments.length - 1; i++) {
6719	      args.push(arguments[i]);
6720	    }
6721
6722	    var level = 1;
6723	    if (options.hash.level != null) {
6724	      level = options.hash.level;
6725	    } else if (options.data && options.data.level != null) {
6726	      level = options.data.level;
6727	    }
6728	    args[0] = level;
6729
6730	    instance.log.apply(instance, args);
6731	  });
6732	};
6733
6734	module.exports = exports['default'];
6735
6736/***/ }),
6737/* 68 */
6738/***/ (function(module, exports) {
6739
6740	'use strict';
6741
6742	exports.__esModule = true;
6743
6744	exports['default'] = function (instance) {
6745	  instance.registerHelper('lookup', function (obj, field, options) {
6746	    if (!obj) {
6747	      // Note for 5.0: Change to "obj == null" in 5.0
6748	      return obj;
6749	    }
6750	    return options.lookupProperty(obj, field);
6751	  });
6752	};
6753
6754	module.exports = exports['default'];
6755
6756/***/ }),
6757/* 69 */
6758/***/ (function(module, exports, __webpack_require__) {
6759
6760	'use strict';
6761
6762	var _interopRequireDefault = __webpack_require__(1)['default'];
6763
6764	exports.__esModule = true;
6765
6766	var _utils = __webpack_require__(5);
6767
6768	var _exception = __webpack_require__(6);
6769
6770	var _exception2 = _interopRequireDefault(_exception);
6771
6772	exports['default'] = function (instance) {
6773	  instance.registerHelper('with', function (context, options) {
6774	    if (arguments.length != 2) {
6775	      throw new _exception2['default']('#with requires exactly one argument');
6776	    }
6777	    if (_utils.isFunction(context)) {
6778	      context = context.call(this);
6779	    }
6780
6781	    var fn = options.fn;
6782
6783	    if (!_utils.isEmpty(context)) {
6784	      var data = options.data;
6785	      if (options.data && options.ids) {
6786	        data = _utils.createFrame(options.data);
6787	        data.contextPath = _utils.appendContextPath(options.data.contextPath, options.ids[0]);
6788	      }
6789
6790	      return fn(context, {
6791	        data: data,
6792	        blockParams: _utils.blockParams([context], [data && data.contextPath])
6793	      });
6794	    } else {
6795	      return options.inverse(this);
6796	    }
6797	  });
6798	};
6799
6800	module.exports = exports['default'];
6801
6802/***/ }),
6803/* 70 */
6804/***/ (function(module, exports, __webpack_require__) {
6805
6806	'use strict';
6807
6808	var _interopRequireDefault = __webpack_require__(1)['default'];
6809
6810	exports.__esModule = true;
6811	exports.registerDefaultDecorators = registerDefaultDecorators;
6812
6813	var _decoratorsInline = __webpack_require__(71);
6814
6815	var _decoratorsInline2 = _interopRequireDefault(_decoratorsInline);
6816
6817	function registerDefaultDecorators(instance) {
6818	  _decoratorsInline2['default'](instance);
6819	}
6820
6821/***/ }),
6822/* 71 */
6823/***/ (function(module, exports, __webpack_require__) {
6824
6825	'use strict';
6826
6827	exports.__esModule = true;
6828
6829	var _utils = __webpack_require__(5);
6830
6831	exports['default'] = function (instance) {
6832	  instance.registerDecorator('inline', function (fn, props, container, options) {
6833	    var ret = fn;
6834	    if (!props.partials) {
6835	      props.partials = {};
6836	      ret = function (context, options) {
6837	        // Create a new partials stack frame prior to exec.
6838	        var original = container.partials;
6839	        container.partials = _utils.extend({}, original, props.partials);
6840	        var ret = fn(context, options);
6841	        container.partials = original;
6842	        return ret;
6843	      };
6844	    }
6845
6846	    props.partials[options.args[0]] = options.fn;
6847
6848	    return ret;
6849	  });
6850	};
6851
6852	module.exports = exports['default'];
6853
6854/***/ }),
6855/* 72 */
6856/***/ (function(module, exports, __webpack_require__) {
6857
6858	'use strict';
6859
6860	exports.__esModule = true;
6861
6862	var _utils = __webpack_require__(5);
6863
6864	var logger = {
6865	  methodMap: ['debug', 'info', 'warn', 'error'],
6866	  level: 'info',
6867
6868	  // Maps a given level value to the `methodMap` indexes above.
6869	  lookupLevel: function lookupLevel(level) {
6870	    if (typeof level === 'string') {
6871	      var levelMap = _utils.indexOf(logger.methodMap, level.toLowerCase());
6872	      if (levelMap >= 0) {
6873	        level = levelMap;
6874	      } else {
6875	        level = parseInt(level, 10);
6876	      }
6877	    }
6878
6879	    return level;
6880	  },
6881
6882	  // Can be overridden in the host environment
6883	  log: function log(level) {
6884	    level = logger.lookupLevel(level);
6885
6886	    if (typeof console !== 'undefined' && logger.lookupLevel(logger.level) <= level) {
6887	      var method = logger.methodMap[level];
6888	      // eslint-disable-next-line no-console
6889	      if (!console[method]) {
6890	        method = 'log';
6891	      }
6892
6893	      for (var _len = arguments.length, message = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
6894	        message[_key - 1] = arguments[_key];
6895	      }
6896
6897	      console[method].apply(console, message); // eslint-disable-line no-console
6898	    }
6899	  }
6900	};
6901
6902	exports['default'] = logger;
6903	module.exports = exports['default'];
6904
6905/***/ }),
6906/* 73 */
6907/***/ (function(module, exports, __webpack_require__) {
6908
6909	'use strict';
6910
6911	var _Object$create = __webpack_require__(74)['default'];
6912
6913	var _Object$keys = __webpack_require__(60)['default'];
6914
6915	var _interopRequireDefault = __webpack_require__(1)['default'];
6916
6917	exports.__esModule = true;
6918	exports.createProtoAccessControl = createProtoAccessControl;
6919	exports.resultIsAllowed = resultIsAllowed;
6920	exports.resetLoggedProperties = resetLoggedProperties;
6921
6922	var _
6922createNewLookupObject = __webpack_require__(76);
6923
6924	var _logger = __webpack_require__(72);
6925
6926	var _logger2 = _interopRequireDefault(_logger);
6927
6928	var loggedProperties = _Object$create(null);
6929
6930	function createProtoAccessControl(runtimeOptions) {
6931	  var defaultMethodWhiteList = _Object$create(null);
6932	  defaultMethodWhiteList['constructor'] = false;
vendor: 11,824 bytes, lines 6933-7281
6933	  defaultMethodWhiteList['__defineGetter__'] = false;
6934	  defaultMethodWhiteList['__defineSetter__'] = false;
6935	  defaultMethodWhiteList['__lookupGetter__'] = false;
6936
6937	  var defaultPropertyWhiteList = _Object$create(null);
6938	  // eslint-disable-next-line no-proto
6939	  defaultPropertyWhiteList['__proto__'] = false;
6940
6941	  return {
6942	    properties: {
6943	      whitelist: _createNewLookupObject.createNewLookupObject(defaultPropertyWhiteList, runtimeOptions.allowedProtoProperties),
6944	      defaultValue: runtimeOptions.allowProtoPropertiesByDefault
6945	    },
6946	    methods: {
6947	      whitelist: _createNewLookupObject.createNewLookupObject(defaultMethodWhiteList, runtimeOptions.allowedProtoMethods),
6948	      defaultValue: runtimeOptions.allowProtoMethodsByDefault
6949	    }
6950	  };
6951	}
6952
6953	function resultIsAllowed(result, protoAccessControl, propertyName) {
6954	  if (typeof result === 'function') {
6955	    return checkWhiteList(protoAccessControl.methods, propertyName);
6956	  } else {
6957	    return checkWhiteList(protoAccessControl.properties, propertyName);
6958	  }
6959	}
6960
6961	function checkWhiteList(protoAccessControlForType, propertyName) {
6962	  if (protoAccessControlForType.whitelist[propertyName] !== undefined) {
6963	    return protoAccessControlForType.whitelist[propertyName] === true;
6964	  }
6965	  if (protoAccessControlForType.defaultValue !== undefined) {
6966	    return protoAccessControlForType.defaultValue;
6967	  }
6968	  logUnexpecedPropertyAccessOnce(propertyName);
6969	  return false;
6970	}
6971
6972	function logUnexpecedPropertyAccessOnce(propertyName) {
6973	  if (loggedProperties[propertyName] !== true) {
6974	    loggedProperties[propertyName] = true;
6975	    _logger2['default'].log('error', 'Handlebars: Access has been denied to resolve the property "' + propertyName + '" because it is not an "own property" of its parent.\n' + 'You can add a runtime option to disable the check or this warning:\n' + 'See https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details');
6976	  }
6977	}
6978
6979	function resetLoggedProperties() {
6980	  _Object$keys(loggedProperties).forEach(function (propertyName) {
6981	    delete loggedProperties[propertyName];
6982	  });
6983	}
6984
6985/***/ }),
6986/* 74 */
6987/***/ (function(module, exports, __webpack_require__) {
6988
6989	module.exports = { "default": __webpack_require__(75), __esModule: true };
6990
6991/***/ }),
6992/* 75 */
6993/***/ (function(module, exports, __webpack_require__) {
6994
6995	var $ = __webpack_require__(9);
6996	module.exports = function create(P, D){
6997	  return $.create(P, D);
6998	};
6999
7000/***/ }),
7001/* 76 */
7002/***/ (function(module, exports, __webpack_require__) {
7003
7004	'use strict';
7005
7006	var _Object$create = __webpack_require__(74)['default'];
7007
7008	exports.__esModule = true;
7009	exports.createNewLookupObject = createNewLookupObject;
7010
7011	var _utils = __webpack_require__(5);
7012
7013	/**
7014	 * Create a new object with "null"-prototype to avoid truthy results on prototype properties.
7015	 * The resulting object can be used with "object[property]" to check if a property exists
7016	 * @param {...object} sources a varargs parameter of source objects that will be merged
7017	 * @returns {object}
7018	 */
7019
7020	function createNewLookupObject() {
7021	  for (var _len = arguments.length, sources = Array(_len), _key = 0; _key < _len; _key++) {
7022	    sources[_key] = arguments[_key];
7023	  }
7024
7025	  return _utils.extend.apply(undefined, [_Object$create(null)].concat(sources));
7026	}
7027
7028/***/ }),
7029/* 77 */
7030/***/ (function(module, exports) {
7031
7032	// Build out our basic SafeString type
7033	'use strict';
7034
7035	exports.__esModule = true;
7036	function SafeString(string) {
7037	  this.string = string;
7038	}
7039
7040	SafeString.prototype.toString = SafeString.prototype.toHTML = function () {
7041	  return '' + this.string;
7042	};
7043
7044	exports['default'] = SafeString;
7045	module.exports = exports['default'];
7046
7047/***/ }),
7048/* 78 */
7049/***/ (function(module, exports, __webpack_require__) {
7050
7051	'use strict';
7052
7053	var _Object$seal = __webpack_require__(79)['default'];
7054
7055	var _Object$keys = __webpack_require__(60)['default'];
7056
7057	var _interopRequireWildcard = __webpack_require__(3)['default'];
7058
7059	var _interopRequireDefault = __webpack_require__(1)['default'];
7060
7061	exports.__esModule = true;
7062	exports.checkRevision = checkRevision;
7063	exports.template = template;
7064	exports.wrapProgram = wrapProgram;
7065	exports.resolvePartial = resolvePartial;
7066	exports.invokePartial = invokePartial;
7067	exports.noop = noop;
7068
7069	var _utils = __webpack_require__(5);
7070
7071	var Utils = _interopRequireWildcard(_utils);
7072
7073	var _exception = __webpack_require__(6);
7074
7075	var _exception2 = _interopRequireDefault(_exception);
7076
7077	var _base = __webpack_require__(4);
7078
7079	var _helpers = __webpack_require__(10);
7080
7081	var _internalWrapHelper = __webpack_require__(82);
7082
7083	var _internalProtoAccess = __webpack_require__(73);
7084
7085	function checkRevision(compilerInfo) {
7086	  var compilerRevision = compilerInfo && compilerInfo[0] || 1,
7087	      currentRevision = _base.COMPILER_REVISION;
7088
7089	  if (compilerRevision >= _base.LAST_COMPATIBLE_COMPILER_REVISION && compilerRevision <= _base.COMPILER_REVISION) {
7090	    return;
7091	  }
7092
7093	  if (compilerRevision < _base.LAST_COMPATIBLE_COMPILER_REVISION) {
7094	    var runtimeVersions = _base.REVISION_CHANGES[currentRevision],
7095	        compilerVersions = _base.REVISION_CHANGES[compilerRevision];
7096	    throw new _exception2['default']('Template was precompiled with an older version of Handlebars than the current runtime. ' + 'Please update your precompiler to a newer version (' + runtimeVersions + ') or downgrade your runtime to an older version (' + compilerVersions + ').');
7097	  } else {
7098	    // Use the embedded version info since the runtime doesn't know about this revision yet
7099	    throw new _exception2['default']('Template was precompiled with a newer version of Handlebars than the current runtime. ' + 'Please update your runtime to a newer version (' + compilerInfo[1] + ').');
7100	  }
7101	}
7102
7103	function template(templateSpec, env) {
7104	  /* istanbul ignore next */
7105	  if (!env) {
7106	    throw new _exception2['default']('No environment passed to template');
7107	  }
7108	  if (!templateSpec || !templateSpec.main) {
7109	    throw new _exception2['default']('Unknown template object: ' + typeof templateSpec);
7110	  }
7111
7112	  templateSpec.main.decorator = templateSpec.main_d;
7113
7114	  // Note: Using env.VM references rather than local var references throughout this section to allow
7115	  // for external users to override these as pseudo-supported APIs.
7116	  env.VM.checkRevision(templateSpec.compiler);
7117
7118	  // backwards compatibility for precompiled templates with compiler-version 7 (<4.3.0)
7119	  var templateWasPrecompiledWithCompilerV7 = templateSpec.compiler && templateSpec.compiler[0] === 7;
7120
7121	  function invokePartialWrapper(partial, context, options) {
7122	    if (options.hash) {
7123	      context = Utils.extend({}, context, options.hash);
7124	      if (options.ids) {
7125	        options.ids[0] = true;
7126	      }
7127	    }
7128	    partial = env.VM.resolvePartial.call(this, partial, context, options);
7129
7130	    var extendedOptions = Utils.extend({}, options, {
7131	      hooks: this.hooks,
7132	      protoAccessControl: this.protoAccessControl
7133	    });
7134
7135	    var result = env.VM.invokePartial.call(this, partial, context, extendedOptions);
7136
7137	    if (result == null && env.compile) {
7138	      options.partials[options.name] = env.compile(partial, templateSpec.compilerOptions, env);
7139	      result = options.partials[options.name](context, extendedOptions);
7140	    }
7141	    if (result != null) {
7142	      if (options.indent) {
7143	        var lines = result.split('\n');
7144	        for (var i = 0, l = lines.length; i < l; i++) {
7145	          if (!lines[i] && i + 1 === l) {
7146	            break;
7147	          }
7148
7149	          lines[i] = options.indent + lines[i];
7150	        }
7151	        result = lines.join('\n');
7152	      }
7153	      return result;
7154	    } else {
7155	      throw new _exception2['default']('The partial ' + options.name + ' could not be compiled when running in runtime-only mode');
7156	    }
7157	  }
7158
7159	  // Just add water
7160	  var container = {
7161	    strict: function strict(obj, name, loc) {
7162	      if (!obj || !(name in obj)) {
7163	        throw new _exception2['default']('"' + name + '" not defined in ' + obj, {
7164	          loc: loc
7165	        });
7166	      }
7167	      return container.lookupProperty(obj, name);
7168	    },
7169	    lookupProperty: function lookupProperty(parent, propertyName) {
7170	      var result = parent[propertyName];
7171	      if (result == null) {
7172	        return result;
7173	      }
7174	      if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
7175	        return result;
7176	      }
7177
7178	      if (_internalProtoAccess.resultIsAllowed(result, container.protoAccessControl, propertyName)) {
7179	        return result;
7180	      }
7181	      return undefined;
7182	    },
7183	    lookup: function lookup(depths, name) {
7184	      var len = depths.length;
7185	      for (var i = 0; i < len; i++) {
7186	        var result = depths[i] && container.lookupProperty(depths[i], name);
7187	        if (result != null) {
7188	          return depths[i][name];
7189	        }
7190	      }
7191	    },
7192	    lambda: function lambda(current, context) {
7193	      return typeof current === 'function' ? current.call(context) : current;
7194	    },
7195
7196	    escapeExpression: Utils.escapeExpression,
7197	    invokePartial: invokePartialWrapper,
7198
7199	    fn: function fn(i) {
7200	      var ret = templateSpec[i];
7201	      ret.decorator = templateSpec[i + '_d'];
7202	      return ret;
7203	    },
7204
7205	    programs: [],
7206	    program: function program(i, data, declaredBlockParams, blockParams, depths) {
7207	      var programWrapper = this.programs[i],
7208	          fn = this.fn(i);
7209	      if (data || depths || blockParams || declaredBlockParams) {
7210	        programWrapper = wrapProgram(this, i, fn, data, declaredBlockParams, blockParams, depths);
7211	      } else if (!programWrapper) {
7212	        programWrapper = this.programs[i] = wrapProgram(this, i, fn);
7213	      }
7214	      return programWrapper;
7215	    },
7216
7217	    data: function data(value, depth) {
7218	      while (value && depth--) {
7219	        value = value._parent;
7220	      }
7221	      return value;
7222	    },
7223	    mergeIfNeeded: function mergeIfNeeded(param, common) {
7224	      var obj = param || common;
7225
7226	      if (param && common && param !== common) {
7227	        obj = Utils.extend({}, common, param);
7228	      }
7229
7230	      return obj;
7231	    },
7232	    // An empty object to use as replacement for null-contexts
7233	    nullContext: _Object$seal({}),
7234
7235	    noop: env.VM.noop,
7236	    compilerInfo: templateSpec.compiler
7237	  };
7238
7239	  function ret(context) {
7240	    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
7241
7242	    var data = options.data;
7243
7244	    ret._setup(options);
7245	    if (!options.partial && templateSpec.useData) {
7246	      data = initData(context, data);
7247	    }
7248	    var depths = undefined,
7249	        blockParams = templateSpec.useBlockParams ? [] : undefined;
7250	    if (templateSpec.useDepths) {
7251	      if (options.depths) {
7252	        depths = context != options.depths[0] ? [context].concat(options.depths) : options.depths;
7253	      } else {
7254	        depths = [context];
7255	      }
7256	    }
7257
7258	    function main(context /*, options*/) {
7259	      return '' + templateSpec.main(container, context, container.helpers, container.partials, data, blockParams, depths);
7260	    }
7261
7262	    main = executeDecorators(templateSpec.main, main, container, options.depths || [], data, blockParams);
7263	    return main(context, options);
7264	  }
7265
7266	  ret.isTop = true;
7267
7268	  ret._setup = function (options) {
7269	    if (!options.partial) {
7270	      var mergedHelpers = Utils.extend({}, env.helpers, options.helpers);
7271	      wrapHelpersToPassLookupProperty(mergedHelpers, container);
7272	      container.helpers = mergedHelpers;
7273
7274	      if (templateSpec.usePartial) {
7275	        // Use mergeIfNeeded here to prevent compiling global partials multiple times
7276	        container.partials = container.mergeIfNeeded(options.partials, env.partials);
7277	      }
7278	      if (templateSpec.usePartial || templateSpec.useDecorators) {
7279	        container.decorators = Utils.extend({}, env.decorators, options.decorators);
7280	      }
7281
vendor: 4,565 bytes, lines 7282-7410
7282	      container.hooks = {};
7283	      container.protoAccessControl = _internalProtoAccess.createProtoAccessControl(options);
7284
7285	      var keepHelperInHelpers = options.allowCallsToHelperMissing || templateWasPrecompiledWithCompilerV7;
7286	      _helpers.moveHelperToHooks(container, 'helperMissing', keepHelperInHelpers);
7287	      _helpers.moveHelperToHooks(container, 'blockHelperMissing', keepHelperInHelpers);
7288	    } else {
7289	      container.protoAccessControl = options.protoAccessControl; // internal option
7290	      container.helpers = options.helpers;
7291	      container.partials = options.partials;
7292	      container.decorators = options.decorators;
7293	      container.hooks = options.hooks;
7294	    }
7295	  };
7296
7297	  ret._child = function (i, data, blockParams, depths) {
7298	    if (templateSpec.useBlockParams && !blockParams) {
7299	      throw new _exception2['default']('must pass block params');
7300	    }
7301	    if (templateSpec.useDepths && !depths) {
7302	      throw new _exception2['default']('must pass parent depths');
7303	    }
7304
7305	    return wrapProgram(container, i, templateSpec[i], data, 0, blockParams, depths);
7306	  };
7307	  return ret;
7308	}
7309
7310	function wrapProgram(container, i, fn, data, declaredBlockParams, blockParams, depths) {
7311	  function prog(context) {
7312	    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
7313
7314	    var currentDepths = depths;
7315	    if (depths && context != depths[0] && !(context === container.nullContext && depths[0] === null)) {
7316	      currentDepths = [context].concat(depths);
7317	    }
7318
7319	    return fn(container, context, container.helpers, container.partials, options.data || data, blockParams && [options.blockParams].concat(blockParams), currentDepths);
7320	  }
7321
7322	  prog = executeDecorators(fn, prog, container, depths, data, blockParams);
7323
7324	  prog.program = i;
7325	  prog.depth = depths ? depths.length : 0;
7326	  prog.blockParams = declaredBlockParams || 0;
7327	  return prog;
7328	}
7329
7330	/**
7331	 * This is currently part of the official API, therefore implementation details should not be changed.
7332	 */
7333
7334	function resolvePartial(partial, context, options) {
7335	  if (!partial) {
7336	    if (options.name === '@partial-block') {
7337	      partial = options.data['partial-block'];
7338	    } else {
7339	      partial = options.partials[options.name];
7340	    }
7341	  } else if (!partial.call && !options.name) {
7342	    // This is a dynamic partial that returned a string
7343	    options.name = partial;
7344	    partial = options.partials[partial];
7345	  }
7346	  return partial;
7347	}
7348
7349	function invokePartial(partial, context, options) {
7350	  // Use the current closure context to save the partial-block if this partial
7351	  var currentPartialBlock = options.data && options.data['partial-block'];
7352	  options.partial = true;
7353	  if (options.ids) {
7354	    options.data.contextPath = options.ids[0] || options.data.contextPath;
7355	  }
7356
7357	  var partialBlock = undefined;
7358	  if (options.fn && options.fn !== noop) {
7359	    (function () {
7360	      options.data = _base.createFrame(options.data);
7361	      // Wrapper function to get access to currentPartialBlock from the closure
7362	      var fn = options.fn;
7363	      partialBlock = options.data['partial-block'] = function partialBlockWrapper(context) {
7364	        var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
7365
7366	        // Restore the partial-block from the closure for the execution of the block
7367	        // i.e. the part inside the block of the partial call.
7368	        options.data = _base.createFrame(options.data);
7369	        options.data['partial-block'] = currentPartialBlock;
7370	        return fn(context, options);
7371	      };
7372	      if (fn.partials) {
7373	        options.partials = Utils.extend({}, options.partials, fn.partials);
7374	      }
7375	    })();
7376	  }
7377
7378	  if (partial === undefined && partialBlock) {
7379	    partial = partialBlock;
7380	  }
7381
7382	  if (partial === undefined) {
7383	    throw new _exception2['default']('The partial ' + options.name + ' could not be found');
7384	  } else if (partial instanceof Function) {
7385	    return partial(context, options);
7386	  }
7387	}
7388
7389	function noop() {
7390	  return '';
7391	}
7392
7393	function initData(context, data) {
7394	  if (!data || !('root' in data)) {
7395	    data = data ? _base.createFrame(data) : {};
7396	    data.root = context;
7397	  }
7398	  return data;
7399	}
7400
7401	function executeDecorators(fn, prog, container, depths, data, blockParams) {
7402	  if (fn.decorator) {
7403	    var props = {};
7404	    prog = fn.decorator(prog, props, container, depths && depths[0], data, blockParams, depths);
7405	    Utils.extend(prog, props);
7406	  }
7407	  return prog;
7408	}
7409
7410	function wrapHelpersToPassLookupProperty(mergedHelpers, container) {
vendor: 9,825 bytes, lines 7411-7646
7411	  _Object$keys(mergedHelpers).forEach(function (helperName) {
7412	    var helper = mergedHelpers[helperName];
7413	    mergedHelpers[helperName] = passLookupPropertyOption(helper, container);
7414	  });
7415	}
7416
7417	function passLookupPropertyOption(helper, container) {
7418	  var lookupProperty = container.lookupProperty;
7419	  return _internalWrapHelper.wrapHelper(helper, function (options) {
7420	    return Utils.extend({ lookupProperty: lookupProperty }, options);
7421	  });
7422	}
7423
7424/***/ }),
7425/* 79 */
7426/***/ (function(module, exports, __webpack_require__) {
7427
7428	module.exports = { "default": __webpack_require__(80), __esModule: true };
7429
7430/***/ }),
7431/* 80 */
7432/***/ (function(module, exports, __webpack_require__) {
7433
7434	__webpack_require__(81);
7435	module.exports = __webpack_require__(21).Object.seal;
7436
7437/***/ }),
7438/* 81 */
7439/***/ (function(module, exports, __webpack_require__) {
7440
7441	// 19.1.2.17 Object.seal(O)
7442	var isObject = __webpack_require__(40);
7443
7444	__webpack_require__(64)('seal', function($seal){
7445	  return function seal(it){
7446	    return $seal && isObject(it) ? $seal(it) : it;
7447	  };
7448	});
7449
7450/***/ }),
7451/* 82 */
7452/***/ (function(module, exports) {
7453
7454	'use strict';
7455
7456	exports.__esModule = true;
7457	exports.wrapHelper = wrapHelper;
7458
7459	function wrapHelper(helper, transformOptionsFn) {
7460	  if (typeof helper !== 'function') {
7461	    // This should not happen, but apparently it does in https://github.com/wycats/handlebars.js/issues/1639
7462	    // We try to make the wrapper least-invasive by not wrapping it, if the helper is not a function.
7463	    return helper;
7464	  }
7465	  var wrapper = function wrapper() /* dynamic arguments */{
7466	    var options = arguments[arguments.length - 1];
7467	    arguments[arguments.length - 1] = transformOptionsFn(options);
7468	    return helper.apply(this, arguments);
7469	  };
7470	  return wrapper;
7471	}
7472
7473/***/ }),
7474/* 83 */
7475/***/ (function(module, exports) {
7476
7477	/* global globalThis */
7478	'use strict';
7479
7480	exports.__esModule = true;
7481
7482	exports['default'] = function (Handlebars) {
7483	  /* istanbul ignore next */
7484	  // https://mathiasbynens.be/notes/globalthis
7485	  (function () {
7486	    if (typeof globalThis === 'object') return;
7487	    Object.prototype.__defineGetter__('__magic__', function () {
7488	      return this;
7489	    });
7490	    __magic__.globalThis = __magic__; // eslint-disable-line no-undef
7491	    delete Object.prototype.__magic__;
7492	  })();
7493
7494	  var $Handlebars = globalThis.Handlebars;
7495
7496	  /* istanbul ignore next */
7497	  Handlebars.noConflict = function () {
7498	    if (globalThis.Handlebars === Handlebars) {
7499	      globalThis.Handlebars = $Handlebars;
7500	    }
7501	    return Handlebars;
7502	  };
7503	};
7504
7505	module.exports = exports['default'];
7506
7507/***/ }),
7508/* 84 */
7509/***/ (function(module, exports) {
7510
7511	'use strict';
7512
7513	exports.__esModule = true;
7514	var AST = {
7515	  // Public API used to evaluate derived attributes regarding AST nodes
7516	  helpers: {
7517	    // a mustache is definitely a helper if:
7518	    // * it is an eligible helper, and
7519	    // * it has at least one parameter or hash segment
7520	    helperExpression: function helperExpression(node) {
7521	      return node.type === 'SubExpression' || (node.type === 'MustacheStatement' || node.type === 'BlockStatement') && !!(node.params && node.params.length || node.hash);
7522	    },
7523
7524	    scopedId: function scopedId(path) {
7525	      return (/^\.|this\b/.test(path.original)
7526	      );
7527	    },
7528
7529	    // an ID is simple if it only has one part, and that part is not
7530	    // `..` or `this`.
7531	    simpleId: function simpleId(path) {
7532	      return path.parts.length === 1 && !AST.helpers.scopedId(path) && !path.depth;
7533	    }
7534	  }
7535	};
7536
7537	// Must be exported as an object rather than the root of the module as the jison lexer
7538	// must modify the object to operate properly.
7539	exports['default'] = AST;
7540	module.exports = exports['default'];
7541
7542/***/ }),
7543/* 85 */
7544/***/ (function(module, exports, __webpack_require__) {
7545
7546	'use strict';
7547
7548	var _interopRequireDefault = __webpack_require__(1)['default'];
7549
7550	var _interopRequireWildcard = __webpack_require__(3)['default'];
7551
7552	exports.__esModule = true;
7553	exports.parseWithoutProcessing = parseWithoutProcessing;
7554	exports.parse = parse;
7555
7556	var _parser = __webpack_require__(86);
7557
7558	var _parser2 = _interopRequireDefault(_parser);
7559
7560	var _whitespaceControl = __webpack_require__(87);
7561
7562	var _whitespaceControl2 = _interopRequireDefault(_whitespaceControl);
7563
7564	var _helpers = __webpack_require__(89);
7565
7566	var Helpers = _interopRequireWildcard(_helpers);
7567
7568	var _utils = __webpack_require__(5);
7569
7570	exports.parser = _parser2['default'];
7571
7572	var yy = {};
7573	_utils.extend(yy, Helpers);
7574
7575	function parseWithoutProcessing(input, options) {
7576	  // Just return if an already-compiled AST was passed in.
7577	  if (input.type === 'Program') {
7578	    return input;
7579	  }
7580
7581	  _parser2['default'].yy = yy;
7582
7583	  // Altering the shared object here, but this is ok as parser is a sync operation
7584	  yy.locInfo = function (locInfo) {
7585	    return new yy.SourceLocation(options && options.srcName, locInfo);
7586	  };
7587
7588	  var ast = _parser2['default'].parse(input);
7589
7590	  return ast;
7591	}
7592
7593	function parse(input, options) {
7594	  var ast = parseWithoutProcessing(input, options);
7595	  var strip = new _whitespaceControl2['default'](options);
7596
7597	  return strip.accept(ast);
7598	}
7599
7600/***/ }),
7601/* 86 */
7602/***/ (function(module, exports) {
7603
7604	// File ignored in coverage tests via setting in .istanbul.yml
7605	/* Jison generated parser */
7606	"use strict";
7607
7608	exports.__esModule = true;
7609	var handlebars = (function () {
7610	    var parser = { trace: function trace() {},
7611	        yy: {},
7612	        symbols_: { "error": 2, "root": 3, "program": 4, "EOF": 5, "program_repetition0": 6, "statement": 7, "mustache": 8, "block": 9, "rawBlock": 10, "partial": 11, "partialBlock": 12, "content": 13, "COMMENT": 14, "CONTENT": 15, "openRawBlock": 16, "rawBlock_repetition0": 17, "END_RAW_BLOCK": 18, "OPEN_RAW_BLOCK": 19, "helperName": 20, "openRawBlock_repetition0": 21, "openRawBlock_option0": 22, "CLOSE_RAW_BLOCK": 23, "openBlock": 24, "block_option0": 25, "closeBlock": 26, "openInverse": 27, "block_option1": 28, "OPEN_BLOCK": 29, "openBlock_repetition0": 30, "openBlock_option0": 31, "openBlock_option1": 32, "CLOSE": 33, "OPEN_INVERSE": 34, "openInverse_repetition0": 35, "openInverse_option0": 36, "openInverse_option1": 37, "openInverseChain": 38, "OPEN_INVERSE_CHAIN": 39, "openInverseChain_repetition0": 40, "openInverseChain_option0": 41, "openInverseChain_option1": 42, "inverseAndProgram": 43, "INVERSE": 44, "inverseChain": 45, "inverseChain_option0": 46, "OPEN_ENDBLOCK": 47, "OPEN": 48, "mustache_repetition0": 49, "mustache_option0": 50, "OPEN_UNESCAPED": 51, "mustache_repetition1": 52, "mustache_option1": 53, "CLOSE_UNESCAPED": 54, "OPEN_PARTIAL": 55, "partialName": 56, "partial_repetition0": 57, "partial_option0": 58, "openPartialBlock": 59, "OPEN_PARTIAL_BLOCK": 60, "openPartialBlock_repetition0": 61, "openPartialBlock_option0": 62, "param": 63, "sexpr": 64, "OPEN_SEXPR": 65, "sexpr_repetition0": 66, "sexpr_option0": 67, "CLOSE_SEXPR": 68, "hash": 69, "hash_repetition_plus0": 70, "hashSegment": 71, "ID": 72, "EQUALS": 73, "blockParams": 74, "OPEN_BLOCK_PARAMS": 75, "blockParams_repetition_plus0": 76, "CLOSE_BLOCK_PARAMS": 77, "path": 78, "dataName": 79, "STRING": 80, "NUMBER": 81, "BOOLEAN": 82, "UNDEFINED": 83, "NULL": 84, "DATA": 85, "pathSegments": 86, "SEP": 87, "$accept": 0, "$end": 1 },
7613	        terminals_: { 2: "error", 5: "EOF", 14: "COMMENT", 15: "CONTENT", 18: "END_RAW_BLOCK", 19: "OPEN_RAW_BLOCK", 23: "CLOSE_RAW_BLOCK", 29: "OPEN_BLOCK", 33: "CLOSE", 34: "OPEN_INVERSE", 39: "OPEN_INVERSE_CHAIN", 44: "INVERSE", 47: "OPEN_ENDBLOCK", 48: "OPEN", 51: "OPEN_UNESCAPED", 54: "CLOSE_UNESCAPED", 55: "OPEN_PARTIAL", 60: "OPEN_PARTIAL_BLOCK", 65: "OPEN_SEXPR", 68: "CLOSE_SEXPR", 72: "ID", 73: "EQUALS", 75: "OPEN_BLOCK_PARAMS", 77: "CLOSE_BLOCK_PARAMS", 80: "STRING", 81: "NUMBER", 82: "BOOLEAN", 83: "UNDEFINED", 84: "NULL", 85: "DATA", 87: "SEP" },
7614	        productions_: [0, [3, 2], [4, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [13, 1], [10, 3], [16, 5], [9, 4], [9, 4], [24, 6], [27, 6], [38, 6], [43, 2], [45, 3], [45, 1], [26, 3], [8, 5], [8, 5], [11, 5], [12, 3], [59, 5], [63, 1], [63, 1], [64, 5], [69, 1], [71, 3], [74, 3], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [56, 1], [56, 1], [79, 2], [78, 1], [86, 3], [86, 1], [6, 0], [6, 2], [17, 0], [17, 2], [21, 0], [21, 2], [22, 0], [22, 1], [25, 0], [25, 1], [28, 0], [28, 1], [30, 0], [30, 2], [31, 0], [31, 1], [32, 0], [32, 1], [35, 0], [35, 2], [36, 0], [36, 1], [37, 0], [37, 1], [40, 0], [40, 2], [41, 0], [41, 1], [42, 0], [42, 1], [46, 0], [46, 1], [49, 0], [49, 2], [50, 0], [50, 1], [52, 0], [52, 2], [53, 0], [53, 1], [57, 0], [57, 2], [58, 0], [58, 1], [61, 0], [61, 2], [62, 0], [62, 1], [66, 0], [66, 2], [67, 0], [67, 1], [70, 1], [70, 2], [76, 1], [76, 2]],
7615	        performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) {
7616
7617	            var $0 = $$.length - 1;
7618	            switch (yystate) {
7619	                case 1:
7620	                    return $$[$0 - 1];
7621	                    break;
7622	                case 2:
7623	                    this.$ = yy.prepareProgram($$[$0]);
7624	                    break;
7625	                case 3:
7626	                    this.$ = $$[$0];
7627	                    break;
7628	                case 4:
7629	                    this.$ = $$[$0];
7630	                    break;
7631	                case 5:
7632	                    this.$ = $$[$0];
7633	                    break;
7634	                case 6:
7635	                    this.$ = $$[$0];
7636	                    break;
7637	                case 7:
7638	                    this.$ = $$[$0];
7639	                    break;
7640	                case 8:
7641	                    this.$ = $$[$0];
7642	                    break;
7643	                case 9:
7644	                    this.$ = {
7645	                        type: 'CommentStatement',
7646	                        value: yy.stripComment($$[$0]),
vendor: 8,908 bytes, lines 7647-7867
7647	                        strip: yy.stripFlags($$[$0], $$[$0]),
7648	                        loc: yy.locInfo(this._$)
7649	                    };
7650
7651	                    break;
7652	                case 10:
7653	                    this.$ = {
7654	                        type: 'ContentStatement',
7655	                        original: $$[$0],
7656	                        value: $$[$0],
7657	                        loc: yy.locInfo(this._$)
7658	                    };
7659
7660	                    break;
7661	                case 11:
7662	                    this.$ = yy.prepareRawBlock($$[$0 - 2], $$[$0 - 1], $$[$0], this._$);
7663	                    break;
7664	                case 12:
7665	                    this.$ = { path: $$[$0 - 3], params: $$[$0 - 2], hash: $$[$0 - 1] };
7666	                    break;
7667	                case 13:
7668	                    this.$ = yy.prepareBlock($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0], false, this._$);
7669	                    break;
7670	                case 14:
7671	                    this.$ = yy.prepareBlock($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0], true, this._$);
7672	                    break;
7673	                case 15:
7674	                    this.$ = { open: $$[$0 - 5], path: $$[$0 - 4], params: $$[$0 - 3], hash: $$[$0 - 2], blockParams: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 5], $$[$0]) };
7675	                    break;
7676	                case 16:
7677	                    this.$ = { path: $$[$0 - 4], params: $$[$0 - 3], hash: $$[$0 - 2], blockParams: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 5], $$[$0]) };
7678	                    break;
7679	                case 17:
7680	                    this.$ = { path: $$[$0 - 4], params: $$[$0 - 3], hash: $$[$0 - 2], blockParams: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 5], $$[$0]) };
7681	                    break;
7682	                case 18:
7683	                    this.$ = { strip: yy.stripFlags($$[$0 - 1], $$[$0 - 1]), program: $$[$0] };
7684	                    break;
7685	                case 19:
7686	                    var inverse = yy.prepareBlock($$[$0 - 2], $$[$0 - 1], $$[$0], $$[$0], false, this._$),
7687	                        program = yy.prepareProgram([inverse], $$[$0 - 1].loc);
7688	                    program.chained = true;
7689
7690	                    this.$ = { strip: $$[$0 - 2].strip, program: program, chain: true };
7691
7692	                    break;
7693	                case 20:
7694	                    this.$ = $$[$0];
7695	                    break;
7696	                case 21:
7697	                    this.$ = { path: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 2], $$[$0]) };
7698	                    break;
7699	                case 22:
7700	                    this.$ = yy.prepareMustache($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0 - 4], yy.stripFlags($$[$0 - 4], $$[$0]), this._$);
7701	                    break;
7702	                case 23:
7703	                    this.$ = yy.prepareMustache($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0 - 4], yy.stripFlags($$[$0 - 4], $$[$0]), this._$);
7704	                    break;
7705	                case 24:
7706	                    this.$ = {
7707	                        type: 'PartialStatement',
7708	                        name: $$[$0 - 3],
7709	                        params: $$[$0 - 2],
7710	                        hash: $$[$0 - 1],
7711	                        indent: '',
7712	                        strip: yy.stripFlags($$[$0 - 4], $$[$0]),
7713	                        loc: yy.locInfo(this._$)
7714	                    };
7715
7716	                    break;
7717	                case 25:
7718	                    this.$ = yy.preparePartialBlock($$[$0 - 2], $$[$0 - 1], $$[$0], this._$);
7719	                    break;
7720	                case 26:
7721	                    this.$ = { path: $$[$0 - 3], params: $$[$0 - 2], hash: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 4], $$[$0]) };
7722	                    break;
7723	                case 27:
7724	                    this.$ = $$[$0];
7725	                    break;
7726	                case 28:
7727	                    this.$ = $$[$0];
7728	                    break;
7729	                case 29:
7730	                    this.$ = {
7731	                        type: 'SubExpression',
7732	                        path: $$[$0 - 3],
7733	                        params: $$[$0 - 2],
7734	                        hash: $$[$0 - 1],
7735	                        loc: yy.locInfo(this._$)
7736	                    };
7737
7738	                    break;
7739	                case 30:
7740	                    this.$ = { type: 'Hash', pairs: $$[$0], loc: yy.locInfo(this._$) };
7741	                    break;
7742	                case 31:
7743	                    this.$ = { type: 'HashPair', key: yy.id($$[$0 - 2]), value: $$[$0], loc: yy.locInfo(this._$) };
7744	                    break;
7745	                case 32:
7746	                    this.$ = yy.id($$[$0 - 1]);
7747	                    break;
7748	                case 33:
7749	                    this.$ = $$[$0];
7750	                    break;
7751	                case 34:
7752	                    this.$ = $$[$0];
7753	                    break;
7754	                case 35:
7755	                    this.$ = { type: 'StringLiteral', value: $$[$0], original: $$[$0], loc: yy.locInfo(this._$) };
7756	                    break;
7757	                case 36:
7758	                    this.$ = { type: 'NumberLiteral', value: Number($$[$0]), original: Number($$[$0]), loc: yy.locInfo(this._$) };
7759	                    break;
7760	                case 37:
7761	                    this.$ = { type: 'BooleanLiteral', value: $$[$0] === 'true', original: $$[$0] === 'true', loc: yy.locInfo(this._$) };
7762	                    break;
7763	                case 38:
7764	                    this.$ = { type: 'UndefinedLiteral', original: undefined, value: undefined, loc: yy.locInfo(this._$) };
7765	                    break;
7766	                case 39:
7767	                    this.$ = { type: 'NullLiteral', original: null, value: null, loc: yy.locInfo(this._$) };
7768	                    break;
7769	                case 40:
7770	                    this.$ = $$[$0];
7771	                    break;
7772	                case 41:
7773	                    this.$ = $$[$0];
7774	                    break;
7775	                case 42:
7776	                    this.$ = yy.preparePath(true, $$[$0], this._$);
7777	                    break;
7778	                case 43:
7779	                    this.$ = yy.preparePath(false, $$[$0], this._$);
7780	                    break;
7781	                case 44:
7782	                    $$[$0 - 2].push({ part: yy.id($$[$0]), original: $$[$0], separator: $$[$0 - 1] });this.$ = $$[$0 - 2];
7783	                    break;
7784	                case 45:
7785	                    this.$ = [{ part: yy.id($$[$0]), original: $$[$0] }];
7786	                    break;
7787	                case 46:
7788	                    this.$ = [];
7789	                    break;
7790	                case 47:
7791	                    $$[$0 - 1].push($$[$0]);
7792	                    break;
7793	                case 48:
7794	                    this.$ = [];
7795	                    break;
7796	                case 49:
7797	                    $$[$0 - 1].push($$[$0]);
7798	                    break;
7799	                case 50:
7800	                    this.$ = [];
7801	                    break;
7802	                case 51:
7803	                    $$[$0 - 1].push($$[$0]);
7804	                    break;
7805	                case 58:
7806	                    this.$ = [];
7807	                    break;
7808	                case 59:
7809	                    $$[$0 - 1].push($$[$0]);
7810	                    break;
7811	                case 64:
7812	                    this.$ = [];
7813	                    break;
7814	                case 65:
7815	                    $$[$0 - 1].push($$[$0]);
7816	                    break;
7817	                case 70:
7818	                    this.$ = [];
7819	                    break;
7820	                case 71:
7821	                    $$[$0 - 1].push($$[$0]);
7822	                    break;
7823	                case 78:
7824	                    this.$ = [];
7825	                    break;
7826	                case 79:
7827	                    $$[$0 - 1].push($$[$0]);
7828	                    break;
7829	                case 82:
7830	                    this.$ = [];
7831	                    break;
7832	                case 83:
7833	                    $$[$0 - 1].push($$[$0]);
7834	                    break;
7835	                case 86:
7836	                    this.$ = [];
7837	                    break;
7838	                case 87:
7839	                    $$[$0 - 1].push($$[$0]);
7840	                    break;
7841	                case 90:
7842	                    this.$ = [];
7843	                    break;
7844	                case 91:
7845	                    $$[$0 - 1].push($$[$0]);
7846	                    break;
7847	                case 94:
7848	                    this.$ = [];
7849	                    break;
7850	                case 95:
7851	                    $$[$0 - 1].push($$[$0]);
7852	                    break;
7853	                case 98:
7854	                    this.$ = [$$[$0]];
7855	                    break;
7856	                case 99:
7857	                    $$[$0 - 1].push($$[$0]);
7858	                    break;
7859	                case 100:
7860	                    this.$ = [$$[$0]];
7861	                    break;
7862	                case 101:
7863	                    $$[$0 - 1].push($$[$0]);
7864	                    break;
7865	            }
7866	        },
7867	
vendor: 11,458 bytes, line 7867
7867        table: [{ 3: 1, 4: 2, 5: [2, 46], 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 1: [3] }, { 5: [1, 4] }, { 5: [2, 2], 7: 5, 8: 6, 9: 7, 10: 8, 11: 9, 12: 10, 13: 11, 14: [1, 12], 15: [1, 20], 16: 17, 19: [1, 23], 24: 15, 27: 16, 29: [1, 21], 34: [1, 22], 39: [2, 2], 44: [2, 2], 47: [2, 2], 48: [1, 13], 51: [1, 14], 55: [1, 18], 59: 19, 60: [1, 24] }, { 1: [2, 1] }, { 5: [2, 47], 14: [2, 47], 15: [2, 47], 19: [2, 47], 29: [2, 47], 34: [2, 47], 39: [2, 47], 44: [2, 47], 47: [2, 47], 48: [2, 47], 51: [2, 47], 55: [2, 47], 60: [2, 47] }, { 5: [2, 3], 14: [2, 3], 15: [2, 3], 19: [2, 3], 29: [2, 3], 34: [2, 3], 39: [2, 3], 44: [2, 3], 47: [2, 3], 48: [2, 3], 51: [2, 3], 55: [2, 3], 60: [2, 3] }, { 5: [2, 4], 14: [2, 4], 15: [2, 4], 19: [2, 4], 29: [2, 4], 34: [2, 4], 39: [2, 4], 44: [2, 4], 47: [2, 4], 48: [2, 4], 51: [2, 4], 55: [2, 4], 60: [2, 4] }, { 5: [2, 5], 14: [2, 5], 15: [2, 5], 19: [2, 5], 29: [2, 5], 34: [2, 5], 39: [2, 5], 44: [2, 5], 47: [2, 5], 48: [2, 5], 51: [2, 5], 55: [2, 5], 60: [2, 5] }, { 5: [2, 6], 14: [2, 6], 15: [2, 6], 19: [2, 6], 29: [2, 6], 34: [2, 6], 39: [2, 6], 44: [2, 6], 47: [2, 6], 48: [2, 6], 51: [2, 6], 55: [2, 6], 60: [2, 6] }, { 5: [2, 7], 14: [2, 7], 15: [2, 7], 19: [2, 7], 29: [2, 7], 34: [2, 7], 39: [2, 7], 44: [2, 7], 47: [2, 7], 48: [2, 7], 51: [2, 7], 55: [2, 7], 60: [2, 7] }, { 5: [2, 8], 14: [2, 8], 15: [2, 8], 19: [2, 8], 29: [2, 8], 34: [2, 8], 39: [2, 8], 44: [2, 8], 47: [2, 8], 48: [2, 8], 51: [2, 8], 55: [2, 8], 60: [2, 8] }, { 5: [2, 9], 14: [2, 9], 15: [2, 9], 19: [2, 9], 29: [2, 9], 34: [2, 9], 39: [2, 9], 44: [2, 9], 47: [2, 9], 48: [2, 9], 51: [2, 9], 55: [2, 9], 60: [2, 9] }, { 20: 25, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 36, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 4: 37, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 39: [2, 46], 44: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 4: 38, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 44: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 15: [2, 48], 17: 39, 18: [2, 48] }, { 20: 41, 56: 40, 64: 42, 65: [1, 43], 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 4: 44, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 5: [2, 10], 14: [2, 10], 15: [2, 10], 18: [2, 10], 19: [2, 10], 29: [2, 10], 34: [2, 10], 39: [2, 10], 44: [2, 10], 47: [2, 10], 48: [2, 10], 51: [2, 10], 55: [2, 10], 60: [2, 10] }, { 20: 45, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 46, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 47, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 41, 56: 48, 64: 42, 65: [1, 43], 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 33: [2, 78], 49: 49, 65: [2, 78], 72: [2, 78], 80: [2, 78], 81: [2, 78], 82: [2, 78], 83: [2, 78], 84: [2, 78], 85: [2, 78] }, { 23: [2, 33], 33: [2, 33], 54: [2, 33], 65: [2, 33], 68: [2, 33], 72: [2, 33], 75: [2, 33], 80: [2, 33], 81: [2, 33], 82: [2, 33], 83: [2, 33], 84: [2, 33], 85: [2, 33] }, { 23: [2, 34], 33: [2, 34], 54: [2, 34], 65: [2, 34], 68: [2, 34], 72: [2, 34], 75: [2, 34], 80: [2, 34], 81: [2, 34], 82: [2, 34], 83: [2, 34], 84: [2, 34], 85: [2, 34] }, { 23: [2, 35], 33: [2, 35], 54: [2, 35], 65: [2, 35], 68: [2, 35], 72: [2, 35], 75: [2, 35], 80: [2, 35], 81: [2, 35], 82: [2, 35], 83: [2, 35], 84: [2, 35], 85: [2, 35] }, { 23: [2, 36], 33: [2, 36], 54: [2, 36], 65: [2, 36], 68: [2, 36], 72: [2, 36], 75: [2, 36], 80: [2, 36], 81: [2, 36], 82: [2, 36], 83: [2, 36], 84: [2, 36], 85: [2, 36] }, { 23: [2, 37], 33: [2, 37], 54: [2, 37], 65: [2, 37], 68: [2, 37], 72: [2, 37], 75: [2, 37], 80: [2, 37], 81: [2, 37], 82: [2, 37], 83: [2, 37], 84: [2, 37], 85: [2, 37] }, { 23: [2, 38], 33: [2, 38], 54: [2, 38], 65: [2, 38], 68: [2, 38], 72: [2, 38], 75: [2, 38], 80: [2, 38], 81: [2, 38], 82: [2, 38], 83: [2, 38], 84: [2, 38], 85: [2, 38] }, { 23: [2, 39], 33: [2, 39], 54: [2, 39], 65: [2, 39], 68: [2, 39], 72: [2, 39], 75: [2, 39], 80: [2, 39], 81: [2, 39], 82: [2, 39], 83: [2, 39], 84: [2, 39], 85: [2, 39] }, { 23: [2, 43], 33: [2, 43], 54: [2, 43], 65: [2, 43], 68: [2, 43], 72: [2, 43], 75: [2, 43], 80: [2, 43], 81: [2, 43], 82: [2, 43], 83: [2, 43], 84: [2, 43], 85: [2, 43], 87: [1, 50] }, { 72: [1, 35], 86: 51 }, { 23: [2, 45], 33: [2, 45], 54: [2, 45], 65: [2, 45], 68: [2, 45], 72: [2, 45], 75: [2, 45], 80: [2, 45], 81: [2, 45], 82: [2, 45], 83: [2, 45], 84: [2, 45], 85: [2, 45], 87: [2, 45] }, { 52: 52, 54: [2, 82], 65: [2, 82], 72: [2, 82], 80: [2, 82], 81: [2, 82], 82: [2, 82], 83: [2, 82], 84: [2, 82], 85: [2, 82] }, { 25: 53, 38: 55, 39: [1, 57], 43: 56, 44: [1, 58], 45: 54, 47: [2, 54] }, { 28: 59, 43: 60, 44: [1, 58], 47: [2, 56] }, { 13: 62, 15: [1, 20], 18: [1, 61] }, { 33: [2, 86], 57: 63, 65: [2, 86], 72: [2, 86], 80: [2, 86], 81: [2, 86], 82: [2, 86], 83: [2, 86], 84: [2, 86], 85: [2, 86] }, { 33: [2, 40], 65: [2, 40], 72: [2, 40], 80: [2, 40], 81: [2, 40], 82: [2, 40], 83: [2, 40], 84: [2, 40], 85: [2, 40] }, { 33: [2, 41], 65: [2, 41], 72: [2, 41], 80: [2, 41], 81: [2, 41], 82: [2, 41], 83: [2, 41], 84: [2, 41], 85: [2, 41] }, { 20: 64, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 26: 65, 47: [1, 66] }, { 30: 67, 33: [2, 58], 65: [2, 58], 72: [2, 58], 75: [2, 58], 80: [2, 58], 81: [2, 58], 82: [2, 58], 83: [2, 58], 84: [2, 58], 85: [2, 58] }, { 33: [2, 64], 35: 68, 65: [2, 64], 72: [2, 64], 75: [2, 64], 80: [2, 64], 81: [2, 64], 82: [2, 64], 83: [2, 64], 84: [2, 64], 85: [2, 64] }, { 21: 69, 23: [2, 50], 65: [2, 50], 72: [2, 50], 80: [2, 50], 81: [2, 50], 82: [2, 50], 83: [2, 50], 84: [2, 50], 85: [2, 50] }, { 33: [2, 90], 61: 70, 65: [2, 90], 72: [2, 90], 80: [2, 90], 81: [2, 90], 82: [2, 90], 83: [2, 90], 84: [2, 90], 85: [2, 90] }, { 20: 74, 33: [2, 80], 50: 71, 63: 72, 64: 75, 65: [1, 43], 69: 73, 70: 76, 71: 77, 72: [1, 78], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 72: [1, 79] }, { 23: [2, 42], 33: [2, 42], 54: [2, 42], 65: [2, 42], 68: [2, 42], 72: [2, 42], 75: [2, 42], 80: [2, 42], 81: [2, 42], 82: [2, 42], 83: [2, 42], 84: [2, 42], 85: [2, 42], 87: [1, 50] }, { 20: 74, 53: 80, 54: [2, 84], 63: 81, 64: 75, 65: [1, 43], 69: 82, 70: 76, 71: 77, 72: [1, 78], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 26: 83, 47: [1, 66] }, { 47: [2, 55] }, { 4: 84, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 39: [2, 46], 44: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 47: [2, 20] }, { 20: 85, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 4: 86, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 26: 87, 47: [1, 66] }, { 47: [2, 57] }, { 5: [2, 11], 14: [2, 11], 15: [2, 11], 19: [2, 11], 29: [2, 11], 34: [2, 11], 39: [2, 11], 44: [2, 11], 47: [2, 11], 48: [2, 11], 51: [2, 11], 55: [2, 11], 60: [2, 11] }, { 15: [2, 49], 18: [2, 49] }, { 20: 74, 33: [2, 88], 58: 88, 63: 89, 64: 75, 65: [1, 43], 69: 90, 70: 76, 71: 77, 72: [1, 78], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 65: [2, 94], 66: 91, 68: [2, 94], 72: [2, 94], 80: [2, 94], 81: [2, 94], 82: [2, 94], 83: [2, 94], 84: [2, 94], 85: [2, 94] }, { 5: [2, 25], 14: [2, 25], 15: [2, 25], 19: [2, 25], 29: [2, 25], 34: [2, 25], 39: [2, 25], 44: [2, 25], 47: [2, 25], 48: [2, 25], 51: [2, 25], 55: [2, 25], 60: [2, 25] }, { 20: 92, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 74, 31: 93, 33: [2, 60], 63: 94, 64: 75, 65: [1, 43], 69: 95, 70: 76, 71: 77, 72: [1, 78], 75: [2, 60], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 74, 33: [2, 66], 36: 96, 63: 97, 64: 75, 65: [1, 43], 69: 98, 70: 76, 71: 77, 72: [1, 78], 75: [2, 66], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 74, 22: 99, 23: [2, 52], 63: 100, 64: 75, 65: [1, 43], 69: 101, 70: 76, 71: 77, 72: [1, 78], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 74, 33: [2, 92], 62: 102, 63: 103, 64: 75, 65: [1, 43], 69: 104, 70: 76, 71: 77, 72: [1, 78], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 33: [1, 105] }, { 33: [2, 79], 65: [2, 79], 72: [2, 79], 80: [2, 79], 81: [2, 79], 82: [2, 79], 83: [2, 79], 84: [2, 79], 85: [2, 79] }, { 33: [2, 81] }, { 23: [2, 27], 33: [2, 27], 54: [2, 27], 65: [2, 27], 68: [2, 27], 72: [2, 27], 75: [2, 27], 80: [2, 27], 81: [2, 27], 82: [2, 27], 83: [2, 27], 84: [2, 27], 85: [2, 27] }, { 23: [2, 28], 33: [2, 28], 54: [2, 28], 65: [2, 28], 68: [2, 28], 72: [2, 28], 75: [2, 28], 80: [2, 28], 81: [2, 28], 82: [2, 28], 83: [2, 28], 84: [2, 28], 85: [2, 28] }, { 23: [2, 30], 33: [2, 30], 54: [2, 30], 68: [2, 30], 71: 106, 72: [1, 107], 75: [2, 30] }, { 23: [2, 98], 33: [2, 98], 54: [2, 98], 68: [2, 98], 72: [2, 98], 75: [2, 98] }, { 23: [2, 45], 33: [2, 45], 54: [2, 45], 65: [2, 45], 68: [2, 45], 72: [2, 45], 73: [1, 108], 75: [2, 45], 80: [2, 45], 81: [2, 45], 82: [2, 45], 83: [2, 45], 84: [2, 45], 85: [2, 45], 87: [2, 45] }, { 23: [2, 44], 33: [2, 44], 54: [2, 44], 65: [2, 44], 68: [2, 44], 72: [2, 44], 75: [2, 44], 80: [2, 44], 81: [2, 44], 82: [2, 44], 83: [2, 44], 84: [2, 44], 85: [2, 44], 87: [2, 44] }, { 54: [1, 109] }, { 54: [2, 83], 65: [2, 83], 72: [2, 83], 80: [2, 83], 81: [2, 83], 82: [2, 83], 83: [2, 83], 84: [2, 83], 85: [2, 83] }, { 54: [2, 85] }, { 5: [2, 13], 14: [2, 13], 15: [2, 13], 19: [2, 13], 29: [2, 13], 34: [2, 13], 39: [2, 13], 44: [2, 13], 47: [2, 13], 48: [2, 13], 51: [2, 13], 55: [2, 13], 60: [2, 13] }, { 38: 55, 39: [1, 57], 43: 56, 44: [1, 58], 45: 111, 46: 110, 47: [2, 76] }, { 33: [2, 70], 40: 112, 65: [2, 70], 72: [2, 70], 75: [2, 70], 80: [2, 70], 81: [2, 70], 82: [2, 70], 83: [2, 70], 84: [2, 70], 85: [2, 70] }, { 47: [2, 18] }, { 5: [2, 14], 14: [2, 14], 15: [2, 14], 19: [2, 14], 29: [2, 14], 34: [2, 14], 39: [2, 14], 44: [2, 14], 47: [2, 14], 48: [2, 14], 51: [2, 14], 55: [2, 14], 60: [2, 14] }, { 33: [1, 113] }, { 33: [2, 87], 65: [2, 87], 72: [2, 87], 80: [2, 87], 81: [2, 87], 82: [2, 87], 83: [2, 87], 84: [2, 87], 85: [2, 87] }, { 33: [2, 89] }, { 20: 74, 63: 115, 64: 75, 65: [1, 43], 67: 114, 68: [2, 96], 69: 116, 70: 76, 71: 77, 72: [1, 78], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }
vendor: 22,841 bytes, lines 7867-8329
7867, { 33: [1, 117] }, { 32: 118, 33: [2, 62], 74: 119, 75: [1, 120] }, { 33: [2, 59], 65: [2, 59], 72: [2, 59], 75: [2, 59], 80: [2, 59], 81: [2, 59], 82: [2, 59], 83: [2, 59], 84: [2, 59], 85: [2, 59] }, { 33: [2, 61], 75: [2, 61] }, { 33: [2, 68], 37: 121, 74: 122, 75: [1, 120] }, { 33: [2, 65], 65: [2, 65], 72: [2, 65], 75: [2, 65], 80: [2, 65], 81: [2, 65], 82: [2, 65], 83: [2, 65], 84: [2, 65], 85: [2, 65] }, { 33: [2, 67], 75: [2, 67] }, { 23: [1, 123] }, { 23: [2, 51], 65: [2, 51], 72: [2, 51], 80: [2, 51], 81: [2, 51], 82: [2, 51], 83: [2, 51], 84: [2, 51], 85: [2, 51] }, { 23: [2, 53] }, { 33: [1, 124] }, { 33: [2, 91], 65: [2, 91], 72: [2, 91], 80: [2, 91], 81: [2, 91], 82: [2, 91], 83: [2, 91], 84: [2, 91], 85: [2, 91] }, { 33: [2, 93] }, { 5: [2, 22], 14: [2, 22], 15: [2, 22], 19: [2, 22], 29: [2, 22], 34: [2, 22], 39: [2, 22], 44: [2, 22], 47: [2, 22], 48: [2, 22], 51: [2, 22], 55: [2, 22], 60: [2, 22] }, { 23: [2, 99], 33: [2, 99], 54: [2, 99], 68: [2, 99], 72: [2, 99], 75: [2, 99] }, { 73: [1, 108] }, { 20: 74, 63: 125, 64: 75, 65: [1, 43], 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 5: [2, 23], 14: [2, 23], 15: [2, 23], 19: [2, 23], 29: [2, 23], 34: [2, 23], 39: [2, 23], 44: [2, 23], 47: [2, 23], 48: [2, 23], 51: [2, 23], 55: [2, 23], 60: [2, 23] }, { 47: [2, 19] }, { 47: [2, 77] }, { 20: 74, 33: [2, 72], 41: 126, 63: 127, 64: 75, 65: [1, 43], 69: 128, 70: 76, 71: 77, 72: [1, 78], 75: [2, 72], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 5: [2, 24], 14: [2, 24], 15: [2, 24], 19: [2, 24], 29: [2, 24], 34: [2, 24], 39: [2, 24], 44: [2, 24], 47: [2, 24], 48: [2, 24], 51: [2, 24], 55: [2, 24], 60: [2, 24] }, { 68: [1, 129] }, { 65: [2, 95], 68: [2, 95], 72: [2, 95], 80: [2, 95], 81: [2, 95], 82: [2, 95], 83: [2, 95], 84: [2, 95], 85: [2, 95] }, { 68: [2, 97] }, { 5: [2, 21], 14: [2, 21], 15: [2, 21], 19: [2, 21], 29: [2, 21], 34: [2, 21], 39: [2, 21], 44: [2, 21], 47: [2, 21], 48: [2, 21], 51: [2, 21], 55: [2, 21], 60: [2, 21] }, { 33: [1, 130] }, { 33: [2, 63] }, { 72: [1, 132], 76: 131 }, { 33: [1, 133] }, { 33: [2, 69] }, { 15: [2, 12], 18: [2, 12] }, { 14: [2, 26], 15: [2, 26], 19: [2, 26], 29: [2, 26], 34: [2, 26], 47: [2, 26], 48: [2, 26], 51: [2, 26], 55: [2, 26], 60: [2, 26] }, { 23: [2, 31], 33: [2, 31], 54: [2, 31], 68: [2, 31], 72: [2, 31], 75: [2, 31] }, { 33: [2, 74], 42: 134, 74: 135, 75: [1, 120] }, { 33: [2, 71], 65: [2, 71], 72: [2, 71], 75: [2, 71], 80: [2, 71], 81: [2, 71], 82: [2, 71], 83: [2, 71], 84: [2, 71], 85: [2, 71] }, { 33: [2, 73], 75: [2, 73] }, { 23: [2, 29], 33: [2, 29], 54: [2, 29], 65: [2, 29], 68: [2, 29], 72: [2, 29], 75: [2, 29], 80: [2, 29], 81: [2, 29], 82: [2, 29], 83: [2, 29], 84: [2, 29], 85: [2, 29] }, { 14: [2, 15], 15: [2, 15], 19: [2, 15], 29: [2, 15], 34: [2, 15], 39: [2, 15], 44: [2, 15], 47: [2, 15], 48: [2, 15], 51: [2, 15], 55: [2, 15], 60: [2, 15] }, { 72: [1, 137], 77: [1, 136] }, { 72: [2, 100], 77: [2, 100] }, { 14: [2, 16], 15: [2, 16], 19: [2, 16], 29: [2, 16], 34: [2, 16], 44: [2, 16], 47: [2, 16], 48: [2, 16], 51: [2, 16], 55: [2, 16], 60: [2, 16] }, { 33: [1, 138] }, { 33: [2, 75] }, { 33: [2, 32] }, { 72: [2, 101], 77: [2, 101] }, { 14: [2, 17], 15: [2, 17], 19: [2, 17], 29: [2, 17], 34: [2, 17], 39: [2, 17], 44: [2, 17], 47: [2, 17], 48: [2, 17], 51: [2, 17], 55: [2, 17], 60: [2, 17] }],
7868	        defaultActions: { 4: [2, 1], 54: [2, 55], 56: [2, 20], 60: [2, 57], 73: [2, 81], 82: [2, 85], 86: [2, 18], 90: [2, 89], 101: [2, 53], 104: [2, 93], 110: [2, 19], 111: [2, 77], 116: [2, 97], 119: [2, 63], 122: [2, 69], 135: [2, 75], 136: [2, 32] },
7869	        parseError: function parseError(str, hash) {
7870	            throw new Error(str);
7871	        },
7872	        parse: function parse(input) {
7873	            var self = this,
7874	                stack = [0],
7875	                vstack = [null],
7876	                lstack = [],
7877	                table = this.table,
7878	                yytext = "",
7879	                yylineno = 0,
7880	                yyleng = 0,
7881	                recovering = 0,
7882	                TERROR = 2,
7883	                EOF = 1;
7884	            this.lexer.setInput(input);
7885	            this.lexer.yy = this.yy;
7886	            this.yy.lexer = this.lexer;
7887	            this.yy.parser = this;
7888	            if (typeof this.lexer.yylloc == "undefined") this.lexer.yylloc = {};
7889	            var yyloc = this.lexer.yylloc;
7890	            lstack.push(yyloc);
7891	            var ranges = this.lexer.options && this.lexer.options.ranges;
7892	            if (typeof this.yy.parseError === "function") this.parseError = this.yy.parseError;
7893	            function popStack(n) {
7894	                stack.length = stack.length - 2 * n;
7895	                vstack.length = vstack.length - n;
7896	                lstack.length = lstack.length - n;
7897	            }
7898	            function lex() {
7899	                var token;
7900	                token = self.lexer.lex() || 1;
7901	                if (typeof token !== "number") {
7902	                    token = self.symbols_[token] || token;
7903	                }
7904	                return token;
7905	            }
7906	            var symbol,
7907	                preErrorSymbol,
7908	                state,
7909	                action,
7910	                a,
7911	                r,
7912	                yyval = {},
7913	                p,
7914	                len,
7915	                newState,
7916	                expected;
7917	            while (true) {
7918	                state = stack[stack.length - 1];
7919	                if (this.defaultActions[state]) {
7920	                    action = this.defaultActions[state];
7921	                } else {
7922	                    if (symbol === null || typeof symbol == "undefined") {
7923	                        symbol = lex();
7924	                    }
7925	                    action = table[state] && table[state][symbol];
7926	                }
7927	                if (typeof action === "undefined" || !action.length || !action[0]) {
7928	                    var errStr = "";
7929	                    if (!recovering) {
7930	                        expected = [];
7931	                        for (p in table[state]) if (this.terminals_[p] && p > 2) {
7932	                            expected.push("'" + this.terminals_[p] + "'");
7933	                        }
7934	                        if (this.lexer.showPosition) {
7935	                            errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'";
7936	                        } else {
7937	                            errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1 ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'");
7938	                        }
7939	                        this.parseError(errStr, { text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected });
7940	                    }
7941	                }
7942	                if (action[0] instanceof Array && action.length > 1) {
7943	                    throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
7944	                }
7945	                switch (action[0]) {
7946	                    case 1:
7947	                        stack.push(symbol);
7948	                        vstack.push(this.lexer.yytext);
7949	                        lstack.push(this.lexer.yylloc);
7950	                        stack.push(action[1]);
7951	                        symbol = null;
7952	                        if (!preErrorSymbol) {
7953	                            yyleng = this.lexer.yyleng;
7954	                            yytext = this.lexer.yytext;
7955	                            yylineno = this.lexer.yylineno;
7956	                            yyloc = this.lexer.yylloc;
7957	                            if (recovering > 0) recovering--;
7958	                        } else {
7959	                            symbol = preErrorSymbol;
7960	                            preErrorSymbol = null;
7961	                        }
7962	                        break;
7963	                    case 2:
7964	                        len = this.productions_[action[1]][1];
7965	                        yyval.$ = vstack[vstack.length - len];
7966	                        yyval._$ = { first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column };
7967	                        if (ranges) {
7968	                            yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
7969	                        }
7970	                        r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
7971	                        if (typeof r !== "undefined") {
7972	                            return r;
7973	                        }
7974	                        if (len) {
7975	                            stack = stack.slice(0, -1 * len * 2);
7976	                            vstack = vstack.slice(0, -1 * len);
7977	                            lstack = lstack.slice(0, -1 * len);
7978	                        }
7979	                        stack.push(this.productions_[action[1]][0]);
7980	                        vstack.push(yyval.$);
7981	                        lstack.push(yyval._$);
7982	                        newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
7983	                        stack.push(newState);
7984	                        break;
7985	                    case 3:
7986	                        return true;
7987	                }
7988	            }
7989	            return true;
7990	        }
7991	    };
7992	    /* Jison generated lexer */
7993	    var lexer = (function () {
7994	        var lexer = { EOF: 1,
7995	            parseError: function parseError(str, hash) {
7996	                if (this.yy.parser) {
7997	                    this.yy.parser.parseError(str, hash);
7998	                } else {
7999	                    throw new Error(str);
8000	                }
8001	            },
8002	            setInput: function setInput(input) {
8003	                this._input = input;
8004	                this._more = this._less = this.done = false;
8005	                this.yylineno = this.yyleng = 0;
8006	                this.yytext = this.matched = this.match = '';
8007	                this.conditionStack = ['INITIAL'];
8008	                this.yylloc = { first_line: 1, first_column: 0, last_line: 1, last_column: 0 };
8009	                if (this.options.ranges) this.yylloc.range = [0, 0];
8010	                this.offset = 0;
8011	                return this;
8012	            },
8013	            input: function input() {
8014	                var ch = this._input[0];
8015	                this.yytext += ch;
8016	                this.yyleng++;
8017	                this.offset++;
8018	                this.match += ch;
8019	                this.matched += ch;
8020	                var lines = ch.match(/(?:\r\n?|\n).*/g);
8021	                if (lines) {
8022	                    this.yylineno++;
8023	                    this.yylloc.last_line++;
8024	                } else {
8025	                    this.yylloc.last_column++;
8026	                }
8027	                if (this.options.ranges) this.yylloc.range[1]++;
8028
8029	                this._input = this._input.slice(1);
8030	                return ch;
8031	            },
8032	            unput: function unput(ch) {
8033	                var len = ch.length;
8034	                var lines = ch.split(/(?:\r\n?|\n)/g);
8035
8036	                this._input = ch + this._input;
8037	                this.yytext = this.yytext.substr(0, this.yytext.length - len - 1);
8038	                //this.yyleng -= len;
8039	                this.offset -= len;
8040	                var oldLines = this.match.split(/(?:\r\n?|\n)/g);
8041	                this.match = this.match.substr(0, this.match.length - 1);
8042	                this.matched = this.matched.substr(0, this.matched.length - 1);
8043
8044	                if (lines.length - 1) this.yylineno -= lines.length - 1;
8045	                var r = this.yylloc.range;
8046
8047	                this.yylloc = { first_line: this.yylloc.first_line,
8048	                    last_line: this.yylineno + 1,
8049	                    first_column: this.yylloc.first_column,
8050	                    last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len
8051	                };
8052
8053	                if (this.options.ranges) {
8054	                    this.yylloc.range = [r[0], r[0] + this.yyleng - len];
8055	                }
8056	                return this;
8057	            },
8058	            more: function more() {
8059	                this._more = true;
8060	                return this;
8061	            },
8062	            less: function less(n) {
8063	                this.unput(this.match.slice(n));
8064	            },
8065	            pastInput: function pastInput() {
8066	                var past = this.matched.substr(0, this.matched.length - this.match.length);
8067	                return (past.length > 20 ? '...' : '') + past.substr(-20).replace(/\n/g, "");
8068	            },
8069	            upcomingInput: function upcomingInput() {
8070	                var next = this.match;
8071	                if (next.length < 20) {
8072	                    next += this._input.substr(0, 20 - next.length);
8073	                }
8074	                return (next.substr(0, 20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
8075	            },
8076	            showPosition: function showPosition() {
8077	                var pre = this.pastInput();
8078	                var c = new Array(pre.length + 1).join("-");
8079	                return pre + this.upcomingInput() + "\n" + c + "^";
8080	            },
8081	            next: function next() {
8082	                if (this.done) {
8083	                    return this.EOF;
8084	                }
8085	                if (!this._input) this.done = true;
8086
8087	                var token, match, tempMatch, index, col, lines;
8088	                if (!this._more) {
8089	                    this.yytext = '';
8090	                    this.match = '';
8091	                }
8092	                var rules = this._currentRules();
8093	                for (var i = 0; i < rules.length; i++) {
8094	                    tempMatch = this._input.match(this.rules[rules[i]]);
8095	                    if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
8096	                        match = tempMatch;
8097	                        index = i;
8098	                        if (!this.options.flex) break;
8099	                    }
8100	                }
8101	                if (match) {
8102	                    lines = match[0].match(/(?:\r\n?|\n).*/g);
8103	                    if (lines) this.yylineno += lines.length;
8104	                    this.yylloc = { first_line: this.yylloc.last_line,
8105	                        last_line: this.yylineno + 1,
8106	                        first_column: this.yylloc.last_column,
8107	                        last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length };
8108	                    this.yytext += match[0];
8109	                    this.match += match[0];
8110	                    this.matches = match;
8111	                    this.yyleng = this.yytext.length;
8112	                    if (this.options.ranges) {
8113	                        this.yylloc.range = [this.offset, this.offset += this.yyleng];
8114	                    }
8115	                    this._more = false;
8116	                    this._input = this._input.slice(match[0].length);
8117	                    this.matched += match[0];
8118	                    token = this.performAction.call(this, this.yy, this, rules[index], this.conditionStack[this.conditionStack.length - 1]);
8119	                    if (this.done && this._input) this.done = false;
8120	                    if (token) return token;else return;
8121	                }
8122	                if (this._input === "") {
8123	                    return this.EOF;
8124	                } else {
8125	                    return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), { text: "", token: null, line: this.yylineno });
8126	                }
8127	            },
8128	            lex: function lex() {
8129	                var r = this.next();
8130	                if (typeof r !== 'undefined') {
8131	                    return r;
8132	                } else {
8133	                    return this.lex();
8134	                }
8135	            },
8136	            begin: function begin(condition) {
8137	                this.conditionStack.push(condition);
8138	            },
8139	            popState: function popState() {
8140	                return this.conditionStack.pop();
8141	            },
8142	            _currentRules: function _currentRules() {
8143	                return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
8144	            },
8145	            topState: function topState() {
8146	                return this.conditionStack[this.conditionStack.length - 2];
8147	            },
8148	            pushState: function begin(condition) {
8149	                this.begin(condition);
8150	            } };
8151	        lexer.options = {};
8152	        lexer.performAction = function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) {
8153
8154	            function strip(start, end) {
8155	                return yy_.yytext = yy_.yytext.substring(start, yy_.yyleng - end + start);
8156	            }
8157
8158	            var YYSTATE = YY_START;
8159	            switch ($avoiding_name_collisions) {
8160	                case 0:
8161	                    if (yy_.yytext.slice(-2) === "\\\\") {
8162	                        strip(0, 1);
8163	                        this.begin("mu");
8164	                    } else if (yy_.yytext.slice(-1) === "\\") {
8165	                        strip(0, 1);
8166	                        this.begin("emu");
8167	                    } else {
8168	                        this.begin("mu");
8169	                    }
8170	                    if (yy_.yytext) return 15;
8171
8172	                    break;
8173	                case 1:
8174	                    return 15;
8175	                    break;
8176	                case 2:
8177	                    this.popState();
8178	                    return 15;
8179
8180	                    break;
8181	                case 3:
8182	                    this.begin('raw');return 15;
8183	                    break;
8184	                case 4:
8185	                    this.popState();
8186	                    // Should be using `this.topState()` below, but it currently
8187	                    // returns the second top instead of the first top. Opened an
8188	                    // issue about it at https://github.com/zaach/jison/issues/291
8189	                    if (this.conditionStack[this.conditionStack.length - 1] === 'raw') {
8190	                        return 15;
8191	                    } else {
8192	                        strip(5, 9);
8193	                        return 'END_RAW_BLOCK';
8194	                    }
8195
8196	                    break;
8197	                case 5:
8198	                    return 15;
8199	                    break;
8200	                case 6:
8201	                    this.popState();
8202	                    return 14;
8203
8204	                    break;
8205	                case 7:
8206	                    return 65;
8207	                    break;
8208	                case 8:
8209	                    return 68;
8210	                    break;
8211	                case 9:
8212	                    return 19;
8213	                    break;
8214	                case 10:
8215	                    this.popState();
8216	                    this.begin('raw');
8217	                    return 23;
8218
8219	                    break;
8220	                case 11:
8221	                    return 55;
8222	                    break;
8223	                case 12:
8224	                    return 60;
8225	                    break;
8226	                case 13:
8227	                    return 29;
8228	                    break;
8229	                case 14:
8230	                    return 47;
8231	                    break;
8232	                case 15:
8233	                    this.popState();return 44;
8234	                    break;
8235	                case 16:
8236	                    this.popState();return 44;
8237	                    break;
8238	                case 17:
8239	                    return 34;
8240	                    break;
8241	                case 18:
8242	                    return 39;
8243	                    break;
8244	                case 19:
8245	                    return 51;
8246	                    break;
8247	                case 20:
8248	                    return 48;
8249	                    break;
8250	                case 21:
8251	                    this.unput(yy_.yytext);
8252	                    this.popState();
8253	                    this.begin('com');
8254
8255	                    break;
8256	                case 22:
8257	                    this.popState();
8258	                    return 14;
8259
8260	                    break;
8261	                case 23:
8262	                    return 48;
8263	                    break;
8264	                case 24:
8265	                    return 73;
8266	                    break;
8267	                case 25:
8268	                    return 72;
8269	                    break;
8270	                case 26:
8271	                    return 72;
8272	                    break;
8273	                case 27:
8274	                    return 87;
8275	                    break;
8276	                case 28:
8277	                    // ignore whitespace
8278	                    break;
8279	                case 29:
8280	                    this.popState();return 54;
8281	                    break;
8282	                case 30:
8283	                    this.popState();return 33;
8284	                    break;
8285	                case 31:
8286	                    yy_.yytext = strip(1, 2).replace(/\\"/g, '"');return 80;
8287	                    break;
8288	                case 32:
8289	                    yy_.yytext = strip(1, 2).replace(/\\'/g, "'");return 80;
8290	                    break;
8291	                case 33:
8292	                    return 85;
8293	                    break;
8294	                case 34:
8295	                    return 82;
8296	                    break;
8297	                case 35:
8298	                    return 82;
8299	                    break;
8300	                case 36:
8301	                    return 83;
8302	                    break;
8303	                case 37:
8304	                    return 84;
8305	                    break;
8306	                case 38:
8307	                    return 81;
8308	                    break;
8309	                case 39:
8310	                    return 75;
8311	                    break;
8312	                case 40:
8313	                    return 77;
8314	                    break;
8315	                case 41:
8316	                    return 72;
8317	                    break;
8318	                case 42:
8319	                    yy_.yytext = yy_.yytext.replace(/\\([\\\]])/g, '$1');return 72;
8320	                    break;
8321	                case 43:
8322	                    return 'INVALID';
8323	                    break;
8324	                case 44:
8325	                    return 5;
8326	                    break;
8327	            }
8328	        };
8329	        lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/, /^(?:[^\x00]+)/, /^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/, /^(?:\{\{\{\{(?=[^
8329/]))/, /^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/, /^(?:[^\x00]+?(?=(\{\{\{\{)))/, /^(?:[\s\S]*?--(~)?\}\})/, /^(?:\()/, /^(?:\))/, /^(?:\{\{\{\{)/, /^(?:\}\}\}\})/, /^(?:\{\{(~)?>)/, /^(?:\{\{(~)?#>)/, /^(?:\{\{(~)?#\*?)/, /^(?:\{\{(~)?\/)/, /^(?:\{\{(~)?\^\s*(~)?\}\})/, /^(?:\{\{(~)?\s*else\s*(~)?\}\})/, /^(?:\{\{(~)?\^)/, /^(?:\{\{(~)?\s*else\b)/, /^(?:\{\{(~)?\{)/, /^(?:\{\{(~)?&)/, /^(?:\{\{(~)?!--)/, /^(?:\{\{(~)?![\s\S]*?\}\})/, /^(?:\{\{(~)?\*?)/, /^(?:=)/, /^(?:\.\.)/, /^(?:\.(?=([=~}\s\/.)|])))/, /^(?:[\/.])/, /^(?:\s+)/, /^(?:\}(~)?\}\})/, /^(?:(~)?\}\})/, /^(?:"(\\["]|[^"])*")/, /^(?:'(\\[']|[^'])*')/, /^(?:@)/, /^(?:true(?=([~}\s)])))/, /^(?:false(?=([~}\s)])))/, /^(?:undefined(?=([~}\s)])))/, /^(?:null(?=([~}\s)])))/, /^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/, /^(?:as\s+\|)/, /^(?:\|)/, /^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)|]))))/, /^(?:\[(\\\]|[^\]])*\])/, /^(?:.)/, /^(?:$)/];
8330	        lexer.conditions = { "mu": { "rules": [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44], "inclusive": false }, "emu": { "rules": [2], "inclusive": false }, "com": { "rules": [6], "inclusive": false }, "raw": { "rules": [3, 4, 5], "inclusive": false }, "INITIAL": { "rules": [0, 1, 44], "inclusive": true } };
8331	        return lexer;
vendor: 10,902 bytes, lines 8332-8709
8332	    })();
8333	    parser.lexer = lexer;
8334	    function Parser() {
8335	        this.yy = {};
8336	    }Parser.prototype = parser;parser.Parser = Parser;
8337	    return new Parser();
8338	})();exports["default"] = handlebars;
8339	module.exports = exports["default"];
8340
8341/***/ }),
8342/* 87 */
8343/***/ (function(module, exports, __webpack_require__) {
8344
8345	'use strict';
8346
8347	var _interopRequireDefault = __webpack_require__(1)['default'];
8348
8349	exports.__esModule = true;
8350
8351	var _visitor = __webpack_require__(88);
8352
8353	var _visitor2 = _interopRequireDefault(_visitor);
8354
8355	function WhitespaceControl() {
8356	  var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
8357
8358	  this.options = options;
8359	}
8360	WhitespaceControl.prototype = new _visitor2['default']();
8361
8362	WhitespaceControl.prototype.Program = function (program) {
8363	  var doStandalone = !this.options.ignoreStandalone;
8364
8365	  var isRoot = !this.isRootSeen;
8366	  this.isRootSeen = true;
8367
8368	  var body = program.body;
8369	  for (var i = 0, l = body.length; i < l; i++) {
8370	    var current = body[i],
8371	        strip = this.accept(current);
8372
8373	    if (!strip) {
8374	      continue;
8375	    }
8376
8377	    var _isPrevWhitespace = isPrevWhitespace(body, i, isRoot),
8378	        _isNextWhitespace = isNextWhitespace(body, i, isRoot),
8379	        openStandalone = strip.openStandalone && _isPrevWhitespace,
8380	        closeStandalone = strip.closeStandalone && _isNextWhitespace,
8381	        inlineStandalone = strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace;
8382
8383	    if (strip.close) {
8384	      omitRight(body, i, true);
8385	    }
8386	    if (strip.open) {
8387	      omitLeft(body, i, true);
8388	    }
8389
8390	    if (doStandalone && inlineStandalone) {
8391	      omitRight(body, i);
8392
8393	      if (omitLeft(body, i)) {
8394	        // If we are on a standalone node, save the indent info for partials
8395	        if (current.type === 'PartialStatement') {
8396	          // Pull out the whitespace from the final line
8397	          current.indent = /([ \t]+$)/.exec(body[i - 1].original)[1];
8398	        }
8399	      }
8400	    }
8401	    if (doStandalone && openStandalone) {
8402	      omitRight((current.program || current.inverse).body);
8403
8404	      // Strip out the previous content node if it's whitespace only
8405	      omitLeft(body, i);
8406	    }
8407	    if (doStandalone && closeStandalone) {
8408	      // Always strip the next node
8409	      omitRight(body, i);
8410
8411	      omitLeft((current.inverse || current.program).body);
8412	    }
8413	  }
8414
8415	  return program;
8416	};
8417
8418	WhitespaceControl.prototype.BlockStatement = WhitespaceControl.prototype.DecoratorBlock = WhitespaceControl.prototype.PartialBlockStatement = function (block) {
8419	  this.accept(block.program);
8420	  this.accept(block.inverse);
8421
8422	  // Find the inverse program that is involed with whitespace stripping.
8423	  var program = block.program || block.inverse,
8424	      inverse = block.program && block.inverse,
8425	      firstInverse = inverse,
8426	      lastInverse = inverse;
8427
8428	  if (inverse && inverse.chained) {
8429	    firstInverse = inverse.body[0].program;
8430
8431	    // Walk the inverse chain to find the last inverse that is actually in the chain.
8432	    while (lastInverse.chained) {
8433	      lastInverse = lastInverse.body[lastInverse.body.length - 1].program;
8434	    }
8435	  }
8436
8437	  var strip = {
8438	    open: block.openStrip.open,
8439	    close: block.closeStrip.close,
8440
8441	    // Determine the standalone candiacy. Basically flag our content as being possibly standalone
8442	    // so our parent can determine if we actually are standalone
8443	    openStandalone: isNextWhitespace(program.body),
8444	    closeStandalone: isPrevWhitespace((firstInverse || program).body)
8445	  };
8446
8447	  if (block.openStrip.close) {
8448	    omitRight(program.body, null, true);
8449	  }
8450
8451	  if (inverse) {
8452	    var inverseStrip = block.inverseStrip;
8453
8454	    if (inverseStrip.open) {
8455	      omitLeft(program.body, null, true);
8456	    }
8457
8458	    if (inverseStrip.close) {
8459	      omitRight(firstInverse.body, null, true);
8460	    }
8461	    if (block.closeStrip.open) {
8462	      omitLeft(lastInverse.body, null, true);
8463	    }
8464
8465	    // Find standalone else statments
8466	    if (!this.options.ignoreStandalone && isPrevWhitespace(program.body) && isNextWhitespace(firstInverse.body)) {
8467	      omitLeft(program.body);
8468	      omitRight(firstInverse.body);
8469	    }
8470	  } else if (block.closeStrip.open) {
8471	    omitLeft(program.body, null, true);
8472	  }
8473
8474	  return strip;
8475	};
8476
8477	WhitespaceControl.prototype.Decorator = WhitespaceControl.prototype.MustacheStatement = function (mustache) {
8478	  return mustache.strip;
8479	};
8480
8481	WhitespaceControl.prototype.PartialStatement = WhitespaceControl.prototype.CommentStatement = function (node) {
8482	  /* istanbul ignore next */
8483	  var strip = node.strip || {};
8484	  return {
8485	    inlineStandalone: true,
8486	    open: strip.open,
8487	    close: strip.close
8488	  };
8489	};
8490
8491	function isPrevWhitespace(body, i, isRoot) {
8492	  if (i === undefined) {
8493	    i = body.length;
8494	  }
8495
8496	  // Nodes that end with newlines are considered whitespace (but are special
8497	  // cased for strip operations)
8498	  var prev = body[i - 1],
8499	      sibling = body[i - 2];
8500	  if (!prev) {
8501	    return isRoot;
8502	  }
8503
8504	  if (prev.type === 'ContentStatement') {
8505	    return (sibling || !isRoot ? /\r?\n\s*?$/ : /(^|\r?\n)\s*?$/).test(prev.original);
8506	  }
8507	}
8508	function isNextWhitespace(body, i, isRoot) {
8509	  if (i === undefined) {
8510	    i = -1;
8511	  }
8512
8513	  var next = body[i + 1],
8514	      sibling = body[i + 2];
8515	  if (!next) {
8516	    return isRoot;
8517	  }
8518
8519	  if (next.type === 'ContentStatement') {
8520	    return (sibling || !isRoot ? /^\s*?\r?\n/ : /^\s*?(\r?\n|$)/).test(next.original);
8521	  }
8522	}
8523
8524	// Marks the node to the right of the position as omitted.
8525	// I.e. {{foo}}' ' will mark the ' ' node as omitted.
8526	//
8527	// If i is undefined, then the first child will be marked as such.
8528	//
8529	// If mulitple is truthy then all whitespace will be stripped out until non-whitespace
8530	// content is met.
8531	function omitRight(body, i, multiple) {
8532	  var current = body[i == null ? 0 : i + 1];
8533	  if (!current || current.type !== 'ContentStatement' || !multiple && current.rightStripped) {
8534	    return;
8535	  }
8536
8537	  var original = current.value;
8538	  current.value = current.value.replace(multiple ? /^\s+/ : /^[ \t]*\r?\n?/, '');
8539	  current.rightStripped = current.value !== original;
8540	}
8541
8542	// Marks the node to the left of the position as omitted.
8543	// I.e. ' '{{foo}} will mark the ' ' node as omitted.
8544	//
8545	// If i is undefined then the last child will be marked as such.
8546	//
8547	// If mulitple is truthy then all whitespace will be stripped out until non-whitespace
8548	// content is met.
8549	function omitLeft(body, i, multiple) {
8550	  var current = body[i == null ? body.length - 1 : i - 1];
8551	  if (!current || current.type !== 'ContentStatement' || !multiple && current.leftStripped) {
8552	    return;
8553	  }
8554
8555	  // We omit the last node if it's whitespace only and not preceded by a non-content node.
8556	  var original = current.value;
8557	  current.value = current.value.replace(multiple ? /\s+$/ : /[ \t]+$/, '');
8558	  current.leftStripped = current.value !== original;
8559	  return current.leftStripped;
8560	}
8561
8562	exports['default'] = WhitespaceControl;
8563	module.exports = exports['default'];
8564
8565/***/ }),
8566/* 88 */
8567/***/ (function(module, exports, __webpack_require__) {
8568
8569	'use strict';
8570
8571	var _interopRequireDefault = __webpack_require__(1)['default'];
8572
8573	exports.__esModule = true;
8574
8575	var _exception = __webpack_require__(6);
8576
8577	var _exception2 = _interopRequireDefault(_exception);
8578
8579	function Visitor() {
8580	  this.parents = [];
8581	}
8582
8583	Visitor.prototype = {
8584	  constructor: Visitor,
8585	  mutating: false,
8586
8587	  // Visits a given value. If mutating, will replace the value if necessary.
8588	  acceptKey: function acceptKey(node, name) {
8589	    var value = this.accept(node[name]);
8590	    if (this.mutating) {
8591	      // Hacky sanity check: This may have a few false positives for type for the helper
8592	      // methods but will generally do the right thing without a lot of overhead.
8593	      if (value && !Visitor.prototype[value.type]) {
8594	        throw new _exception2['default']('Unexpected node type "' + value.type + '" found when accepting ' + name + ' on ' + node.type);
8595	      }
8596	      node[name] = value;
8597	    }
8598	  },
8599
8600	  // Performs an accept operation with added sanity check to ensure
8601	  // required keys are not removed.
8602	  acceptRequired: function acceptRequired(node, name) {
8603	    this.acceptKey(node, name);
8604
8605	    if (!node[name]) {
8606	      throw new _exception2['default'](node.type + ' requires ' + name);
8607	    }
8608	  },
8609
8610	  // Traverses a given array. If mutating, empty respnses will be removed
8611	  // for child elements.
8612	  acceptArray: function acceptArray(array) {
8613	    for (var i = 0, l = array.length; i < l; i++) {
8614	      this.acceptKey(array, i);
8615
8616	      if (!array[i]) {
8617	        array.splice(i, 1);
8618	        i--;
8619	        l--;
8620	      }
8621	    }
8622	  },
8623
8624	  accept: function accept(object) {
8625	    if (!object) {
8626	      return;
8627	    }
8628
8629	    /* istanbul ignore next: Sanity code */
8630	    if (!this[object.type]) {
8631	      throw new _exception2['default']('Unknown type: ' + object.type, object);
8632	    }
8633
8634	    if (this.current) {
8635	      this.parents.unshift(this.current);
8636	    }
8637	    this.current = object;
8638
8639	    var ret = this[object.type](object);
8640
8641	    this.current = this.parents.shift();
8642
8643	    if (!this.mutating || ret) {
8644	      return ret;
8645	    } else if (ret !== false) {
8646	      return object;
8647	    }
8648	  },
8649
8650	  Program: function Program(program) {
8651	    this.acceptArray(program.body);
8652	  },
8653
8654	  MustacheStatement: visitSubExpression,
8655	  Decorator: visitSubExpression,
8656
8657	  BlockStatement: visitBlock,
8658	  DecoratorBlock: visitBlock,
8659
8660	  PartialStatement: visitPartial,
8661	  PartialBlockStatement: function PartialBlockStatement(partial) {
8662	    visitPartial.call(this, partial);
8663
8664	    this.acceptKey(partial, 'program');
8665	  },
8666
8667	  ContentStatement: function ContentStatement() /* content */{},
8668	  CommentStatement: function CommentStatement() /* comment */{},
8669
8670	  SubExpression: visitSubExpression,
8671
8672	  PathExpression: function PathExpression() /* path */{},
8673
8674	  StringLiteral: function StringLiteral() /* string */{},
8675	  NumberLiteral: function NumberLiteral() /* number */{},
8676	  BooleanLiteral: function BooleanLiteral() /* bool */{},
8677	  UndefinedLiteral: function UndefinedLiteral() /* literal */{},
8678	  NullLiteral: function NullLiteral() /* literal */{},
8679
8680	  Hash: function Hash(hash) {
8681	    this.acceptArray(hash.pairs);
8682	  },
8683	  HashPair: function HashPair(pair) {
8684	    this.acceptRequired(pair, 'value');
8685	  }
8686	};
8687
8688	function visitSubExpression(mustache) {
8689	  this.acceptRequired(mustache, 'path');
8690	  this.acceptArray(mustache.params);
8691	  this.acceptKey(mustache, 'hash');
8692	}
8693	function visitBlock(block) {
8694	  visitSubExpression.call(this, block);
8695
8696	  this.acceptKey(block, 'program');
8697	  this.acceptKey(block, 'inverse');
8698	}
8699	function visitPartial(partial) {
8700	  this.acceptRequired(partial, 'name');
8701	  this.acceptArray(partial.params);
8702	  this.acceptKey(partial, 'hash');
8703	}
8704
8705	exports['default'] = Visitor;
8706	module.exports = exports['default'];
8707
8708/***/ }),
8709/* 89
vendor: 5,593 bytes, lines 8709-8940
8709 */
8710/***/ (function(module, exports, __webpack_require__) {
8711
8712	'use strict';
8713
8714	var _interopRequireDefault = __webpack_require__(1)['default'];
8715
8716	exports.__esModule = true;
8717	exports.SourceLocation = SourceLocation;
8718	exports.id = id;
8719	exports.stripFlags = stripFlags;
8720	exports.stripComment = stripComment;
8721	exports.preparePath = preparePath;
8722	exports.prepareMustache = prepareMustache;
8723	exports.prepareRawBlock = prepareRawBlock;
8724	exports.prepareBlock = prepareBlock;
8725	exports.prepareProgram = prepareProgram;
8726	exports.preparePartialBlock = preparePartialBlock;
8727
8728	var _exception = __webpack_require__(6);
8729
8730	var _exception2 = _interopRequireDefault(_exception);
8731
8732	function validateClose(open, close) {
8733	  close = close.path ? close.path.original : close;
8734
8735	  if (open.path.original !== close) {
8736	    var errorNode = { loc: open.path.loc };
8737
8738	    throw new _exception2['default'](open.path.original + " doesn't match " + close, errorNode);
8739	  }
8740	}
8741
8742	function SourceLocation(source, locInfo) {
8743	  this.source = source;
8744	  this.start = {
8745	    line: locInfo.first_line,
8746	    column: locInfo.first_column
8747	  };
8748	  this.end = {
8749	    line: locInfo.last_line,
8750	    column: locInfo.last_column
8751	  };
8752	}
8753
8754	function id(token) {
8755	  if (/^\[.*\]$/.test(token)) {
8756	    return token.substring(1, token.length - 1);
8757	  } else {
8758	    return token;
8759	  }
8760	}
8761
8762	function stripFlags(open, close) {
8763	  return {
8764	    open: open.charAt(2) === '~',
8765	    close: close.charAt(close.length - 3) === '~'
8766	  };
8767	}
8768
8769	function stripComment(comment) {
8770	  return comment.replace(/^\{\{~?!-?-?/, '').replace(/-?-?~?\}\}$/, '');
8771	}
8772
8773	function preparePath(data, parts, loc) {
8774	  loc = this.locInfo(loc);
8775
8776	  var original = data ? '@' : '',
8777	      dig = [],
8778	      depth = 0;
8779
8780	  for (var i = 0, l = parts.length; i < l; i++) {
8781	    var part = parts[i].part,
8782
8783	    // If we have [] syntax then we do not treat path references as operators,
8784	    // i.e. foo.[this] resolves to approximately context.foo['this']
8785	    isLiteral = parts[i].original !== part;
8786	    original += (parts[i].separator || '') + part;
8787
8788	    if (!isLiteral && (part === '..' || part === '.' || part === 'this')) {
8789	      if (dig.length > 0) {
8790	        throw new _exception2['default']('Invalid path: ' + original, { loc: loc });
8791	      } else if (part === '..') {
8792	        depth++;
8793	      }
8794	    } else {
8795	      dig.push(part);
8796	    }
8797	  }
8798
8799	  return {
8800	    type: 'PathExpression',
8801	    data: data,
8802	    depth: depth,
8803	    parts: dig,
8804	    original: original,
8805	    loc: loc
8806	  };
8807	}
8808
8809	function prepareMustache(path, params, hash, open, strip, locInfo) {
8810	  // Must use charAt to support IE pre-10
8811	  var escapeFlag = open.charAt(3) || open.charAt(2),
8812	      escaped = escapeFlag !== '{' && escapeFlag !== '&';
8813
8814	  var decorator = /\*/.test(open);
8815	  return {
8816	    type: decorator ? 'Decorator' : 'MustacheStatement',
8817	    path: path,
8818	    params: params,
8819	    hash: hash,
8820	    escaped: escaped,
8821	    strip: strip,
8822	    loc: this.locInfo(locInfo)
8823	  };
8824	}
8825
8826	function prepareRawBlock(openRawBlock, contents, close, locInfo) {
8827	  validateClose(openRawBlock, close);
8828
8829	  locInfo = this.locInfo(locInfo);
8830	  var program = {
8831	    type: 'Program',
8832	    body: contents,
8833	    strip: {},
8834	    loc: locInfo
8835	  };
8836
8837	  return {
8838	    type: 'BlockStatement',
8839	    path: openRawBlock.path,
8840	    params: openRawBlock.params,
8841	    hash: openRawBlock.hash,
8842	    program: program,
8843	    openStrip: {},
8844	    inverseStrip: {},
8845	    closeStrip: {},
8846	    loc: locInfo
8847	  };
8848	}
8849
8850	function prepareBlock(openBlock, program, inverseAndProgram, close, inverted, locInfo) {
8851	  if (close && close.path) {
8852	    validateClose(openBlock, close);
8853	  }
8854
8855	  var decorator = /\*/.test(openBlock.open);
8856
8857	  program.blockParams = openBlock.blockParams;
8858
8859	  var inverse = undefined,
8860	      inverseStrip = undefined;
8861
8862	  if (inverseAndProgram) {
8863	    if (decorator) {
8864	      throw new _exception2['default']('Unexpected inverse block on decorator', inverseAndProgram);
8865	    }
8866
8867	    if (inverseAndProgram.chain) {
8868	      inverseAndProgram.program.body[0].closeStrip = close.strip;
8869	    }
8870
8871	    inverseStrip = inverseAndProgram.strip;
8872	    inverse = inverseAndProgram.program;
8873	  }
8874
8875	  if (inverted) {
8876	    inverted = inverse;
8877	    inverse = program;
8878	    program = inverted;
8879	  }
8880
8881	  return {
8882	    type: decorator ? 'DecoratorBlock' : 'BlockStatement',
8883	    path: openBlock.path,
8884	    params: openBlock.params,
8885	    hash: openBlock.hash,
8886	    program: program,
8887	    inverse: inverse,
8888	    openStrip: openBlock.strip,
8889	    inverseStrip: inverseStrip,
8890	    closeStrip: close && close.strip,
8891	    loc: this.locInfo(locInfo)
8892	  };
8893	}
8894
8895	function prepareProgram(statements, loc) {
8896	  if (!loc && statements.length) {
8897	    var firstLoc = statements[0].loc,
8898	        lastLoc = statements[statements.length - 1].loc;
8899
8900	    /* istanbul ignore else */
8901	    if (firstLoc && lastLoc) {
8902	      loc = {
8903	        source: firstLoc.source,
8904	        start: {
8905	          line: firstLoc.start.line,
8906	          column: firstLoc.start.column
8907	        },
8908	        end: {
8909	          line: lastLoc.end.line,
8910	          column: lastLoc.end.column
8911	        }
8912	      };
8913	    }
8914	  }
8915
8916	  return {
8917	    type: 'Program',
8918	    body: statements,
8919	    strip: {},
8920	    loc: loc
8921	  };
8922	}
8923
8924	function preparePartialBlock(open, program, close, locInfo) {
8925	  validateClose(open, close);
8926
8927	  return {
8928	    type: 'PartialBlockStatement',
8929	    name: open.path,
8930	    params: open.params,
8931	    hash: open.hash,
8932	    program: program,
8933	    openStrip: open.strip,
8934	    closeStrip: close && close.strip,
8935	    loc: this.locInfo(locInfo)
8936	  };
8937	}
8938
8939/***/ }),
8940/* 
894090 */
8941/***/ (function(module, exports, __webpack_require__) {
8942
8943	/* eslint-disable new-cap */
8944
8945	'use strict';
8946
8947	var _Object$create = __webpack_require__(74)['default'];
8948
8949	var _interopRequireDefault = __webpack_require__(1)['default'];
8950
8951	exports.__esModule = true;
8952	exports.Compiler = Compiler;
8953	exports.precompile = precompile;
8954	exports.compile = compile;
8955
8956	var _exception = __webpack_require__(6);
8957
8958	var _exception2 = _interopRequireDefault(_exception);
8959
8960	var _utils = __webpack_require__(5);
8961
8962	var _ast = __webpack_require__(84
vendor: 15,890 bytes, lines 8962-9511
8962);
8963
8964	var _ast2 = _interopRequireDefault(_ast);
8965
8966	var slice = [].slice;
8967
8968	function Compiler() {}
8969
8970	// the foundHelper register will disambiguate helper lookup from finding a
8971	// function in a context. This is necessary for mustache compatibility, which
8972	// requires that context functions in blocks are evaluated by blockHelperMissing,
8973	// and then proceed as if the resulting value was provided to blockHelperMissing.
8974
8975	Compiler.prototype = {
8976	  compiler: Compiler,
8977
8978	  equals: function equals(other) {
8979	    var len = this.opcodes.length;
8980	    if (other.opcodes.length !== len) {
8981	      return false;
8982	    }
8983
8984	    for (var i = 0; i < len; i++) {
8985	      var opcode = this.opcodes[i],
8986	          otherOpcode = other.opcodes[i];
8987	      if (opcode.opcode !== otherOpcode.opcode || !argEquals(opcode.args, otherOpcode.args)) {
8988	        return false;
8989	      }
8990	    }
8991
8992	    // We know that length is the same between the two arrays because they are directly tied
8993	    // to the opcode behavior above.
8994	    len = this.children.length;
8995	    for (var i = 0; i < len; i++) {
8996	      if (!this.children[i].equals(other.children[i])) {
8997	        return false;
8998	      }
8999	    }
9000
9001	    return true;
9002	  },
9003
9004	  guid: 0,
9005
9006	  compile: function compile(program, options) {
9007	    this.sourceNode = [];
9008	    this.opcodes = [];
9009	    this.children = [];
9010	    this.options = options;
9011	    this.stringParams = options.stringParams;
9012	    this.trackIds = options.trackIds;
9013
9014	    options.blockParams = options.blockParams || [];
9015
9016	    options.knownHelpers = _utils.extend(_Object$create(null), {
9017	      helperMissing: true,
9018	      blockHelperMissing: true,
9019	      each: true,
9020	      'if': true,
9021	      unless: true,
9022	      'with': true,
9023	      log: true,
9024	      lookup: true
9025	    }, options.knownHelpers);
9026
9027	    return this.accept(program);
9028	  },
9029
9030	  compileProgram: function compileProgram(program) {
9031	    var childCompiler = new this.compiler(),
9032	        // eslint-disable-line new-cap
9033	    result = childCompiler.compile(program, this.options),
9034	        guid = this.guid++;
9035
9036	    this.usePartial = this.usePartial || result.usePartial;
9037
9038	    this.children[guid] = result;
9039	    this.useDepths = this.useDepths || result.useDepths;
9040
9041	    return guid;
9042	  },
9043
9044	  accept: function accept(node) {
9045	    /* istanbul ignore next: Sanity code */
9046	    if (!this[node.type]) {
9047	      throw new _exception2['default']('Unknown type: ' + node.type, node);
9048	    }
9049
9050	    this.sourceNode.unshift(node);
9051	    var ret = this[node.type](node);
9052	    this.sourceNode.shift();
9053	    return ret;
9054	  },
9055
9056	  Program: function Program(program) {
9057	    this.options.blockParams.unshift(program.blockParams);
9058
9059	    var body = program.body,
9060	        bodyLength = body.length;
9061	    for (var i = 0; i < bodyLength; i++) {
9062	      this.accept(body[i]);
9063	    }
9064
9065	    this.options.blockParams.shift();
9066
9067	    this.isSimple = bodyLength === 1;
9068	    this.blockParams = program.blockParams ? program.blockParams.length : 0;
9069
9070	    return this;
9071	  },
9072
9073	  BlockStatement: function BlockStatement(block) {
9074	    transformLiteralToPath(block);
9075
9076	    var program = block.program,
9077	        inverse = block.inverse;
9078
9079	    program = program && this.compileProgram(program);
9080	    inverse = inverse && this.compileProgram(inverse);
9081
9082	    var type = this.classifySexpr(block);
9083
9084	    if (type === 'helper') {
9085	      this.helperSexpr(block, program, inverse);
9086	    } else if (type === 'simple') {
9087	      this.simpleSexpr(block);
9088
9089	      // now that the simple mustache is resolved, we need to
9090	      // evaluate it by executing `blockHelperMissing`
9091	      this.opcode('pushProgram', program);
9092	      this.opcode('pushProgram', inverse);
9093	      this.opcode('emptyHash');
9094	      this.opcode('blockValue', block.path.original);
9095	    } else {
9096	      this.ambiguousSexpr(block, program, inverse);
9097
9098	      // now that the simple mustache is resolved, we need to
9099	      // evaluate it by executing `blockHelperMissing`
9100	      this.opcode('pushProgram', program);
9101	      this.opcode('pushProgram', inverse);
9102	      this.opcode('emptyHash');
9103	      this.opcode('ambiguousBlockValue');
9104	    }
9105
9106	    this.opcode('append');
9107	  },
9108
9109	  DecoratorBlock: function DecoratorBlock(decorator) {
9110	    var program = decorator.program && this.compileProgram(decorator.program);
9111	    var params = this.setupFullMustacheParams(decorator, program, undefined),
9112	        path = decorator.path;
9113
9114	    this.useDecorators = true;
9115	    this.opcode('registerDecorator', params.length, path.original);
9116	  },
9117
9118	  PartialStatement: function PartialStatement(partial) {
9119	    this.usePartial = true;
9120
9121	    var program = partial.program;
9122	    if (program) {
9123	      program = this.compileProgram(partial.program);
9124	    }
9125
9126	    var params = partial.params;
9127	    if (params.length > 1) {
9128	      throw new _exception2['default']('Unsupported number of partial arguments: ' + params.length, partial);
9129	    } else if (!params.length) {
9130	      if (this.options.explicitPartialContext) {
9131	        this.opcode('pushLiteral', 'undefined');
9132	      } else {
9133	        params.push({ type: 'PathExpression', parts: [], depth: 0 });
9134	      }
9135	    }
9136
9137	    var partialName = partial.name.original,
9138	        isDynamic = partial.name.type === 'SubExpression';
9139	    if (isDynamic) {
9140	      this.accept(partial.name);
9141	    }
9142
9143	    this.setupFullMustacheParams(partial, program, undefined, true);
9144
9145	    var indent = partial.indent || '';
9146	    if (this.options.preventIndent && indent) {
9147	      this.opcode('appendContent', indent);
9148	      indent = '';
9149	    }
9150
9151	    this.opcode('invokePartial', isDynamic, partialName, indent);
9152	    this.opcode('append');
9153	  },
9154	  PartialBlockStatement: function PartialBlockStatement(partialBlock) {
9155	    this.PartialStatement(partialBlock);
9156	  },
9157
9158	  MustacheStatement: function MustacheStatement(mustache) {
9159	    this.SubExpression(mustache);
9160
9161	    if (mustache.escaped && !this.options.noEscape) {
9162	      this.opcode('appendEscaped');
9163	    } else {
9164	      this.opcode('append');
9165	    }
9166	  },
9167	  Decorator: function Decorator(decorator) {
9168	    this.DecoratorBlock(decorator);
9169	  },
9170
9171	  ContentStatement: function ContentStatement(content) {
9172	    if (content.value) {
9173	      this.opcode('appendContent', content.value);
9174	    }
9175	  },
9176
9177	  CommentStatement: function CommentStatement() {},
9178
9179	  SubExpression: function SubExpression(sexpr) {
9180	    transformLiteralToPath(sexpr);
9181	    var type = this.classifySexpr(sexpr);
9182
9183	    if (type === 'simple') {
9184	      this.simpleSexpr(sexpr);
9185	    } else if (type === 'helper') {
9186	      this.helperSexpr(sexpr);
9187	    } else {
9188	      this.ambiguousSexpr(sexpr);
9189	    }
9190	  },
9191	  ambiguousSexpr: function ambiguousSexpr(sexpr, program, inverse) {
9192	    var path = sexpr.path,
9193	        name = path.parts[0],
9194	        isBlock = program != null || inverse != null;
9195
9196	    this.opcode('getContext', path.depth);
9197
9198	    this.opcode('pushProgram', program);
9199	    this.opcode('pushProgram', inverse);
9200
9201	    path.strict = true;
9202	    this.accept(path);
9203
9204	    this.opcode('invokeAmbiguous', name, isBlock);
9205	  },
9206
9207	  simpleSexpr: function simpleSexpr(sexpr) {
9208	    var path = sexpr.path;
9209	    path.strict = true;
9210	    this.accept(path);
9211	    this.opcode('resolvePossibleLambda');
9212	  },
9213
9214	  helperSexpr: function helperSexpr(sexpr, program, inverse) {
9215	    var params = this.setupFullMustacheParams(sexpr, program, inverse),
9216	        path = sexpr.path,
9217	        name = path.parts[0];
9218
9219	    if (this.options.knownHelpers[name]) {
9220	      this.opcode('invokeKnownHelper', params.length, name);
9221	    } else if (this.options.knownHelpersOnly) {
9222	      throw new _exception2['default']('You specified knownHelpersOnly, but used the unknown helper ' + name, sexpr);
9223	    } else {
9224	      path.strict = true;
9225	      path.falsy = true;
9226
9227	      this.accept(path);
9228	      this.opcode('invokeHelper', params.length, path.original, _ast2['default'].helpers.simpleId(path));
9229	    }
9230	  },
9231
9232	  PathExpression: function PathExpression(path) {
9233	    this.addDepth(path.depth);
9234	    this.opcode('getContext', path.depth);
9235
9236	    var name = path.parts[0],
9237	        scoped = _ast2['default'].helpers.scopedId(path),
9238	        blockParamId = !path.depth && !scoped && this.blockParamIndex(name);
9239
9240	    if (blockParamId) {
9241	      this.opcode('lookupBlockParam', blockParamId, path.parts);
9242	    } else if (!name) {
9243	      // Context reference, i.e. `{{foo .}}` or `{{foo ..}}`
9244	      this.opcode('pushContext');
9245	    } else if (path.data) {
9246	      this.options.data = true;
9247	      this.opcode('lookupData', path.depth, path.parts, path.strict);
9248	    } else {
9249	      this.opcode('lookupOnContext', path.parts, path.falsy, path.strict, scoped);
9250	    }
9251	  },
9252
9253	  StringLiteral: function StringLiteral(string) {
9254	    this.opcode('pushString', string.value);
9255	  },
9256
9257	  NumberLiteral: function NumberLiteral(number) {
9258	    this.opcode('pushLiteral', number.value);
9259	  },
9260
9261	  BooleanLiteral: function BooleanLiteral(bool) {
9262	    this.opcode('pushLiteral', bool.value);
9263	  },
9264
9265	  UndefinedLiteral: function UndefinedLiteral() {
9266	    this.opcode('pushLiteral', 'undefined');
9267	  },
9268
9269	  NullLiteral: function NullLiteral() {
9270	    this.opcode('pushLiteral', 'null');
9271	  },
9272
9273	  Hash: function Hash(hash) {
9274	    var pairs = hash.pairs,
9275	        i = 0,
9276	        l = pairs.length;
9277
9278	    this.opcode('pushHash');
9279
9280	    for (; i < l; i++) {
9281	      this.pushParam(pairs[i].value);
9282	    }
9283	    while (i--) {
9284	      this.opcode('assignToHash', pairs[i].key);
9285	    }
9286	    this.opcode('popHash');
9287	  },
9288
9289	  // HELPERS
9290	  opcode: function opcode(name) {
9291	    this.opcodes.push({
9292	      opcode: name,
9293	      args: slice.call(arguments, 1),
9294	      loc: this.sourceNode[0].loc
9295	    });
9296	  },
9297
9298	  addDepth: function addDepth(depth) {
9299	    if (!depth) {
9300	      return;
9301	    }
9302
9303	    this.useDepths = true;
9304	  },
9305
9306	  classifySexpr: function classifySexpr(sexpr) {
9307	    var isSimple = _ast2['default'].helpers.simpleId(sexpr.path);
9308
9309	    var isBlockParam = isSimple && !!this.blockParamIndex(sexpr.path.parts[0]);
9310
9311	    // a mustache is an eligible helper if:
9312	    // * its id is simple (a single part, not `this` or `..`)
9313	    var isHelper = !isBlockParam && _ast2['default'].helpers.helperExpression(sexpr);
9314
9315	    // if a mustache is an eligible helper but not a definite
9316	    // helper, it is ambiguous, and will be resolved in a later
9317	    // pass or at runtime.
9318	    var isEligible = !isBlockParam && (isHelper || isSimple);
9319
9320	    // if ambiguous, we can possibly resolve the ambiguity now
9321	    // An eligible helper is one that does not have a complex path, i.e. `this.foo`, `../foo` etc.
9322	    if (isEligible && !isHelper) {
9323	      var _name = sexpr.path.parts[0],
9324	          options = this.options;
9325	      if (options.knownHelpers[_name]) {
9326	        isHelper = true;
9327	      } else if (options.knownHelpersOnly) {
9328	        isEligible = false;
9329	      }
9330	    }
9331
9332	    if (isHelper) {
9333	      return 'helper';
9334	    } else if (isEligible) {
9335	      return 'ambiguous';
9336	    } else {
9337	      return 'simple';
9338	    }
9339	  },
9340
9341	  pushParams: function pushParams(params) {
9342	    for (var i = 0, l = params.length; i < l; i++) {
9343	      this.pushParam(params[i]);
9344	    }
9345	  },
9346
9347	  pushParam: function pushParam(val) {
9348	    var value = val.value != null ? val.value : val.original || '';
9349
9350	    if (this.stringParams) {
9351	      if (value.replace) {
9352	        value = value.replace(/^(\.?\.\/)*/g, '').replace(/\//g, '.');
9353	      }
9354
9355	      if (val.depth) {
9356	        this.addDepth(val.depth);
9357	      }
9358	      this.opcode('getContext', val.depth || 0);
9359	      this.opcode('pushStringParam', value, val.type);
9360
9361	      if (val.type === 'SubExpression') {
9362	        // SubExpressions get evaluated and passed in
9363	        // in string params mode.
9364	        this.accept(val);
9365	      }
9366	    } else {
9367	      if (this.trackIds) {
9368	        var blockParamIndex = undefined;
9369	        if (val.parts && !_ast2['default'].helpers.scopedId(val) && !val.depth) {
9370	          blockParamIndex = this.blockParamIndex(val.parts[0]);
9371	        }
9372	        if (blockParamIndex) {
9373	          var blockParamChild = val.parts.slice(1).join('.');
9374	          this.opcode('pushId', 'BlockParam', blockParamIndex, blockParamChild);
9375	        } else {
9376	          value = val.original || value;
9377	          if (value.replace) {
9378	            value = value.replace(/^this(?:\.|$)/, '').replace(/^\.\//, '').replace(/^\.$/, '');
9379	          }
9380
9381	          this.opcode('pushId', val.type, value);
9382	        }
9383	      }
9384	      this.accept(val);
9385	    }
9386	  },
9387
9388	  setupFullMustacheParams: function setupFullMustacheParams(sexpr, program, inverse, omitEmpty) {
9389	    var params = sexpr.params;
9390	    this.pushParams(params);
9391
9392	    this.opcode('pushProgram', program);
9393	    this.opcode('pushProgram', inverse);
9394
9395	    if (sexpr.hash) {
9396	      this.accept(sexpr.hash);
9397	    } else {
9398	      this.opcode('emptyHash', omitEmpty);
9399	    }
9400
9401	    return params;
9402	  },
9403
9404	  blockParamIndex: function blockParamIndex(name) {
9405	    for (var depth = 0, len = this.options.blockParams.length; depth < len; depth++) {
9406	      var blockParams = this.options.blockParams[depth],
9407	          param = blockParams && _utils.indexOf(blockParams, name);
9408	      if (blockParams && param >= 0) {
9409	        return [depth, param];
9410	      }
9411	    }
9412	  }
9413	};
9414
9415	function precompile(input, options, env) {
9416	  if (input == null || typeof input !== 'string' && input.type !== 'Program') {
9417	    throw new _exception2['default']('You must pass a string or Handlebars AST to Handlebars.precompile. You passed ' + input);
9418	  }
9419
9420	  options = options || {};
9421	  if (!('data' in options)) {
9422	    options.data = true;
9423	  }
9424	  if (options.compat) {
9425	    options.useDepths = true;
9426	  }
9427
9428	  var ast = env.parse(input, options),
9429	      environment = new env.Compiler().compile(ast, options);
9430	  return new env.JavaScriptCompiler().compile(environment, options);
9431	}
9432
9433	function compile(input, options, env) {
9434	  if (options === undefined) options = {};
9435
9436	  if (input == null || typeof input !== 'string' && input.type !== 'Program') {
9437	    throw new _exception2['default']('You must pass a string or Handlebars AST to Handlebars.compile. You passed ' + input);
9438	  }
9439
9440	  options = _utils.extend({}, options);
9441	  if (!('data' in options)) {
9442	    options.data = true;
9443	  }
9444	  if (options.compat) {
9445	    options.useDepths = true;
9446	  }
9447
9448	  var compiled = undefined;
9449
9450	  function compileInput() {
9451	    var ast = env.parse(input, options),
9452	        environment = new env.Compiler().compile(ast, options),
9453	        templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true);
9454	    return env.template(templateSpec);
9455	  }
9456
9457	  // Template is only compiled on first use and cached after that point.
9458	  function ret(context, execOptions) {
9459	    if (!compiled) {
9460	      compiled = compileInput();
9461	    }
9462	    return compiled.call(this, context, execOptions);
9463	  }
9464	  ret._setup = function (setupOptions) {
9465	    if (!compiled) {
9466	      compiled = compileInput();
9467	    }
9468	    return compiled._setup(setupOptions);
9469	  };
9470	  ret._child = function (i, data, blockParams, depths) {
9471	    if (!compiled) {
9472	      compiled = compileInput();
9473	    }
9474	    return compiled._child(i, data, blockParams, depths);
9475	  };
9476	  return ret;
9477	}
9478
9479	function argEquals(a, b) {
9480	  if (a === b) {
9481	    return true;
9482	  }
9483
9484	  if (_utils.isArray(a) && _utils.isArray(b) && a.length === b.length) {
9485	    for (var i = 0; i < a.length; i++) {
9486	      if (!argEquals(a[i], b[i])) {
9487	        return false;
9488	      }
9489	    }
9490	    return true;
9491	  }
9492	}
9493
9494	function transformLiteralToPath(sexpr) {
9495	  if (!sexpr.path.parts) {
9496	    var literal = sexpr.path;
9497	    // Casting to string here to make false and 0 literal values play nicely with the rest
9498	    // of the system.
9499	    sexpr.path = {
9500	      type: 'PathExpression',
9501	      data: false,
9502	      depth: 0,
9503	      parts: [literal.original + ''],
9504	      original: literal.original + '',
9505	      loc: literal.loc
9506	    };
9507	  }
9508	}
9509
9510/***/ }),
9511/* 9
vendor: 5,335 bytes, lines 9511-9680
95111 */
9512/***/ (function(module, exports, __webpack_require__) {
9513
9514	'use strict';
9515
9516	var _Object$keys = __webpack_require__(60)['default'];
9517
9518	var _interopRequireDefault = __webpack_require__(1)['default'];
9519
9520	exports.__esModule = true;
9521
9522	var _base = __webpack_require__(4);
9523
9524	var _exception = __webpack_require__(6);
9525
9526	var _exception2 = _interopRequireDefault(_exception);
9527
9528	var _utils = __webpack_require__(5);
9529
9530	var _codeGen = __webpack_require__(92);
9531
9532	var _codeGen2 = _interopRequireDefault(_codeGen);
9533
9534	function Literal(value) {
9535	  this.value = value;
9536	}
9537
9538	function JavaScriptCompiler() {}
9539
9540	JavaScriptCompiler.prototype = {
9541	  // PUBLIC API: You can override these methods in a subclass to provide
9542	  // alternative compiled forms for name lookup and buffering semantics
9543	  nameLookup: function nameLookup(parent, name /*,  type */) {
9544	    return this.internalNameLookup(parent, name);
9545	  },
9546	  depthedLookup: function depthedLookup(name) {
9547	    return [this.aliasable('container.lookup'), '(depths, ', JSON.stringify(name), ')'];
9548	  },
9549
9550	  compilerInfo: function compilerInfo() {
9551	    var revision = _base.COMPILER_REVISION,
9552	        versions = _base.REVISION_CHANGES[revision];
9553	    return [revision, versions];
9554	  },
9555
9556	  appendToBuffer: function appendToBuffer(source, location, explicit) {
9557	    // Force a source as this simplifies the merge logic.
9558	    if (!_utils.isArray(source)) {
9559	      source = [source];
9560	    }
9561	    source = this.source.wrap(source, location);
9562
9563	    if (this.environment.isSimple) {
9564	      return ['return ', source, ';'];
9565	    } else if (explicit) {
9566	      // This is a case where the buffer operation occurs as a child of another
9567	      // construct, generally braces. We have to explicitly output these buffer
9568	      // operations to ensure that the emitted code goes in the correct location.
9569	      return ['buffer += ', source, ';'];
9570	    } else {
9571	      source.appendToBuffer = true;
9572	      return source;
9573	    }
9574	  },
9575
9576	  initializeBuffer: function initializeBuffer() {
9577	    return this.quotedString('');
9578	  },
9579	  // END PUBLIC API
9580	  internalNameLookup: function internalNameLookup(parent, name) {
9581	    this.lookupPropertyFunctionIsUsed = true;
9582	    return ['lookupProperty(', parent, ',', JSON.stringify(name), ')'];
9583	  },
9584
9585	  lookupPropertyFunctionIsUsed: false,
9586
9587	  compile: function compile(environment, options, context, asObject) {
9588	    this.environment = environment;
9589	    this.options = options;
9590	    this.stringParams = this.options.stringParams;
9591	    this.trackIds = this.options.trackIds;
9592	    this.precompile = !asObject;
9593
9594	    this.name = this.environment.name;
9595	    this.isChild = !!context;
9596	    this.context = context || {
9597	      decorators: [],
9598	      programs: [],
9599	      environments: []
9600	    };
9601
9602	    this.preamble();
9603
9604	    this.stackSlot = 0;
9605	    this.stackVars = [];
9606	    this.aliases = {};
9607	    this.registers = { list: [] };
9608	    this.hashes = [];
9609	    this.compileStack = [];
9610	    this.inlineStack = [];
9611	    this.blockParams = [];
9612
9613	    this.compileChildren(environment, options);
9614
9615	    this.useDepths = this.useDepths || environment.useDepths || environment.useDecorators || this.options.compat;
9616	    this.useBlockParams = this.useBlockParams || environment.useBlockParams;
9617
9618	    var opcodes = environment.opcodes,
9619	        opcode = undefined,
9620	        firstLoc = undefined,
9621	        i = undefined,
9622	        l = undefined;
9623
9624	    for (i = 0, l = opcodes.length; i < l; i++) {
9625	      opcode = opcodes[i];
9626
9627	      this.source.currentLocation = opcode.loc;
9628	      firstLoc = firstLoc || opcode.loc;
9629	      this[opcode.opcode].apply(this, opcode.args);
9630	    }
9631
9632	    // Flush any trailing content that might be pending.
9633	    this.source.currentLocation = firstLoc;
9634	    this.pushSource('');
9635
9636	    /* istanbul ignore next */
9637	    if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {
9638	      throw new _exception2['default']('Compile completed with content left on stack');
9639	    }
9640
9641	    if (!this.decorators.isEmpty()) {
9642	      this.useDecorators = true;
9643
9644	      this.decorators.prepend(['var decorators = container.decorators, ', this.lookupPropertyFunctionVarDeclaration(), ';\n']);
9645	      this.decorators.push('return fn;');
9646
9647	      if (asObject) {
9648	        this.decorators = Function.apply(this, ['fn', 'props', 'container', 'depth0', 'data', 'blockParams', 'depths', this.decorators.merge()]);
9649	      } else {
9650	        this.decorators.prepend('function(fn, props, container, depth0, data, blockParams, depths) {\n');
9651	        this.decorators.push('}\n');
9652	        this.decorators = this.decorators.merge();
9653	      }
9654	    } else {
9655	      this.decorators = undefined;
9656	    }
9657
9658	    var fn = this.createFunctionContext(asObject);
9659	    if (!this.isChild) {
9660	      var ret = {
9661	        compiler: this.compilerInfo(),
9662	        main: fn
9663	      };
9664
9665	      if (this.decorators) {
9666	        ret.main_d = this.decorators; // eslint-disable-line camelcase
9667	        ret.useDecorators = true;
9668	      }
9669
9670	      var _context = this.context;
9671	      var programs = _context.programs;
9672	      var decorators = _context.decorators;
9673
9674	      for (i = 0, l = programs.length; i < l; i++) {
9675	        if (programs[i]) {
9676	          ret[i] = programs[i];
9677	          if (decorators[i]) {
9678	            ret[i + '_d'] = decorators[i];
9679	            ret.useDecorators = true;
9680	          }
vendor: 10,178 bytes, lines 9680-10006
9680
9681	        }
9682	      }
9683
9684	      if (this.environment.usePartial) {
9685	        ret.usePartial = true;
9686	      }
9687	      if (this.options.data) {
9688	        ret.useData = true;
9689	      }
9690	      if (this.useDepths) {
9691	        ret.useDepths = true;
9692	      }
9693	      if (this.useBlockParams) {
9694	        ret.useBlockParams = true;
9695	      }
9696	      if (this.options.compat) {
9697	        ret.compat = true;
9698	      }
9699
9700	      if (!asObject) {
9701	        ret.compiler = JSON.stringify(ret.compiler);
9702
9703	        this.source.currentLocation = { start: { line: 1, column: 0 } };
9704	        ret = this.objectLiteral(ret);
9705
9706	        if (options.srcName) {
9707	          ret = ret.toStringWithSourceMap({ file: options.destName });
9708	          ret.map = ret.map && ret.map.toString();
9709	        } else {
9710	          ret = ret.toString();
9711	        }
9712	      } else {
9713	        ret.compilerOptions = this.options;
9714	      }
9715
9716	      return ret;
9717	    } else {
9718	      return fn;
9719	    }
9720	  },
9721
9722	  preamble: function preamble() {
9723	    // track the last context pushed into place to allow skipping the
9724	    // getContext opcode when it would be a noop
9725	    this.lastContext = 0;
9726	    this.source = new _codeGen2['default'](this.options.srcName);
9727	    this.decorators = new _codeGen2['default'](this.options.srcName);
9728	  },
9729
9730	  createFunctionContext: function createFunctionContext(asObject) {
9731	    // istanbul ignore next
9732
9733	    var _this = this;
9734
9735	    var varDeclarations = '';
9736
9737	    var locals = this.stackVars.concat(this.registers.list);
9738	    if (locals.length > 0) {
9739	      varDeclarations += ', ' + locals.join(', ');
9740	    }
9741
9742	    // Generate minimizer alias mappings
9743	    //
9744	    // When using true SourceNodes, this will update all references to the given alias
9745	    // as the source nodes are reused in situ. For the non-source node compilation mode,
9746	    // aliases will not be used, but this case is already being run on the client and
9747	    // we aren't concern about minimizing the template size.
9748	    var aliasCount = 0;
9749	    _Object$keys(this.aliases).forEach(function (alias) {
9750	      var node = _this.aliases[alias];
9751	      if (node.children && node.referenceCount > 1) {
9752	        varDeclarations += ', alias' + ++aliasCount + '=' + alias;
9753	        node.children[0] = 'alias' + aliasCount;
9754	      }
9755	    });
9756
9757	    if (this.lookupPropertyFunctionIsUsed) {
9758	      varDeclarations += ', ' + this.lookupPropertyFunctionVarDeclaration();
9759	    }
9760
9761	    var params = ['container', 'depth0', 'helpers', 'partials', 'data'];
9762
9763	    if (this.useBlockParams || this.useDepths) {
9764	      params.push('blockParams');
9765	    }
9766	    if (this.useDepths) {
9767	      params.push('depths');
9768	    }
9769
9770	    // Perform a second pass over the output to merge content when possible
9771	    var source = this.mergeSource(varDeclarations);
9772
9773	    if (asObject) {
9774	      params.push(source);
9775
9776	      return Function.apply(this, params);
9777	    } else {
9778	      return this.source.wrap(['function(', params.join(','), ') {\n  ', source, '}']);
9779	    }
9780	  },
9781	  mergeSource: function mergeSource(varDeclarations) {
9782	    var isSimple = this.environment.isSimple,
9783	        appendOnly = !this.forceBuffer,
9784	        appendFirst = undefined,
9785	        sourceSeen = undefined,
9786	        bufferStart = undefined,
9787	        bufferEnd = undefined;
9788	    this.source.each(function (line) {
9789	      if (line.appendToBuffer) {
9790	        if (bufferStart) {
9791	          line.prepend('  + ');
9792	        } else {
9793	          bufferStart = line;
9794	        }
9795	        bufferEnd = line;
9796	      } else {
9797	        if (bufferStart) {
9798	          if (!sourceSeen) {
9799	            appendFirst = true;
9800	          } else {
9801	            bufferStart.prepend('buffer += ');
9802	          }
9803	          bufferEnd.add(';');
9804	          bufferStart = bufferEnd = undefined;
9805	        }
9806
9807	        sourceSeen = true;
9808	        if (!isSimple) {
9809	          appendOnly = false;
9810	        }
9811	      }
9812	    });
9813
9814	    if (appendOnly) {
9815	      if (bufferStart) {
9816	        bufferStart.prepend('return ');
9817	        bufferEnd.add(';');
9818	      } else if (!sourceSeen) {
9819	        this.source.push('return "";');
9820	      }
9821	    } else {
9822	      varDeclarations += ', buffer = ' + (appendFirst ? '' : this.initializeBuffer());
9823
9824	      if (bufferStart) {
9825	        bufferStart.prepend('return buffer + ');
9826	        bufferEnd.add(';');
9827	      } else {
9828	        this.source.push('return buffer;');
9829	      }
9830	    }
9831
9832	    if (varDeclarations) {
9833	      this.source.prepend('var ' + varDeclarations.substring(2) + (appendFirst ? '' : ';\n'));
9834	    }
9835
9836	    return this.source.merge();
9837	  },
9838
9839	  lookupPropertyFunctionVarDeclaration: function lookupPropertyFunctionVarDeclaration() {
9840	    return '\n      lookupProperty = container.lookupProperty || function(parent, propertyName) {\n        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {\n          return parent[propertyName];\n        }\n        return undefined\n    }\n    '.trim();
9841	  },
9842
9843	  // [blockValue]
9844	  //
9845	  // On stack, before: hash, inverse, program, value
9846	  // On stack, after: return value of blockHelperMissing
9847	  //
9848	  // The purpose of this opcode is to take a block of the form
9849	  // `{{#this.foo}}...{{/this.foo}}`, resolve the value of `foo`, and
9850	  // replace it on the stack with the result of properly
9851	  // invoking blockHelperMissing.
9852	  blockValue: function blockValue(name) {
9853	    var blockHelperMissing = this.aliasable('container.hooks.blockHelperMissing'),
9854	        params = [this.contextName(0)];
9855	    this.setupHelperArgs(name, 0, params);
9856
9857	    var blockName = this.popStack();
9858	    params.splice(1, 0, blockName);
9859
9860	    this.push(this.source.functionCall(blockHelperMissing, 'call', params));
9861	  },
9862
9863	  // [ambiguousBlockValue]
9864	  //
9865	  // On stack, before: hash, inverse, program, value
9866	  // Compiler value, before: lastHelper=value of last found helper, if any
9867	  // On stack, after, if no lastHelper: same as [blockValue]
9868	  // On stack, after, if lastHelper: value
9869	  ambiguousBlockValue: function ambiguousBlockValue() {
9870	    // We're being a bit cheeky and reusing the options value from the prior exec
9871	    var blockHelperMissing = this.aliasable('container.hooks.blockHelperMissing'),
9872	        params = [this.contextName(0)];
9873	    this.setupHelperArgs('', 0, params, true);
9874
9875	    this.flushInline();
9876
9877	    var current = this.topStack();
9878	    params.splice(1, 0, current);
9879
9880	    this.pushSource(['if (!', this.lastHelper, ') { ', current, ' = ', this.source.functionCall(blockHelperMissing, 'call', params), '}']);
9881	  },
9882
9883	  // [appendContent]
9884	  //
9885	  // On stack, before: ...
9886	  // On stack, after: ...
9887	  //
9888	  // Appends the string value of `content` to the current buffer
9889	  appendContent: function appendContent(content) {
9890	    if (this.pendingContent) {
9891	      content = this.pendingContent + content;
9892	    } else {
9893	      this.pendingLocation = this.source.currentLocation;
9894	    }
9895
9896	    this.pendingContent = content;
9897	  },
9898
9899	  // [append]
9900	  //
9901	  // On stack, before: value, ...
9902	  // On stack, after: ...
9903	  //
9904	  // Coerces `value` to a String and appends it to the current buffer.
9905	  //
9906	  // If `value` is truthy, or 0, it is coerced into a string and appended
9907	  // Otherwise, the empty string is appended
9908	  append: function append() {
9909	    if (this.isInline()) {
9910	      this.replaceStack(function (current) {
9911	        return [' != null ? ', current, ' : ""'];
9912	      });
9913
9914	      this.pushSource(this.appendToBuffer(this.popStack()));
9915	    } else {
9916	      var local = this.popStack();
9917	      this.pushSource(['if (', local, ' != null) { ', this.appendToBuffer(local, undefined, true), ' }']);
9918	      if (this.environment.isSimple) {
9919	        this.pushSource(['else { ', this.appendToBuffer("''", undefined, true), ' }']);
9920	      }
9921	    }
9922	  },
9923
9924	  // [appendEscaped]
9925	  //
9926	  // On stack, before: value, ...
9927	  // On stack, after: ...
9928	  //
9929	  // Escape `value` and append it to the buffer
9930	  appendEscaped: function appendEscaped() {
9931	    this.pushSource(this.appendToBuffer([this.aliasable('container.escapeExpression'), '(', this.popStack(), ')']));
9932	  },
9933
9934	  // [getContext]
9935	  //
9936	  // On stack, before: ...
9937	  // On stack, after: ...
9938	  // Compiler value, after: lastContext=depth
9939	  //
9940	  // Set the value of the `lastContext` compiler value to the depth
9941	  getContext: function getContext(depth) {
9942	    this.lastContext = depth;
9943	  },
9944
9945	  // [pushContext]
9946	  //
9947	  // On stack, before: ...
9948	  // On stack, after: currentContext, ...
9949	  //
9950	  // Pushes the value of the current context onto the stack.
9951	  pushContext: function pushContext() {
9952	    this.pushStackLiteral(this.contextName(this.lastContext));
9953	  },
9954
9955	  // [lookupOnContext]
9956	  //
9957	  // On stack, before: ...
9958	  // On stack, after: currentContext[name], ...
9959	  //
9960	  // Looks up the value of `name` on the current context and pushes
9961	  // it onto the stack.
9962	  lookupOnContext: function lookupOnContext(parts, falsy, strict, scoped) {
9963	    var i = 0;
9964
9965	    if (!scoped && this.options.compat && !this.lastContext) {
9966	      // The depthed query is expected to handle the undefined logic for the root level that
9967	      // is implemented below, so we evaluate that directly in compat mode
9968	      this.push(this.depthedLookup(parts[i++]));
9969	    } else {
9970	      this.pushContext();
9971	    }
9972
9973	    this.resolvePath('context', parts, i, falsy, strict);
9974	  },
9975
9976	  // [lookupBlockParam]
9977	  //
9978	  // On stack, before: ...
9979	  // On stack, after: blockParam[name], ...
9980	  //
9981	  // Looks up the value of `parts` on the given block param and pushes
9982	  // it onto the stack.
9983	  lookupBlockParam: function lookupBlockParam(blockParamId, parts) {
9984	    this.useBlockParams = true;
9985
9986	    this.push(['blockParams[', blockParamId[0], '][', blockParamId[1], ']']);
9987	    this.resolvePath('context', parts, 1);
9988	  },
9989
9990	  // [lookupData]
9991	  //
9992	  // On stack, before: ...
9993	  // On stack, after: data, ...
9994	  //
9995	  // Push the data lookup operator
9996	  lookupData: function lookupData(depth, parts, strict) {
9997	    if (!depth) {
9998	      this.pushStackLiteral('data');
9999	    } else {
10000	      this.pushStackLiteral('container.data(data, ' + depth + ')');
10001	    }
10002
10003	    this.resolvePath('data', parts, 0, true, strict);
10004	  },
10005
10006	  resolvePath: function resolvePath(type, parts, 
vendor: 2,919 bytes, lines 10006-10103
10006i, falsy, strict) {
10007	    // istanbul ignore next
10008
10009	    var _this2 = this;
10010
10011	    if (this.options.strict || this.options.assumeObjects) {
10012	      this.push(strictLookup(this.options.strict && strict, this, parts, i, type));
10013	      return;
10014	    }
10015
10016	    var len = parts.length;
10017	    for (; i < len; i++) {
10018	      /* eslint-disable no-loop-func */
10019	      this.replaceStack(function (current) {
10020	        var lookup = _this2.nameLookup(current, parts[i], type);
10021	        // We want to ensure that zero and false are handled properly if the context (falsy flag)
10022	        // needs to have the special handling for these values.
10023	        if (!falsy) {
10024	          return [' != null ? ', lookup, ' : ', current];
10025	        } else {
10026	          // Otherwise we can use generic falsy handling
10027	          return [' && ', lookup];
10028	        }
10029	      });
10030	      /* eslint-enable no-loop-func */
10031	    }
10032	  },
10033
10034	  // [resolvePossibleLambda]
10035	  //
10036	  // On stack, before: value, ...
10037	  // On stack, after: resolved value, ...
10038	  //
10039	  // If the `value` is a lambda, replace it on the stack by
10040	  // the return value of the lambda
10041	  resolvePossibleLambda: function resolvePossibleLambda() {
10042	    this.push([this.aliasable('container.lambda'), '(', this.popStack(), ', ', this.contextName(0), ')']);
10043	  },
10044
10045	  // [pushStringParam]
10046	  //
10047	  // On stack, before: ...
10048	  // On stack, after: string, currentContext, ...
10049	  //
10050	  // This opcode is designed for use in string mode, which
10051	  // provides the string value of a parameter along with its
10052	  // depth rather than resolving it immediately.
10053	  pushStringParam: function pushStringParam(string, type) {
10054	    this.pushContext();
10055	    this.pushString(type);
10056
10057	    // If it's a subexpression, the string result
10058	    // will be pushed after this opcode.
10059	    if (type !== 'SubExpression') {
10060	      if (typeof string === 'string') {
10061	        this.pushString(string);
10062	      } else {
10063	        this.pushStackLiteral(string);
10064	      }
10065	    }
10066	  },
10067
10068	  emptyHash: function emptyHash(omitEmpty) {
10069	    if (this.trackIds) {
10070	      this.push('{}'); // hashIds
10071	    }
10072	    if (this.stringParams) {
10073	      this.push('{}'); // hashContexts
10074	      this.push('{}'); // hashTypes
10075	    }
10076	    this.pushStackLiteral(omitEmpty ? 'undefined' : '{}');
10077	  },
10078	  pushHash: function pushHash() {
10079	    if (this.hash) {
10080	      this.hashes.push(this.hash);
10081	    }
10082	    this.hash = { values: {}, types: [], contexts: [], ids: [] };
10083	  },
10084	  popHash: function popHash() {
10085	    var hash = this.hash;
10086	    this.hash = this.hashes.pop();
10087
10088	    if (this.trackIds) {
10089	      this.push(this.objectLiteral(hash.ids));
10090	    }
10091	    if (this.stringParams) {
10092	      this.push(this.objectLiteral(hash.contexts));
10093	      this.push(this.objectLiteral(hash.types));
10094	    }
10095
10096	    this.push(this.objectLiteral(hash.values));
10097	  },
10098
10099	  // [pushString]
10100	  //
10101	  // On stack, before: ...
10102	  // On stack, after: quotedString(string), ...
10103	  //
vendor: 7,424 bytes, lines 10104-10332
10104	  // Push a quoted version of `string` onto the stack
10105	  pushString: function pushString(string) {
10106	    this.pushStackLiteral(this.quotedString(string));
10107	  },
10108
10109	  // [pushLiteral]
10110	  //
10111	  // On stack, before: ...
10112	  // On stack, after: value, ...
10113	  //
10114	  // Pushes a value onto the stack. This operation prevents
10115	  // the compiler from creating a temporary variable to hold
10116	  // it.
10117	  pushLiteral: function pushLiteral(value) {
10118	    this.pushStackLiteral(value);
10119	  },
10120
10121	  // [pushProgram]
10122	  //
10123	  // On stack, before: ...
10124	  // On stack, after: program(guid), ...
10125	  //
10126	  // Push a program expression onto the stack. This takes
10127	  // a compile-time guid and converts it into a runtime-accessible
10128	  // expression.
10129	  pushProgram: function pushProgram(guid) {
10130	    if (guid != null) {
10131	      this.pushStackLiteral(this.programExpression(guid));
10132	    } else {
10133	      this.pushStackLiteral(null);
10134	    }
10135	  },
10136
10137	  // [registerDecorator]
10138	  //
10139	  // On stack, before: hash, program, params..., ...
10140	  // On stack, after: ...
10141	  //
10142	  // Pops off the decorator's parameters, invokes the decorator,
10143	  // and inserts the decorator into the decorators list.
10144	  registerDecorator: function registerDecorator(paramSize, name) {
10145	    var foundDecorator = this.nameLookup('decorators', name, 'decorator'),
10146	        options = this.setupHelperArgs(name, paramSize);
10147
10148	    this.decorators.push(['fn = ', this.decorators.functionCall(foundDecorator, '', ['fn', 'props', 'container', options]), ' || fn;']);
10149	  },
10150
10151	  // [invokeHelper]
10152	  //
10153	  // On stack, before: hash, inverse, program, params..., ...
10154	  // On stack, after: result of helper invocation
10155	  //
10156	  // Pops off the helper's parameters, invokes the helper,
10157	  // and pushes the helper's return value onto the stack.
10158	  //
10159	  // If the helper is not found, `helperMissing` is called.
10160	  invokeHelper: function invokeHelper(paramSize, name, isSimple) {
10161	    var nonHelper = this.popStack(),
10162	        helper = this.setupHelper(paramSize, name);
10163
10164	    var possibleFunctionCalls = [];
10165
10166	    if (isSimple) {
10167	      // direct call to helper
10168	      possibleFunctionCalls.push(helper.name);
10169	    }
10170	    // call a function from the input object
10171	    possibleFunctionCalls.push(nonHelper);
10172	    if (!this.options.strict) {
10173	      possibleFunctionCalls.push(this.aliasable('container.hooks.helperMissing'));
10174	    }
10175
10176	    var functionLookupCode = ['(', this.itemsSeparatedBy(possibleFunctionCalls, '||'), ')'];
10177	    var functionCall = this.source.functionCall(functionLookupCode, 'call', helper.callParams);
10178	    this.push(functionCall);
10179	  },
10180
10181	  itemsSeparatedBy: function itemsSeparatedBy(items, separator) {
10182	    var result = [];
10183	    result.push(items[0]);
10184	    for (var i = 1; i < items.length; i++) {
10185	      result.push(separator, items[i]);
10186	    }
10187	    return result;
10188	  },
10189	  // [invokeKnownHelper]
10190	  //
10191	  // On stack, before: hash, inverse, program, params..., ...
10192	  // On stack, after: result of helper invocation
10193	  //
10194	  // This operation is used when the helper is known to exist,
10195	  // so a `helperMissing` fallback is not required.
10196	  invokeKnownHelper: function invokeKnownHelper(paramSize, name) {
10197	    var helper = this.setupHelper(paramSize, name);
10198	    this.push(this.source.functionCall(helper.name, 'call', helper.callParams));
10199	  },
10200
10201	  // [invokeAmbiguous]
10202	  //
10203	  // On stack, before: hash, inverse, program, params..., ...
10204	  // On stack, after: result of disambiguation
10205	  //
10206	  // This operation is used when an expression like `{{foo}}`
10207	  // is provided, but we don't know at compile-time whether it
10208	  // is a helper or a path.
10209	  //
10210	  // This operation emits more code than the other options,
10211	  // and can be avoided by passing the `knownHelpers` and
10212	  // `knownHelpersOnly` flags at compile-time.
10213	  invokeAmbiguous: function invokeAmbiguous(name, helperCall) {
10214	    this.useRegister('helper');
10215
10216	    var nonHelper = this.popStack();
10217
10218	    this.emptyHash();
10219	    var helper = this.setupHelper(0, name, helperCall);
10220
10221	    var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
10222
10223	    var lookup = ['(', '(helper = ', helperName, ' || ', nonHelper, ')'];
10224	    if (!this.options.strict) {
10225	      lookup[0] = '(helper = ';
10226	      lookup.push(' != null ? helper : ', this.aliasable('container.hooks.helperMissing'));
10227	    }
10228
10229	    this.push(['(', lookup, helper.paramsInit ? ['),(', helper.paramsInit] : [], '),', '(typeof helper === ', this.aliasable('"function"'), ' ? ', this.source.functionCall('helper', 'call', helper.callParams), ' : helper))']);
10230	  },
10231
10232	  // [invokePartial]
10233	  //
10234	  // On stack, before: context, ...
10235	  // On stack after: result of partial invocation
10236	  //
10237	  // This operation pops off a context, invokes a partial with that context,
10238	  // and pushes the result of the invocation back.
10239	  invokePartial: function invokePartial(isDynamic, name, indent) {
10240	    var params = [],
10241	        options = this.setupParams(name, 1, params);
10242
10243	    if (isDynamic) {
10244	      name = this.popStack();
10245	      delete options.name;
10246	    }
10247
10248	    if (indent) {
10249	      options.indent = JSON.stringify(indent);
10250	    }
10251	    options.helpers = 'helpers';
10252	    options.partials = 'partials';
10253	    options.decorators = 'container.decorators';
10254
10255	    if (!isDynamic) {
10256	      params.unshift(this.nameLookup('partials', name, 'partial'));
10257	    } else {
10258	      params.unshift(name);
10259	    }
10260
10261	    if (this.options.compat) {
10262	      options.depths = 'depths';
10263	    }
10264	    options = this.objectLiteral(options);
10265	    params.push(options);
10266
10267	    this.push(this.source.functionCall('container.invokePartial', '', params));
10268	  },
10269
10270	  // [assignToHash]
10271	  //
10272	  // On stack, before: value, ..., hash, ...
10273	  // On stack, after: ..., hash, ...
10274	  //
10275	  // Pops a value off the stack and assigns it to the current hash
10276	  assignToHash: function assignToHash(key) {
10277	    var value = this.popStack(),
10278	        context = undefined,
10279	        type = undefined,
10280	        id = undefined;
10281
10282	    if (this.trackIds) {
10283	      id = this.popStack();
10284	    }
10285	    if (this.stringParams) {
10286	      type = this.popStack();
10287	      context = this.popStack();
10288	    }
10289
10290	    var hash = this.hash;
10291	    if (context) {
10292	      hash.contexts[key] = context;
10293	    }
10294	    if (type) {
10295	      hash.types[key] = type;
10296	    }
10297	    if (id) {
10298	      hash.ids[key] = id;
10299	    }
10300	    hash.values[key] = value;
10301	  },
10302
10303	  pushId: function pushId(type, name, child) {
10304	    if (type === 'BlockParam') {
10305	      this.pushStackLiteral('blockParams[' + name[0] + '].path[' + name[1] + ']' + (child ? ' + ' + JSON.stringify('.' + child) : ''));
10306	    } else if (type === 'PathExpression') {
10307	      this.pushString(name);
10308	    } else if (type === 'SubExpression') {
10309	      this.pushStackLiteral('true');
10310	    } else {
10311	      this.pushStackLiteral('null');
10312	    }
10313	  },
10314
10315	  // HELPERS
10316
10317	  compiler: JavaScriptCompiler,
10318
10319	  compileChildren: function compileChildren(environment, options) {
10320	    var children = environment.children,
10321	        child = undefined,
10322	        compiler = undefined;
10323
10324	    for (var i = 0, l = children.length; i < l; i++) {
10325	      child = children[i];
10326	      compiler = new this.compiler(); // eslint-disable-line new-cap
10327
10328	      var existing = this.matchExistingProgram(child);
10329
10330	      if (existing == null) {
10331	        this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
10332	        var index = this.context.programs.length
vendor: 9,546 bytes, lines 10332-10652
10332;
10333	        child.index = index;
10334	        child.name = 'program' + index;
10335	        this.context.programs[index] = compiler.compile(child, options, this.context, !this.precompile);
10336	        this.context.decorators[index] = compiler.decorators;
10337	        this.context.environments[index] = child;
10338
10339	        this.useDepths = this.useDepths || compiler.useDepths;
10340	        this.useBlockParams = this.useBlockParams || compiler.useBlockParams;
10341	        child.useDepths = this.useDepths;
10342	        child.useBlockParams = this.useBlockParams;
10343	      } else {
10344	        child.index = existing.index;
10345	        child.name = 'program' + existing.index;
10346
10347	        this.useDepths = this.useDepths || existing.useDepths;
10348	        this.useBlockParams = this.useBlockParams || existing.useBlockParams;
10349	      }
10350	    }
10351	  },
10352	  matchExistingProgram: function matchExistingProgram(child) {
10353	    for (var i = 0, len = this.context.environments.length; i < len; i++) {
10354	      var environment = this.context.environments[i];
10355	      if (environment && environment.equals(child)) {
10356	        return environment;
10357	      }
10358	    }
10359	  },
10360
10361	  programExpression: function programExpression(guid) {
10362	    var child = this.environment.children[guid],
10363	        programParams = [child.index, 'data', child.blockParams];
10364
10365	    if (this.useBlockParams || this.useDepths) {
10366	      programParams.push('blockParams');
10367	    }
10368	    if (this.useDepths) {
10369	      programParams.push('depths');
10370	    }
10371
10372	    return 'container.program(' + programParams.join(', ') + ')';
10373	  },
10374
10375	  useRegister: function useRegister(name) {
10376	    if (!this.registers[name]) {
10377	      this.registers[name] = true;
10378	      this.registers.list.push(name);
10379	    }
10380	  },
10381
10382	  push: function push(expr) {
10383	    if (!(expr instanceof Literal)) {
10384	      expr = this.source.wrap(expr);
10385	    }
10386
10387	    this.inlineStack.push(expr);
10388	    return expr;
10389	  },
10390
10391	  pushStackLiteral: function pushStackLiteral(item) {
10392	    this.push(new Literal(item));
10393	  },
10394
10395	  pushSource: function pushSource(source) {
10396	    if (this.pendingContent) {
10397	      this.source.push(this.appendToBuffer(this.source.quotedString(this.pendingContent), this.pendingLocation));
10398	      this.pendingContent = undefined;
10399	    }
10400
10401	    if (source) {
10402	      this.source.push(source);
10403	    }
10404	  },
10405
10406	  replaceStack: function replaceStack(callback) {
10407	    var prefix = ['('],
10408	        stack = undefined,
10409	        createdStack = undefined,
10410	        usedLiteral = undefined;
10411
10412	    /* istanbul ignore next */
10413	    if (!this.isInline()) {
10414	      throw new _exception2['default']('replaceStack on non-inline');
10415	    }
10416
10417	    // We want to merge the inline statement into the replacement statement via ','
10418	    var top = this.popStack(true);
10419
10420	    if (top instanceof Literal) {
10421	      // Literals do not need to be inlined
10422	      stack = [top.value];
10423	      prefix = ['(', stack];
10424	      usedLiteral = true;
10425	    } else {
10426	      // Get or create the current stack name for use by the inline
10427	      createdStack = true;
10428	      var _name = this.incrStack();
10429
10430	      prefix = ['((', this.push(_name), ' = ', top, ')'];
10431	      stack = this.topStack();
10432	    }
10433
10434	    var item = callback.call(this, stack);
10435
10436	    if (!usedLiteral) {
10437	      this.popStack();
10438	    }
10439	    if (createdStack) {
10440	      this.stackSlot--;
10441	    }
10442	    this.push(prefix.concat(item, ')'));
10443	  },
10444
10445	  incrStack: function incrStack() {
10446	    this.stackSlot++;
10447	    if (this.stackSlot > this.stackVars.length) {
10448	      this.stackVars.push('stack' + this.stackSlot);
10449	    }
10450	    return this.topStackName();
10451	  },
10452	  topStackName: function topStackName() {
10453	    return 'stack' + this.stackSlot;
10454	  },
10455	  flushInline: function flushInline() {
10456	    var inlineStack = this.inlineStack;
10457	    this.inlineStack = [];
10458	    for (var i = 0, len = inlineStack.length; i < len; i++) {
10459	      var entry = inlineStack[i];
10460	      /* istanbul ignore if */
10461	      if (entry instanceof Literal) {
10462	        this.compileStack.push(entry);
10463	      } else {
10464	        var stack = this.incrStack();
10465	        this.pushSource([stack, ' = ', entry, ';']);
10466	        this.compileStack.push(stack);
10467	      }
10468	    }
10469	  },
10470	  isInline: function isInline() {
10471	    return this.inlineStack.length;
10472	  },
10473
10474	  popStack: function popStack(wrapped) {
10475	    var inline = this.isInline(),
10476	        item = (inline ? this.inlineStack : this.compileStack).pop();
10477
10478	    if (!wrapped && item instanceof Literal) {
10479	      return item.value;
10480	    } else {
10481	      if (!inline) {
10482	        /* istanbul ignore next */
10483	        if (!this.stackSlot) {
10484	          throw new _exception2['default']('Invalid stack pop');
10485	        }
10486	        this.stackSlot--;
10487	      }
10488	      return item;
10489	    }
10490	  },
10491
10492	  topStack: function topStack() {
10493	    var stack = this.isInline() ? this.inlineStack : this.compileStack,
10494	        item = stack[stack.length - 1];
10495
10496	    /* istanbul ignore if */
10497	    if (item instanceof Literal) {
10498	      return item.value;
10499	    } else {
10500	      return item;
10501	    }
10502	  },
10503
10504	  contextName: function contextName(context) {
10505	    if (this.useDepths && context) {
10506	      return 'depths[' + context + ']';
10507	    } else {
10508	      return 'depth' + context;
10509	    }
10510	  },
10511
10512	  quotedString: function quotedString(str) {
10513	    return this.source.quotedString(str);
10514	  },
10515
10516	  objectLiteral: function objectLiteral(obj) {
10517	    return this.source.objectLiteral(obj);
10518	  },
10519
10520	  aliasable: function aliasable(name) {
10521	    var ret = this.aliases[name];
10522	    if (ret) {
10523	      ret.referenceCount++;
10524	      return ret;
10525	    }
10526
10527	    ret = this.aliases[name] = this.source.wrap(name);
10528	    ret.aliasable = true;
10529	    ret.referenceCount = 1;
10530
10531	    return ret;
10532	  },
10533
10534	  setupHelper: function setupHelper(paramSize, name, blockHelper) {
10535	    var params = [],
10536	        paramsInit = this.setupHelperArgs(name, paramSize, params, blockHelper);
10537	    var foundHelper = this.nameLookup('helpers', name, 'helper'),
10538	        callContext = this.aliasable(this.contextName(0) + ' != null ? ' + this.contextName(0) + ' : (container.nullContext || {})');
10539
10540	    return {
10541	      params: params,
10542	      paramsInit: paramsInit,
10543	      name: foundHelper,
10544	      callParams: [callContext].concat(params)
10545	    };
10546	  },
10547
10548	  setupParams: function setupParams(helper, paramSize, params) {
10549	    var options = {},
10550	        contexts = [],
10551	        types = [],
10552	        ids = [],
10553	        objectArgs = !params,
10554	        param = undefined;
10555
10556	    if (objectArgs) {
10557	      params = [];
10558	    }
10559
10560	    options.name = this.quotedString(helper);
10561	    options.hash = this.popStack();
10562
10563	    if (this.trackIds) {
10564	      options.hashIds = this.popStack();
10565	    }
10566	    if (this.stringParams) {
10567	      options.hashTypes = this.popStack();
10568	      options.hashContexts = this.popStack();
10569	    }
10570
10571	    var inverse = this.popStack(),
10572	        program = this.popStack();
10573
10574	    // Avoid setting fn and inverse if neither are set. This allows
10575	    // helpers to do a check for `if (options.fn)`
10576	    if (program || inverse) {
10577	      options.fn = program || 'container.noop';
10578	      options.inverse = inverse || 'container.noop';
10579	    }
10580
10581	    // The parameters go on to the stack in order (making sure that they are evaluated in order)
10582	    // so we need to pop them off the stack in reverse order
10583	    var i = paramSize;
10584	    while (i--) {
10585	      param = this.popStack();
10586	      params[i] = param;
10587
10588	      if (this.trackIds) {
10589	        ids[i] = this.popStack();
10590	      }
10591	      if (this.stringParams) {
10592	        types[i] = this.popStack();
10593	        contexts[i] = this.popStack();
10594	      }
10595	    }
10596
10597	    if (objectArgs) {
10598	      options.args = this.source.generateArray(params);
10599	    }
10600
10601	    if (this.trackIds) {
10602	      options.ids = this.source.generateArray(ids);
10603	    }
10604	    if (this.stringParams) {
10605	      options.types = this.source.generateArray(types);
10606	      options.contexts = this.source.generateArray(contexts);
10607	    }
10608
10609	    if (this.options.data) {
10610	      options.data = 'data';
10611	    }
10612	    if (this.useBlockParams) {
10613	      options.blockParams = 'blockParams';
10614	    }
10615	    return options;
10616	  },
10617
10618	  setupHelperArgs: function setupHelperArgs(helper, paramSize, params, useRegister) {
10619	    var options = this.setupParams(helper, paramSize, params);
10620	    options.loc = JSON.stringify(this.source.currentLocation);
10621	    options = this.objectLiteral(options);
10622	    if (useRegister) {
10623	      this.useRegister('options');
10624	      params.push('options');
10625	      return ['options=', options];
10626	    } else if (params) {
10627	      params.push(options);
10628	      return '';
10629	    } else {
10630	      return options;
10631	    }
10632	  }
10633	};
10634
10635	(function () {
10636	  var reservedWords = ('break else new var' + ' case finally return void' + ' catch for switch while' + ' continue function this with' + ' default if throw' + ' delete in try' + ' do instanceof typeof' + ' abstract enum int short' + ' boolean export interface static' + ' byte extends long super' + ' char final native synchronized' + ' class float package throws' + ' const goto private transient' + ' debugger implements protected volatile' + ' double import public let yield await' + ' null true false').split(' ');
10637
10638	  var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
10639
10640	  for (var i = 0, l = reservedWords.length; i < l; i++) {
10641	    compilerWords[reservedWords[i]] = true;
10642	  }
10643	})();
10644
10645	/**
10646	 * @deprecated May be removed in the next major version
10647	 */
10648	JavaScriptCompiler.isValidJavaScriptVariableName = function (name) {
10649	  return !JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name);
10650	};
10651
10652	function strictLookup(requireTerminal, compiler, parts, 
vendor: 4,006 bytes, lines 10652-10800
10652i, type) {
10653	  var stack = compiler.popStack(),
10654	      len = parts.length;
10655	  if (requireTerminal) {
10656	    len--;
10657	  }
10658
10659	  for (; i < len; i++) {
10660	    stack = compiler.nameLookup(stack, parts[i], type);
10661	  }
10662
10663	  if (requireTerminal) {
10664	    return [compiler.aliasable('container.strict'), '(', stack, ', ', compiler.quotedString(parts[i]), ', ', JSON.stringify(compiler.source.currentLocation), ' )'];
10665	  } else {
10666	    return stack;
10667	  }
10668	}
10669
10670	exports['default'] = JavaScriptCompiler;
10671	module.exports = exports['default'];
10672
10673/***/ }),
10674/* 92 */
10675/***/ (function(module, exports, __webpack_require__) {
10676
10677	/* global define, require */
10678	'use strict';
10679
10680	var _Object$keys = __webpack_require__(60)['default'];
10681
10682	exports.__esModule = true;
10683
10684	var _utils = __webpack_require__(5);
10685
10686	var SourceNode = undefined;
10687
10688	try {
10689	  /* istanbul ignore next */
10690	  if (false) {
10691	    // We don't support this in AMD environments. For these environments, we assume that
10692	    // they are running on the browser and thus have no need for the source-map library.
10693	    var SourceMap = require('source-map');
10694	    SourceNode = SourceMap.SourceNode;
10695	  }
10696	} catch (err) {}
10697	/* NOP */
10698
10699	/* istanbul ignore if: tested but not covered in istanbul due to dist build  */
10700	if (!SourceNode) {
10701	  SourceNode = function (line, column, srcFile, chunks) {
10702	    this.src = '';
10703	    if (chunks) {
10704	      this.add(chunks);
10705	    }
10706	  };
10707	  /* istanbul ignore next */
10708	  SourceNode.prototype = {
10709	    add: function add(chunks) {
10710	      if (_utils.isArray(chunks)) {
10711	        chunks = chunks.join('');
10712	      }
10713	      this.src += chunks;
10714	    },
10715	    prepend: function prepend(chunks) {
10716	      if (_utils.isArray(chunks)) {
10717	        chunks = chunks.join('');
10718	      }
10719	      this.src = chunks + this.src;
10720	    },
10721	    toStringWithSourceMap: function toStringWithSourceMap() {
10722	      return { code: this.toString() };
10723	    },
10724	    toString: function toString() {
10725	      return this.src;
10726	    }
10727	  };
10728	}
10729
10730	function castChunk(chunk, codeGen, loc) {
10731	  if (_utils.isArray(chunk)) {
10732	    var ret = [];
10733
10734	    for (var i = 0, len = chunk.length; i < len; i++) {
10735	      ret.push(codeGen.wrap(chunk[i], loc));
10736	    }
10737	    return ret;
10738	  } else if (typeof chunk === 'boolean' || typeof chunk === 'number') {
10739	    // Handle primitives that the SourceNode will throw up on
10740	    return chunk + '';
10741	  }
10742	  return chunk;
10743	}
10744
10745	function CodeGen(srcFile) {
10746	  this.srcFile = srcFile;
10747	  this.source = [];
10748	}
10749
10750	CodeGen.prototype = {
10751	  isEmpty: function isEmpty() {
10752	    return !this.source.length;
10753	  },
10754	  prepend: function prepend(source, loc) {
10755	    this.source.unshift(this.wrap(source, loc));
10756	  },
10757	  push: function push(source, loc) {
10758	    this.source.push(this.wrap(source, loc));
10759	  },
10760
10761	  merge: function merge() {
10762	    var source = this.empty();
10763	    this.each(function (line) {
10764	      source.add(['  ', line, '\n']);
10765	    });
10766	    return source;
10767	  },
10768
10769	  each: function each(iter) {
10770	    for (var i = 0, len = this.source.length; i < len; i++) {
10771	      iter(this.source[i]);
10772	    }
10773	  },
10774
10775	  empty: function empty() {
10776	    var loc = this.currentLocation || { start: {} };
10777	    return new SourceNode(loc.start.line, loc.start.column, this.srcFile);
10778	  },
10779	  wrap: function wrap(chunk) {
10780	    var loc = arguments.length <= 1 || arguments[1] === undefined ? this.currentLocation || { start: {} } : arguments[1];
10781
10782	    if (chunk instanceof SourceNode) {
10783	      return chunk;
10784	    }
10785
10786	    chunk = castChunk(chunk, this, loc);
10787
10788	    return new SourceNode(loc.start.line, loc.start.column, this.srcFile, chunk);
10789	  },
10790
10791	  functionCall: function functionCall(fn, type, params) {
10792	    params = this.generateList(params);
10793	    return this.wrap([fn, type ? '.' + type + '(' : '(', params, ')']);
10794	  },
10795
10796	  quotedString: function quotedString(str) {
10797	    return '"' + (str + '').replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n').replace(/\r/g, '\\r').replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4
10798	    .replace(/\u2029/g, '\\u2029') + '"';
10799	  },
10800
10801	  objectLiteral: function objectLiteral(obj) {
10802	    // istanbul ignore next
10803
10804	    var _this = this;
10805
10806	    var pairs = [];
10807
10808	    _Object$keys(obj).forEach(function (key) {
10809	      var value = castChunk(obj[key], _this);
10810	      if (value !== 'undefined') {
10811	        pairs.push([_this.quotedString(key), ':', value]);
10812	      }
10813	    });
10814
10815	    var ret = this.generateList(pairs);
10816	    ret.prepend('{');
10817	    ret.add('}');
10818	    return ret;
10819	  },
10820
10821	  generateList: function generateList(entries) {
10822	    var ret = this.empty();
10823
10824	    for (var i = 0, len = entries.length; i < len; i++) {
10825	      if (i) {
10826	        ret.add(',');
10827	      }
10828
10829	      ret.add(castChunk(entries[i], this));
10830	    }
10831
10832	    return ret;
10833	  },
10834
10835	  generateArray: function generateArray(entries) {
10836	    var ret = this.generateList(entries);
10837	    ret.prepend('[');
10838	    ret.add(']');
10839
10840	    return ret;
10841	  }
10842	};
10843
10844	exports['default'] = CodeGen;
10845	module.exports = exports['default'];
10846
10847/***/ })
10848/******/ ])
10849});
10850;
10851//     Backbone.js 1.0.0
10852
10853//     (c) 2010-2013 Jeremy Ashkenas, DocumentCloud Inc.
10854//     Backbone may be freely distributed under the MIT license.
10855//     For all details and documentation:
10856//     http://backbonejs.org
10857
10858(function(){
10859
10860  // Initial Setup
10861  // -------------
10862
10863  // Save a reference to the global object (`window` in the browser, `exports`
10864  // on the server).
10865  var root = this;
10866
10867  // Save the previous value of the `Backbone` variable, so that it can be
10868  // restored later on, if `noConflict` is used.
10869  var previousBackbone = root.Backbone;
10870
10871  // Create local references to array methods we'll want to use later.
10872  var array = [];
10873  var push = array.push;
10874  var slice = array.slice;
10875  var splice = array.splice;
10876
10877  // The top-level namespace. All public Backbone classes and modules will
10878  // be attached to this. Exported for both the browser and the server.
10879  var Backbone;
10880  if (typeof exports !== 'undefined') {
10881    Backbone = exports;
10882  } else {
10883    Backbone = root.Backbone = {};
10884  }
10885
10886  // Current version of the library. Keep in sync with `package.json`.
10887  Backbone.VERSION = '1.0.0';
10888
10889  // Require Underscore, if we're on the server, and it's not already present.
10890  var _ = root._;
10891  if (!_ && (typeof require !== 'undefined')) _ = require('underscore');
10892
10893  // For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
10894  // the `$` variable.
10895  Backbone.$ = root.jQuery || root.Zepto || root.ender || root.$;
10896
10897  // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
10898  // to its previous owner. Returns a reference to this Backbone object.
10899  Backbone.noConflict = function() {
10900    root.Backbone = previousBackbone;
10901    return this;
10902  };
10903
10904  // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option
10905  // will fake `"PUT"` and `"DELETE"` requests via the `_method` parameter and
10906  // set a `X-Http-Method-Override` header.
10907  Backbone.emulateHTTP = false;
10908
10909  // Turn on `emulateJSON` to support legacy servers that can't deal with direct
10910  // `application/json` requests ... will encode the body as
10911  // `application/x-www-form-urlencoded` instead and will send the model in a
10912  // form param named `model`.
10913  Backbone.emulateJSON = false;
10914
10915  // Backbone.Events
10916  // ---------------
10917
10918  // A module that can be mixed in to *any object* in order to provide it with
10919  // custom events. You may bind with `on` or remove with `off` callback
10920  // functions to an event; `trigger`-ing an event fires all callbacks in
10921  // succession.
10922  //
10923  //     var object = {};
10924  //     _.extend(object, Backbone.Events);
10925  //     object.on('expand', function(){ alert('expanded'); });
10926  //     object.trigger('expand');
10927  //
10928  var Events = Backbone.Events = {
10929
10930    // Bind an event to a `callback` function. Passing `"all"` will bind
10931    // the callback to all events fired.
10932    on: function(name, callback, context) {
10933      if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this;
10934      this._events || (this._events = {});
10935      var events = this._events[name] || (this._events[name] = []);
10936      events.push({callback: callback, context: context, ctx: context || this});
10937      return this;
10938    },
10939
10940    // Bind an event to only be triggered a single time. After the first time
10941    // the callback is invoked, it will be removed.
10942    once: function(name, callback, context) {
10943      if (!eventsApi(this, 'once', name, [callback, context]) || !callback) return this;
10944      var self = this;
10945      var once = _.once(function() {
10946        self.off(name, once);
10947        callback.apply(this, arguments);
10948      });
10949      once._callback = callback;
10950      return this.on(name, once, context);
10951    },
10952
10953    // Remove one or many callbacks. If `context` is null, removes all
10954    // callbacks with that function. If `callback` is null, removes all
10955    // callbacks for the event. If `name` is null, removes all bound
10956    // callbacks for all events.
10957    off: function(name, callback, context) {
10958      var retain, ev, events, names, i, l, j, k;
10959      if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this;
10960      if (!name && !callback && !context) {
10961        this._events = {};
10962        return this;
10963      }
10964
10965      names = name ? [name] : _.keys(this._events);
10966      for (i = 0, l = names.length; i < l; i++) {
10967        name = names[i];
10968        if (events = this._events[name]) {
10969          this._events[name] = retain = [];
10970          if (callback || context) {
10971            for (j = 0, k = events.length; j < k; j++) {
10972              ev = events[j];
10973              if ((callback && callback !== ev.callback && callback !== ev.callback._callback) ||
10974                  (context && context !== ev.context)) {
10975                retain.push(ev);
10976              }
10977            }
10978          }
10979          if (!retain.length) delete this._events[name];
10980        }
10981      }
10982
10983      return this;
10984    },
10985
10986    // Trigger one or many events, firing all bound callbacks. Callbacks are
10987    // passed the same arguments as `trigger` is, apart from the event name
10988    // (unless you're listening on `"all"`, which will cause your callback to
10989    // receive the true name of the event as the first argument).
10990    trigger: function(name) {
10991      if (!this._events) return this;
10992      var args = slice.call(arguments, 1);
10993      if (!eventsApi(this, 'trigger', name, args)) return this;
10994      var events = this._events[name];
10995      var allEvents = this._events.all;
10996      if (events) triggerEvents(events, args);
10997      if (allEvents) triggerEvents(allEvents, arguments);
10998      return this;
10999    },
11000
11001    // Tell this object to stop listening to either specific events ... or
11002    // to every object it's currently listening to.
11003    stopListening: function(obj, name, callback) {
11004      var listeners = this._listeners;
11005      if (!listeners) return this;
11006      var deleteListener = !name && !callback;
11007      if (typeof name === 'object') callback = this;
11008      if (obj) (listeners = {})[obj._listenerId] = obj;
11009      for (var id in listeners) {
11010        listeners[id].off(name, callback, this);
11011        if (deleteListener) delete this._listeners[id];
11012      }
11013      return this;
11014    }
11015
11016  };
11017
11018  // Regular expression used to split event strings.
11019  var eventSplitter = /\s+/;
11020
11021  // Implement fancy features of the Events API such as multiple event
11022  // names `"change blur"` and jQuery-style event maps `{change: action}`
11023  // in terms of the existing API.
11024  var eventsApi = function(obj, action, name, rest) {
11025    if (!name) return true;
11026
11027    // Handle event maps.
11028    if (typeof name === 'object') {
11029      for (var key in name) {
11030        obj[action].apply(obj, [key, name[key]].concat(rest));
11031      }
11032      return false;
11033    }
11034
11035    // Handle space separated event names.
11036    if (eventSplitter.test(name)) {
11037      var names = name.split(eventSplitter);
11038      for (var i = 0, l = names.length; i < l; i++) {
11039        obj[action].apply(obj, [names[i]].concat(rest));
11040      }
11041      return false;
11042    }
11043
11044    return true;
11045  };
11046
11047  // A difficult-to-believe, but optimized internal dispatch function for
11048  // triggering events. Tries to keep the usual cases speedy (most internal
11049  // Backbone events have 3 arguments).
11050  var triggerEvents = function(events, args) {
11051    var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
11052    switch (args.length) {
11053      case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
11054      case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
11055      case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
11056      case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
11057      default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args);
11058    }
11059  };
11060
11061  var listenMethods = {listenTo: 'on', listenToOnce: 'once'};
11062
11063  // Inversion-of-control versions of `on` and `once`. Tell *this* object to
11064  // listen to an event in another object ... keeping track of what it's
11065  // listening to.
11066  _.each(listenMethods, function(implementation, method) {
11067    Events[method] = function(obj, name, callback) {
11068      var listeners = this._listeners || (this._listeners = {});
11069      var id = obj._listenerId || (obj._listenerId = _.uniqueId('l'));
11070      listeners[id] = obj;
11071      if (typeof name === 'object') callback = this;
11072      obj[implementation](name, callback, this);
11073      return this;
11074    };
11075  });
11076
11077  // Aliases for backwards compatibility.
11078  Events.bind   = Events.on;
11079  Events.unbind = Events.off;
11080
11081  // Allow the `Backbone` object to serve as a global event bus, for folks who
11082  // want global "pubsub" in a convenient place.
11083  _.extend(Backbone, Events);
11084
11085  // Backbone.Model
11086  // --------------
11087
11088  // Backbone **Models** are the basic data object in the framework --
11089  // frequently representing a row in a table in a database on your server.
11090  // A discrete chunk of data and a bunch of useful, related methods for
11091  // performing computations and transformations on that data.
11092
11093  // Create a new model with the specified attributes. A client id (`cid`)
11094  // is automatically generated and assigned for you.
11095  var Model = Backbone.Model = function(attributes, options) {
11096    var defaults;
11097    var attrs = attributes || {};
11098    options || (options = {});
11099    this.cid = _.uniqueId('c');
11100    this.attributes = {};
11101    _.extend(this, _.pick(options, modelOptions));
11102    if (options.parse) attrs = this.parse(attrs, options) || {};
11103    if (defaults = _.result(this, 'defaults')) {
11104      attrs = _.defaults({}, attrs, defaults);
11105    }
11106    this.set(attrs, options);
11107    this.changed = {};
11108    this.initialize.apply(this, arguments);
11109  };
11110
11111  // A list of options to be attached directly to the model, if provided.
11112  var modelOptions = ['url', 'urlRoot', 'collection'];
11113
11114  // Attach all inheritable methods to the Model prototype.
11115  _.extend(Model.prototype, Events, {
11116
11117    // A hash of attributes whose current and previous value differ.
11118    changed: null,
11119
11120    // The value returned during the last failed validation.
11121    validationError: null,
11122
11123    // The default name for the JSON `id` attribute is `"id"`. MongoDB and
11124    // CouchDB users may want to set this to `"_id"`.
11125    idAttribute: 'id',
11126
11127    // Initialize is an empty function by default. Override it with your own
11128    // initialization logic.
11129    initialize: function(){},
11130
11131    // Return a copy of the model's `attributes` object.
11132    toJSON: function(options) {
11133      return _.clone(this.attributes);
11134    },
11135
11136    // Proxy `Backbone.sync` by default -- but override this if you need
11137    // custom syncing semantics for *this* particular model.
11138    sync: function() {
11139      return Backbone.sync.apply(this, arguments);
11140    },
11141
11142    // Get the value of an attribute.
11143    get: function(attr) {
11144      return this.attributes[attr];
11145    },
11146
11147    // Get the HTML-escaped value of an attribute.
11148    escape: function(attr) {
11149      return _.escape(this.get(attr));
11150    },
11151
11152    // Returns `true` if the attribute contains a value that is not null
11153    // or undefined.
11154    has: function(attr) {
11155      return this.get(attr) != null;
11156    },
11157
11158    // Set a hash of model attributes on the object, firing `"change"`. This is
11159    // the core primitive operation of a model, updating the data and notifying
11160    // anyone who needs to know about the change in state. The heart of the beast.
11161    set: function(key, val, options) {
11162      var attr, attrs, unset, changes, silent, changing, prev, current;
11163      if (key == null) return this;
11164
11165      // Handle both `"key", value` and `{key: value}` -style arguments.
11166      if (typeof key === 'object') {
11167        attrs = key;
11168        options = val;
11169      } else {
11170        (attrs = {})[key] = val;
11171      }
11172
11173      options || (options = {});
11174
11175      // Run validation.
11176      if (!this._validate(attrs, options)) return false;
11177
11178      // Extract attributes and options.
11179      unset           = options.unset;
11180      silent          = options.silent;
11181      changes         = [];
11182      changing        = this._changing;
11183      this._changing  = true;
11184
11185      if (!changing) {
11186        this._previousAttributes = _.clone(this.attributes);
11187        this.changed = {};
11188      }
11189      current = this.attributes, prev = this._previousAttributes;
11190
11191      // Check for changes of `id`.
11192      if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
11193
11194      // For each `set` attribute, update or delete the current value.
11195      for (attr in attrs) {
11196        val = attrs[attr];
11197        if (!_.isEqual(current[attr], val)) changes.push(attr);
11198        if (!_.isEqual(prev[attr], val)) {
11199          this.changed[attr] = val;
11200        } else {
11201          delete this.changed[attr];
11202        }
11203        unset ? delete current[attr] : current[attr] = val;
11204      }
11205
11206      // Trigger all relevant attribute changes.
11207      if (!silent) {
11208        if (changes.length) this._pending = true;
11209        for (var i = 0, l = changes.length; i < l; i++) {
11210          this.trigger('change:' + changes[i], this, current[changes[i]], options);
11211        }
11212      }
11213
11214      // You might be wondering why there's a `while` loop here. Changes can
11215      // be recursively nested within `"change"` events.
11216      if (changing) return this;
11217      if (!silent) {
11218        while (this._pending) {
11219          this._pending = false;
11220          this.trigger('change', this, options);
11221        }
11222      }
11223      this._pending = false;
11224      this._changing = false;
11225      return this;
11226    },
11227
11228    // Remove an attribute from the model, firing `"change"`. `unset` is a noop
11229    // if the attribute doesn't exist.
11230    unset: function(attr, options) {
11231      return this.set(attr, void 0, _.extend({}, options, {unset: true}));
11232    },
11233
11234    // Clear all attributes on the model, firing `"change"`.
11235    clear: function(options) {
11236      var attrs = {};
11237      for (var key in this.attributes) attrs[key] = void 0;
11238      return this.set(attrs, _.extend({}, options, {unset: true}));
11239    },
11240
11241    // Determine if the model has changed since the last `"change"` event.
11242    // If you specify an attribute name, determine if that attribute has changed.
11243    hasChanged: function(attr) {
11244      if (attr == null) return !_.isEmpty(this.changed);
11245      return _.has(this.changed, attr);
11246    },
11247
11248    // Return an object containing all the attributes that have changed, or
11249    // false if there are no changed attributes. Useful for determining what
11250    // parts of a view need to be updated and/or what attributes need to be
11251    // persisted to the server. Unset attributes will be set to undefined.
11252    // You can also pass an attributes object to diff against the model,
11253    // determining if there *would be* a change.
11254    changedAttributes: function(diff) {
11255      if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
11256      var val, changed = false;
11257      var old = this._changing ? this._previousAttributes : this.attributes;
11258      for (var attr in diff) {
11259        if (_.isEqual(old[attr], (val = diff[attr]))) continue;
11260        (changed || (changed = {}))[attr] = val;
11261      }
11262      return changed;
11263    },
11264
11265    // Get the previous value of an attribute, recorded at the time the last
11266    // `"change"` event was fired.
11267    previous: function(attr) {
11268      if (attr == null || !this._previousAttributes) return null;
11269      return this._previousAttributes[attr];
11270    },
11271
11272    // Get all of the attributes of the model at the time of the previous
11273    // `"change"` event.
11274    previousAttributes: function() {
11275      return _.clone(this._previousAttributes);
11276    },
11277
11278    // Fetch the model from the server. If the server's representation of the
11279    // model differs from its current attributes, they will be overridden,
11280    // triggering a `"change"` event.
11281    fetch: function(options) {
11282      options = options ? _.clone(options) : {};
11283      if (options.parse === void 0) options.parse = true;
11284      var model = this;
11285      var success = options.success;
11286      options.success = function(resp) {
11287        if (!model.set(model.parse(resp, options), options)) return false;
11288        if (success) success(model, resp, options);
11289        model.trigger('sync', model, resp, options);
11290      };
11291      wrapError(this, options);
11292      return this.sync('read', this, options);
11293    },
11294
11295    // Set a hash of model attributes, and sync the model to the server.
11296    // If the server returns an attributes hash that differs, the model's
11297    // state will be `set` again.
11298    save: function(key, val, options) {
11299      var attrs, method, xhr, attributes = this.attributes;
11300
11301      // Handle both `"key", value` and `{key: value}` -style arguments.
11302      if (key == null || typeof key === 'object') {
11303        attrs = key;
11304        options = val;
11305      } else {
11306        (attrs = {})[key] = val;
11307      }
11308
11309      // If we're not waiting and attributes exist, save acts as `set(attr).save(null, opts)`.
11310      if (attrs && (!options || !options.wait) && !this.set(attrs, options)) return false;
11311
11312      options = _.extend({validate: true}, options);
11313
11314      // Do not persist invalid models.
11315      if (!this._validate(attrs, options)) return false;
11316
11317      // Set temporary attributes if `{wait: true}`.
11318      if (attrs && options.wait) {
11319        this.attributes = _.extend({}, attributes, attrs);
11320      }
11321
11322      // After a successful server-side save, the client is (optionally)
11323      // updated with the server-side state.
11324      if (options.parse === void 0) options.parse = true;
11325      var model = this;
11326      var success = options.success;
11327      options.success = function(resp) {
11328        // Ensure attributes are restored during synchronous saves.
11329        model.attributes = attributes;
11330        var serverAttrs = model.parse(resp, options);
11331        if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs);
11332        if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) {
11333          return false;
11334        }
11335        if (success) success(model, resp, options);
11336        model.trigger('sync', model, resp, options);
11337      };
11338      wrapError(this, options);
11339
11340      method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
11341      if (method === 'patch') options.attrs = attrs;
11342      xhr = this.sync(method, this, options);
11343
11344      // Restore attributes.
11345      if (attrs && options.wait) this.attributes = attributes;
11346
11347      return xhr;
11348    },
11349
11350    // Destroy this model on the server if it was already persisted.
11351    // Optimistically removes the model from its collection, if it has one.
11352    // If `wait: true` is passed, waits for the server to respond before removal.
11353    destroy: function(options) {
11354      options = options ? _.clone(options) : {};
11355      var model = this;
11356      var success = options.success;
11357
11358      var destroy = function() {
11359        model.trigger('destroy', model, model.collection, options);
11360      };
11361
11362      options.success = function(resp) {
11363        if (options.wait || model.isNew()) destroy();
11364        if (success) success(model, resp, options);
11365        if (!model.isNew()) model.trigger('sync', model, resp, options);
11366      };
11367
11368      if (this.isNew()) {
11369        options.success();
11370        return false;
11371      }
11372      wrapError(this, options);
11373
11374      var xhr = this.sync('delete', this, options);
11375      if (!options.wait) destroy();
11376      return xhr;
11377    },
11378
11379    // Default URL for the model's representation on the server -- if you're
11380    // using Backbone's restful methods, override this to change the endpoint
11381    // that will be called.
11382    url: function() {
11383      var base = _.result(this, 'urlRoot') || _.result(this.collection, 'url') || urlError();
11384      if (this.isNew()) return base;
11385      return base + (base.charAt(base.length - 1) === '/' ? '' : '/') + encodeURIComponent(this.id);
11386    },
11387
11388    // **parse** converts a response into the hash of attributes to be `set` on
11389    // the model. The default implementation is just to pass the response along.
11390    parse: function(resp, options) {
11391      return resp;
11392    },
11393
11394    // Create a new model with identical attributes to this one.
11395    clone: function() {
11396      return new this.constructor(this.attributes);
11397    },
11398
11399    // A model is new if it has never been saved to the server, and lacks an id.
11400    isNew: function() {
11401      return this.id == null;
11402    },
11403
11404    // Check if the model is currently in a valid state.
11405    isValid: function(options) {
11406      return this._validate({}, _.extend(options || {}, { validate: true }));
11407    },
11408
11409    // Run validation against the next complete set of model attributes,
11410    // returning `true` if all is well. Otherwise, fire an `"invalid"` event.
11411    _validate: function(attrs, options) {
11412      if (!options.validate || !this.validate) return true;
11413      attrs = _.extend({}, this.attributes, attrs);
11414      var error = this.validationError = this.validate(attrs, options) || null;
11415      if (!error) return true;
11416      this.trigger('invalid', this, error, _.extend(options || {}, {validationError: error}));
11417      return false;
11418    }
11419
11420  });
11421
11422  // Underscore methods that we want to implement on the Model.
11423  var modelMethods = ['keys', 'values', 'pairs', 'invert', 'pick', 'omit'];
11424
11425  // Mix in each Underscore method as a proxy to `Model#attributes`.
11426  _.each(modelMethods, function(method) {
11427    Model.prototype[method] = function() {
11428      var args = slice.call(arguments);
11429      args.unshift(this.attributes);
11430      return _[method].apply(_, args);
11431    };
11432  });
11433
11434  // Backbone.Collection
11435  // -------------------
11436
11437  // If models tend to represent a single row of data, a Backbone Collection is
11438  // more analagous to a table full of data ... or a small slice or page of that
11439  // table, or a collection of rows that belong together for a particular reason
11440  // -- all of the messages in this particular folder, all of the documents
11441  // belonging to this particular author, and so on. Collections maintain
11442  // indexes of their models, both in order, and for lookup by `id`.
11443
11444  // Create a new **Collection**, perhaps to contain a specific type of `model`.
11445  // If a `comparator` is specified, the Collection will maintain
11446  // its models in sort order, as they're added and removed.
11447  var Collection = Backbone.Collection = function(models, options) {
11448    options || (options = {});
11449    if (options.url) this.url = options.url;
11450    if (options.model) this.model = options.model;
11451    if (options.comparator !== void 0) this.comparator = options.comparator;
11452    this._reset();
11453    this.initialize.apply(this, arguments);
11454    if (models) this.reset(models, _.extend({silent: true}, options));
11455  };
11456
11457  // Default options for `Collection#set`.
11458  var setOptions = {add: true, remove: true, merge: true};
11459  var addOptions = {add: true, merge: false, remove: false};
11460
11461  // Define the Collection's inheritable methods.
11462  _.extend(Collection.prototype, Events, {
11463
11464    // The default model for a collection is just a **Backbone.Model**.
11465    // This should be overridden in most cases.
11466    model: Model,
11467
11468    // Initialize is an empty function by default. Override it with your own
11469    // initialization logic.
11470    initialize: function(){},
11471
11472    // The JSON representation of a Collection is an array of the
11473    // models' attributes.
11474    toJSON: function(options) {
11475      return this.map(function(model){ return model.toJSON(options); });
11476    },
11477
11478    // Proxy `Backbone.sync` by default.
11479    sync: function() {
11480      return Backbone.sync.apply(this, arguments);
11481    },
11482
11483    // Add a model, or list of models to the set.
11484    add: function(models, options) {
11485      return this.set(models, _.defaults(options || {}, addOptions));
11486    },
11487
11488    // Remove a model, or a list of models from the set.
11489    remove: function(models, options) {
11490      models = _.isArray(models) ? models.slice() : [models];
11491      options || (options = {});
11492      var i, l, index, model;
11493      for (i = 0, l = models.length; i < l; i++) {
11494        model = this.get(models[i]);
11495        if (!model) continue;
11496        delete this._byId[model.id];
11497        delete this._byId[model.cid];
11498        index = this.indexOf(model);
11499        this.models.splice(index, 1);
11500        this.length--;
11501        if (!options.silent) {
11502          options.index = index;
11503          model.trigger('remove', model, this, options);
11504        }
11505        this._removeReference(model);
11506      }
11507      return this;
11508    },
11509
11510    // Update a collection by `set`-ing a new list of models, adding new ones,
11511    // removing models that are no longer present, and merging models that
11512    // already exist in the collection, as necessary. Similar to **Model#set**,
11513    // the core operation for updating the data contained by the collection.
11514    set: function(models, options) {
11515      options = _.defaults(options || {}, setOptions);
11516      if (options.parse) models = this.parse(models, options);
11517      if (!_.isArray(models)) models = models ? [models] : [];
11518      var i, l, model, attrs, existing, sort;
11519      var at = options.at;
11520      var sortable = this.comparator && (at == null) && options.sort !== false;
11521      var sortAttr = _.isString(this.comparator) ? this.comparator : null;
11522      var toAdd = [], toRemove = [], modelMap = {};
11523
11524      // Turn bare objects into model references, and prevent invalid models
11525      // from being added.
11526      for (i = 0, l = models.length; i < l; i++) {
11527        if (!(model = this._prepareModel(models[i], options))) continue;
11528
11529        // If a duplicate is found, prevent it from being added and
11530        // optionally merge it into the existing model.
11531        if (existing = this.get(model)) {
11532          if (options.remove) modelMap[existing.cid] = true;
11533          if (options.merge) {
11534            existing.set(model.attributes, options);
11535            if (sortable && !sort && existing.hasChanged(sortAttr)) sort = true;
11536          }
11537
11538        // This is a new model, push it to the `toAdd` list.
11539        } else if (options.add) {
11540          toAdd.push(model);
11541
11542          // Listen to added models' events, and index models for lookup by
11543          // `id` and by `cid`.
11544          model.on('all', this._onModelEvent, this);
11545          this._byId[model.cid] = model;
11546          if (model.id != null) this._byId[model.id] = model;
11547        }
11548      }
11549
11550      // Remove nonexistent models if appropriate.
11551      if (options.remove) {
11552        for (i = 0, l = this.length; i < l; ++i) {
11553          if (!modelMap[(model = this.models[i]).cid]) toRemove.push(model);
11554        }
11555        if (toRemove.length) this.remove(toRemove, options);
11556      }
11557
11558      // See if sorting is needed, update `length` and splice in new models.
11559      if (toAdd.length) {
11560        if (sortable) sort = true;
11561        this.length += toAdd.length;
11562        if (at != null) {
11563          splice.apply(this.models, [at, 0].concat(toAdd));
11564        } else {
11565          push.apply(this.models, toAdd);
11566        }
11567      }
11568
11569      // Silently sort the collection if appropriate.
11570      if (sort) this.sort({silent: true});
11571
11572      if (options.silent) return this;
11573
11574      // Trigger `add` events.
11575      for (i = 0, l = toAdd.length; i < l; i++) {
11576        (model = toAdd[i]).trigger('add', model, this, options);
11577      }
11578
11579      // Trigger `sort` if the collection was sorted.
11580      if (sort) this.trigger('sort', this, options);
11581      return this;
11582    },
11583
11584    // When you have more items than you want to add or remove individually,
11585    // you can reset the entire set with a new list of models, without firing
11586    // any granular `add` or `remove` events. Fires `reset` when finished.
11587    // Useful for bulk operations and optimizations.
11588    reset: function(models, options) {
11589      options || (options = {});
11590      for (var i = 0, l = this.models.length; i < l; i++) {
11591        this._removeReference(this.models[i]);
11592      }
11593      options.previousModels = this.models;
11594      this._reset();
11595      this.add(models, _.extend({silent: true}, options));
11596      if (!options.silent) this.trigger('reset', this, options);
11597      return this;
11598    },
11599
11600    // Add a model to the end of the collection.
11601    push: function(model, options) {
11602      model = this._prepareModel(model, options);
11603      this.add(model, _.extend({at: this.length}, options));
11604      return model;
11605    },
11606
11607    // Remove a model from the end of the collection.
11608    pop: function(options) {
11609      var model = this.at(this.length - 1);
11610      this.remove(model, options);
11611      return model;
11612    },
11613
11614    // Add a model to the beginning of the collection.
11615    unshift: function(model, options) {
11616      model = this._prepareModel(model, options);
11617      this.add(model, _.extend({at: 0}, options));
11618      return model;
11619    },
11620
11621    // Remove a model from the beginning of the collection.
11622    shift: function(options) {
11623      var model = this.at(0);
11624      this.remove(model, options);
11625      return model;
11626    },
11627
11628    // Slice out a sub-array of models from the collection.
11629    slice: function(begin, end) {
11630      return this.models.slice(begin, end);
11631    },
11632
11633    // Get a model from the set by id.
11634    get: function(obj) {
11635      if (obj == null) return void 0;
11636      return this._byId[obj.id != null ? obj.id : obj.cid || obj];
11637    },
11638
11639    // Get the model at the given index.
11640    at: function(index) {
11641      return this.models[index];
11642    },
11643
11644    // Return models with matching attributes. Useful for simple cases of
11645    // `filter`.
11646    where: function(attrs, first) {
11647      if (_.isEmpty(attrs)) return first ? void 0 : [];
11648      return this[first ? 'find' : 'filter'](function(model) {
11649        for (var key in attrs) {
11650          if (attrs[key] !== model.get(key)) return false;
11651        }
11652        return true;
11653      });
11654    },
11655
11656    // Return the first model with matching attributes. Useful for simple cases
11657    // of `find`.
11658    findWhere: function(attrs) {
11659      return this.where(attrs, true);
11660    },
11661
11662    // Force the collection to re-sort itself. You don't need to call this under
11663    // normal circumstances, as the set will maintain sort order as each item
11664    // is added.
11665    sort: function(options) {
11666      if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
11667      options || (options = {});
11668
11669      // Run sort based on type of `comparator`.
11670      if (_.isString(this.comparator) || this.comparator.length === 1) {
11671        this.models = this.sortBy(this.comparator, this);
11672      } else {
11673        this.models.sort(_.bind(this.comparator, this));
11674      }
11675
11676      if (!options.silent) this.trigger('sort', this, options);
11677      return this;
11678    },
11679
11680    // Figure out the smallest index at which a model should be inserted so as
11681    // to maintain order.
11682    sortedIndex: function(model, value, context) {
11683      value || (value = this.comparator);
11684      var iterator = _.isFunction(value) ? value : function(model) {
11685        return model.get(value);
11686      };
11687      return _.sortedIndex(this.models, model, iterator, context);
11688    },
11689
11690    // Pluck an attribute from each model in the collection.
11691    pluck: function(attr) {
11692      return _.invoke(this.models, 'get', attr);
11693    },
11694
11695    // Fetch the default set of models for this collection, resetting the
11696    // collection when they arrive. If `reset: true` is passed, the response
11697    // data will be passed through the `reset` method instead of `set`.
11698    fetch: function(options) {
11699      options = options ? _.clone(options) : {};
11700      if (options.parse === void 0) options.parse = true;
11701      var success = options.success;
11702      var collection = this;
11703      options.success = function(resp) {
11704        var method = options.reset ? 'reset' : 'set';
11705        collection[method](resp, options);
11706        if (success) success(collection, resp, options);
11707        collection.trigger('sync', collection, resp, options);
11708      };
11709      wrapError(this, options);
11710      return this.sync('read', this, options);
11711    },
11712
11713    // Create a new instance of a model in this collection. Add the model to the
11714    // collection immediately, unless `wait: true` is passed, in which case we
11715    // wait for the server to agree.
11716    create: function(model, options) {
11717      options = options ? _.clone(options) : {};
11718      if (!(model = this._prepareModel(model, options))) return false;
11719      if (!options.wait) this.add(model, options);
11720      var collection = this;
11721      var success = options.success;
11722      options.success = function(resp) {
11723        if (options.wait) collection.add(model, options);
11724        if (success) success(model, resp, options);
11725      };
11726      model.save(null, options);
11727      return model;
11728    },
11729
11730    // **parse** converts a response into a list of models to be added to the
11731    // collection. The default implementation is just to pass it through.
11732    parse: function(resp, options) {
11733      return resp;
11734    },
11735
11736    // Create a new collection with an identical list of models as this one.
11737    clone: function() {
11738      return new this.constructor(this.models);
11739    },
11740
11741    // Private method to reset all internal state. Called when the collection
11742    // is first initialized or reset.
11743    _reset: function() {
11744      this.length = 0;
11745      this.models = [];
11746      this._byId  = {};
11747    },
11748
11749    // Prepare a hash of attributes (or other model) to be added to this
11750    // collection.
11751    _prepareModel: function(attrs, options) {
11752      if (attrs instanceof Model) {
11753        if (!attrs.collection) attrs.collection = this;
11754        return attrs;
11755      }
11756      options || (options = {});
11757      options.collection = this;
11758      var model = new this.model(attrs, options);
11759      if (!model._validate(attrs, options)) {
11760        this.trigger('invalid', this, attrs, options);
11761        return false;
11762      }
11763      return model;
11764    },
11765
11766    // Internal method to sever a model's ties to a collection.
11767    _removeReference: function(model) {
11768      if (this === model.collection) delete model.collection;
11769      model.off('all', this._onModelEvent, this);
11770    },
11771
11772    // Internal method called every time a model in the set fires an event.
11773    // Sets need to update their indexes when models change ids. All other
11774    // events simply proxy through. "add" and "remove" events that originate
11775    // in other collections are ignored.
11776    _onModelEvent: function(event, model, collection, options) {
11777      if ((event === 'add' || event === 'remove') && collection !== this) return;
11778      if (event === 'destroy') this.remove(model, options);
11779      if (model && event === 'change:' + model.idAttribute) {
11780        delete this._byId[model.previous(model.idAttribute)];
11781        if (model.id != null) this._byId[model.id] = model;
11782      }
11783      this.trigger.apply(this, arguments);
11784    }
11785
11786  });
11787
11788  // Underscore methods that we want to implement on the Collection.
11789  // 90% of the core usefulness of Backbone Collections is actually implemented
11790  // right here:
11791  var methods = ['forEach', 'each', 'map', 'collect', 'reduce', 'foldl',
11792    'inject', 'reduceRight', 'foldr', 'find', 'detect', 'filter', 'select',
11793    'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke',
11794    'max', 'min', 'toArray', 'size', 'first', 'head', 'take', 'initial', 'rest',
11795    'tail', 'drop', 'last', 'without', 'indexOf', 'shuffle', 'lastIndexOf',
11796    'isEmpty', 'chain'];
11797
11798  // Mix in each Underscore method as a proxy to `Collection#models`.
11799  _.each(methods, function(method) {
11800    Collection.prototype[method] = function() {
11801      var args = slice.call(arguments);
11802      args.unshift(this.models);
11803      return _[method].apply(_, args);
11804    };
11805  });
11806
11807  // Underscore methods that take a property name as an argument.
11808  var attributeMethods = ['groupBy', 'countBy', 'sortBy'];
11809
11810  // Use attributes instead of properties.
11811  _.each(attributeMethods, function(method) {
11812    Collection.prototype[method] = function(value, context) {
11813      var iterator = _.isFunction(value) ? value : function(model) {
11814        return model.get(value);
11815      };
11816      return _[method](this.models, iterator, context);
11817    };
11818  });
11819
11820  // Backbone.View
11821  // -------------
11822
11823  // Backbone Views are almost more convention than they are actual code. A View
11824  // is simply a JavaScript object that represents a logical chunk of UI in the
11825  // DOM. This might be a single item, an entire list, a sidebar or panel, or
11826  // even the surrounding frame which wraps your whole app. Defining a chunk of
11827  // UI as a **View** allows you to define your DOM events declaratively, without
11828  // having to worry about render order ... and makes it easy for the view to
11829  // react to specific changes in the state of your models.
11830
11831  // Creating a Backbone.View creates its initial element outside of the DOM,
11832  // if an existing element is not provided...
11833  var View = Backbone.View = function(options) {
11834    this.cid = _.uniqueId('view');
11835    this._configure(options || {});
11836    this._ensureElement();
11837    this.initialize.apply(this, arguments);
11838    this.delegateEvents();
11839  };
11840
11841  // Cached regex to split keys for `delegate`.
11842  var delegateEventSplitter = /^(\S+)\s*(.*)$/;
11843
11844  // List of view options to be merged as properties.
11845  var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
11846
11847  // Set up all inheritable **Backbone.View** properties and methods.
11848  _.extend(View.prototype, Events, {
11849
11850    // The default `tagName` of a View's element is `"div"`.
11851    tagName: 'div',
11852
11853    // jQuery delegate for element lookup, scoped to DOM elements within the
11854    // current view. This should be prefered to global lookups where possible.
11855    $: function(selector) {
11856      return this.$el.find(selector);
11857    },
11858
11859    // Initialize is an empty function by default. Override it with your own
11860    // initialization logic.
11861    initialize: function(){},
11862
11863    // **render** is the core function that your view should override, in order
11864    // to populate its element (`this.el`), with the appropriate HTML. The
11865    // convention is for **render** to always return `this`.
11866    render: function() {
11867      return this;
11868    },
11869
11870    // Remove this view by taking the element out of the DOM, and removing any
11871    // applicable Backbone.Events listeners.
11872    remove: function() {
11873      this.$el.remove();
11874      this.stopListening();
11875      return this;
11876    },
11877
11878    // Change the view's element (`this.el` property), including event
11879    // re-delegation.
11880    setElement: function(element, delegate) {
11881      if (this.$el) this.undelegateEvents();
11882      this.$el = element instanceof Backbone.$ ? element : Backbone.$(element);
11883      this.el = this.$el[0];
11884      if (delegate !== false) this.delegateEvents();
11885      return this;
11886    },
11887
11888    // Set callbacks, where `this.events` is a hash of
11889    //
11890    // *{"event selector": "callback"}*
11891    //
11892    //     {
11893    //       'mousedown .title':  'edit',
11894    //       'click .button':     'save'
11895    //       'click .open':       function(e) { ... }
11896    //     }
11897    //
11898    // pairs. Callbacks will be bound to the view, with `this` set properly.
11899    // Uses event delegation for efficiency.
11900    // Omitting the selector binds the event to `this.el`.
11901    // This only works for delegate-able events: not `focus`, `blur`, and
11902    // not `change`, `submit`, and `reset` in Internet Explorer.
11903    delegateEvents: function(events) {
11904      if (!(events || (events = _.result(this, 'events')))) return this;
11905      this.undelegateEvents();
11906      for (var key in events) {
11907        var method = events[key];
11908        if (!_.isFunction(method)) method = this[events[key]];
11909        if (!method) continue;
11910
11911        var match = key.match(delegateEventSplitter);
11912        var eventName = match[1], selector = match[2];
11913        method = _.bind(method, this);
11914        eventName += '.delegateEvents' + this.cid;
11915        if (selector === '') {
11916          this.$el.on(eventName, method);
11917        } else {
11918          this.$el.on(eventName, selector, method);
11919        }
11920      }
11921      return this;
11922    },
11923
11924    // Clears all callbacks previously bound to the view with `delegateEvents`.
11925    // You usually don't need to use this, but may wish to if you have multiple
11926    // Backbone views attached to the same DOM element.
11927    undelegateEvents: function() {
11928      this.$el.off('.delegateEvents' + this.cid);
11929      return this;
11930    },
11931
11932    // Performs the initial configuration of a View with a set of options.
11933    // Keys with special meaning *(e.g. model, collection, id, className)* are
11934    // attached directly to the view.  See `viewOptions` for an exhaustive
11935    // list.
11936    _configure: function(options) {
11937      if (this.options) options = _.extend({}, _.result(this, 'options'), options);
11938      _.extend(this, _.pick(options, viewOptions));
11939      this.options = options;
11940    },
11941
11942    // Ensure that the View has a DOM element to render into.
11943    // If `this.el` is a string, pass it through `$()`, take the first
11944    // matching element, and re-assign it to `el`. Otherwise, create
11945    // an element from the `id`, `className` and `tagName` properties.
11946    _ensureElement: function() {
11947      if (!this.el) {
11948        var attrs = _.extend({}, _.result(this, 'attributes'));
11949        if (this.id) attrs.id = _.result(this, 'id');
11950        if (this.className) attrs['class'] = _.result(this, 'className');
11951        var $el = Backbone.$('<' + _.result(this, 'tagName') + '/>').attr(attrs);
11952        this.setElement($el, false);
11953      } else {
11954        this.setElement(_.result(this, 'el'), false);
11955      }
11956    }
11957
11958  });
11959
11960  // Backbone.sync
11961  // -------------
11962
11963  // Override this function to change the manner in which Backbone persists
11964  // models to the server. You will be passed the type of request, and the
11965  // model in question. By default, makes a RESTful Ajax request
11966  // to the model's `url()`. Some possible customizations could be:
11967  //
11968  // * Use `setTimeout` to batch rapid-fire updates into a single request.
11969  // * Send up the models as XML instead of JSON.
11970  // * Persist models via WebSockets instead of Ajax.
11971  //
11972  // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests
11973  // as `POST`, with a `_method` parameter containing the true HTTP method,
11974  // as well as all requests with the body as `application/x-www-form-urlencoded`
11975  // instead of `application/json` with the model in a param named `model`.
11976  // Useful when interfacing with server-side languages like **PHP** that make
11977  // it difficult to read the body of `PUT` requests.
11978  Backbone.sync = function(method, model, options) {
11979    var type = methodMap[method];
11980
11981    // Default options, unless specified.
11982    _.defaults(options || (options = {}), {
11983      emulateHTTP: Backbone.emulateHTTP,
11984      emulateJSON: Backbone.emulateJSON
11985    });
11986
11987    // Default JSON-request options.
11988    var params = {type: type, dataType: 'json'};
11989
11990    // Ensure that we have a URL.
11991    if (!options.url) {
11992      params.url = _.result(model, 'url') || urlError();
11993    }
11994
11995    // Ensure that we have the appropriate request data.
11996    if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
11997      params.contentType = 'application/json';
11998      params.data = JSON.stringify(options.attrs || model.toJSON(options));
11999    }
12000
12001    // For older servers, emulate JSON by encoding the request into an HTML-form.
12002    if (options.emulateJSON) {
12003      params.contentType = 'application/x-www-form-urlencoded';
12004      params.data = params.data ? {model: params.data} : {};
12005    }
12006
12007    // For older servers, emulate HTTP by mimicking the HTTP method with `_method`
12008    // And an `X-HTTP-Method-Override` header.
12009    if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
12010      params.type = 'POST';
12011      if (options.emulateJSON) params.data._method = type;
12012      var beforeSend = options.beforeSend;
12013      options.beforeSend = function(xhr) {
12014        xhr.setRequestHeader('X-HTTP-Method-Override', type);
12015        if (beforeSend) return beforeSend.apply(this, arguments);
12016      };
12017    }
12018
12019    // Don't process data on a non-GET request.
12020    if (params.type !== 'GET' && !options.emulateJSON) {
12021      params.processData = false;
12022    }
12023
12024    // If we're sending a `PATCH` request, and we're in an old Internet Explorer
12025    // that still has ActiveX enabled by default, override jQuery to use that
12026    // for XHR instead. Remove this line when jQuery supports `PATCH` on IE8.
12027    if (params.type === 'PATCH' && window.ActiveXObject &&
12028          !(window.external && window.external.msActiveXFilteringEnabled)) {
12029      params.xhr = function() {
12030        return new ActiveXObject("Microsoft.XMLHTTP");
12031      };
12032    }
12033
12034    // Make the request, allowing the user to override any Ajax options.
12035    var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
12036    model.trigger('request', model, xhr, options);
12037    return xhr;
12038  };
12039
12040  // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
12041  var methodMap = {
12042    'create': 'POST',
12043    'update': 'PUT',
12044    'patch':  'PATCH',
12045    'delete': 'DELETE',
12046    'read':   'GET'
12047  };
12048
12049  // Set the default implementation of `Backbone.ajax` to proxy through to `$`.
12050  // Override this if you'd like to use a different library.
12051  Backbone.ajax = function() {
12052    return Backbone.$.ajax.apply(Backbone.$, arguments);
12053  };
12054
12055  // Backbone.Router
12056  // ---------------
12057
12058  // Routers map faux-URLs to actions, and fire events when routes are
12059  // matched. Creating a new one sets its `routes` hash, if not set statically.
12060  var Router = Backbone.Router = function(options) {
12061    options || (options = {});
12062    if (options.routes) this.routes = options.routes;
12063    this._bindRoutes();
12064    this.initialize.apply(this, arguments);
12065  };
12066
12067  // Cached regular expressions for matching named param parts and splatted
12068  // parts of route strings.
12069  var optionalParam = /\((.*?)\)/g;
12070  var namedParam    = /(\(\?)?:\w+/g;
12071  var splatParam    = /\*\w+/g;
12072  var escapeRegExp  = /[\-{}\[\]+?.,\\\^$|#\s]/g;
12073
12074  // Set up all inheritable **Backbone.Router** properties and methods.
12075  _.extend(Router.prototype, Events, {
12076
12077    // Initialize is an empty function by default. Override it with your own
12078    // initialization logic.
12079    initialize: function(){},
12080
12081    // Manually bind a single named route to a callback. For example:
12082    //
12083    //     this.route('search/:query/p:num', 'search', function(query, num) {
12084    //       ...
12085    //     });
12086    //
12087    route: function(route, name, callback) {
12088      if (!_.isRegExp(route)) route = this._routeToRegExp(route);
12089      if (_.isFunction(name)) {
12090        callback = name;
12091        name = '';
12092      }
12093      if (!callback) callback = this[name];
12094      var router = this;
12095      Backbone.history.route(route, function(fragment) {
12096        var args = router._extractParameters(route, fragment);
12097        callback && callback.apply(router, args);
12098        router.trigger.apply(router, ['route:' + name].concat(args));
12099        router.trigger('route', name, args);
12100        Backbone.history.trigger('route', router, name, args);
12101      });
12102      return this;
12103    },
12104
12105    // Simple proxy to `Backbone.history` to save a fragment into the history.
12106    navigate: function(fragment, options) {
12107      Backbone.history.navigate(fragment, options);
12108      return this;
12109    },
12110
12111    // Bind all defined routes to `Backbone.history`. We have to reverse the
12112    // order of the routes here to support behavior where the most general
12113    // routes can be defined at the bottom of the route map.
12114    _bindRoutes: function() {
12115      if (!this.routes) return;
12116      this.routes = _.result(this, 'routes');
12117      var route, routes = _.keys(this.routes);
12118      while ((route = routes.pop()) != null) {
12119        this.route(route, this.routes[route]);
12120      }
12121    },
12122
12123    // Convert a route string into a regular expression, suitable for matching
12124    // against the current location hash.
12125    _routeToRegExp: function(route) {
12126      route = route.replace(escapeRegExp, '\\$&')
12127                   .replace(optionalParam, '(?:$1)?')
12128                   .replace(namedParam, function(match, optional){
12129                     return optional ? match : '([^\/]+)';
12130                   })
12131                   .replace(splatParam, '(.*?)');
12132      return new RegExp('^' + route + '$');
12133    },
12134
12135    // Given a route, and a URL fragment that it matches, return the array of
12136    // extracted decoded parameters. Empty or unmatched parameters will be
12137    // treated as `null` to normalize cross-browser behavior.
12138    _extractParameters: function(route, fragment) {
12139      var params = route.exec(fragment).slice(1);
12140      return _.map(params, function(param) {
12141        return param ? decodeURIComponent(param) : null;
12142      });
12143    }
12144
12145  });
12146
12147  // Backbone.History
12148  // ----------------
12149
12150  // Handles cross-browser history management, based on either
12151  // [pushState](http://diveintohtml5.info/history.html) and real URLs, or
12152  // [onhashchange](https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange)
12153  // and URL fragments. If the browser supports neither (old IE, natch),
12154  // falls back to polling.
12155  var History = Backbone.History = function() {
12156    this.handlers = [];
12157    _.bindAll(this, 'checkUrl');
12158
12159    // Ensure that `History` can be used outside of the browser.
12160    if (typeof window !== 'undefined') {
12161      this.location = window.location;
12162      this.history = window.history;
12163    }
12164  };
12165
12166  // Cached regex for stripping a leading hash/slash and trailing space.
12167  var routeStripper = /^[#\/]|\s+$/g;
12168
12169  // Cached regex for stripping leading and trailing slashes.
12170  var rootStripper = /^\/+|\/+$/g;
12171
12172  // Cached regex for detecting MSIE.
12173  var isExplorer = /msie [\w.]+/;
12174
12175  // Cached regex for removing a trailing slash.
12176  var trailingSlash = /\/$/;
12177
12178  // Has the history handling already been started?
12179  History.started = false;
12180
12181  // Set up all inheritable **Backbone.History** properties and methods.
12182  _.extend(History.prototype, Events, {
12183
12184    // The default interval to poll for hash changes, if necessary, is
12185    // twenty times a second.
12186    interval: 50,
12187
12188    // Gets the true hash value. Cannot use location.hash directly due to bug
12189    // in Firefox where location.hash will always be decoded.
12190    getHash: function(window) {
12191      var match = (window || this).location.href.match(/#(.*)$/);
12192      return match ? match[1] : '';
12193    },
12194
12195    // Get the cross-browser normalized URL fragment, either from the URL,
12196    // the hash, or the override.
12197    getFragment: function(fragment, forcePushState) {
12198      if (fragment == null) {
12199        if (this._hasPushState || !this._wantsHashChange || forcePushState) {
12200          fragment = this.location.pathname;
12201          var root = this.root.replace(trailingSlash, '');
12202          if (!fragment.indexOf(root)) fragment = fragment.substr(root.length);
12203        } else {
12204          fragment = this.getHash();
12205        }
12206      }
12207      return fragment.replace(routeStripper, '');
12208    },
12209
12210    // Start the hash change handling, returning `true` if the current URL matches
12211    // an existing route, and `false` otherwise.
12212    start: function(options) {
12213      if (History.started) throw new Error("Backbone.history has already been started");
12214      History.started = true;
12215
12216      // Figure out the initial configuration. Do we need an iframe?
12217      // Is pushState desired ... is it available?
12218      this.options          = _.extend({}, {root: '/'}, this.options, options);
12219      this.root             = this.options.root;
12220      this._wantsHashChange = this.options.hashChange !== false;
12221      this._wantsPushState  = !!this.options.pushState;
12222      this._hasPushState    = !!(this.options.pushState && this.history && this.history.pushState);
12223      var fragment          = this.getFragment();
12224      var docMode           = document.documentMode;
12225      var oldIE             = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7));
12226
12227      // Normalize root to always include a leading and trailing slash.
12228      this.root = ('/' + this.root + '/').replace(rootStripper, '/');
12229
12230      if (oldIE && this._wantsHashChange) {
12231        this.iframe = Backbone.$('<iframe src="javascript:0" tabindex="-1" ></iframe>').hide().appendTo('body')[0].contentWindow;
12232        this.navigate(fragment);
12233      }
12234
12235      // Depending on whether we're using pushState or hashes, and whether
12236      // 'onhashchange' is supported, determine how we check the URL state.
12237      if (this._hasPushState) {
12238        Backbone.$(window).on('popstate', this.checkUrl);
12239      } else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) {
12240        Backbone.$(window).on('hashchange', this.checkUrl);
12241      } else if (this._wantsHashChange) {
12242        this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
12243      }
12244
12245      // Determine if we need to change the base url, for a pushState link
12246      // opened by a non-pushState browser.
12247      this.fragment = fragment;
12248      var loc = this.location;
12249      var atRoot = loc.pathname.replace(/[^\/]$/, '$&/') === this.root;
12250
12251      // If we've started off with a route from a `pushState`-enabled browser,
12252      // but we're currently in a browser that doesn't support it...
12253      if (this._wantsHashChange && this._wantsPushState && !this._hasPushState && !atRoot) {
12254        this.fragment = this.getFragment(null, true);
12255        this.location.replace(this.root + this.location.search + '#' + this.fragment);
12256        // Return immediately as browser will do redirect to new url
12257        return true;
12258
12259      // Or if we've started out with a hash-based route, but we're currently
12260      // in a browser where it could be `pushState`-based instead...
12261      } else if (this._wantsPushState && this._hasPushState && atRoot && loc.hash) {
12262        this.fragment = this.getHash().replace(routeStripper, '');
12263        this.history.replaceState({}, document.title, this.root + this.fragment + loc.search);
12264      }
12265
12266      if (!this.options.silent) return this.loadUrl();
12267    },
12268
12269    // Disable Backbone.history, perhaps temporarily. Not useful in a real app,
12270    // but possibly useful for unit testing Routers.
12271    stop: function() {
12272      Backbone.$(window).off('popstate', this.checkUrl).off('hashchange', this.checkUrl);
12273      clearInterval(this._checkUrlInterval);
12274      History.started = false;
12275    },
12276
12277    // Add a route to be tested when the fragment changes. Routes added later
12278    // may override previous routes.
12279    route: function(route, callback) {
12280      this.handlers.unshift({route: route, callback: callback});
12281    },
12282
12283    // Checks the current URL to see if it has changed, and if it has,
12284    // calls `loadUrl`, normalizing across the hidden iframe.
12285    checkUrl: function(e) {
12286      var current = this.getFragment();
12287      if (current === this.fragment && this.iframe) {
12288        current = this.getFragment(this.getHash(this.iframe));
12289      }
12290      if (current === this.fragment) return false;
12291      if (this.iframe) this.navigate(current);
12292      this.loadUrl() || this.loadUrl(this.getHash());
12293    },
12294
12295    // Attempt to load the current URL fragment. If a route succeeds with a
12296    // match, returns `true`. If no defined routes matches the fragment,
12297    // returns `false`.
12298    loadUrl: function(fragmentOverride) {
12299      var fragment = this.fragment = this.getFragment(fragmentOverride);
12300      var matched = _.any(this.handlers, function(handler) {
12301        if (handler.route.test(fragment)) {
12302          handler.callback(fragment);
12303          return true;
12304        }
12305      });
12306      return matched;
12307    },
12308
12309    // Save a fragment into the hash history, or replace the URL state if the
12310    // 'replace' option is passed. You are responsible for properly URL-encoding
12311    // the fragment in advance.
12312    //
12313    // The options object can contain `trigger: true` if you wish to have the
12314    // route callback be fired (not usually desirable), or `replace: true`, if
12315    // you wish to modify the current URL without adding an entry to the history.
12316    navigate: function(fragment, options) {
12317      if (!History.started) return false;
12318      if (!options || options === true) options = {trigger: options};
12319      fragment = this.getFragment(fragment || '');
12320      if (this.fragment === fragment) return;
12321      this.fragment = fragment;
12322      var url = this.root + fragment;
12323
12324      // If pushState is available, we use it to set the fragment as a real URL.
12325      if (this._hasPushState) {
12326        this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url);
12327
12328      // If hash changes haven't been explicitly disabled, update the hash
12329      // fragment to store history.
12330      } else if (this._wantsHashChange) {
12331        this._updateHash(this.location, fragment, options.replace);
12332        if (this.iframe && (fragment !== this.getFragment(this.getHash(this.iframe)))) {
12333          // Opening and closing the iframe tricks IE7 and earlier to push a
12334          // history entry on hash-tag change.  When replace is true, we don't
12335          // want this.
12336          if(!options.replace) this.iframe.document.open().close();
12337          this._updateHash(this.iframe.location, fragment, options.replace);
12338        }
12339
12340      // If you've told us that you explicitly don't want fallback hashchange-
12341      // based history, then `navigate` becomes a page refresh.
12342      } else {
12343        return this.location.assign(url);
12344      }
12345      if (options.trigger) this.loadUrl(fragment);
12346    },
12347
12348    // Update the hash location, either replacing the current entry, or adding
12349    // a new one to the browser history.
12350    _updateHash: function(location, fragment, replace) {
12351      if (replace) {
12352        var href = location.href.replace(/(javascript:|#).*$/, '');
12353        location.replace(href + '#' + fragment);
12354      } else {
12355        // Some browsers require that `hash` contains a leading #.
12356        location.hash = '#' + fragment;
12357      }
12358    }
12359
12360  });
12361
12362  // Create the default Backbone.history.
12363  Backbone.history = new History;
12364
12365  // Helpers
12366  // -------
12367
12368  // Helper function to correctly set up the prototype chain, for subclasses.
12369  // Similar to `goog.inherits`, but uses a hash of prototype properties and
12370  // class properties to be extended.
12371  var extend = function(protoProps, staticProps) {
12372    var parent = this;
12373    var child;
12374
12375    // The constructor function for the new subclass is either defined by you
12376    // (the "constructor" property in your `extend` definition), or defaulted
12377    // by us to simply call the parent's constructor.
12378    if (protoProps && _.has(protoProps, 'constructor')) {
12379      child = protoProps.constructor;
12380    } else {
12381      child = function(){ return parent.apply(this, arguments); };
12382    }
12383
12384    // Add static properties to the constructor function, if supplied.
12385    _.extend(child, parent, staticProps);
12386
12387    // Set the prototype chain to inherit from `parent`, without calling
12388    // `parent`'s constructor function.
12389    var Surrogate = function(){ this.constructor = child; };
12390    Surrogate.prototype = parent.prototype;
12391    child.prototype = new Surrogate;
12392
12393    // Add prototype properties (instance properties) to the subclass,
12394    // if supplied.
12395    if (protoProps) _.extend(child.prototype, protoProps);
12396
12397    // Set a convenience property in case the parent's prototype is needed
12398    // later.
12399    child.__super__ = parent.prototype;
12400
12401    return child;
12402  };
12403
12404  // Set up inheritance for the model, collection, router, view and history.
12405  Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;
12406
12407  // Throw an error when a URL is needed, and none is supplied.
12408  var urlError = function() {
12409    throw new Error('A "url" property or function must be specified');
12410  };
12411
12412  // Wrap an optional error callback with a fallback error event.
12413  var wrapError = function (model, options) {
12414    var error = options.error;
12415    options.error = function(resp) {
12416      if (error) error(model, resp, options);
12417      model.trigger('error', model, resp, options);
12418    };
12419  };
12420
12421}).call(this);
12422
12423//! moment.js
12424//! version : 2.29.4
12425//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
12426//! license : MIT
12427//! momentjs.com
12428
12429;(function (global, factory) {
12430    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
12431    typeof define === 'function' && define.amd ? define(factory) :
12432    global.moment = factory()
12433}(this, (function () { 'use strict';
12434
12435    var hookCallback;
12436
12437    function hooks() {
12438        return hookCallback.apply(null, arguments);
12439    }
12440
12441    // This is done to register the method called with moment()
12442    // without creating circular dependencies.
12443    function setHookCallback(callback) {
12444        hookCallback = callback;
12445    }
12446
12447    function isArray(input) {
12448        return (
12449            input instanceof Array ||
12450            Object.prototype.toString.call(input) === '[object Array]'
12451        );
12452    }
12453
12454    function isObject(input) {
12455        // IE8 will treat undefined and null as object if it wasn't for
12456        // input != null
12457        return (
12458            input != null &&
12459            Object.prototype.toString.call(input) === '[object Object]'
12460        );
12461    }
12462
12463    function hasOwnProp(a, b) {
12464        return Object.prototype.hasOwnProperty.call(a, b);
12465    }
12466
12467    function isObjectEmpty(obj) {
12468        if (Object.getOwnPropertyNames) {
12469            return Object.getOwnPropertyNames(obj).length === 0;
12470        } else {
12471            var k;
12472            for (k in obj) {
12473                if (hasOwnProp(obj, k)) {
12474                    return false;
12475                }
12476            }
12477            return true;
12478        }
12479    }
12480
12481    function isUndefined(input) {
12482        return input === void 0;
12483    }
12484
12485    function isNumber(input) {
12486        return (
12487            typeof input === 'number' ||
12488            Object.prototype.toString.call(input) === '[object Number]'
12489        );
12490    }
12491
12492    function isDate(input) {
12493        return (
12494            input instanceof Date ||
12495            Object.prototype.toString.call(input) === '[object Date]'
12496        );
12497    }
12498
12499    function map(arr, fn) {
12500        var res = [],
12501            i,
12502            arrLen = arr.length;
12503        for (i = 0; i < arrLen; ++i) {
12504            res.push(fn(arr[i], i));
12505        }
12506        return res;
12507    }
12508
12509    function extend(a, b) {
12510        for (var i in b) {
12511            if (hasOwnProp(b, i)) {
12512                a[i] = b[i];
12513            }
12514        }
12515
12516        if (hasOwnProp(b, 'toString')) {
12517            a.toString = b.toString;
12518        }
12519
12520        if (hasOwnProp(b, 'valueOf')) {
12521            a.valueOf = b.valueOf;
12522        }
12523
12524        return a;
12525    }
12526
12527    function createUTC(input, format, locale, strict) {
12528        return createLocalOrUTC(input, format, locale, strict, true).utc();
12529    }
12530
12531    function defaultParsingFlags() {
12532        // We need to deep clone this object.
12533        return {
12534            empty: false,
12535            unusedTokens: [],
12536            unusedInput: [],
12537            overflow: -2,
12538            charsLeftOver: 0,
12539            nullInput: false,
12540            invalidEra: null,
12541            invalidMonth: null,
12542            invalidFormat: false,
12543            userInvalidated: false,
12544            iso: false,
12545            parsedDateParts: [],
12546            era: null,
12547            meridiem: null,
12548            rfc2822: false,
12549            weekdayMismatch: false,
12550        };
12551    }
12552
12553    function getParsingFlags(m) {
12554        if (m._pf == null) {
12555            m._pf = defaultParsingFlags();
12556        }
12557        return m._pf;
12558    }
12559
12560    var some;
12561    if (Array.prototype.some) {
12562        some = Array.prototype.some;
12563    } else {
12564        some = function (fun) {
12565            var t = Object(this),
12566                len = t.length >>> 0,
12567                i;
12568
12569            for (i = 0; i < len; i++) {
12570                if (i in t && fun.call(this, t[i], i, t)) {
12571                    return true;
12572                }
12573            }
12574
12575            return false;
vendor: 66,440 bytes, lines 12576-14712
12576        };
12577    }
12578
12579    function isValid(m) {
12580        if (m._isValid == null) {
12581            var flags = getParsingFlags(m),
12582                parsedParts = some.call(flags.parsedDateParts, function (i) {
12583                    return i != null;
12584                }),
12585                isNowValid =
12586                    !isNaN(m._d.getTime()) &&
12587                    flags.overflow < 0 &&
12588                    !flags.empty &&
12589                    !flags.invalidEra &&
12590                    !flags.invalidMonth &&
12591                    !flags.invalidWeekday &&
12592                    !flags.weekdayMismatch &&
12593                    !flags.nullInput &&
12594                    !flags.invalidFormat &&
12595                    !flags.userInvalidated &&
12596                    (!flags.meridiem || (flags.meridiem && parsedParts));
12597
12598            if (m._strict) {
12599                isNowValid =
12600                    isNowValid &&
12601                    flags.charsLeftOver === 0 &&
12602                    flags.unusedTokens.length === 0 &&
12603                    flags.bigHour === undefined;
12604            }
12605
12606            if (Object.isFrozen == null || !Object.isFrozen(m)) {
12607                m._isValid = isNowValid;
12608            } else {
12609                return isNowValid;
12610            }
12611        }
12612        return m._isValid;
12613    }
12614
12615    function createInvalid(flags) {
12616        var m = createUTC(NaN);
12617        if (flags != null) {
12618            extend(getParsingFlags(m), flags);
12619        } else {
12620            getParsingFlags(m).userInvalidated = true;
12621        }
12622
12623        return m;
12624    }
12625
12626    // Plugins that add properties should also add the key here (null value),
12627    // so we can properly clone ourselves.
12628    var momentProperties = (hooks.momentProperties = []),
12629        updateInProgress = false;
12630
12631    function copyConfig(to, from) {
12632        var i,
12633            prop,
12634            val,
12635            momentPropertiesLen = momentProperties.length;
12636
12637        if (!isUndefined(from._isAMomentObject)) {
12638            to._isAMomentObject = from._isAMomentObject;
12639        }
12640        if (!isUndefined(from._i)) {
12641            to._i = from._i;
12642        }
12643        if (!isUndefined(from._f)) {
12644            to._f = from._f;
12645        }
12646        if (!isUndefined(from._l)) {
12647            to._l = from._l;
12648        }
12649        if (!isUndefined(from._strict)) {
12650            to._strict = from._strict;
12651        }
12652        if (!isUndefined(from._tzm)) {
12653            to._tzm = from._tzm;
12654        }
12655        if (!isUndefined(from._isUTC)) {
12656            to._isUTC = from._isUTC;
12657        }
12658        if (!isUndefined(from._offset)) {
12659            to._offset = from._offset;
12660        }
12661        if (!isUndefined(from._pf)) {
12662            to._pf = getParsingFlags(from);
12663        }
12664        if (!isUndefined(from._locale)) {
12665            to._locale = from._locale;
12666        }
12667
12668        if (momentPropertiesLen > 0) {
12669            for (i = 0; i < momentPropertiesLen; i++) {
12670                prop = momentProperties[i];
12671                val = from[prop];
12672                if (!isUndefined(val)) {
12673                    to[prop] = val;
12674                }
12675            }
12676        }
12677
12678        return to;
12679    }
12680
12681    // Moment prototype object
12682    function Moment(config) {
12683        copyConfig(this, config);
12684        this._d = new Date(config._d != null ? config._d.getTime() : NaN);
12685        if (!this.isValid()) {
12686            this._d = new Date(NaN);
12687        }
12688        // Prevent infinite loop in case updateOffset creates new moment
12689        // objects.
12690        if (updateInProgress === false) {
12691            updateInProgress = true;
12692            hooks.updateOffset(this);
12693            updateInProgress = false;
12694        }
12695    }
12696
12697    function isMoment(obj) {
12698        return (
12699            obj instanceof Moment || (obj != null && obj._isAMomentObject != null)
12700        );
12701    }
12702
12703    function warn(msg) {
12704        if (
12705            hooks.suppressDeprecationWarnings === false &&
12706            typeof console !== 'undefined' &&
12707            console.warn
12708        ) {
12709            console.warn('Deprecation warning: ' + msg);
12710        }
12711    }
12712
12713    function deprecate(msg, fn) {
12714        var firstTime = true;
12715
12716        return extend(function () {
12717            if (hooks.deprecationHandler != null) {
12718                hooks.deprecationHandler(null, msg);
12719            }
12720            if (firstTime) {
12721                var args = [],
12722                    arg,
12723                    i,
12724                    key,
12725                    argLen = arguments.length;
12726                for (i = 0; i < argLen; i++) {
12727                    arg = '';
12728                    if (typeof arguments[i] === 'object') {
12729                        arg += '\n[' + i + '] ';
12730                        for (key in arguments[0]) {
12731                            if (hasOwnProp(arguments[0], key)) {
12732                                arg += key + ': ' + arguments[0][key] + ', ';
12733                            }
12734                        }
12735                        arg = arg.slice(0, -2); // Remove trailing comma and space
12736                    } else {
12737                        arg = arguments[i];
12738                    }
12739                    args.push(arg);
12740                }
12741                warn(
12742                    msg +
12743                        '\nArguments: ' +
12744                        Array.prototype.slice.call(args).join('') +
12745                        '\n' +
12746                        new Error().stack
12747                );
12748                firstTime = false;
12749            }
12750            return fn.apply(this, arguments);
12751        }, fn);
12752    }
12753
12754    var deprecations = {};
12755
12756    function deprecateSimple(name, msg) {
12757        if (hooks.deprecationHandler != null) {
12758            hooks.deprecationHandler(name, msg);
12759        }
12760        if (!deprecations[name]) {
12761            warn(msg);
12762            deprecations[name] = true;
12763        }
12764    }
12765
12766    hooks.suppressDeprecationWarnings = false;
12767    hooks.deprecationHandler = null;
12768
12769    function isFunction(input) {
12770        return (
12771            (typeof Function !== 'undefined' && input instanceof Function) ||
12772            Object.prototype.toString.call(input) === '[object Function]'
12773        );
12774    }
12775
12776    function set(config) {
12777        var prop, i;
12778        for (i in config) {
12779            if (hasOwnProp(config, i)) {
12780                prop = config[i];
12781                if (isFunction(prop)) {
12782                    this[i] = prop;
12783                } else {
12784                    this['_' + i] = prop;
12785                }
12786            }
12787        }
12788        this._config = config;
12789        // Lenient ordinal parsing accepts just a number in addition to
12790        // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
12791        // TODO: Remove "ordinalParse" fallback in next major release.
12792        this._dayOfMonthOrdinalParseLenient = new RegExp(
12793            (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +
12794                '|' +
12795                /\d{1,2}/.source
12796        );
12797    }
12798
12799    function mergeConfigs(parentConfig, childConfig) {
12800        var res = extend({}, parentConfig),
12801            prop;
12802        for (prop in childConfig) {
12803            if (hasOwnProp(childConfig, prop)) {
12804                if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
12805                    res[prop] = {};
12806                    extend(res[prop], parentConfig[prop]);
12807                    extend(res[prop], childConfig[prop]);
12808                } else if (childConfig[prop] != null) {
12809                    res[prop] = childConfig[prop];
12810                } else {
12811                    delete res[prop];
12812                }
12813            }
12814        }
12815        for (prop in parentConfig) {
12816            if (
12817                hasOwnProp(parentConfig, prop) &&
12818                !hasOwnProp(childConfig, prop) &&
12819                isObject(parentConfig[prop])
12820            ) {
12821                // make sure changes to properties don't modify parent config
12822                res[prop] = extend({}, res[prop]);
12823            }
12824        }
12825        return res;
12826    }
12827
12828    function Locale(config) {
12829        if (config != null) {
12830            this.set(config);
12831        }
12832    }
12833
12834    var keys;
12835
12836    if (Object.keys) {
12837        keys = Object.keys;
12838    } else {
12839        keys = function (obj) {
12840            var i,
12841                res = [];
12842            for (i in obj) {
12843                if (hasOwnProp(obj, i)) {
12844                    res.push(i);
12845                }
12846            }
12847            return res;
12848        };
12849    }
12850
12851    var defaultCalendar = {
12852        sameDay: '[Today at] LT',
12853        nextDay: '[Tomorrow at] LT',
12854        nextWeek: 'dddd [at] LT',
12855        lastDay: '[Yesterday at] LT',
12856        lastWeek: '[Last] dddd [at] LT',
12857        sameElse: 'L',
12858    };
12859
12860    function calendar(key, mom, now) {
12861        var output = this._calendar[key] || this._calendar['sameElse'];
12862        return isFunction(output) ? output.call(mom, now) : output;
12863    }
12864
12865    function zeroFill(number, targetLength, forceSign) {
12866        var absNumber = '' + Math.abs(number),
12867            zerosToFill = targetLength - absNumber.length,
12868            sign = number >= 0;
12869        return (
12870            (sign ? (forceSign ? '+' : '') : '-') +
12871            Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) +
12872            absNumber
12873        );
12874    }
12875
12876    var formattingTokens =
12877            /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,
12878        localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,
12879        formatFunctions = {},
12880        formatTokenFunctions = {};
12881
12882    // token:    'M'
12883    // padded:   ['MM', 2]
12884    // ordinal:  'Mo'
12885    // callback: function () { this.month() + 1 }
12886    function addFormatToken(token, padded, ordinal, callback) {
12887        var func = callback;
12888        if (typeof callback === 'string') {
12889            func = function () {
12890                return this[callback]();
12891            };
12892        }
12893        if (token) {
12894            formatTokenFunctions[token] = func;
12895        }
12896        if (padded) {
12897            formatTokenFunctions[padded[0]] = function () {
12898                return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
12899            };
12900        }
12901        if (ordinal) {
12902            formatTokenFunctions[ordinal] = function () {
12903                return this.localeData().ordinal(
12904                    func.apply(this, arguments),
12905                    token
12906                );
12907            };
12908        }
12909    }
12910
12911    function removeFormattingTokens(input) {
12912        if (input.match(/\[[\s\S]/)) {
12913            return input.replace(/^\[|\]$/g, '');
12914        }
12915        return input.replace(/\\/g, '');
12916    }
12917
12918    function makeFormatFunction(format) {
12919        var array = format.match(formattingTokens),
12920            i,
12921            length;
12922
12923        for (i = 0, length = array.length; i < length; i++) {
12924            if (formatTokenFunctions[array[i]]) {
12925                array[i] = formatTokenFunctions[array[i]];
12926            } else {
12927                array[i] = removeFormattingTokens(array[i]);
12928            }
12929        }
12930
12931        return function (mom) {
12932            var output = '',
12933                i;
12934            for (i = 0; i < length; i++) {
12935                output += isFunction(array[i])
12936                    ? array[i].call(mom, format)
12937                    : array[i];
12938            }
12939            return output;
12940        };
12941    }
12942
12943    // format date using native date object
12944    function formatMoment(m, format) {
12945        if (!m.isValid()) {
12946            return m.localeData().invalidDate();
12947        }
12948
12949        format = expandFormat(format, m.localeData());
12950        formatFunctions[format] =
12951            formatFunctions[format] || makeFormatFunction(format);
12952
12953        return formatFunctions[format](m);
12954    }
12955
12956    function expandFormat(format, locale) {
12957        var i = 5;
12958
12959        function replaceLongDateFormatTokens(input) {
12960            return locale.longDateFormat(input) || input;
12961        }
12962
12963        localFormattingTokens.lastIndex = 0;
12964        while (i >= 0 && localFormattingTokens.test(format)) {
12965            format = format.replace(
12966                localFormattingTokens,
12967                replaceLongDateFormatTokens
12968            );
12969            localFormattingTokens.lastIndex = 0;
12970            i -= 1;
12971        }
12972
12973        return format;
12974    }
12975
12976    var defaultLongDateFormat = {
12977        LTS: 'h:mm:ss A',
12978        LT: 'h:mm A',
12979        L: 'MM/DD/YYYY',
12980        LL: 'MMMM D, YYYY',
12981        LLL: 'MMMM D, YYYY h:mm A',
12982        LLLL: 'dddd, MMMM D, YYYY h:mm A',
12983    };
12984
12985    function longDateFormat(key) {
12986        var format = this._longDateFormat[key],
12987            formatUpper = this._longDateFormat[key.toUpperCase()];
12988
12989        if (format || !formatUpper) {
12990            return format;
12991        }
12992
12993        this._longDateFormat[key] = formatUpper
12994            .match(formattingTokens)
12995            .map(function (tok) {
12996                if (
12997                    tok === 'MMMM' ||
12998                    tok === 'MM' ||
12999                    tok === 'DD' ||
13000                    tok === 'dddd'
13001                ) {
13002                    return tok.slice(1);
13003                }
13004                return tok;
13005            })
13006            .join('');
13007
13008        return this._longDateFormat[key];
13009    }
13010
13011    var defaultInvalidDate = 'Invalid date';
13012
13013    function invalidDate() {
13014        return this._invalidDate;
13015    }
13016
13017    var defaultOrdinal = '%d',
13018        defaultDayOfMonthOrdinalParse = /\d{1,2}/;
13019
13020    function ordinal(number) {
13021        return this._ordinal.replace('%d', number);
13022    }
13023
13024    var defaultRelativeTime = {
13025        future: 'in %s',
13026        past: '%s ago',
13027        s: 'a few seconds',
13028        ss: '%d seconds',
13029        m: 'a minute',
13030        mm: '%d minutes',
13031        h: 'an hour',
13032        hh: '%d hours',
13033        d: 'a day',
13034        dd: '%d days',
13035        w: 'a week',
13036        ww: '%d weeks',
13037        M: 'a month',
13038        MM: '%d months',
13039        y: 'a year',
13040        yy: '%d years',
13041    };
13042
13043    function relativeTime(number, withoutSuffix, string, isFuture) {
13044        var output = this._relativeTime[string];
13045        return isFunction(output)
13046            ? output(number, withoutSuffix, string, isFuture)
13047            : output.replace(/%d/i, number);
13048    }
13049
13050    function pastFuture(diff, output) {
13051        var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
13052        return isFunction(format) ? format(output) : format.replace(/%s/i, output);
13053    }
13054
13055    var aliases = {};
13056
13057    function addUnitAlias(unit, shorthand) {
13058        var lowerCase = unit.toLowerCase();
13059        aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
13060    }
13061
13062    function normalizeUnits(units) {
13063        return typeof units === 'string'
13064            ? aliases[units] || aliases[units.toLowerCase()]
13065            : undefined;
13066    }
13067
13068    function normalizeObjectUnits(inputObject) {
13069        var normalizedInput = {},
13070            normalizedProp,
13071            prop;
13072
13073        for (prop in inputObject) {
13074            if (hasOwnProp(inputObject, prop)) {
13075                normalizedProp = normalizeUnits(prop);
13076                if (normalizedProp) {
13077                    normalizedInput[normalizedProp] = inputObject[prop];
13078                }
13079            }
13080        }
13081
13082        return normalizedInput;
13083    }
13084
13085    var priorities = {};
13086
13087    function addUnitPriority(unit, priority) {
13088        priorities[unit] = priority;
13089    }
13090
13091    function getPrioritizedUnits(unitsObj) {
13092        var units = [],
13093            u;
13094        for (u in unitsObj) {
13095            if (hasOwnProp(unitsObj, u)) {
13096                units.push({ unit: u, priority: priorities[u] });
13097            }
13098        }
13099        units.sort(function (a, b) {
13100            return a.priority - b.priority;
13101        });
13102        return units;
13103    }
13104
13105    function isLeapYear(year) {
13106        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
13107    }
13108
13109    function absFloor(number) {
13110        if (number < 0) {
13111            // -0 -> 0
13112            return Math.ceil(number) || 0;
13113        } else {
13114            return Math.floor(number);
13115        }
13116    }
13117
13118    function toInt(argumentForCoercion) {
13119        var coercedNumber = +argumentForCoercion,
13120            value = 0;
13121
13122        if (coercedNumber !== 0 && isFinite(coercedNumber)) {
13123            value = absFloor(coercedNumber);
13124        }
13125
13126        return value;
13127    }
13128
13129    function makeGetSet(unit, keepTime) {
13130        return function (value) {
13131            if (value != null) {
13132                set$1(this, unit, value);
13133                hooks.updateOffset(this, keepTime);
13134                return this;
13135            } else {
13136                return get(this, unit);
13137            }
13138        };
13139    }
13140
13141    function get(mom, unit) {
13142        return mom.isValid()
13143            ? mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]()
13144            : NaN;
13145    }
13146
13147    function set$1(mom, unit, value) {
13148        if (mom.isValid() && !isNaN(value)) {
13149            if (
13150                unit === 'FullYear' &&
13151                isLeapYear(mom.year()) &&
13152                mom.month() === 1 &&
13153                mom.date() === 29
13154            ) {
13155                value = toInt(value);
13156                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](
13157                    value,
13158                    mom.month(),
13159                    daysInMonth(value, mom.month())
13160                );
13161            } else {
13162                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
13163            }
13164        }
13165    }
13166
13167    // MOMENTS
13168
13169    function stringGet(units) {
13170        units = normalizeUnits(units);
13171        if (isFunction(this[units])) {
13172            return this[units]();
13173        }
13174        return this;
13175    }
13176
13177    function stringSet(units, value) {
13178        if (typeof units === 'object') {
13179            units = normalizeObjectUnits(units);
13180            var prioritized = getPrioritizedUnits(units),
13181                i,
13182                prioritizedLen = prioritized.length;
13183            for (i = 0; i < prioritizedLen; i++) {
13184                this[prioritized[i].unit](units[prioritized[i].unit]);
13185            }
13186        } else {
13187            units = normalizeUnits(units);
13188            if (isFunction(this[units])) {
13189                return this[units](value);
13190            }
13191        }
13192        return this;
13193    }
13194
13195    var match1 = /\d/, //       0 - 9
13196        match2 = /\d\d/, //      00 - 99
13197        match3 = /\d{3}/, //     000 - 999
13198        match4 = /\d{4}/, //    0000 - 9999
13199        match6 = /[+-]?\d{6}/, // -999999 - 999999
13200        match1to2 = /\d\d?/, //       0 - 99
13201        match3to4 = /\d\d\d\d?/, //     999 - 9999
13202        match5to6 = /\d\d\d\d\d\d?/, //   99999 - 999999
13203        match1to3 = /\d{1,3}/, //       0 - 999
13204        match1to4 = /\d{1,4}/, //       0 - 9999
13205        match1to6 = /[+-]?\d{1,6}/, // -999999 - 999999
13206        matchUnsigned = /\d+/, //       0 - inf
13207        matchSigned = /[+-]?\d+/, //    -inf - inf
13208        matchOffset = /Z|[+-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z
13209        matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi, // +00 -00 +00:00 -00:00 +0000 -0000 or Z
13210        matchTimestamp = /[+-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123
13211        // any word (or two) characters or numbers including two/three word month in arabic.
13212        // includes scottish gaelic two word and hyphenated months
13213        matchWord =
13214            /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,
13215        regexes;
13216
13217    regexes = {};
13218
13219    function addRegexToken(token, regex, strictRegex) {
13220        regexes[token] = isFunction(regex)
13221            ? regex
13222            : function (isStrict, localeData) {
13223                  return isStrict && strictRegex ? strictRegex : regex;
13224              };
13225    }
13226
13227    function getParseRegexForToken(token, config) {
13228        if (!hasOwnProp(regexes, token)) {
13229            return new RegExp(unescapeFormat(token));
13230        }
13231
13232        return regexes[token](config._strict, config._locale);
13233    }
13234
13235    // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
13236    function unescapeFormat(s) {
13237        return regexEscape(
13238            s
13239                .replace('\\', '')
13240                .replace(
13241                    /\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,
13242                    function (matched, p1, p2, p3, p4) {
13243                        return p1 || p2 || p3 || p4;
13244                    }
13245                )
13246        );
13247    }
13248
13249    function regexEscape(s) {
13250        return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
13251    }
13252
13253    var tokens = {};
13254
13255    function addParseToken(token, callback) {
13256        var i,
13257            func = callback,
13258            tokenLen;
13259        if (typeof token === 'string') {
13260            token = [token];
13261        }
13262        if (isNumber(callback)) {
13263            func = function (input, array) {
13264                array[callback] = toInt(input);
13265            };
13266        }
13267        tokenLen = token.length;
13268        for (i = 0; i < tokenLen; i++) {
13269            tokens[token[i]] = func;
13270        }
13271    }
13272
13273    function addWeekParseToken(token, callback) {
13274        addParseToken(token, function (input, array, config, token) {
13275            config._w = config._w || {};
13276            callback(input, config._w, config, token);
13277        });
13278    }
13279
13280    function addTimeToArrayFromToken(token, input, config) {
13281        if (input != null && hasOwnProp(tokens, token)) {
13282            tokens[token](input, config._a, config, token);
13283        }
13284    }
13285
13286    var YEAR = 0,
13287        MONTH = 1,
13288        DATE = 2,
13289        HOUR = 3,
13290        MINUTE = 4,
13291        SECOND = 5,
13292        MILLISECOND = 6,
13293        WEEK = 7,
13294        WEEKDAY = 8;
13295
13296    function mod(n, x) {
13297        return ((n % x) + x) % x;
13298    }
13299
13300    var indexOf;
13301
13302    if (Array.prototype.indexOf) {
13303        indexOf = Array.prototype.indexOf;
13304    } else {
13305        indexOf = function (o) {
13306            // I know
13307            var i;
13308            for (i = 0; i < this.length; ++i) {
13309                if (this[i] === o) {
13310                    return i;
13311                }
13312            }
13313            return -1;
13314        };
13315    }
13316
13317    function daysInMonth(year, month) {
13318        if (isNaN(year) || isNaN(month)) {
13319            return NaN;
13320        }
13321        var modMonth = mod(month, 12);
13322        year += (month - modMonth) / 12;
13323        return modMonth === 1
13324            ? isLeapYear(year)
13325                ? 29
13326                : 28
13327            : 31 - ((modMonth % 7) % 2);
13328    }
13329
13330    // FORMATTING
13331
13332    addFormatToken('M', ['MM', 2], 'Mo', function () {
13333        return this.month() + 1;
13334    });
13335
13336    addFormatToken('MMM', 0, 0, function (format) {
13337        return this.localeData().monthsShort(this, format);
13338    });
13339
13340    addFormatToken('MMMM', 0, 0, function (format) {
13341        return this.localeData().months(this, format);
13342    });
13343
13344    // ALIASES
13345
13346    addUnitAlias('month', 'M');
13347
13348    // PRIORITY
13349
13350    addUnitPriority('month', 8);
13351
13352    // PARSING
13353
13354    addRegexToken('M', match1to2);
13355    addRegexToken('MM', match1to2, match2);
13356    addRegexToken('MMM', function (isStrict, locale) {
13357        return locale.monthsShortRegex(isStrict);
13358    });
13359    addRegexToken('MMMM', function (isStrict, locale) {
13360        return locale.monthsRegex(isStrict);
13361    });
13362
13363    addParseToken(['M', 'MM'], function (input, array) {
13364        array[MONTH] = toInt(input) - 1;
13365    });
13366
13367    addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
13368        var month = config._locale.monthsParse(input, token, config._strict);
13369        // if we didn't find a month name, mark the date as invalid.
13370        if (month != null) {
13371            array[MONTH] = month;
13372        } else {
13373            getParsingFlags(config).invalidMonth = input;
13374        }
13375    });
13376
13377    // LOCALES
13378
13379    var defaultLocaleMonths =
13380            'January_February_March_April_May_June_July_August_September_October_November_December'.split(
13381                '_'
13382            ),
13383        defaultLocaleMonthsShort =
13384            'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
13385        MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,
13386        defaultMonthsShortRegex = matchWord,
13387        defaultMonthsRegex = matchWord;
13388
13389    function localeMonths(m, format) {
13390        if (!m) {
13391            return isArray(this._months)
13392                ? this._months
13393                : this._months['standalone'];
13394        }
13395        return isArray(this._months)
13396            ? this._months[m.month()]
13397            : this._months[
13398                  (this._months.isFormat || MONTHS_IN_FORMAT).test(format)
13399                      ? 'format'
13400                      : 'standalone'
13401              ][m.month()];
13402    }
13403
13404    function localeMonthsShort(m, format) {
13405        if (!m) {
13406            return isArray(this._monthsShort)
13407                ? this._monthsShort
13408                : this._monthsShort['standalone'];
13409        }
13410        return isArray(this._monthsShort)
13411            ? this._monthsShort[m.month()]
13412            : this._monthsShort[
13413                  MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'
13414              ][m.month()];
13415    }
13416
13417    function handleStrictParse(monthName, format, strict) {
13418        var i,
13419            ii,
13420            mom,
13421            llc = monthName.toLocaleLowerCase();
13422        if (!this._monthsParse) {
13423            // this is not used
13424            this._monthsParse = [];
13425            this._longMonthsParse = [];
13426            this._shortMonthsParse = [];
13427            for (i = 0; i < 12; ++i) {
13428                mom = createUTC([2000, i]);
13429                this._shortMonthsParse[i] = this.monthsShort(
13430                    mom,
13431                    ''
13432                ).toLocaleLowerCase();
13433                this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
13434            }
13435        }
13436
13437        if (strict) {
13438            if (format === 'MMM') {
13439                ii = indexOf.call(this._shortMonthsParse, llc);
13440                return ii !== -1 ? ii : null;
13441            } else {
13442                ii = indexOf.call(this._longMonthsParse, llc);
13443                return ii !== -1 ? ii : null;
13444            }
13445        } else {
13446            if (format === 'MMM') {
13447                ii = indexOf.call(this._shortMonthsParse, llc);
13448                if (ii !== -1) {
13449                    return ii;
13450                }
13451                ii = indexOf.call(this._longMonthsParse, llc);
13452                return ii !== -1 ? ii : null;
13453            } else {
13454                ii = indexOf.call(this._longMonthsParse, llc);
13455                if (ii !== -1) {
13456                    return ii;
13457                }
13458                ii = indexOf.call(this._shortMonthsParse, llc);
13459                return ii !== -1 ? ii : null;
13460            }
13461        }
13462    }
13463
13464    function localeMonthsParse(monthName, format, strict) {
13465        var i, mom, regex;
13466
13467        if (this._monthsParseExact) {
13468            return handleStrictParse.call(this, monthName, format, strict);
13469        }
13470
13471        if (!this._monthsParse) {
13472            this._monthsParse = [];
13473            this._longMonthsParse = [];
13474            this._shortMonthsParse = [];
13475        }
13476
13477        // TODO: add sorting
13478        // Sorting makes sure if one month (or abbr) is a prefix of another
13479        // see sorting in computeMonthsParse
13480        for (i = 0; i < 12; i++) {
13481            // make the regex if we don't have it already
13482            mom = createUTC([2000, i]);
13483            if (strict && !this._longMonthsParse[i]) {
13484                this._longMonthsParse[i] = new RegExp(
13485                    '^' + this.months(mom, '').replace('.', '') + '$',
13486                    'i'
13487                );
13488                this._shortMonthsParse[i] = new RegExp(
13489                    '^' + this.monthsShort(mom, '').replace('.', '') + '$',
13490                    'i'
13491                );
13492            }
13493            if (!strict && !this._monthsParse[i]) {
13494                regex =
13495                    '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
13496                this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
13497            }
13498            // test the regex
13499            if (
13500                strict &&
13501                format === 'MMMM' &&
13502                this._longMonthsParse[i].test(monthName)
13503            ) {
13504                return i;
13505            } else if (
13506                strict &&
13507                format === 'MMM' &&
13508                this._shortMonthsParse[i].test(monthName)
13509            ) {
13510                return i;
13511            } else if (!strict && this._monthsParse[i].test(monthName)) {
13512                return i;
13513            }
13514        }
13515    }
13516
13517    // MOMENTS
13518
13519    function setMonth(mom, value) {
13520        var dayOfMonth;
13521
13522        if (!mom.isValid()) {
13523            // No op
13524            return mom;
13525        }
13526
13527        if (typeof value === 'string') {
13528            if (/^\d+$/.test(value)) {
13529                value = toInt(value);
13530            } else {
13531                value = mom.localeData().monthsParse(value);
13532                // TODO: Another silent failure?
13533                if (!isNumber(value)) {
13534                    return mom;
13535                }
13536            }
13537        }
13538
13539        dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
13540        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
13541        return mom;
13542    }
13543
13544    function getSetMonth(value) {
13545        if (value != null) {
13546            setMonth(this, value);
13547            hooks.updateOffset(this, true);
13548            return this;
13549        } else {
13550            return get(this, 'Month');
13551        }
13552    }
13553
13554    function getDaysInMonth() {
13555        return daysInMonth(this.year(), this.month());
13556    }
13557
13558    function monthsShortRegex(isStrict) {
13559        if (this._monthsParseExact) {
13560            if (!hasOwnProp(this, '_monthsRegex')) {
13561                computeMonthsParse.call(this);
13562            }
13563            if (isStrict) {
13564                return this._monthsShortStrictRegex;
13565            } else {
13566                return this._monthsShortRegex;
13567            }
13568        } else {
13569            if (!hasOwnProp(this, '_monthsShortRegex')) {
13570                this._monthsShortRegex = defaultMonthsShortRegex;
13571            }
13572            return this._monthsShortStrictRegex && isStrict
13573                ? this._monthsShortStrictRegex
13574                : this._monthsShortRegex;
13575        }
13576    }
13577
13578    function monthsRegex(isStrict) {
13579        if (this._monthsParseExact) {
13580            if (!hasOwnProp(this, '_monthsRegex')) {
13581                computeMonthsParse.call(this);
13582            }
13583            if (isStrict) {
13584                return this._monthsStrictRegex;
13585            } else {
13586                return this._monthsRegex;
13587            }
13588        } else {
13589            if (!hasOwnProp(this, '_monthsRegex')) {
13590                this._monthsRegex = defaultMonthsRegex;
13591            }
13592            return this._monthsStrictRegex && isStrict
13593                ? this._monthsStrictRegex
13594                : this._monthsRegex;
13595        }
13596    }
13597
13598    function computeMonthsParse() {
13599        function cmpLenRev(a, b) {
13600            return b.length - a.length;
13601        }
13602
13603        var shortPieces = [],
13604            longPieces = [],
13605            mixedPieces = [],
13606            i,
13607            mom;
13608        for (i = 0; i < 12; i++) {
13609            // make the regex if we don't have it already
13610            mom = createUTC([2000, i]);
13611            shortPieces.push(this.monthsShort(mom, ''));
13612            longPieces.push(this.months(mom, ''));
13613            mixedPieces.push(this.months(mom, ''));
13614            mixedPieces.push(this.monthsShort(mom, ''));
13615        }
13616        // Sorting makes sure if one month (or abbr) is a prefix of another it
13617        // will match the longer piece.
13618        shortPieces.sort(cmpLenRev);
13619        longPieces.sort(cmpLenRev);
13620        mixedPieces.sort(cmpLenRev);
13621        for (i = 0; i < 12; i++) {
13622            shortPieces[i] = regexEscape(shortPieces[i]);
13623            longPieces[i] = regexEscape(longPieces[i]);
13624        }
13625        for (i = 0; i < 24; i++) {
13626            mixedPieces[i] = regexEscape(mixedPieces[i]);
13627        }
13628
13629        this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
13630        this._monthsShortRegex = this._monthsRegex;
13631        this._monthsStrictRegex = new RegExp(
13632            '^(' + longPieces.join('|') + ')',
13633            'i'
13634        );
13635        this._monthsShortStrictRegex = new RegExp(
13636            '^(' + shortPieces.join('|') + ')',
13637            'i'
13638        );
13639    }
13640
13641    // FORMATTING
13642
13643    addFormatToken('Y', 0, 0, function () {
13644        var y = this.year();
13645        return y <= 9999 ? zeroFill(y, 4) : '+' + y;
13646    });
13647
13648    addFormatToken(0, ['YY', 2], 0, function () {
13649        return this.year() % 100;
13650    });
13651
13652    addFormatToken(0, ['YYYY', 4], 0, 'year');
13653    addFormatToken(0, ['YYYYY', 5], 0, 'year');
13654    addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');
13655
13656    // ALIASES
13657
13658    addUnitAlias('year', 'y');
13659
13660    // PRIORITIES
13661
13662    addUnitPriority('year', 1);
13663
13664    // PARSING
13665
13666    addRegexToken('Y', matchSigned);
13667    addRegexToken('YY', match1to2, match2);
13668    addRegexToken('YYYY', match1to4, match4);
13669    addRegexToken('YYYYY', match1to6, match6);
13670    addRegexToken('YYYYYY', match1to6, match6);
13671
13672    addParseToken(['YYYYY', 'YYYYYY'], YEAR);
13673    addParseToken('YYYY', function (input, array) {
13674        array[YEAR] =
13675            input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
13676    });
13677    addParseToken('YY', function (input, array) {
13678        array[YEAR] = hooks.parseTwoDigitYear(input);
13679    });
13680    addParseToken('Y', function (input, array) {
13681        array[YEAR] = parseInt(input, 10);
13682    });
13683
13684    // HELPERS
13685
13686    function daysInYear(year) {
13687        return isLeapYear(year) ? 366 : 365;
13688    }
13689
13690    // HOOKS
13691
13692    hooks.parseTwoDigitYear = function (input) {
13693        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
13694    };
13695
13696    // MOMENTS
13697
13698    var getSetYear = makeGetSet('FullYear', true);
13699
13700    function getIsLeapYear() {
13701        return isLeapYear(this.year());
13702    }
13703
13704    function createDate(y, m, d, h, M, s, ms) {
13705        // can't just apply() to create a date:
13706        // https://stackoverflow.com/q/181348
13707        var date;
13708        // the date constructor remaps years 0-99 to 1900-1999
13709        if (y < 100 && y >= 0) {
13710            // preserve leap years using a full 400 year cycle, then reset
13711            date = new Date(y + 400, m, d, h, M, s, ms);
13712            if (isFinite(date.getFullYear())) {
13713                date.setFullYear(y);
13714            }
13715        } else {
13716            date = new Date(y, m, d, h, M, s, ms);
13717        }
13718
13719        return date;
13720    }
13721
13722    function createUTCDate(y) {
13723        var date, args;
13724        // the Date.UTC function remaps years 0-99 to 1900-1999
13725        if (y < 100 && y >= 0) {
13726            args = Array.prototype.slice.call(arguments);
13727            // preserve leap years using a full 400 year cycle, then reset
13728            args[0] = y + 400;
13729            date = new Date(Date.UTC.apply(null, args));
13730            if (isFinite(date.getUTCFullYear())) {
13731                date.setUTCFullYear(y);
13732            }
13733        } else {
13734            date = new Date(Date.UTC.apply(null, arguments));
13735        }
13736
13737        return date;
13738    }
13739
13740    // start-of-first-week - start-of-year
13741    function firstWeekOffset(year, dow, doy) {
13742        var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
13743            fwd = 7 + dow - doy,
13744            // first-week day local weekday -- which local weekday is fwd
13745            fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
13746
13747        return -fwdlw + fwd - 1;
13748    }
13749
13750    // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
13751    function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
13752        var localWeekday = (7 + weekday - dow) % 7,
13753            weekOffset = firstWeekOffset(year, dow, doy),
13754            dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
13755            resYear,
13756            resDayOfYear;
13757
13758        if (dayOfYear <= 0) {
13759            resYear = year - 1;
13760            resDayOfYear = daysInYear(resYear) + dayOfYear;
13761        } else if (dayOfYear > daysInYear(year)) {
13762            resYear = year + 1;
13763            resDayOfYear = dayOfYear - daysInYear(year);
13764        } else {
13765            resYear = year;
13766            resDayOfYear = dayOfYear;
13767        }
13768
13769        return {
13770            year: resYear,
13771            dayOfYear: resDayOfYear,
13772        };
13773    }
13774
13775    function weekOfYear(mom, dow, doy) {
13776        var weekOffset = firstWeekOffset(mom.year(), dow, doy),
13777            week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
13778            resWeek,
13779            resYear;
13780
13781        if (week < 1) {
13782            resYear = mom.year() - 1;
13783            resWeek = week + weeksInYear(resYear, dow, doy);
13784        } else if (week > weeksInYear(mom.year(), dow, doy)) {
13785            resWeek = week - weeksInYear(mom.year(), dow, doy);
13786            resYear = mom.year() + 1;
13787        } else {
13788            resYear = mom.year();
13789            resWeek = week;
13790        }
13791
13792        return {
13793            week: resWeek,
13794            year: resYear,
13795        };
13796    }
13797
13798    function weeksInYear(year, dow, doy) {
13799        var weekOffset = firstWeekOffset(year, dow, doy),
13800            weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
13801        return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
13802    }
13803
13804    // FORMATTING
13805
13806    addFormatToken('w', ['ww', 2], 'wo', 'week');
13807    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
13808
13809    // ALIASES
13810
13811    addUnitAlias('week', 'w');
13812    addUnitAlias('isoWeek', 'W');
13813
13814    // PRIORITIES
13815
13816    addUnitPriority('week', 5);
13817    addUnitPriority('isoWeek', 5);
13818
13819    // PARSING
13820
13821    addRegexToken('w', match1to2);
13822    addRegexToken('ww', match1to2, match2);
13823    addRegexToken('W', match1to2);
13824    addRegexToken('WW', match1to2, match2);
13825
13826    addWeekParseToken(
13827        ['w', 'ww', 'W', 'WW'],
13828        function (input, week, config, token) {
13829            week[token.substr(0, 1)] = toInt(input);
13830        }
13831    );
13832
13833    // HELPERS
13834
13835    // LOCALES
13836
13837    function localeWeek(mom) {
13838        return weekOfYear(mom, this._week.dow, this._week.doy).week;
13839    }
13840
13841    var defaultLocaleWeek = {
13842        dow: 0, // Sunday is the first day of the week.
13843        doy: 6, // The week that contains Jan 6th is the first week of the year.
13844    };
13845
13846    function localeFirstDayOfWeek() {
13847        return this._week.dow;
13848    }
13849
13850    function localeFirstDayOfYear() {
13851        return this._week.doy;
13852    }
13853
13854    // MOMENTS
13855
13856    function getSetWeek(input) {
13857        var week = this.localeData().week(this);
13858        return input == null ? week : this.add((input - week) * 7, 'd');
13859    }
13860
13861    function getSetISOWeek(input) {
13862        var week = weekOfYear(this, 1, 4).week;
13863        return input == null ? week : this.add((input - week) * 7, 'd');
13864    }
13865
13866    // FORMATTING
13867
13868    addFormatToken('d', 0, 'do', 'day');
13869
13870    addFormatToken('dd', 0, 0, function (format) {
13871        return this.localeData().weekdaysMin(this, format);
13872    });
13873
13874    addFormatToken('ddd', 0, 0, function (format) {
13875        return this.localeData().weekdaysShort(this, format);
13876    });
13877
13878    addFormatToken('dddd', 0, 0, function (format) {
13879        return this.localeData().weekdays(this, format);
13880    });
13881
13882    addFormatToken('e', 0, 0, 'weekday');
13883    addFormatToken('E', 0, 0, 'isoWeekday');
13884
13885    // ALIASES
13886
13887    addUnitAlias('day', 'd');
13888    addUnitAlias('weekday', 'e');
13889    addUnitAlias('isoWeekday', 'E');
13890
13891    // PRIORITY
13892    addUnitPriority('day', 11);
13893    addUnitPriority('weekday', 11);
13894    addUnitPriority('isoWeekday', 11);
13895
13896    // PARSING
13897
13898    addRegexToken('d', match1to2);
13899    addRegexToken('e', match1to2);
13900    addRegexToken('E', match1to2);
13901    addRegexToken('dd', function (isStrict, locale) {
13902        return locale.weekdaysMinRegex(isStrict);
13903    });
13904    addRegexToken('ddd', function (isStrict, locale) {
13905        return locale.weekdaysShortRegex(isStrict);
13906    });
13907    addRegexToken('dddd', function (isStrict, locale) {
13908        return locale.weekdaysRegex(isStrict);
13909    });
13910
13911    addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
13912        var weekday = config._locale.weekdaysParse(input, token, config._strict);
13913        // if we didn't get a weekday name, mark the date as invalid
13914        if (weekday != null) {
13915            week.d = weekday;
13916        } else {
13917            getParsingFlags(config).invalidWeekday = input;
13918        }
13919    });
13920
13921    addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
13922        week[token] = toInt(input);
13923    });
13924
13925    // HELPERS
13926
13927    function parseWeekday(input, locale) {
13928        if (typeof input !== 'string') {
13929            return input;
13930        }
13931
13932        if (!isNaN(input)) {
13933            return parseInt(input, 10);
13934        }
13935
13936        input = locale.weekdaysParse(input);
13937        if (typeof input === 'number') {
13938            return input;
13939        }
13940
13941        return null;
13942    }
13943
13944    function parseIsoWeekday(input, locale) {
13945        if (typeof input === 'string') {
13946            return locale.weekdaysParse(input) % 7 || 7;
13947        }
13948        return isNaN(input) ? null : input;
13949    }
13950
13951    // LOCALES
13952    function shiftWeekdays(ws, n) {
13953        return ws.slice(n, 7).concat(ws.slice(0, n));
13954    }
13955
13956    var defaultLocaleWeekdays =
13957            'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
13958        defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
13959        defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
13960        defaultWeekdaysRegex = matchWord,
13961        defaultWeekdaysShortRegex = matchWord,
13962        defaultWeekdaysMinRegex = matchWord;
13963
13964    function localeWeekdays(m, format) {
13965        var weekdays = isArray(this._weekdays)
13966            ? this._weekdays
13967            : this._weekdays[
13968                  m && m !== true && this._weekdays.isFormat.test(format)
13969                      ? 'format'
13970                      : 'standalone'
13971              ];
13972        return m === true
13973            ? shiftWeekdays(weekdays, this._week.dow)
13974            : m
13975            ? weekdays[m.day()]
13976            : weekdays;
13977    }
13978
13979    function localeWeekdaysShort(m) {
13980        return m === true
13981            ? shiftWeekdays(this._weekdaysShort, this._week.dow)
13982            : m
13983            ? this._weekdaysShort[m.day()]
13984            : this._weekdaysShort;
13985    }
13986
13987    function localeWeekdaysMin(m) {
13988        return m === true
13989            ? shiftWeekdays(this._weekdaysMin, this._week.dow)
13990            : m
13991            ? this._weekdaysMin[m.day()]
13992            : this._weekdaysMin;
13993    }
13994
13995    function handleStrictParse$1(weekdayName, format, strict) {
13996        var i,
13997            ii,
13998            mom,
13999            llc = weekdayName.toLocaleLowerCase();
14000        if (!this._weekdaysParse) {
14001            this._weekdaysParse = [];
14002            this._shortWeekdaysParse = [];
14003            this._minWeekdaysParse = [];
14004
14005            for (i = 0; i < 7; ++i) {
14006                mom = createUTC([2000, 1]).day(i);
14007                this._minWeekdaysParse[i] = this.weekdaysMin(
14008                    mom,
14009                    ''
14010                ).toLocaleLowerCase();
14011                this._shortWeekdaysParse[i] = this.weekdaysShort(
14012                    mom,
14013                    ''
14014                ).toLocaleLowerCase();
14015                this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
14016            }
14017        }
14018
14019        if (strict) {
14020            if (format === 'dddd') {
14021                ii = indexOf.call(this._weekdaysParse, llc);
14022                return ii !== -1 ? ii : null;
14023            } else if (format === 'ddd') {
14024                ii = indexOf.call(this._shortWeekdaysParse, llc);
14025                return ii !== -1 ? ii : null;
14026            } else {
14027                ii = indexOf.call(this._minWeekdaysParse, llc);
14028                return ii !== -1 ? ii : null;
14029            }
14030        } else {
14031            if (format === 'dddd') {
14032                ii = indexOf.call(this._weekdaysParse, llc);
14033                if (ii !== -1) {
14034                    return ii;
14035                }
14036                ii = indexOf.call(this._shortWeekdaysParse, llc);
14037                if (ii !== -1) {
14038                    return ii;
14039                }
14040                ii = indexOf.call(this._minWeekdaysParse, llc);
14041                return ii !== -1 ? ii : null;
14042            } else if (format === 'ddd') {
14043                ii = indexOf.call(this._shortWeekdaysParse, llc);
14044                if (ii !== -1) {
14045                    return ii;
14046                }
14047                ii = indexOf.call(this._weekdaysParse, llc);
14048                if (ii !== -1) {
14049                    return ii;
14050                }
14051                ii = indexOf.call(this._minWeekdaysParse, llc);
14052                return ii !== -1 ? ii : null;
14053            } else {
14054                ii = indexOf.call(this._minWeekdaysParse, llc);
14055                if (ii !== -1) {
14056                    return ii;
14057                }
14058                ii = indexOf.call(this._weekdaysParse, llc);
14059                if (ii !== -1) {
14060                    return ii;
14061                }
14062                ii = indexOf.call(this._shortWeekdaysParse, llc);
14063                return ii !== -1 ? ii : null;
14064            }
14065        }
14066    }
14067
14068    function localeWeekdaysParse(weekdayName, format, strict) {
14069        var i, mom, regex;
14070
14071        if (this._weekdaysParseExact) {
14072            return handleStrictParse$1.call(this, weekdayName, format, strict);
14073        }
14074
14075        if (!this._weekdaysParse) {
14076            this._weekdaysParse = [];
14077            this._minWeekdaysParse = [];
14078            this._shortWeekdaysParse = [];
14079            this._fullWeekdaysParse = [];
14080        }
14081
14082        for (i = 0; i < 7; i++) {
14083            // make the regex if we don't have it already
14084
14085            mom = createUTC([2000, 1]).day(i);
14086            if (strict && !this._fullWeekdaysParse[i]) {
14087                this._fullWeekdaysParse[i] = new RegExp(
14088                    '^' + this.weekdays(mom, '').replace('.', '\\.?') + '$',
14089                    'i'
14090                );
14091                this._shortWeekdaysParse[i] = new RegExp(
14092                    '^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$',
14093                    'i'
14094                );
14095                this._minWeekdaysParse[i] = new RegExp(
14096                    '^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$',
14097                    'i'
14098                );
14099            }
14100            if (!this._weekdaysParse[i]) {
14101                regex =
14102                    '^' +
14103                    this.weekdays(mom, '') +
14104                    '|^' +
14105                    this.weekdaysShort(mom, '') +
14106                    '|^' +
14107                    this.weekdaysMin(mom, '');
14108                this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
14109            }
14110            // test the regex
14111            if (
14112                strict &&
14113                format === 'dddd' &&
14114                this._fullWeekdaysParse[i].test(weekdayName)
14115            ) {
14116                return i;
14117            } else if (
14118                strict &&
14119                format === 'ddd' &&
14120                this._shortWeekdaysParse[i].test(weekdayName)
14121            ) {
14122                return i;
14123            } else if (
14124                strict &&
14125                format === 'dd' &&
14126                this._minWeekdaysParse[i].test(weekdayName)
14127            ) {
14128                return i;
14129            } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
14130                return i;
14131            }
14132        }
14133    }
14134
14135    // MOMENTS
14136
14137    function getSetDayOfWeek(input) {
14138        if (!this.isValid()) {
14139            return input != null ? this : NaN;
14140        }
14141        var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
14142        if (input != null) {
14143            input = parseWeekday(input, this.localeData());
14144            return this.add(input - day, 'd');
14145        } else {
14146            return day;
14147        }
14148    }
14149
14150    function getSetLocaleDayOfWeek(input) {
14151        if (!this.isValid()) {
14152            return input != null ? this : NaN;
14153        }
14154        var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
14155        return input == null ? weekday : this.add(input - weekday, 'd');
14156    }
14157
14158    function getSetISODayOfWeek(input) {
14159        if (!this.isValid()) {
14160            return input != null ? this : NaN;
14161        }
14162
14163        // behaves the same as moment#day except
14164        // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
14165        // as a setter, sunday should belong to the previous week.
14166
14167        if (input != null) {
14168            var weekday = parseIsoWeekday(input, this.localeData());
14169            return this.day(this.day() % 7 ? weekday : weekday - 7);
14170        } else {
14171            return this.day() || 7;
14172        }
14173    }
14174
14175    function weekdaysRegex(isStrict) {
14176        if (this._weekdaysParseExact) {
14177            if (!hasOwnProp(this, '_weekdaysRegex')) {
14178                computeWeekdaysParse.call(this);
14179            }
14180            if (isStrict) {
14181                return this._weekdaysStrictRegex;
14182            } else {
14183                return this._weekdaysRegex;
14184            }
14185        } else {
14186            if (!hasOwnProp(this, '_weekdaysRegex')) {
14187                this._weekdaysRegex = defaultWeekdaysRegex;
14188            }
14189            return this._weekdaysStrictRegex && isStrict
14190                ? this._weekdaysStrictRegex
14191                : this._weekdaysRegex;
14192        }
14193    }
14194
14195    function weekdaysShortRegex(isStrict) {
14196        if (this._weekdaysParseExact) {
14197            if (!hasOwnProp(this, '_weekdaysRegex')) {
14198                computeWeekdaysParse.call(this);
14199            }
14200            if (isStrict) {
14201                return this._weekdaysShortStrictRegex;
14202            } else {
14203                return this._weekdaysShortRegex;
14204            }
14205        } else {
14206            if (!hasOwnProp(this, '_weekdaysShortRegex')) {
14207                this._weekdaysShortRegex = defaultWeekdaysShortRegex;
14208            }
14209            return this._weekdaysShortStrictRegex && isStrict
14210                ? this._weekdaysShortStrictRegex
14211                : this._weekdaysShortRegex;
14212        }
14213    }
14214
14215    function weekdaysMinRegex(isStrict) {
14216        if (this._weekdaysParseExact) {
14217            if (!hasOwnProp(this, '_weekdaysRegex')) {
14218                computeWeekdaysParse.call(this);
14219            }
14220            if (isStrict) {
14221                return this._weekdaysMinStrictRegex;
14222            } else {
14223                return this._weekdaysMinRegex;
14224            }
14225        } else {
14226            if (!hasOwnProp(this, '_weekdaysMinRegex')) {
14227                this._weekdaysMinRegex = defaultWeekdaysMinRegex;
14228            }
14229            return this._weekdaysMinStrictRegex && isStrict
14230                ? this._weekdaysMinStrictRegex
14231                : this._weekdaysMinRegex;
14232        }
14233    }
14234
14235    function computeWeekdaysParse() {
14236        function cmpLenRev(a, b) {
14237            return b.length - a.length;
14238        }
14239
14240        var minPieces = [],
14241            shortPieces = [],
14242            longPieces = [],
14243            mixedPieces = [],
14244            i,
14245            mom,
14246            minp,
14247            shortp,
14248            longp;
14249        for (i = 0; i < 7; i++) {
14250            // make the regex if we don't have it already
14251            mom = createUTC([2000, 1]).day(i);
14252            minp = regexEscape(this.weekdaysMin(mom, ''));
14253            shortp = regexEscape(this.weekdaysShort(mom, ''));
14254            longp = regexEscape(this.weekdays(mom, ''));
14255            minPieces.push(minp);
14256            shortPieces.push(shortp);
14257            longPieces.push(longp);
14258            mixedPieces.push(minp);
14259            mixedPieces.push(shortp);
14260            mixedPieces.push(longp);
14261        }
14262        // Sorting makes sure if one weekday (or abbr) is a prefix of another it
14263        // will match the longer piece.
14264        minPieces.sort(cmpLenRev);
14265        shortPieces.sort(cmpLenRev);
14266        longPieces.sort(cmpLenRev);
14267        mixedPieces.sort(cmpLenRev);
14268
14269        this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
14270        this._weekdaysShortRegex = this._weekdaysRegex;
14271        this._weekdaysMinRegex = this._weekdaysRegex;
14272
14273        this._weekdaysStrictRegex = new RegExp(
14274            '^(' + longPieces.join('|') + ')',
14275            'i'
14276        );
14277        this._weekdaysShortStrictRegex = new RegExp(
14278            '^(' + shortPieces.join('|') + ')',
14279            'i'
14280        );
14281        this._weekdaysMinStrictRegex = new RegExp(
14282            '^(' + minPieces.join('|') + ')',
14283            'i'
14284        );
14285    }
14286
14287    // FORMATTING
14288
14289    function hFormat() {
14290        return this.hours() % 12 || 12;
14291    }
14292
14293    function kFormat() {
14294        return this.hours() || 24;
14295    }
14296
14297    addFormatToken('H', ['HH', 2], 0, 'hour');
14298    addFormatToken('h', ['hh', 2], 0, hFormat);
14299    addFormatToken('k', ['kk', 2], 0, kFormat);
14300
14301    addFormatToken('hmm', 0, 0, function () {
14302        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
14303    });
14304
14305    addFormatToken('hmmss', 0, 0, function () {
14306        return (
14307            '' +
14308            hFormat.apply(this) +
14309            zeroFill(this.minutes(), 2) +
14310            zeroFill(this.seconds(), 2)
14311        );
14312    });
14313
14314    addFormatToken('Hmm', 0, 0, function () {
14315        return '' + this.hours() + zeroFill(this.minutes(), 2);
14316    });
14317
14318    addFormatToken('Hmmss', 0, 0, function () {
14319        return (
14320            '' +
14321            this.hours() +
14322            zeroFill(this.minutes(), 2) +
14323            zeroFill(this.seconds(), 2)
14324        );
14325    });
14326
14327    function meridiem(token, lowercase) {
14328        addFormatToken(token, 0, 0, function () {
14329            return this.localeData().meridiem(
14330                this.hours(),
14331                this.minutes(),
14332                lowercase
14333            );
14334        });
14335    }
14336
14337    meridiem('a', true);
14338    meridiem('A', false);
14339
14340    // ALIASES
14341
14342    addUnitAlias('hour', 'h');
14343
14344    // PRIORITY
14345    addUnitPriority('hour', 13);
14346
14347    // PARSING
14348
14349    function matchMeridiem(isStrict, locale) {
14350        return locale._meridiemParse;
14351    }
14352
14353    addRegexToken('a', matchMeridiem);
14354    addRegexToken('A', matchMeridiem);
14355    addRegexToken('H', match1to2);
14356    addRegexToken('h', match1to2);
14357    addRegexToken('k', match1to2);
14358    addRegexToken('HH', match1to2, match2);
14359    addRegexToken('hh', match1to2, match2);
14360    addRegexToken('kk', match1to2, match2);
14361
14362    addRegexToken('hmm', match3to4);
14363    addRegexToken('hmmss', match5to6);
14364    addRegexToken('Hmm', match3to4);
14365    addRegexToken('Hmmss', match5to6);
14366
14367    addParseToken(['H', 'HH'], HOUR);
14368    addParseToken(['k', 'kk'], function (input, array, config) {
14369        var kInput = toInt(input);
14370        array[HOUR] = kInput === 24 ? 0 : kInput;
14371    });
14372    addParseToken(['a', 'A'], function (input, array, config) {
14373        config._isPm = config._locale.isPM(input);
14374        config._meridiem = input;
14375    });
14376    addParseToken(['h', 'hh'], function (input, array, config) {
14377        array[HOUR] = toInt(input);
14378        getParsingFlags(config).bigHour = true;
14379    });
14380    addParseToken('hmm', function (input, array, config) {
14381        var pos = input.length - 2;
14382        array[HOUR] = toInt(input.substr(0, pos));
14383        array[MINUTE] = toInt(input.substr(pos));
14384        getParsingFlags(config).bigHour = true;
14385    });
14386    addParseToken('hmmss', function (input, array, config) {
14387        var pos1 = input.length - 4,
14388            pos2 = input.length - 2;
14389        array[HOUR] = toInt(input.substr(0, pos1));
14390        array[MINUTE] = toInt(input.substr(pos1, 2));
14391        array[SECOND] = toInt(input.substr(pos2));
14392        getParsingFlags(config).bigHour = true;
14393    });
14394    addParseToken('Hmm', function (input, array, config) {
14395        var pos = input.length - 2;
14396        array[HOUR] = toInt(input.substr(0, pos));
14397        array[MINUTE] = toInt(input.substr(pos));
14398    });
14399    addParseToken('Hmmss', function (input, array, config) {
14400        var pos1 = input.length - 4,
14401            pos2 = input.length - 2;
14402        array[HOUR] = toInt(input.substr(0, pos1));
14403        array[MINUTE] = toInt(input.substr(pos1, 2));
14404        array[SECOND] = toInt(input.substr(pos2));
14405    });
14406
14407    // LOCALES
14408
14409    function localeIsPM(input) {
14410        // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
14411        // Using charAt should be more compatible.
14412        return (input + '').toLowerCase().charAt(0) === 'p';
14413    }
14414
14415    var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i,
14416        // Setting the hour should keep the time, because the user explicitly
14417        // specified which hour they want. So trying to maintain the same hour (in
14418        // a new timezone) makes sense. Adding/subtracting hours does not follow
14419        // this rule.
14420        getSetHour = makeGetSet('Hours', true);
14421
14422    function localeMeridiem(hours, minutes, isLower) {
14423        if (hours > 11) {
14424            return isLower ? 'pm' : 'PM';
14425        } else {
14426            return isLower ? 'am' : 'AM';
14427        }
14428    }
14429
14430    var baseConfig = {
14431        calendar: defaultCalendar,
14432        longDateFormat: defaultLongDateFormat,
14433        invalidDate: defaultInvalidDate,
14434        ordinal: defaultOrdinal,
14435        dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
14436        relativeTime: defaultRelativeTime,
14437
14438        months: defaultLocaleMonths,
14439        monthsShort: defaultLocaleMonthsShort,
14440
14441        week: defaultLocaleWeek,
14442
14443        weekdays: defaultLocaleWeekdays,
14444        weekdaysMin: defaultLocaleWeekdaysMin,
14445        weekdaysShort: defaultLocaleWeekdaysShort,
14446
14447        meridiemParse: defaultLocaleMeridiemParse,
14448    };
14449
14450    // internal storage for locale config files
14451    var locales = {},
14452        localeFamilies = {},
14453        globalLocale;
14454
14455    function commonPrefix(arr1, arr2) {
14456        var i,
14457            minl = Math.min(arr1.length, arr2.length);
14458        for (i = 0; i < minl; i += 1) {
14459            if (arr1[i] !== arr2[i]) {
14460                return i;
14461            }
14462        }
14463        return minl;
14464    }
14465
14466    function normalizeLocale(key) {
14467        return key ? key.toLowerCase().replace('_', '-') : key;
14468    }
14469
14470    // pick the locale from the array
14471    // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
14472    // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
14473    function chooseLocale(names) {
14474        var i = 0,
14475            j,
14476            next,
14477            locale,
14478            split;
14479
14480        while (i < names.length) {
14481            split = normalizeLocale(names[i]).split('-');
14482            j = split.length;
14483            next = normalizeLocale(names[i + 1]);
14484            next = next ? next.split('-') : null;
14485            while (j > 0) {
14486                locale = loadLocale(split.slice(0, j).join('-'));
14487                if (locale) {
14488                    return locale;
14489                }
14490                if (
14491                    next &&
14492                    next.length >= j &&
14493                    commonPrefix(split, next) >= j - 1
14494                ) {
14495                    //the next array item is better than a shallower substring of this one
14496                    break;
14497                }
14498                j--;
14499            }
14500            i++;
14501        }
14502        return globalLocale;
14503    }
14504
14505    function isLocaleNameSane(name) {
14506        // Prevent names that look like filesystem paths, i.e contain '/' or '\'
14507        return name.match('^[^/\\\\]*$') != null;
14508    }
14509
14510    function loadLocale(name) {
14511        var oldLocale = null,
14512            aliasedRequire;
14513        // TODO: Find a better way to register and load all the locales in Node
14514        if (
14515            locales[name] === undefined &&
14516            typeof module !== 'undefined' &&
14517            module &&
14518            module.exports &&
14519            isLocaleNameSane(name)
14520        ) {
14521            try {
14522                oldLocale = globalLocale._abbr;
14523                aliasedRequire = require;
14524                aliasedRequire('./locale/' + name);
14525                getSetGlobalLocale(oldLocale);
14526            } catch (e) {
14527                // mark as not found to avoid repeating expensive file require call causing high CPU
14528                // when trying to find en-US, en_US, en-us for every format call
14529                locales[name] = null; // null means not found
14530            }
14531        }
14532        return locales[name];
14533    }
14534
14535    // This function will load locale and then set the global locale.  If
14536    // no arguments are passed in, it will simply return the current global
14537    // locale key.
14538    function getSetGlobalLocale(key, values) {
14539        var data;
14540        if (key) {
14541            if (isUndefined(values)) {
14542                data = getLocale(key);
14543            } else {
14544                data = defineLocale(key, values);
14545            }
14546
14547            if (data) {
14548                // moment.duration._locale = moment._locale = data;
14549                globalLocale = data;
14550            } else {
14551                if (typeof console !== 'undefined' && console.warn) {
14552                    //warn user if arguments are passed but the locale could not be set
14553                    console.warn(
14554                        'Locale ' + key + ' not found. Did you forget to load it?'
14555                    );
14556                }
14557            }
14558        }
14559
14560        return globalLocale._abbr;
14561    }
14562
14563    function defineLocale(name, config) {
14564        if (config !== null) {
14565            var locale,
14566                parentConfig = baseConfig;
14567            config.abbr = name;
14568            if (locales[name] != null) {
14569                deprecateSimple(
14570                    'defineLocaleOverride',
14571                    'use moment.updateLocale(localeName, config) to change ' +
14572                        'an existing locale. moment.defineLocale(localeName, ' +
14573                        'config) should only be used for creating a new locale ' +
14574                        'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'
14575                );
14576                parentConfig = locales[name]._config;
14577            } else if (config.parentLocale != null) {
14578                if (locales[config.parentLocale] != null) {
14579                    parentConfig = locales[config.parentLocale]._config;
14580                } else {
14581                    locale = loadLocale(config.parentLocale);
14582                    if (locale != null) {
14583                        parentConfig = locale._config;
14584                    } else {
14585                        if (!localeFamilies[config.parentLocale]) {
14586                            localeFamilies[config.parentLocale] = [];
14587                        }
14588                        localeFamilies[config.parentLocale].push({
14589                            name: name,
14590                            config: config,
14591                        });
14592                        return null;
14593                    }
14594                }
14595            }
14596            locales[name] = new Locale(mergeConfigs(parentConfig, config));
14597
14598            if (localeFamilies[name]) {
14599                localeFamilies[name].forEach(function (x) {
14600                    defineLocale(x.name, x.config);
14601                });
14602            }
14603
14604            // backwards compat for now: also set the locale
14605            // make sure we set the locale AFTER all child locales have been
14606            // created, so we won't end up with the child locale set.
14607            getSetGlobalLocale(name);
14608
14609            return locales[name];
14610        } else {
14611            // useful for testing
14612            delete locales[name];
14613            return null;
14614        }
14615    }
14616
14617    function updateLocale(name, config) {
14618        if (config != null) {
14619            var locale,
14620                tmpLocale,
14621                parentConfig = baseConfig;
14622
14623            if (locales[name] != null && locales[name].parentLocale != null) {
14624                // Update existing child locale in-place to avoid memory-leaks
14625                locales[name].set(mergeConfigs(locales[name]._config, config));
14626            } else {
14627                // MERGE
14628                tmpLocale = loadLocale(name);
14629                if (tmpLocale != null) {
14630                    parentConfig = tmpLocale._config;
14631                }
14632                config = mergeConfigs(parentConfig, config);
14633                if (tmpLocale == null) {
14634                    // updateLocale is called for creating a new locale
14635                    // Set abbr so it will have a name (getters return
14636                    // undefined otherwise).
14637                    config.abbr = name;
14638                }
14639                locale = new Locale(config);
14640                locale.parentLocale = locales[name];
14641                locales[name] = locale;
14642            }
14643
14644            // backwards compat for now: also set the locale
14645            getSetGlobalLocale(name);
14646        } else {
14647            // pass null for config to unupdate, useful for tests
14648            if (locales[name] != null) {
14649                if (locales[name].parentLocale != null) {
14650                    locales[name] = locales[name].parentLocale;
14651                    if (name === getSetGlobalLocale()) {
14652                        getSetGlobalLocale(name);
14653                    }
14654                } else if (locales[name] != null) {
14655                    delete locales[name];
14656                }
14657            }
14658        }
14659        return locales[name];
14660    }
14661
14662    // returns locale data
14663    function getLocale(key) {
14664        var locale;
14665
14666        if (key && key._locale && key._locale._abbr) {
14667            key = key._locale._abbr;
14668        }
14669
14670        if (!key) {
14671            return globalLocale;
14672        }
14673
14674        if (!isArray(key)) {
14675            //short-circuit everything else
14676            locale = loadLocale(key);
14677            if (locale) {
14678                return locale;
14679            }
14680            key = [key];
14681        }
14682
14683        return chooseLocale(key);
14684    }
14685
14686    function listLocales() {
14687        return keys(locales);
14688    }
14689
14690    function checkOverflow(m) {
14691        var overflow,
14692            a = m._a;
14693
14694        if (a && getParsingFlags(m).overflow === -2) {
14695            overflow =
14696                a[MONTH] < 0 || a[MONTH] > 11
14697                    ? MONTH
14698                    : a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH])
14699                    ? DATE
14700                    : a[HOUR] < 0 ||
14701                      a[HOUR] > 24 ||
14702                      (a[HOUR] === 24 &&
14703                          (a[MINUTE] !== 0 ||
14704                              a[SECOND] !== 0 ||
14705                              a[MILLISECOND] !== 0))
14706                    ? HOUR
14707                    : a[MINUTE] < 0 || a[MINUTE] > 59
14708                    ? MINUTE
14709                    : a[SECOND] < 0 || a[SECOND] > 59
14710                    ? SECOND
14711                    : a[MILLISECOND] < 0 || a[MILLISECOND] > 999
14712                    ? MILLISECOND
vendor: 9,346 bytes, lines 14713-14996
14713                    : -1;
14714
14715            if (
14716                getParsingFlags(m)._overflowDayOfYear &&
14717                (overflow < YEAR || overflow > DATE)
14718            ) {
14719                overflow = DATE;
14720            }
14721            if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
14722                overflow = WEEK;
14723            }
14724            if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
14725                overflow = WEEKDAY;
14726            }
14727
14728            getParsingFlags(m).overflow = overflow;
14729        }
14730
14731        return m;
14732    }
14733
14734    // iso 8601 regex
14735    // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
14736    var extendedIsoRegex =
14737            /^\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)?)?$/,
14738        basicIsoRegex =
14739            /^\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)?)?$/,
14740        tzRegex = /Z|[+-]\d\d(?::?\d\d)?/,
14741        isoDates = [
14742            ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
14743            ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
14744            ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
14745            ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
14746            ['YYYY-DDD', /\d{4}-\d{3}/],
14747            ['YYYY-MM', /\d{4}-\d\d/, false],
14748            ['YYYYYYMMDD', /[+-]\d{10}/],
14749            ['YYYYMMDD', /\d{8}/],
14750            ['GGGG[W]WWE', /\d{4}W\d{3}/],
14751            ['GGGG[W]WW', /\d{4}W\d{2}/, false],
14752            ['YYYYDDD', /\d{7}/],
14753            ['YYYYMM', /\d{6}/, false],
14754            ['YYYY', /\d{4}/, false],
14755        ],
14756        // iso time formats and regexes
14757        isoTimes = [
14758            ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
14759            ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
14760            ['HH:mm:ss', /\d\d:\d\d:\d\d/],
14761            ['HH:mm', /\d\d:\d\d/],
14762            ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
14763            ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
14764            ['HHmmss', /\d\d\d\d\d\d/],
14765            ['HHmm', /\d\d\d\d/],
14766            ['HH', /\d\d/],
14767        ],
14768        aspNetJsonRegex = /^\/?Date\((-?\d+)/i,
14769        // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
14770        rfc2822 =
14771            /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/,
14772        obsOffsets = {
14773            UT: 0,
14774            GMT: 0,
14775            EDT: -4 * 60,
14776            EST: -5 * 60,
14777            CDT: -5 * 60,
14778            CST: -6 * 60,
14779            MDT: -6 * 60,
14780            MST: -7 * 60,
14781            PDT: -7 * 60,
14782            PST: -8 * 60,
14783        };
14784
14785    // date from iso format
14786    function configFromISO(config) {
14787        var i,
14788            l,
14789            string = config._i,
14790            match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
14791            allowTime,
14792            dateFormat,
14793            timeFormat,
14794            tzFormat,
14795            isoDatesLen = isoDates.length,
14796            isoTimesLen = isoTimes.length;
14797
14798        if (match) {
14799            getParsingFlags(config).iso = true;
14800            for (i = 0, l = isoDatesLen; i < l; i++) {
14801                if (isoDates[i][1].exec(match[1])) {
14802                    dateFormat = isoDates[i][0];
14803                    allowTime = isoDates[i][2] !== false;
14804                    break;
14805                }
14806            }
14807            if (dateFormat == null) {
14808                config._isValid = false;
14809                return;
14810            }
14811            if (match[3]) {
14812                for (i = 0, l = isoTimesLen; i < l; i++) {
14813                    if (isoTimes[i][1].exec(match[3])) {
14814                        // match[2] should be 'T' or space
14815                        timeFormat = (match[2] || ' ') + isoTimes[i][0];
14816                        break;
14817                    }
14818                }
14819                if (timeFormat == null) {
14820                    config._isValid = false;
14821                    return;
14822                }
14823            }
14824            if (!allowTime && timeFormat != null) {
14825                config._isValid = false;
14826                return;
14827            }
14828            if (match[4]) {
14829                if (tzRegex.exec(match[4])) {
14830                    tzFormat = 'Z';
14831                } else {
14832                    config._isValid = false;
14833                    return;
14834                }
14835            }
14836            config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
14837            configFromStringAndFormat(config);
14838        } else {
14839            config._isValid = false;
14840        }
14841    }
14842
14843    function extractFromRFC2822Strings(
14844        yearStr,
14845        monthStr,
14846        dayStr,
14847        hourStr,
14848        minuteStr,
14849        secondStr
14850    ) {
14851        var result = [
14852            untruncateYear(yearStr),
14853            defaultLocaleMonthsShort.indexOf(monthStr),
14854            parseInt(dayStr, 10),
14855            parseInt(hourStr, 10),
14856            parseInt(minuteStr, 10),
14857        ];
14858
14859        if (secondStr) {
14860            result.push(parseInt(secondStr, 10));
14861        }
14862
14863        return result;
14864    }
14865
14866    function untruncateYear(yearStr) {
14867        var year = parseInt(yearStr, 10);
14868        if (year <= 49) {
14869            return 2000 + year;
14870        } else if (year <= 999) {
14871            return 1900 + year;
14872        }
14873        return year;
14874    }
14875
14876    function preprocessRFC2822(s) {
14877        // Remove comments and folding whitespace and replace multiple-spaces with a single space
14878        return s
14879            .replace(/\([^()]*\)|[\n\t]/g, ' ')
14880            .replace(/(\s\s+)/g, ' ')
14881            .replace(/^\s\s*/, '')
14882            .replace(/\s\s*$/, '');
14883    }
14884
14885    function checkWeekday(weekdayStr, parsedInput, config) {
14886        if (weekdayStr) {
14887            // TODO: Replace the vanilla JS Date object with an independent day-of-week check.
14888            var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
14889                weekdayActual = new Date(
14890                    parsedInput[0],
14891                    parsedInput[1],
14892                    parsedInput[2]
14893                ).getDay();
14894            if (weekdayProvided !== weekdayActual) {
14895                getParsingFlags(config).weekdayMismatch = true;
14896                config._isValid = false;
14897                return false;
14898            }
14899        }
14900        return true;
14901    }
14902
14903    function calculateOffset(obsOffset, militaryOffset, numOffset) {
14904        if (obsOffset) {
14905            return obsOffsets[obsOffset];
14906        } else if (militaryOffset) {
14907            // the only allowed military tz is Z
14908            return 0;
14909        } else {
14910            var hm = parseInt(numOffset, 10),
14911                m = hm % 100,
14912                h = (hm - m) / 100;
14913            return h * 60 + m;
14914        }
14915    }
14916
14917    // date and time from ref 2822 format
14918    function configFromRFC2822(config) {
14919        var match = rfc2822.exec(preprocessRFC2822(config._i)),
14920            parsedArray;
14921        if (match) {
14922            parsedArray = extractFromRFC2822Strings(
14923                match[4],
14924                match[3],
14925                match[2],
14926                match[5],
14927                match[6],
14928                match[7]
14929            );
14930            if (!checkWeekday(match[1], parsedArray, config)) {
14931                return;
14932            }
14933
14934            config._a = parsedArray;
14935            config._tzm = calculateOffset(match[8], match[9], match[10]);
14936
14937            config._d = createUTCDate.apply(null, config._a);
14938            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
14939
14940            getParsingFlags(config).rfc2822 = true;
14941        } else {
14942            config._isValid = false;
14943        }
14944    }
14945
14946    // date from 1) ASP.NET, 2) ISO, 3) RFC 2822 formats, or 4) optional fallback if parsing isn't strict
14947    function configFromString(config) {
14948        var matched = aspNetJsonRegex.exec(config._i);
14949        if (matched !== null) {
14950            config._d = new Date(+matched[1]);
14951            return;
14952        }
14953
14954        configFromISO(config);
14955        if (config._isValid === false) {
14956            delete config._isValid;
14957        } else {
14958            return;
14959        }
14960
14961        configFromRFC2822(config);
14962        if (config._isValid === false) {
14963            delete config._isValid;
14964        } else {
14965            return;
14966        }
14967
14968        if (config._strict) {
14969            config._isValid = false;
14970        } else {
14971            // Final attempt, use Input Fallback
14972            hooks.createFromInputFallback(config);
14973        }
14974    }
14975
14976    hooks.createFromInputFallback = deprecate(
14977        'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
14978            'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
14979            'discouraged. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.',
14980        function (config) {
14981            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
14982        }
14983    );
14984
14985    // Pick the first defined of two or three arguments.
14986    function defaults(a, b, c) {
14987        if (a != null) {
14988            return a;
14989        }
14990        if (b != null) {
14991            return b;
14992        }
14993        return c;
14994    }
14995
14996    function currentDateArray(config
vendor: 95,065 bytes, lines 14996-18114
14996) {
14997        // hooks is actually the exported moment object
14998        var nowValue = new Date(hooks.now());
14999        if (config._useUTC) {
15000            return [
15001                nowValue.getUTCFullYear(),
15002                nowValue.getUTCMonth(),
15003                nowValue.getUTCDate(),
15004            ];
15005        }
15006        return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
15007    }
15008
15009    // convert an array to a date.
15010    // the array should mirror the parameters below
15011    // note: all values past the year are optional and will default to the lowest possible value.
15012    // [year, month, day , hour, minute, second, millisecond]
15013    function configFromArray(config) {
15014        var i,
15015            date,
15016            input = [],
15017            currentDate,
15018            expectedWeekday,
15019            yearToUse;
15020
15021        if (config._d) {
15022            return;
15023        }
15024
15025        currentDate = currentDateArray(config);
15026
15027        //compute day of the year from weeks and weekdays
15028        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
15029            dayOfYearFromWeekInfo(config);
15030        }
15031
15032        //if the day of the year is set, figure out what it is
15033        if (config._dayOfYear != null) {
15034            yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
15035
15036            if (
15037                config._dayOfYear > daysInYear(yearToUse) ||
15038                config._dayOfYear === 0
15039            ) {
15040                getParsingFlags(config)._overflowDayOfYear = true;
15041            }
15042
15043            date = createUTCDate(yearToUse, 0, config._dayOfYear);
15044            config._a[MONTH] = date.getUTCMonth();
15045            config._a[DATE] = date.getUTCDate();
15046        }
15047
15048        // Default to current date.
15049        // * if no year, month, day of month are given, default to today
15050        // * if day of month is given, default month and year
15051        // * if month is given, default only year
15052        // * if year is given, don't default anything
15053        for (i = 0; i < 3 && config._a[i] == null; ++i) {
15054            config._a[i] = input[i] = currentDate[i];
15055        }
15056
15057        // Zero out whatever was not defaulted, including time
15058        for (; i < 7; i++) {
15059            config._a[i] = input[i] =
15060                config._a[i] == null ? (i === 2 ? 1 : 0) : config._a[i];
15061        }
15062
15063        // Check for 24:00:00.000
15064        if (
15065            config._a[HOUR] === 24 &&
15066            config._a[MINUTE] === 0 &&
15067            config._a[SECOND] === 0 &&
15068            config._a[MILLISECOND] === 0
15069        ) {
15070            config._nextDay = true;
15071            config._a[HOUR] = 0;
15072        }
15073
15074        config._d = (config._useUTC ? createUTCDate : createDate).apply(
15075            null,
15076            input
15077        );
15078        expectedWeekday = config._useUTC
15079            ? config._d.getUTCDay()
15080            : config._d.getDay();
15081
15082        // Apply timezone offset from input. The actual utcOffset can be changed
15083        // with parseZone.
15084        if (config._tzm != null) {
15085            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
15086        }
15087
15088        if (config._nextDay) {
15089            config._a[HOUR] = 24;
15090        }
15091
15092        // check for mismatching day of week
15093        if (
15094            config._w &&
15095            typeof config._w.d !== 'undefined' &&
15096            config._w.d !== expectedWeekday
15097        ) {
15098            getParsingFlags(config).weekdayMismatch = true;
15099        }
15100    }
15101
15102    function dayOfYearFromWeekInfo(config) {
15103        var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow, curWeek;
15104
15105        w = config._w;
15106        if (w.GG != null || w.W != null || w.E != null) {
15107            dow = 1;
15108            doy = 4;
15109
15110            // TODO: We need to take the current isoWeekYear, but that depends on
15111            // how we interpret now (local, utc, fixed offset). So create
15112            // a now version of current config (take local/utc/offset flags, and
15113            // create now).
15114            weekYear = defaults(
15115                w.GG,
15116                config._a[YEAR],
15117                weekOfYear(createLocal(), 1, 4).year
15118            );
15119            week = defaults(w.W, 1);
15120            weekday = defaults(w.E, 1);
15121            if (weekday < 1 || weekday > 7) {
15122                weekdayOverflow = true;
15123            }
15124        } else {
15125            dow = config._locale._week.dow;
15126            doy = config._locale._week.doy;
15127
15128            curWeek = weekOfYear(createLocal(), dow, doy);
15129
15130            weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);
15131
15132            // Default to current week.
15133            week = defaults(w.w, curWeek.week);
15134
15135            if (w.d != null) {
15136                // weekday -- low day numbers are considered next week
15137                weekday = w.d;
15138                if (weekday < 0 || weekday > 6) {
15139                    weekdayOverflow = true;
15140                }
15141            } else if (w.e != null) {
15142                // local weekday -- counting starts from beginning of week
15143                weekday = w.e + dow;
15144                if (w.e < 0 || w.e > 6) {
15145                    weekdayOverflow = true;
15146                }
15147            } else {
15148                // default to beginning of week
15149                weekday = dow;
15150            }
15151        }
15152        if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
15153            getParsingFlags(config)._overflowWeeks = true;
15154        } else if (weekdayOverflow != null) {
15155            getParsingFlags(config)._overflowWeekday = true;
15156        } else {
15157            temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
15158            config._a[YEAR] = temp.year;
15159            config._dayOfYear = temp.dayOfYear;
15160        }
15161    }
15162
15163    // constant that refers to the ISO standard
15164    hooks.ISO_8601 = function () {};
15165
15166    // constant that refers to the RFC 2822 form
15167    hooks.RFC_2822 = function () {};
15168
15169    // date from string and format string
15170    function configFromStringAndFormat(config) {
15171        // TODO: Move this to another part of the creation flow to prevent circular deps
15172        if (config._f === hooks.ISO_8601) {
15173            configFromISO(config);
15174            return;
15175        }
15176        if (config._f === hooks.RFC_2822) {
15177            configFromRFC2822(config);
15178            return;
15179        }
15180        config._a = [];
15181        getParsingFlags(config).empty = true;
15182
15183        // This array is used to make a Date, either with `new Date` or `Date.UTC`
15184        var string = '' + config._i,
15185            i,
15186            parsedInput,
15187            tokens,
15188            token,
15189            skipped,
15190            stringLength = string.length,
15191            totalParsedInputLength = 0,
15192            era,
15193            tokenLen;
15194
15195        tokens =
15196            expandFormat(config._f, config._locale).match(formattingTokens) || [];
15197        tokenLen = tokens.length;
15198        for (i = 0; i < tokenLen; i++) {
15199            token = tokens[i];
15200            parsedInput = (string.match(getParseRegexForToken(token, config)) ||
15201                [])[0];
15202            if (parsedInput) {
15203                skipped = string.substr(0, string.indexOf(parsedInput));
15204                if (skipped.length > 0) {
15205                    getParsingFlags(config).unusedInput.push(skipped);
15206                }
15207                string = string.slice(
15208                    string.indexOf(parsedInput) + parsedInput.length
15209                );
15210                totalParsedInputLength += parsedInput.length;
15211            }
15212            // don't parse if it's not a known token
15213            if (formatTokenFunctions[token]) {
15214                if (parsedInput) {
15215                    getParsingFlags(config).empty = false;
15216                } else {
15217                    getParsingFlags(config).unusedTokens.push(token);
15218                }
15219                addTimeToArrayFromToken(token, parsedInput, config);
15220            } else if (config._strict && !parsedInput) {
15221                getParsingFlags(config).unusedTokens.push(token);
15222            }
15223        }
15224
15225        // add remaining unparsed input length to the string
15226        getParsingFlags(config).charsLeftOver =
15227            stringLength - totalParsedInputLength;
15228        if (string.length > 0) {
15229            getParsingFlags(config).unusedInput.push(string);
15230        }
15231
15232        // clear _12h flag if hour is <= 12
15233        if (
15234            config._a[HOUR] <= 12 &&
15235            getParsingFlags(config).bigHour === true &&
15236            config._a[HOUR] > 0
15237        ) {
15238            getParsingFlags(config).bigHour = undefined;
15239        }
15240
15241        getParsingFlags(config).parsedDateParts = config._a.slice(0);
15242        getParsingFlags(config).meridiem = config._meridiem;
15243        // handle meridiem
15244        config._a[HOUR] = meridiemFixWrap(
15245            config._locale,
15246            config._a[HOUR],
15247            config._meridiem
15248        );
15249
15250        // handle era
15251        era = getParsingFlags(config).era;
15252        if (era !== null) {
15253            config._a[YEAR] = config._locale.erasConvertYear(era, config._a[YEAR]);
15254        }
15255
15256        configFromArray(config);
15257        checkOverflow(config);
15258    }
15259
15260    function meridiemFixWrap(locale, hour, meridiem) {
15261        var isPm;
15262
15263        if (meridiem == null) {
15264            // nothing to do
15265            return hour;
15266        }
15267        if (locale.meridiemHour != null) {
15268            return locale.meridiemHour(hour, meridiem);
15269        } else if (locale.isPM != null) {
15270            // Fallback
15271            isPm = locale.isPM(meridiem);
15272            if (isPm && hour < 12) {
15273                hour += 12;
15274            }
15275            if (!isPm && hour === 12) {
15276                hour = 0;
15277            }
15278            return hour;
15279        } else {
15280            // this is not supposed to happen
15281            return hour;
15282        }
15283    }
15284
15285    // date from string and array of format strings
15286    function configFromStringAndArray(config) {
15287        var tempConfig,
15288            bestMoment,
15289            scoreToBeat,
15290            i,
15291            currentScore,
15292            validFormatFound,
15293            bestFormatIsValid = false,
15294            configfLen = config._f.length;
15295
15296        if (configfLen === 0) {
15297            getParsingFlags(config).invalidFormat = true;
15298            config._d = new Date(NaN);
15299            return;
15300        }
15301
15302        for (i = 0; i < configfLen; i++) {
15303            currentScore = 0;
15304            validFormatFound = false;
15305            tempConfig = copyConfig({}, config);
15306            if (config._useUTC != null) {
15307                tempConfig._useUTC = config._useUTC;
15308            }
15309            tempConfig._f = config._f[i];
15310            configFromStringAndFormat(tempConfig);
15311
15312            if (isValid(tempConfig)) {
15313                validFormatFound = true;
15314            }
15315
15316            // if there is any input that was not parsed add a penalty for that format
15317            currentScore += getParsingFlags(tempConfig).charsLeftOver;
15318
15319            //or tokens
15320            currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
15321
15322            getParsingFlags(tempConfig).score = currentScore;
15323
15324            if (!bestFormatIsValid) {
15325                if (
15326                    scoreToBeat == null ||
15327                    currentScore < scoreToBeat ||
15328                    validFormatFound
15329                ) {
15330                    scoreToBeat = currentScore;
15331                    bestMoment = tempConfig;
15332                    if (validFormatFound) {
15333                        bestFormatIsValid = true;
15334                    }
15335                }
15336            } else {
15337                if (currentScore < scoreToBeat) {
15338                    scoreToBeat = currentScore;
15339                    bestMoment = tempConfig;
15340                }
15341            }
15342        }
15343
15344        extend(config, bestMoment || tempConfig);
15345    }
15346
15347    function configFromObject(config) {
15348        if (config._d) {
15349            return;
15350        }
15351
15352        var i = normalizeObjectUnits(config._i),
15353            dayOrDate = i.day === undefined ? i.date : i.day;
15354        config._a = map(
15355            [i.year, i.month, dayOrDate, i.hour, i.minute, i.second, i.millisecond],
15356            function (obj) {
15357                return obj && parseInt(obj, 10);
15358            }
15359        );
15360
15361        configFromArray(config);
15362    }
15363
15364    function createFromConfig(config) {
15365        var res = new Moment(checkOverflow(prepareConfig(config)));
15366        if (res._nextDay) {
15367            // Adding is smart enough around DST
15368            res.add(1, 'd');
15369            res._nextDay = undefined;
15370        }
15371
15372        return res;
15373    }
15374
15375    function prepareConfig(config) {
15376        var input = config._i,
15377            format = config._f;
15378
15379        config._locale = config._locale || getLocale(config._l);
15380
15381        if (input === null || (format === undefined && input === '')) {
15382            return createInvalid({ nullInput: true });
15383        }
15384
15385        if (typeof input === 'string') {
15386            config._i = input = config._locale.preparse(input);
15387        }
15388
15389        if (isMoment(input)) {
15390            return new Moment(checkOverflow(input));
15391        } else if (isDate(input)) {
15392            config._d = input;
15393        } else if (isArray(format)) {
15394            configFromStringAndArray(config);
15395        } else if (format) {
15396            configFromStringAndFormat(config);
15397        } else {
15398            configFromInput(config);
15399        }
15400
15401        if (!isValid(config)) {
15402            config._d = null;
15403        }
15404
15405        return config;
15406    }
15407
15408    function configFromInput(config) {
15409        var input = config._i;
15410        if (isUndefined(input)) {
15411            config._d = new Date(hooks.now());
15412        } else if (isDate(input)) {
15413            config._d = new Date(input.valueOf());
15414        } else if (typeof input === 'string') {
15415            configFromString(config);
15416        } else if (isArray(input)) {
15417            config._a = map(input.slice(0), function (obj) {
15418                return parseInt(obj, 10);
15419            });
15420            configFromArray(config);
15421        } else if (isObject(input)) {
15422            configFromObject(config);
15423        } else if (isNumber(input)) {
15424            // from milliseconds
15425            config._d = new Date(input);
15426        } else {
15427            hooks.createFromInputFallback(config);
15428        }
15429    }
15430
15431    function createLocalOrUTC(input, format, locale, strict, isUTC) {
15432        var c = {};
15433
15434        if (format === true || format === false) {
15435            strict = format;
15436            format = undefined;
15437        }
15438
15439        if (locale === true || locale === false) {
15440            strict = locale;
15441            locale = undefined;
15442        }
15443
15444        if (
15445            (isObject(input) && isObjectEmpty(input)) ||
15446            (isArray(input) && input.length === 0)
15447        ) {
15448            input = undefined;
15449        }
15450        // object construction must be done this way.
15451        // https://github.com/moment/moment/issues/1423
15452        c._isAMomentObject = true;
15453        c._useUTC = c._isUTC = isUTC;
15454        c._l = locale;
15455        c._i = input;
15456        c._f = format;
15457        c._strict = strict;
15458
15459        return createFromConfig(c);
15460    }
15461
15462    function createLocal(input, format, locale, strict) {
15463        return createLocalOrUTC(input, format, locale, strict, false);
15464    }
15465
15466    var prototypeMin = deprecate(
15467            'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',
15468            function () {
15469                var other = createLocal.apply(null, arguments);
15470                if (this.isValid() && other.isValid()) {
15471                    return other < this ? this : other;
15472                } else {
15473                    return createInvalid();
15474                }
15475            }
15476        ),
15477        prototypeMax = deprecate(
15478            'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',
15479            function () {
15480                var other = createLocal.apply(null, arguments);
15481                if (this.isValid() && other.isValid()) {
15482                    return other > this ? this : other;
15483                } else {
15484                    return createInvalid();
15485                }
15486            }
15487        );
15488
15489    // Pick a moment m from moments so that m[fn](other) is true for all
15490    // other. This relies on the function fn to be transitive.
15491    //
15492    // moments should either be an array of moment objects or an array, whose
15493    // first element is an array of moment objects.
15494    function pickBy(fn, moments) {
15495        var res, i;
15496        if (moments.length === 1 && isArray(moments[0])) {
15497            moments = moments[0];
15498        }
15499        if (!moments.length) {
15500            return createLocal();
15501        }
15502        res = moments[0];
15503        for (i = 1; i < moments.length; ++i) {
15504            if (!moments[i].isValid() || moments[i][fn](res)) {
15505                res = moments[i];
15506            }
15507        }
15508        return res;
15509    }
15510
15511    // TODO: Use [].sort instead?
15512    function min() {
15513        var args = [].slice.call(arguments, 0);
15514
15515        return pickBy('isBefore', args);
15516    }
15517
15518    function max() {
15519        var args = [].slice.call(arguments, 0);
15520
15521        return pickBy('isAfter', args);
15522    }
15523
15524    var now = function () {
15525        return Date.now ? Date.now() : +new Date();
15526    };
15527
15528    var ordering = [
15529        'year',
15530        'quarter',
15531        'month',
15532        'week',
15533        'day',
15534        'hour',
15535        'minute',
15536        'second',
15537        'millisecond',
15538    ];
15539
15540    function isDurationValid(m) {
15541        var key,
15542            unitHasDecimal = false,
15543            i,
15544            orderLen = ordering.length;
15545        for (key in m) {
15546            if (
15547                hasOwnProp(m, key) &&
15548                !(
15549                    indexOf.call(ordering, key) !== -1 &&
15550                    (m[key] == null || !isNaN(m[key]))
15551                )
15552            ) {
15553                return false;
15554            }
15555        }
15556
15557        for (i = 0; i < orderLen; ++i) {
15558            if (m[ordering[i]]) {
15559                if (unitHasDecimal) {
15560                    return false; // only allow non-integers for smallest unit
15561                }
15562                if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
15563                    unitHasDecimal = true;
15564                }
15565            }
15566        }
15567
15568        return true;
15569    }
15570
15571    function isValid$1() {
15572        return this._isValid;
15573    }
15574
15575    function createInvalid$1() {
15576        return createDuration(NaN);
15577    }
15578
15579    function Duration(duration) {
15580        var normalizedInput = normalizeObjectUnits(duration),
15581            years = normalizedInput.year || 0,
15582            quarters = normalizedInput.quarter || 0,
15583            months = normalizedInput.month || 0,
15584            weeks = normalizedInput.week || normalizedInput.isoWeek || 0,
15585            days = normalizedInput.day || 0,
15586            hours = normalizedInput.hour || 0,
15587            minutes = normalizedInput.minute || 0,
15588            seconds = normalizedInput.second || 0,
15589            milliseconds = normalizedInput.millisecond || 0;
15590
15591        this._isValid = isDurationValid(normalizedInput);
15592
15593        // representation for dateAddRemove
15594        this._milliseconds =
15595            +milliseconds +
15596            seconds * 1e3 + // 1000
15597            minutes * 6e4 + // 1000 * 60
15598            hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
15599        // Because of dateAddRemove treats 24 hours as different from a
15600        // day when working around DST, we need to store them separately
15601        this._days = +days + weeks * 7;
15602        // It is impossible to translate months into days without knowing
15603        // which months you are are talking about, so we have to store
15604        // it separately.
15605        this._months = +months + quarters * 3 + years * 12;
15606
15607        this._data = {};
15608
15609        this._locale = getLocale();
15610
15611        this._bubble();
15612    }
15613
15614    function isDuration(obj) {
15615        return obj instanceof Duration;
15616    }
15617
15618    function absRound(number) {
15619        if (number < 0) {
15620            return Math.round(-1 * number) * -1;
15621        } else {
15622            return Math.round(number);
15623        }
15624    }
15625
15626    // compare two arrays, return the number of differences
15627    function compareArrays(array1, array2, dontConvert) {
15628        var len = Math.min(array1.length, array2.length),
15629            lengthDiff = Math.abs(array1.length - array2.length),
15630            diffs = 0,
15631            i;
15632        for (i = 0; i < len; i++) {
15633            if (
15634                (dontConvert && array1[i] !== array2[i]) ||
15635                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))
15636            ) {
15637                diffs++;
15638            }
15639        }
15640        return diffs + lengthDiff;
15641    }
15642
15643    // FORMATTING
15644
15645    function offset(token, separator) {
15646        addFormatToken(token, 0, 0, function () {
15647            var offset = this.utcOffset(),
15648                sign = '+';
15649            if (offset < 0) {
15650                offset = -offset;
15651                sign = '-';
15652            }
15653            return (
15654                sign +
15655                zeroFill(~~(offset / 60), 2) +
15656                separator +
15657                zeroFill(~~offset % 60, 2)
15658            );
15659        });
15660    }
15661
15662    offset('Z', ':');
15663    offset('ZZ', '');
15664
15665    // PARSING
15666
15667    addRegexToken('Z', matchShortOffset);
15668    addRegexToken('ZZ', matchShortOffset);
15669    addParseToken(['Z', 'ZZ'], function (input, array, config) {
15670        config._useUTC = true;
15671        config._tzm = offsetFromString(matchShortOffset, input);
15672    });
15673
15674    // HELPERS
15675
15676    // timezone chunker
15677    // '+10:00' > ['10',  '00']
15678    // '-1530'  > ['-15', '30']
15679    var chunkOffset = /([\+\-]|\d\d)/gi;
15680
15681    function offsetFromString(matcher, string) {
15682        var matches = (string || '').match(matcher),
15683            chunk,
15684            parts,
15685            minutes;
15686
15687        if (matches === null) {
15688            return null;
15689        }
15690
15691        chunk = matches[matches.length - 1] || [];
15692        parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
15693        minutes = +(parts[1] * 60) + toInt(parts[2]);
15694
15695        return minutes === 0 ? 0 : parts[0] === '+' ? minutes : -minutes;
15696    }
15697
15698    // Return a moment from input, that is local/utc/zone equivalent to model.
15699    function cloneWithOffset(input, model) {
15700        var res, diff;
15701        if (model._isUTC) {
15702            res = model.clone();
15703            diff =
15704                (isMoment(input) || isDate(input)
15705                    ? input.valueOf()
15706                    : createLocal(input).valueOf()) - res.valueOf();
15707            // Use low-level api, because this fn is low-level api.
15708            res._d.setTime(res._d.valueOf() + diff);
15709            hooks.updateOffset(res, false);
15710            return res;
15711        } else {
15712            return createLocal(input).local();
15713        }
15714    }
15715
15716    function getDateOffset(m) {
15717        // On Firefox.24 Date#getTimezoneOffset returns a floating point.
15718        // https://github.com/moment/moment/pull/1871
15719        return -Math.round(m._d.getTimezoneOffset());
15720    }
15721
15722    // HOOKS
15723
15724    // This function will be called whenever a moment is mutated.
15725    // It is intended to keep the offset in sync with the timezone.
15726    hooks.updateOffset = function () {};
15727
15728    // MOMENTS
15729
15730    // keepLocalTime = true means only change the timezone, without
15731    // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
15732    // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
15733    // +0200, so we adjust the time as needed, to be valid.
15734    //
15735    // Keeping the time actually adds/subtracts (one hour)
15736    // from the actual represented time. That is why we call updateOffset
15737    // a second time. In case it wants us to change the offset again
15738    // _changeInProgress == true case, then we have to adjust, because
15739    // there is no such time in the given timezone.
15740    function getSetOffset(input, keepLocalTime, keepMinutes) {
15741        var offset = this._offset || 0,
15742            localAdjust;
15743        if (!this.isValid()) {
15744            return input != null ? this : NaN;
15745        }
15746        if (input != null) {
15747            if (typeof input === 'string') {
15748                input = offsetFromString(matchShortOffset, input);
15749                if (input === null) {
15750                    return this;
15751                }
15752            } else if (Math.abs(input) < 16 && !keepMinutes) {
15753                input = input * 60;
15754            }
15755            if (!this._isUTC && keepLocalTime) {
15756                localAdjust = getDateOffset(this);
15757            }
15758            this._offset = input;
15759            this._isUTC = true;
15760            if (localAdjust != null) {
15761                this.add(localAdjust, 'm');
15762            }
15763            if (offset !== input) {
15764                if (!keepLocalTime || this._changeInProgress) {
15765                    addSubtract(
15766                        this,
15767                        createDuration(input - offset, 'm'),
15768                        1,
15769                        false
15770                    );
15771                } else if (!this._changeInProgress) {
15772                    this._changeInProgress = true;
15773                    hooks.updateOffset(this, true);
15774                    this._changeInProgress = null;
15775                }
15776            }
15777            return this;
15778        } else {
15779            return this._isUTC ? offset : getDateOffset(this);
15780        }
15781    }
15782
15783    function getSetZone(input, keepLocalTime) {
15784        if (input != null) {
15785            if (typeof input !== 'string') {
15786                input = -input;
15787            }
15788
15789            this.utcOffset(input, keepLocalTime);
15790
15791            return this;
15792        } else {
15793            return -this.utcOffset();
15794        }
15795    }
15796
15797    function setOffsetToUTC(keepLocalTime) {
15798        return this.utcOffset(0, keepLocalTime);
15799    }
15800
15801    function setOffsetToLocal(keepLocalTime) {
15802        if (this._isUTC) {
15803            this.utcOffset(0, keepLocalTime);
15804            this._isUTC = false;
15805
15806            if (keepLocalTime) {
15807                this.subtract(getDateOffset(this), 'm');
15808            }
15809        }
15810        return this;
15811    }
15812
15813    function setOffsetToParsedOffset() {
15814        if (this._tzm != null) {
15815            this.utcOffset(this._tzm, false, true);
15816        } else if (typeof this._i === 'string') {
15817            var tZone = offsetFromString(matchOffset, this._i);
15818            if (tZone != null) {
15819                this.utcOffset(tZone);
15820            } else {
15821                this.utcOffset(0, true);
15822            }
15823        }
15824        return this;
15825    }
15826
15827    function hasAlignedHourOffset(input) {
15828        if (!this.isValid()) {
15829            return false;
15830        }
15831        input = input ? createLocal(input).utcOffset() : 0;
15832
15833        return (this.utcOffset() - input) % 60 === 0;
15834    }
15835
15836    function isDaylightSavingTime() {
15837        return (
15838            this.utcOffset() > this.clone().month(0).utcOffset() ||
15839            this.utcOffset() > this.clone().month(5).utcOffset()
15840        );
15841    }
15842
15843    function isDaylightSavingTimeShifted() {
15844        if (!isUndefined(this._isDSTShifted)) {
15845            return this._isDSTShifted;
15846        }
15847
15848        var c = {},
15849            other;
15850
15851        copyConfig(c, this);
15852        c = prepareConfig(c);
15853
15854        if (c._a) {
15855            other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
15856            this._isDSTShifted =
15857                this.isValid() && compareArrays(c._a, other.toArray()) > 0;
15858        } else {
15859            this._isDSTShifted = false;
15860        }
15861
15862        return this._isDSTShifted;
15863    }
15864
15865    function isLocal() {
15866        return this.isValid() ? !this._isUTC : false;
15867    }
15868
15869    function isUtcOffset() {
15870        return this.isValid() ? this._isUTC : false;
15871    }
15872
15873    function isUtc() {
15874        return this.isValid() ? this._isUTC && this._offset === 0 : false;
15875    }
15876
15877    // ASP.NET json date format regex
15878    var aspNetRegex = /^(-|\+)?(?:(\d*)[. ])?(\d+):(\d+)(?::(\d+)(\.\d*)?)?$/,
15879        // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
15880        // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
15881        // and further modified to allow for strings containing both week and day
15882        isoRegex =
15883            /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;
15884
15885    function createDuration(input, key) {
15886        var duration = input,
15887            // matching against regexp is expensive, do it on demand
15888            match = null,
15889            sign,
15890            ret,
15891            diffRes;
15892
15893        if (isDuration(input)) {
15894            duration = {
15895                ms: input._milliseconds,
15896                d: input._days,
15897                M: input._months,
15898            };
15899        } else if (isNumber(input) || !isNaN(+input)) {
15900            duration = {};
15901            if (key) {
15902                duration[key] = +input;
15903            } else {
15904                duration.milliseconds = +input;
15905            }
15906        } else if ((match = aspNetRegex.exec(input))) {
15907            sign = match[1] === '-' ? -1 : 1;
15908            duration = {
15909                y: 0,
15910                d: toInt(match[DATE]) * sign,
15911                h: toInt(match[HOUR]) * sign,
15912                m: toInt(match[MINUTE]) * sign,
15913                s: toInt(match[SECOND]) * sign,
15914                ms: toInt(absRound(match[MILLISECOND] * 1000)) * sign, // the millisecond decimal point is included in the match
15915            };
15916        } else if ((match = isoRegex.exec(input))) {
15917            sign = match[1] === '-' ? -1 : 1;
15918            duration = {
15919                y: parseIso(match[2], sign),
15920                M: parseIso(match[3], sign),
15921                w: parseIso(match[4], sign),
15922                d: parseIso(match[5], sign),
15923                h: parseIso(match[6], sign),
15924                m: parseIso(match[7], sign),
15925                s: parseIso(match[8], sign),
15926            };
15927        } else if (duration == null) {
15928            // checks for null or undefined
15929            duration = {};
15930        } else if (
15931            typeof duration === 'object' &&
15932            ('from' in duration || 'to' in duration)
15933        ) {
15934            diffRes = momentsDifference(
15935                createLocal(duration.from),
15936                createLocal(duration.to)
15937            );
15938
15939            duration = {};
15940            duration.ms = diffRes.milliseconds;
15941            duration.M = diffRes.months;
15942        }
15943
15944        ret = new Duration(duration);
15945
15946        if (isDuration(input) && hasOwnProp(input, '_locale')) {
15947            ret._locale = input._locale;
15948        }
15949
15950        if (isDuration(input) && hasOwnProp(input, '_isValid')) {
15951            ret._isValid = input._isValid;
15952        }
15953
15954        return ret;
15955    }
15956
15957    createDuration.fn = Duration.prototype;
15958    createDuration.invalid = createInvalid$1;
15959
15960    function parseIso(inp, sign) {
15961        // We'd normally use ~~inp for this, but unfortunately it also
15962        // converts floats to ints.
15963        // inp may be undefined, so careful calling replace on it.
15964        var res = inp && parseFloat(inp.replace(',', '.'));
15965        // apply sign while we're at it
15966        return (isNaN(res) ? 0 : res) * sign;
15967    }
15968
15969    function positiveMomentsDifference(base, other) {
15970        var res = {};
15971
15972        res.months =
15973            other.month() - base.month() + (other.year() - base.year()) * 12;
15974        if (base.clone().add(res.months, 'M').isAfter(other)) {
15975            --res.months;
15976        }
15977
15978        res.milliseconds = +other - +base.clone().add(res.months, 'M');
15979
15980        return res;
15981    }
15982
15983    function momentsDifference(base, other) {
15984        var res;
15985        if (!(base.isValid() && other.isValid())) {
15986            return { milliseconds: 0, months: 0 };
15987        }
15988
15989        other = cloneWithOffset(other, base);
15990        if (base.isBefore(other)) {
15991            res = positiveMomentsDifference(base, other);
15992        } else {
15993            res = positiveMomentsDifference(other, base);
15994            res.milliseconds = -res.milliseconds;
15995            res.months = -res.months;
15996        }
15997
15998        return res;
15999    }
16000
16001    // TODO: remove 'name' arg after deprecation is removed
16002    function createAdder(direction, name) {
16003        return function (val, period) {
16004            var dur, tmp;
16005            //invert the arguments, but complain about it
16006            if (period !== null && !isNaN(+period)) {
16007                deprecateSimple(
16008                    name,
16009                    'moment().' +
16010                        name +
16011                        '(period, number) is deprecated. Please use moment().' +
16012                        name +
16013                        '(number, period). ' +
16014                        'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'
16015                );
16016                tmp = val;
16017                val = period;
16018                period = tmp;
16019            }
16020
16021            dur = createDuration(val, period);
16022            addSubtract(this, dur, direction);
16023            return this;
16024        };
16025    }
16026
16027    function addSubtract(mom, duration, isAdding, updateOffset) {
16028        var milliseconds = duration._milliseconds,
16029            days = absRound(duration._days),
16030            months = absRound(duration._months);
16031
16032        if (!mom.isValid()) {
16033            // No op
16034            return;
16035        }
16036
16037        updateOffset = updateOffset == null ? true : updateOffset;
16038
16039        if (months) {
16040            setMonth(mom, get(mom, 'Month') + months * isAdding);
16041        }
16042        if (days) {
16043            set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
16044        }
16045        if (milliseconds) {
16046            mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
16047        }
16048        if (updateOffset) {
16049            hooks.updateOffset(mom, days || months);
16050        }
16051    }
16052
16053    var add = createAdder(1, 'add'),
16054        subtract = createAdder(-1, 'subtract');
16055
16056    function isString(input) {
16057        return typeof input === 'string' || input instanceof String;
16058    }
16059
16060    // type MomentInput = Moment | Date | string | number | (number | string)[] | MomentInputObject | void; // null | undefined
16061    function isMomentInput(input) {
16062        return (
16063            isMoment(input) ||
16064            isDate(input) ||
16065            isString(input) ||
16066            isNumber(input) ||
16067            isNumberOrStringArray(input) ||
16068            isMomentInputObject(input) ||
16069            input === null ||
16070            input === undefined
16071        );
16072    }
16073
16074    function isMomentInputObject(input) {
16075        var objectTest = isObject(input) && !isObjectEmpty(input),
16076            propertyTest = false,
16077            properties = [
16078                'years',
16079                'year',
16080                'y',
16081                'months',
16082                'month',
16083                'M',
16084                'days',
16085                'day',
16086                'd',
16087                'dates',
16088                'date',
16089                'D',
16090                'hours',
16091                'hour',
16092                'h',
16093                'minutes',
16094                'minute',
16095                'm',
16096                'seconds',
16097                'second',
16098                's',
16099                'milliseconds',
16100                'millisecond',
16101                'ms',
16102            ],
16103            i,
16104            property,
16105            propertyLen = properties.length;
16106
16107        for (i = 0; i < propertyLen; i += 1) {
16108            property = properties[i];
16109            propertyTest = propertyTest || hasOwnProp(input, property);
16110        }
16111
16112        return objectTest && propertyTest;
16113    }
16114
16115    function isNumberOrStringArray(input) {
16116        var arrayTest = isArray(input),
16117            dataTypeTest = false;
16118        if (arrayTest) {
16119            dataTypeTest =
16120                input.filter(function (item) {
16121                    return !isNumber(item) && isString(input);
16122                }).length === 0;
16123        }
16124        return arrayTest && dataTypeTest;
16125    }
16126
16127    function isCalendarSpec(input) {
16128        var objectTest = isObject(input) && !isObjectEmpty(input),
16129            propertyTest = false,
16130            properties = [
16131                'sameDay',
16132                'nextDay',
16133                'lastDay',
16134                'nextWeek',
16135                'lastWeek',
16136                'sameElse',
16137            ],
16138            i,
16139            property;
16140
16141        for (i = 0; i < properties.length; i += 1) {
16142            property = properties[i];
16143            propertyTest = propertyTest || hasOwnProp(input, property);
16144        }
16145
16146        return objectTest && propertyTest;
16147    }
16148
16149    function getCalendarFormat(myMoment, now) {
16150        var diff = myMoment.diff(now, 'days', true);
16151        return diff < -6
16152            ? 'sameElse'
16153            : diff < -1
16154            ? 'lastWeek'
16155            : diff < 0
16156            ? 'lastDay'
16157            : diff < 1
16158            ? 'sameDay'
16159            : diff < 2
16160            ? 'nextDay'
16161            : diff < 7
16162            ? 'nextWeek'
16163            : 'sameElse';
16164    }
16165
16166    function calendar$1(time, formats) {
16167        // Support for single parameter, formats only overload to the calendar function
16168        if (arguments.length === 1) {
16169            if (!arguments[0]) {
16170                time = undefined;
16171                formats = undefined;
16172            } else if (isMomentInput(arguments[0])) {
16173                time = arguments[0];
16174                formats = undefined;
16175            } else if (isCalendarSpec(arguments[0])) {
16176                formats = arguments[0];
16177                time = undefined;
16178            }
16179        }
16180        // We want to compare the start of today, vs this.
16181        // Getting start-of-today depends on whether we're local/utc/offset or not.
16182        var now = time || createLocal(),
16183            sod = cloneWithOffset(now, this).startOf('day'),
16184            format = hooks.calendarFormat(this, sod) || 'sameElse',
16185            output =
16186                formats &&
16187                (isFunction(formats[format])
16188                    ? formats[format].call(this, now)
16189                    : formats[format]);
16190
16191        return this.format(
16192            output || this.localeData().calendar(format, this, createLocal(now))
16193        );
16194    }
16195
16196    function clone() {
16197        return new Moment(this);
16198    }
16199
16200    function isAfter(input, units) {
16201        var localInput = isMoment(input) ? input : createLocal(input);
16202        if (!(this.isValid() && localInput.isValid())) {
16203            return false;
16204        }
16205        units = normalizeUnits(units) || 'millisecond';
16206        if (units === 'millisecond') {
16207            return this.valueOf() > localInput.valueOf();
16208        } else {
16209            return localInput.valueOf() < this.clone().startOf(units).valueOf();
16210        }
16211    }
16212
16213    function isBefore(input, units) {
16214        var localInput = isMoment(input) ? input : createLocal(input);
16215        if (!(this.isValid() && localInput.isValid())) {
16216            return false;
16217        }
16218        units = normalizeUnits(units) || 'millisecond';
16219        if (units === 'millisecond') {
16220            return this.valueOf() < localInput.valueOf();
16221        } else {
16222            return this.clone().endOf(units).valueOf() < localInput.valueOf();
16223        }
16224    }
16225
16226    function isBetween(from, to, units, inclusivity) {
16227        var localFrom = isMoment(from) ? from : createLocal(from),
16228            localTo = isMoment(to) ? to : createLocal(to);
16229        if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {
16230            return false;
16231        }
16232        inclusivity = inclusivity || '()';
16233        return (
16234            (inclusivity[0] === '('
16235                ? this.isAfter(localFrom, units)
16236                : !this.isBefore(localFrom, units)) &&
16237            (inclusivity[1] === ')'
16238                ? this.isBefore(localTo, units)
16239                : !this.isAfter(localTo, units))
16240        );
16241    }
16242
16243    function isSame(input, units) {
16244        var localInput = isMoment(input) ? input : createLocal(input),
16245            inputMs;
16246        if (!(this.isValid() && localInput.isValid())) {
16247            return false;
16248        }
16249        units = normalizeUnits(units) || 'millisecond';
16250        if (units === 'millisecond') {
16251            return this.valueOf() === localInput.valueOf();
16252        } else {
16253            inputMs = localInput.valueOf();
16254            return (
16255                this.clone().startOf(units).valueOf() <= inputMs &&
16256                inputMs <= this.clone().endOf(units).valueOf()
16257            );
16258        }
16259    }
16260
16261    function isSameOrAfter(input, units) {
16262        return this.isSame(input, units) || this.isAfter(input, units);
16263    }
16264
16265    function isSameOrBefore(input, units) {
16266        return this.isSame(input, units) || this.isBefore(input, units);
16267    }
16268
16269    function diff(input, units, asFloat) {
16270        var that, zoneDelta, output;
16271
16272        if (!this.isValid()) {
16273            return NaN;
16274        }
16275
16276        that = cloneWithOffset(input, this);
16277
16278        if (!that.isValid()) {
16279            return NaN;
16280        }
16281
16282        zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
16283
16284        units = normalizeUnits(units);
16285
16286        switch (units) {
16287            case 'year':
16288                output = monthDiff(this, that) / 12;
16289                break;
16290            case 'month':
16291                output = monthDiff(this, that);
16292                break;
16293            case 'quarter':
16294                output = monthDiff(this, that) / 3;
16295                break;
16296            case 'second':
16297                output = (this - that) / 1e3;
16298                break; // 1000
16299            case 'minute':
16300                output = (this - that) / 6e4;
16301                break; // 1000 * 60
16302            case 'hour':
16303                output = (this - that) / 36e5;
16304                break; // 1000 * 60 * 60
16305            case 'day':
16306                output = (this - that - zoneDelta) / 864e5;
16307                break; // 1000 * 60 * 60 * 24, negate dst
16308            case 'week':
16309                output = (this - that - zoneDelta) / 6048e5;
16310                break; // 1000 * 60 * 60 * 24 * 7, negate dst
16311            default:
16312                output = this - that;
16313        }
16314
16315        return asFloat ? output : absFloor(output);
16316    }
16317
16318    function monthDiff(a, b) {
16319        if (a.date() < b.date()) {
16320            // end-of-month calculations work correct when the start month has more
16321            // days than the end month.
16322            return -monthDiff(b, a);
16323        }
16324        // difference in months
16325        var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month()),
16326            // b is in (anchor - 1 month, anchor + 1 month)
16327            anchor = a.clone().add(wholeMonthDiff, 'months'),
16328            anchor2,
16329            adjust;
16330
16331        if (b - anchor < 0) {
16332            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
16333            // linear across the month
16334            adjust = (b - anchor) / (anchor - anchor2);
16335        } else {
16336            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
16337            // linear across the month
16338            adjust = (b - anchor) / (anchor2 - anchor);
16339        }
16340
16341        //check for negative zero, return zero if negative zero
16342        return -(wholeMonthDiff + adjust) || 0;
16343    }
16344
16345    hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
16346    hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
16347
16348    function toString() {
16349        return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
16350    }
16351
16352    function toISOString(keepOffset) {
16353        if (!this.isValid()) {
16354            return null;
16355        }
16356        var utc = keepOffset !== true,
16357            m = utc ? this.clone().utc() : this;
16358        if (m.year() < 0 || m.year() > 9999) {
16359            return formatMoment(
16360                m,
16361                utc
16362                    ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'
16363                    : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'
16364            );
16365        }
16366        if (isFunction(Date.prototype.toISOString)) {
16367            // native implementation is ~50x faster, use it when we can
16368            if (utc) {
16369                return this.toDate().toISOString();
16370            } else {
16371                return new Date(this.valueOf() + this.utcOffset() * 60 * 1000)
16372                    .toISOString()
16373                    .replace('Z', formatMoment(m, 'Z'));
16374            }
16375        }
16376        return formatMoment(
16377            m,
16378            utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'
16379        );
16380    }
16381
16382    /**
16383     * Return a human readable representation of a moment that can
16384     * also be evaluated to get a new moment which is the same
16385     *
16386     * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
16387     */
16388    function inspect() {
16389        if (!this.isValid()) {
16390            return 'moment.invalid(/* ' + this._i + ' */)';
16391        }
16392        var func = 'moment',
16393            zone = '',
16394            prefix,
16395            year,
16396            datetime,
16397            suffix;
16398        if (!this.isLocal()) {
16399            func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
16400            zone = 'Z';
16401        }
16402        prefix = '[' + func + '("]';
16403        year = 0 <= this.year() && this.year() <= 9999 ? 'YYYY' : 'YYYYYY';
16404        datetime = '-MM-DD[T]HH:mm:ss.SSS';
16405        suffix = zone + '[")]';
16406
16407        return this.format(prefix + year + datetime + suffix);
16408    }
16409
16410    function format(inputString) {
16411        if (!inputString) {
16412            inputString = this.isUtc()
16413                ? hooks.defaultFormatUtc
16414                : hooks.defaultFormat;
16415        }
16416        var output = formatMoment(this, inputString);
16417        return this.localeData().postformat(output);
16418    }
16419
16420    function from(time, withoutSuffix) {
16421        if (
16422            this.isValid() &&
16423            ((isMoment(time) && time.isValid()) || createLocal(time).isValid())
16424        ) {
16425            return createDuration({ to: this, from: time })
16426                .locale(this.locale())
16427                .humanize(!withoutSuffix);
16428        } else {
16429            return this.localeData().invalidDate();
16430        }
16431    }
16432
16433    function fromNow(withoutSuffix) {
16434        return this.from(createLocal(), withoutSuffix);
16435    }
16436
16437    function to(time, withoutSuffix) {
16438        if (
16439            this.isValid() &&
16440            ((isMoment(time) && time.isValid()) || createLocal(time).isValid())
16441        ) {
16442            return createDuration({ from: this, to: time })
16443                .locale(this.locale())
16444                .humanize(!withoutSuffix);
16445        } else {
16446            return this.localeData().invalidDate();
16447        }
16448    }
16449
16450    function toNow(withoutSuffix) {
16451        return this.to(createLocal(), withoutSuffix);
16452    }
16453
16454    // If passed a locale key, it will set the locale for this
16455    // instance.  Otherwise, it will return the locale configuration
16456    // variables for this instance.
16457    function locale(key) {
16458        var newLocaleData;
16459
16460        if (key === undefined) {
16461            return this._locale._abbr;
16462        } else {
16463            newLocaleData = getLocale(key);
16464            if (newLocaleData != null) {
16465                this._locale = newLocaleData;
16466            }
16467            return this;
16468        }
16469    }
16470
16471    var lang = deprecate(
16472        'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
16473        function (key) {
16474            if (key === undefined) {
16475                return this.localeData();
16476            } else {
16477                return this.locale(key);
16478            }
16479        }
16480    );
16481
16482    function localeData() {
16483        return this._locale;
16484    }
16485
16486    var MS_PER_SECOND = 1000,
16487        MS_PER_MINUTE = 60 * MS_PER_SECOND,
16488        MS_PER_HOUR = 60 * MS_PER_MINUTE,
16489        MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR;
16490
16491    // actual modulo - handles negative numbers (for dates before 1970):
16492    function mod$1(dividend, divisor) {
16493        return ((dividend % divisor) + divisor) % divisor;
16494    }
16495
16496    function localStartOfDate(y, m, d) {
16497        // the date constructor remaps years 0-99 to 1900-1999
16498        if (y < 100 && y >= 0) {
16499            // preserve leap years using a full 400 year cycle, then reset
16500            return new Date(y + 400, m, d) - MS_PER_400_YEARS;
16501        } else {
16502            return new Date(y, m, d).valueOf();
16503        }
16504    }
16505
16506    function utcStartOfDate(y, m, d) {
16507        // Date.UTC remaps years 0-99 to 1900-1999
16508        if (y < 100 && y >= 0) {
16509            // preserve leap years using a full 400 year cycle, then reset
16510            return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;
16511        } else {
16512            return Date.UTC(y, m, d);
16513        }
16514    }
16515
16516    function startOf(units) {
16517        var time, startOfDate;
16518        units = normalizeUnits(units);
16519        if (units === undefined || units === 'millisecond' || !this.isValid()) {
16520            return this;
16521        }
16522
16523        startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
16524
16525        switch (units) {
16526            case 'year':
16527                time = startOfDate(this.year(), 0, 1);
16528                break;
16529            case 'quarter':
16530                time = startOfDate(
16531                    this.year(),
16532                    this.month() - (this.month() % 3),
16533                    1
16534                );
16535                break;
16536            case 'month':
16537                time = startOfDate(this.year(), this.month(), 1);
16538                break;
16539            case 'week':
16540                time = startOfDate(
16541                    this.year(),
16542                    this.month(),
16543                    this.date() - this.weekday()
16544                );
16545                break;
16546            case 'isoWeek':
16547                time = startOfDate(
16548                    this.year(),
16549                    this.month(),
16550                    this.date() - (this.isoWeekday() - 1)
16551                );
16552                break;
16553            case 'day':
16554            case 'date':
16555                time = startOfDate(this.year(), this.month(), this.date());
16556                break;
16557            case 'hour':
16558                time = this._d.valueOf();
16559                time -= mod$1(
16560                    time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE),
16561                    MS_PER_HOUR
16562                );
16563                break;
16564            case 'minute':
16565                time = this._d.valueOf();
16566                time -= mod$1(time, MS_PER_MINUTE);
16567                break;
16568            case 'second':
16569                time = this._d.valueOf();
16570                time -= mod$1(time, MS_PER_SECOND);
16571                break;
16572        }
16573
16574        this._d.setTime(time);
16575        hooks.updateOffset(this, true);
16576        return this;
16577    }
16578
16579    function endOf(units) {
16580        var time, startOfDate;
16581        units = normalizeUnits(units);
16582        if (units === undefined || units === 'millisecond' || !this.isValid()) {
16583            return this;
16584        }
16585
16586        startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
16587
16588        switch (units) {
16589            case 'year':
16590                time = startOfDate(this.year() + 1, 0, 1) - 1;
16591                break;
16592            case 'quarter':
16593                time =
16594                    startOfDate(
16595                        this.year(),
16596                        this.month() - (this.month() % 3) + 3,
16597                        1
16598                    ) - 1;
16599                break;
16600            case 'month':
16601                time = startOfDate(this.year(), this.month() + 1, 1) - 1;
16602                break;
16603            case 'week':
16604                time =
16605                    startOfDate(
16606                        this.year(),
16607                        this.month(),
16608                        this.date() - this.weekday() + 7
16609                    ) - 1;
16610                break;
16611            case 'isoWeek':
16612                time =
16613                    startOfDate(
16614                        this.year(),
16615                        this.month(),
16616                        this.date() - (this.isoWeekday() - 1) + 7
16617                    ) - 1;
16618                break;
16619            case 'day':
16620            case 'date':
16621                time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;
16622                break;
16623            case 'hour':
16624                time = this._d.valueOf();
16625                time +=
16626                    MS_PER_HOUR -
16627                    mod$1(
16628                        time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE),
16629                        MS_PER_HOUR
16630                    ) -
16631                    1;
16632                break;
16633            case 'minute':
16634                time = this._d.valueOf();
16635                time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;
16636                break;
16637            case 'second':
16638                time = this._d.valueOf();
16639                time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;
16640                break;
16641        }
16642
16643        this._d.setTime(time);
16644        hooks.updateOffset(this, true);
16645        return this;
16646    }
16647
16648    function valueOf() {
16649        return this._d.valueOf() - (this._offset || 0) * 60000;
16650    }
16651
16652    function unix() {
16653        return Math.floor(this.valueOf() / 1000);
16654    }
16655
16656    function toDate() {
16657        return new Date(this.valueOf());
16658    }
16659
16660    function toArray() {
16661        var m = this;
16662        return [
16663            m.year(),
16664            m.month(),
16665            m.date(),
16666            m.hour(),
16667            m.minute(),
16668            m.second(),
16669            m.millisecond(),
16670        ];
16671    }
16672
16673    function toObject() {
16674        var m = this;
16675        return {
16676            years: m.year(),
16677            months: m.month(),
16678            date: m.date(),
16679            hours: m.hours(),
16680            minutes: m.minutes(),
16681            seconds: m.seconds(),
16682            milliseconds: m.milliseconds(),
16683        };
16684    }
16685
16686    function toJSON() {
16687        // new Date(NaN).toJSON() === null
16688        return this.isValid() ? this.toISOString() : null;
16689    }
16690
16691    function isValid$2() {
16692        return isValid(this);
16693    }
16694
16695    function parsingFlags() {
16696        return extend({}, getParsingFlags(this));
16697    }
16698
16699    function invalidAt() {
16700        return getParsingFlags(this).overflow;
16701    }
16702
16703    function creationData() {
16704        return {
16705            input: this._i,
16706            format: this._f,
16707            locale: this._locale,
16708            isUTC: this._isUTC,
16709            strict: this._strict,
16710        };
16711    }
16712
16713    addFormatToken('N', 0, 0, 'eraAbbr');
16714    addFormatToken('NN', 0, 0, 'eraAbbr');
16715    addFormatToken('NNN', 0, 0, 'eraAbbr');
16716    addFormatToken('NNNN', 0, 0, 'eraName');
16717    addFormatToken('NNNNN', 0, 0, 'eraNarrow');
16718
16719    addFormatToken('y', ['y', 1], 'yo', 'eraYear');
16720    addFormatToken('y', ['yy', 2], 0, 'eraYear');
16721    addFormatToken('y', ['yyy', 3], 0, 'eraYear');
16722    addFormatToken('y', ['yyyy', 4], 0, 'eraYear');
16723
16724    addRegexToken('N', matchEraAbbr);
16725    addRegexToken('NN', matchEraAbbr);
16726    addRegexToken('NNN', matchEraAbbr);
16727    addRegexToken('NNNN', matchEraName);
16728    addRegexToken('NNNNN', matchEraNarrow);
16729
16730    addParseToken(
16731        ['N', 'NN', 'NNN', 'NNNN', 'NNNNN'],
16732        function (input, array, config, token) {
16733            var era = config._locale.erasParse(input, token, config._strict);
16734            if (era) {
16735                getParsingFlags(config).era = era;
16736            } else {
16737                getParsingFlags(config).invalidEra = input;
16738            }
16739        }
16740    );
16741
16742    addRegexToken('y', matchUnsigned);
16743    addRegexToken('yy', matchUnsigned);
16744    addRegexToken('yyy', matchUnsigned);
16745    addRegexToken('yyyy', matchUnsigned);
16746    addRegexToken('yo', matchEraYearOrdinal);
16747
16748    addParseToken(['y', 'yy', 'yyy', 'yyyy'], YEAR);
16749    addParseToken(['yo'], function (input, array, config, token) {
16750        var match;
16751        if (config._locale._eraYearOrdinalRegex) {
16752            match = input.match(config._locale._eraYearOrdinalRegex);
16753        }
16754
16755        if (config._locale.eraYearOrdinalParse) {
16756            array[YEAR] = config._locale.eraYearOrdinalParse(input, match);
16757        } else {
16758            array[YEAR] = parseInt(input, 10);
16759        }
16760    });
16761
16762    function localeEras(m, format) {
16763        var i,
16764            l,
16765            date,
16766            eras = this._eras || getLocale('en')._eras;
16767        for (i = 0, l = eras.length; i < l; ++i) {
16768            switch (typeof eras[i].since) {
16769                case 'string':
16770                    // truncate time
16771                    date = hooks(eras[i].since).startOf('day');
16772                    eras[i].since = date.valueOf();
16773                    break;
16774            }
16775
16776            switch (typeof eras[i].until) {
16777                case 'undefined':
16778                    eras[i].until = +Infinity;
16779                    break;
16780                case 'string':
16781                    // truncate time
16782                    date = hooks(eras[i].until).startOf('day').valueOf();
16783                    eras[i].until = date.valueOf();
16784                    break;
16785            }
16786        }
16787        return eras;
16788    }
16789
16790    function localeErasParse(eraName, format, strict) {
16791        var i,
16792            l,
16793            eras = this.eras(),
16794            name,
16795            abbr,
16796            narrow;
16797        eraName = eraName.toUpperCase();
16798
16799        for (i = 0, l = eras.length; i < l; ++i) {
16800            name = eras[i].name.toUpperCase();
16801            abbr = eras[i].abbr.toUpperCase();
16802            narrow = eras[i].narrow.toUpperCase();
16803
16804            if (strict) {
16805                switch (format) {
16806                    case 'N':
16807                    case 'NN':
16808                    case 'NNN':
16809                        if (abbr === eraName) {
16810                            return eras[i];
16811                        }
16812                        break;
16813
16814                    case 'NNNN':
16815                        if (name === eraName) {
16816                            return eras[i];
16817                        }
16818                        break;
16819
16820                    case 'NNNNN':
16821                        if (narrow === eraName) {
16822                            return eras[i];
16823                        }
16824                        break;
16825                }
16826            } else if ([name, abbr, narrow].indexOf(eraName) >= 0) {
16827                return eras[i];
16828            }
16829        }
16830    }
16831
16832    function localeErasConvertYear(era, year) {
16833        var dir = era.since <= era.until ? +1 : -1;
16834        if (year === undefined) {
16835            return hooks(era.since).year();
16836        } else {
16837            return hooks(era.since).year() + (year - era.offset) * dir;
16838        }
16839    }
16840
16841    function getEraName() {
16842        var i,
16843            l,
16844            val,
16845            eras = this.localeData().eras();
16846        for (i = 0, l = eras.length; i < l; ++i) {
16847            // truncate time
16848            val = this.clone().startOf('day').valueOf();
16849
16850            if (eras[i].since <= val && val <= eras[i].until) {
16851                return eras[i].name;
16852            }
16853            if (eras[i].until <= val && val <= eras[i].since) {
16854                return eras[i].name;
16855            }
16856        }
16857
16858        return '';
16859    }
16860
16861    function getEraNarrow() {
16862        var i,
16863            l,
16864            val,
16865            eras = this.localeData().eras();
16866        for (i = 0, l = eras.length; i < l; ++i) {
16867            // truncate time
16868            val = this.clone().startOf('day').valueOf();
16869
16870            if (eras[i].since <= val && val <= eras[i].until) {
16871                return eras[i].narrow;
16872            }
16873            if (eras[i].until <= val && val <= eras[i].since) {
16874                return eras[i].narrow;
16875            }
16876        }
16877
16878        return '';
16879    }
16880
16881    function getEraAbbr() {
16882        var i,
16883            l,
16884            val,
16885            eras = this.localeData().eras();
16886        for (i = 0, l = eras.length; i < l; ++i) {
16887            // truncate time
16888            val = this.clone().startOf('day').valueOf();
16889
16890            if (eras[i].since <= val && val <= eras[i].until) {
16891                return eras[i].abbr;
16892            }
16893            if (eras[i].until <= val && val <= eras[i].since) {
16894                return eras[i].abbr;
16895            }
16896        }
16897
16898        return '';
16899    }
16900
16901    function getEraYear() {
16902        var i,
16903            l,
16904            dir,
16905            val,
16906            eras = this.localeData().eras();
16907        for (i = 0, l = eras.length; i < l; ++i) {
16908            dir = eras[i].since <= eras[i].until ? +1 : -1;
16909
16910            // truncate time
16911            val = this.clone().startOf('day').valueOf();
16912
16913            if (
16914                (eras[i].since <= val && val <= eras[i].until) ||
16915                (eras[i].until <= val && val <= eras[i].since)
16916            ) {
16917                return (
16918                    (this.year() - hooks(eras[i].since).year()) * dir +
16919                    eras[i].offset
16920                );
16921            }
16922        }
16923
16924        return this.year();
16925    }
16926
16927    function erasNameRegex(isStrict) {
16928        if (!hasOwnProp(this, '_erasNameRegex')) {
16929            computeErasParse.call(this);
16930        }
16931        return isStrict ? this._erasNameRegex : this._erasRegex;
16932    }
16933
16934    function erasAbbrRegex(isStrict) {
16935        if (!hasOwnProp(this, '_erasAbbrRegex')) {
16936            computeErasParse.call(this);
16937        }
16938        return isStrict ? this._erasAbbrRegex : this._erasRegex;
16939    }
16940
16941    function erasNarrowRegex(isStrict) {
16942        if (!hasOwnProp(this, '_erasNarrowRegex')) {
16943            computeErasParse.call(this);
16944        }
16945        return isStrict ? this._erasNarrowRegex : this._erasRegex;
16946    }
16947
16948    function matchEraAbbr(isStrict, locale) {
16949        return locale.erasAbbrRegex(isStrict);
16950    }
16951
16952    function matchEraName(isStrict, locale) {
16953        return locale.erasNameRegex(isStrict);
16954    }
16955
16956    function matchEraNarrow(isStrict, locale) {
16957        return locale.erasNarrowRegex(isStrict);
16958    }
16959
16960    function matchEraYearOrdinal(isStrict, locale) {
16961        return locale._eraYearOrdinalRegex || matchUnsigned;
16962    }
16963
16964    function computeErasParse() {
16965        var abbrPieces = [],
16966            namePieces = [],
16967            narrowPieces = [],
16968            mixedPieces = [],
16969            i,
16970            l,
16971            eras = this.eras();
16972
16973        for (i = 0, l = eras.length; i < l; ++i) {
16974            namePieces.push(regexEscape(eras[i].name));
16975            abbrPieces.push(regexEscape(eras[i].abbr));
16976            narrowPieces.push(regexEscape(eras[i].narrow));
16977
16978            mixedPieces.push(regexEscape(eras[i].name));
16979            mixedPieces.push(regexEscape(eras[i].abbr));
16980            mixedPieces.push(regexEscape(eras[i].narrow));
16981        }
16982
16983        this._erasRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
16984        this._erasNameRegex = new RegExp('^(' + namePieces.join('|') + ')', 'i');
16985        this._erasAbbrRegex = new RegExp('^(' + abbrPieces.join('|') + ')', 'i');
16986        this._erasNarrowRegex = new RegExp(
16987            '^(' + narrowPieces.join('|') + ')',
16988            'i'
16989        );
16990    }
16991
16992    // FORMATTING
16993
16994    addFormatToken(0, ['gg', 2], 0, function () {
16995        return this.weekYear() % 100;
16996    });
16997
16998    addFormatToken(0, ['GG', 2], 0, function () {
16999        return this.isoWeekYear() % 100;
17000    });
17001
17002    function addWeekYearFormatToken(token, getter) {
17003        addFormatToken(0, [token, token.length], 0, getter);
17004    }
17005
17006    addWeekYearFormatToken('gggg', 'weekYear');
17007    addWeekYearFormatToken('ggggg', 'weekYear');
17008    addWeekYearFormatToken('GGGG', 'isoWeekYear');
17009    addWeekYearFormatToken('GGGGG', 'isoWeekYear');
17010
17011    // ALIASES
17012
17013    addUnitAlias('weekYear', 'gg');
17014    addUnitAlias('isoWeekYear', 'GG');
17015
17016    // PRIORITY
17017
17018    addUnitPriority('weekYear', 1);
17019    addUnitPriority('isoWeekYear', 1);
17020
17021    // PARSING
17022
17023    addRegexToken('G', matchSigned);
17024    addRegexToken('g', matchSigned);
17025    addRegexToken('GG', match1to2, match2);
17026    addRegexToken('gg', match1to2, match2);
17027    addRegexToken('GGGG', match1to4, match4);
17028    addRegexToken('gggg', match1to4, match4);
17029    addRegexToken('GGGGG', match1to6, match6);
17030    addRegexToken('ggggg', match1to6, match6);
17031
17032    addWeekParseToken(
17033        ['gggg', 'ggggg', 'GGGG', 'GGGGG'],
17034        function (input, week, config, token) {
17035            week[token.substr(0, 2)] = toInt(input);
17036        }
17037    );
17038
17039    addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
17040        week[token] = hooks.parseTwoDigitYear(input);
17041    });
17042
17043    // MOMENTS
17044
17045    function getSetWeekYear(input) {
17046        return getSetWeekYearHelper.call(
17047            this,
17048            input,
17049            this.week(),
17050            this.weekday(),
17051            this.localeData()._week.dow,
17052            this.localeData()._week.doy
17053        );
17054    }
17055
17056    function getSetISOWeekYear(input) {
17057        return getSetWeekYearHelper.call(
17058            this,
17059            input,
17060            this.isoWeek(),
17061            this.isoWeekday(),
17062            1,
17063            4
17064        );
17065    }
17066
17067    function getISOWeeksInYear() {
17068        return weeksInYear(this.year(), 1, 4);
17069    }
17070
17071    function getISOWeeksInISOWeekYear() {
17072        return weeksInYear(this.isoWeekYear(), 1, 4);
17073    }
17074
17075    function getWeeksInYear() {
17076        var weekInfo = this.localeData()._week;
17077        return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
17078    }
17079
17080    function getWeeksInWeekYear() {
17081        var weekInfo = this.localeData()._week;
17082        return weeksInYear(this.weekYear(), weekInfo.dow, weekInfo.doy);
17083    }
17084
17085    function getSetWeekYearHelper(input, week, weekday, dow, doy) {
17086        var weeksTarget;
17087        if (input == null) {
17088            return weekOfYear(this, dow, doy).year;
17089        } else {
17090            weeksTarget = weeksInYear(input, dow, doy);
17091            if (week > weeksTarget) {
17092                week = weeksTarget;
17093            }
17094            return setWeekAll.call(this, input, week, weekday, dow, doy);
17095        }
17096    }
17097
17098    function setWeekAll(weekYear, week, weekday, dow, doy) {
17099        var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
17100            date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
17101
17102        this.year(date.getUTCFullYear());
17103        this.month(date.getUTCMonth());
17104        this.date(date.getUTCDate());
17105        return this;
17106    }
17107
17108    // FORMATTING
17109
17110    addFormatToken('Q', 0, 'Qo', 'quarter');
17111
17112    // ALIASES
17113
17114    addUnitAlias('quarter', 'Q');
17115
17116    // PRIORITY
17117
17118    addUnitPriority('quarter', 7);
17119
17120    // PARSING
17121
17122    addRegexToken('Q', match1);
17123    addParseToken('Q', function (input, array) {
17124        array[MONTH] = (toInt(input) - 1) * 3;
17125    });
17126
17127    // MOMENTS
17128
17129    function getSetQuarter(input) {
17130        return input == null
17131            ? Math.ceil((this.month() + 1) / 3)
17132            : this.month((input - 1) * 3 + (this.month() % 3));
17133    }
17134
17135    // FORMATTING
17136
17137    addFormatToken('D', ['DD', 2], 'Do', 'date');
17138
17139    // ALIASES
17140
17141    addUnitAlias('date', 'D');
17142
17143    // PRIORITY
17144    addUnitPriority('date', 9);
17145
17146    // PARSING
17147
17148    addRegexToken('D', match1to2);
17149    addRegexToken('DD', match1to2, match2);
17150    addRegexToken('Do', function (isStrict, locale) {
17151        // TODO: Remove "ordinalParse" fallback in next major release.
17152        return isStrict
17153            ? locale._dayOfMonthOrdinalParse || locale._ordinalParse
17154            : locale._dayOfMonthOrdinalParseLenient;
17155    });
17156
17157    addParseToken(['D', 'DD'], DATE);
17158    addParseToken('Do', function (input, array) {
17159        array[DATE] = toInt(input.match(match1to2)[0]);
17160    });
17161
17162    // MOMENTS
17163
17164    var getSetDayOfMonth = makeGetSet('Date', true);
17165
17166    // FORMATTING
17167
17168    addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
17169
17170    // ALIASES
17171
17172    addUnitAlias('dayOfYear', 'DDD');
17173
17174    // PRIORITY
17175    addUnitPriority('dayOfYear', 4);
17176
17177    // PARSING
17178
17179    addRegexToken('DDD', match1to3);
17180    addRegexToken('DDDD', match3);
17181    addParseToken(['DDD', 'DDDD'], function (input, array, config) {
17182        config._dayOfYear = toInt(input);
17183    });
17184
17185    // HELPERS
17186
17187    // MOMENTS
17188
17189    function getSetDayOfYear(input) {
17190        var dayOfYear =
17191            Math.round(
17192                (this.clone().startOf('day') - this.clone().startOf('year')) / 864e5
17193            ) + 1;
17194        return input == null ? dayOfYear : this.add(input - dayOfYear, 'd');
17195    }
17196
17197    // FORMATTING
17198
17199    addFormatToken('m', ['mm', 2], 0, 'minute');
17200
17201    // ALIASES
17202
17203    addUnitAlias('minute', 'm');
17204
17205    // PRIORITY
17206
17207    addUnitPriority('minute', 14);
17208
17209    // PARSING
17210
17211    addRegexToken('m', match1to2);
17212    addRegexToken('mm', match1to2, match2);
17213    addParseToken(['m', 'mm'], MINUTE);
17214
17215    // MOMENTS
17216
17217    var getSetMinute = makeGetSet('Minutes', false);
17218
17219    // FORMATTING
17220
17221    addFormatToken('s', ['ss', 2], 0, 'second');
17222
17223    // ALIASES
17224
17225    addUnitAlias('second', 's');
17226
17227    // PRIORITY
17228
17229    addUnitPriority('second', 15);
17230
17231    // PARSING
17232
17233    addRegexToken('s', match1to2);
17234    addRegexToken('ss', match1to2, match2);
17235    addParseToken(['s', 'ss'], SECOND);
17236
17237    // MOMENTS
17238
17239    var getSetSecond = makeGetSet('Seconds', false);
17240
17241    // FORMATTING
17242
17243    addFormatToken('S', 0, 0, function () {
17244        return ~~(this.millisecond() / 100);
17245    });
17246
17247    addFormatToken(0, ['SS', 2], 0, function () {
17248        return ~~(this.millisecond() / 10);
17249    });
17250
17251    addFormatToken(0, ['SSS', 3], 0, 'millisecond');
17252    addFormatToken(0, ['SSSS', 4], 0, function () {
17253        return this.millisecond() * 10;
17254    });
17255    addFormatToken(0, ['SSSSS', 5], 0, function () {
17256        return this.millisecond() * 100;
17257    });
17258    addFormatToken(0, ['SSSSSS', 6], 0, function () {
17259        return this.millisecond() * 1000;
17260    });
17261    addFormatToken(0, ['SSSSSSS', 7], 0, function () {
17262        return this.millisecond() * 10000;
17263    });
17264    addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
17265        return this.millisecond() * 100000;
17266    });
17267    addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
17268        return this.millisecond() * 1000000;
17269    });
17270
17271    // ALIASES
17272
17273    addUnitAlias('millisecond', 'ms');
17274
17275    // PRIORITY
17276
17277    addUnitPriority('millisecond', 16);
17278
17279    // PARSING
17280
17281    addRegexToken('S', match1to3, match1);
17282    addRegexToken('SS', match1to3, match2);
17283    addRegexToken('SSS', match1to3, match3);
17284
17285    var token, getSetMillisecond;
17286    for (token = 'SSSS'; token.length <= 9; token += 'S') {
17287        addRegexToken(token, matchUnsigned);
17288    }
17289
17290    function parseMs(input, array) {
17291        array[MILLISECOND] = toInt(('0.' + input) * 1000);
17292    }
17293
17294    for (token = 'S'; token.length <= 9; token += 'S') {
17295        addParseToken(token, parseMs);
17296    }
17297
17298    getSetMillisecond = makeGetSet('Milliseconds', false);
17299
17300    // FORMATTING
17301
17302    addFormatToken('z', 0, 0, 'zoneAbbr');
17303    addFormatToken('zz', 0, 0, 'zoneName');
17304
17305    // MOMENTS
17306
17307    function getZoneAbbr() {
17308        return this._isUTC ? 'UTC' : '';
17309    }
17310
17311    function getZoneName() {
17312        return this._isUTC ? 'Coordinated Universal Time' : '';
17313    }
17314
17315    var proto = Moment.prototype;
17316
17317    proto.add = add;
17318    proto.calendar = calendar$1;
17319    proto.clone = clone;
17320    proto.diff = diff;
17321    proto.endOf = endOf;
17322    proto.format = format;
17323    proto.from = from;
17324    proto.fromNow = fromNow;
17325    proto.to = to;
17326    proto.toNow = toNow;
17327    proto.get = stringGet;
17328    proto.invalidAt = invalidAt;
17329    proto.isAfter = isAfter;
17330    proto.isBefore = isBefore;
17331    proto.isBetween = isBetween;
17332    proto.isSame = isSame;
17333    proto.isSameOrAfter = isSameOrAfter;
17334    proto.isSameOrBefore = isSameOrBefore;
17335    proto.isValid = isValid$2;
17336    proto.lang = lang;
17337    proto.locale = locale;
17338    proto.localeData = localeData;
17339    proto.max = prototypeMax;
17340    proto.min = prototypeMin;
17341    proto.parsingFlags = parsingFlags;
17342    proto.set = stringSet;
17343    proto.startOf = startOf;
17344    proto.subtract = subtract;
17345    proto.toArray = toArray;
17346    proto.toObject = toObject;
17347    proto.toDate = toDate;
17348    proto.toISOString = toISOString;
17349    proto.inspect = inspect;
17350    if (typeof Symbol !== 'undefined' && Symbol.for != null) {
17351        proto[Symbol.for('nodejs.util.inspect.custom')] = function () {
17352            return 'Moment<' + this.format() + '>';
17353        };
17354    }
17355    proto.toJSON = toJSON;
17356    proto.toString = toString;
17357    proto.unix = unix;
17358    proto.valueOf = valueOf;
17359    proto.creationData = creationData;
17360    proto.eraName = getEraName;
17361    proto.eraNarrow = getEraNarrow;
17362    proto.eraAbbr = getEraAbbr;
17363    proto.eraYear = getEraYear;
17364    proto.year = getSetYear;
17365    proto.isLeapYear = getIsLeapYear;
17366    proto.weekYear = getSetWeekYear;
17367    proto.isoWeekYear = getSetISOWeekYear;
17368    proto.quarter = proto.quarters = getSetQuarter;
17369    proto.month = getSetMonth;
17370    proto.daysInMonth = getDaysInMonth;
17371    proto.week = proto.weeks = getSetWeek;
17372    proto.isoWeek = proto.isoWeeks = getSetISOWeek;
17373    proto.weeksInYear = getWeeksInYear;
17374    proto.weeksInWeekYear = getWeeksInWeekYear;
17375    proto.isoWeeksInYear = getISOWeeksInYear;
17376    proto.isoWeeksInISOWeekYear = getISOWeeksInISOWeekYear;
17377    proto.date = getSetDayOfMonth;
17378    proto.day = proto.days = getSetDayOfWeek;
17379    proto.weekday = getSetLocaleDayOfWeek;
17380    proto.isoWeekday = getSetISODayOfWeek;
17381    proto.dayOfYear = getSetDayOfYear;
17382    proto.hour = proto.hours = getSetHour;
17383    proto.minute = proto.minutes = getSetMinute;
17384    proto.second = proto.seconds = getSetSecond;
17385    proto.millisecond = proto.milliseconds = getSetMillisecond;
17386    proto.utcOffset = getSetOffset;
17387    proto.utc = setOffsetToUTC;
17388    proto.local = setOffsetToLocal;
17389    proto.parseZone = setOffsetToParsedOffset;
17390    proto.hasAlignedHourOffset = hasAlignedHourOffset;
17391    proto.isDST = isDaylightSavingTime;
17392    proto.isLocal = isLocal;
17393    proto.isUtcOffset = isUtcOffset;
17394    proto.isUtc = isUtc;
17395    proto.isUTC = isUtc;
17396    proto.zoneAbbr = getZoneAbbr;
17397    proto.zoneName = getZoneName;
17398    proto.dates = deprecate(
17399        'dates accessor is deprecated. Use date instead.',
17400        getSetDayOfMonth
17401    );
17402    proto.months = deprecate(
17403        'months accessor is deprecated. Use month instead',
17404        getSetMonth
17405    );
17406    proto.years = deprecate(
17407        'years accessor is deprecated. Use year instead',
17408        getSetYear
17409    );
17410    proto.zone = deprecate(
17411        'moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/',
17412        getSetZone
17413    );
17414    proto.isDSTShifted = deprecate(
17415        'isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information',
17416        isDaylightSavingTimeShifted
17417    );
17418
17419    function createUnix(input) {
17420        return createLocal(input * 1000);
17421    }
17422
17423    function createInZone() {
17424        return createLocal.apply(null, arguments).parseZone();
17425    }
17426
17427    function preParsePostFormat(string) {
17428        return string;
17429    }
17430
17431    var proto$1 = Locale.prototype;
17432
17433    proto$1.calendar = calendar;
17434    proto$1.longDateFormat = longDateFormat;
17435    proto$1.invalidDate = invalidDate;
17436    proto$1.ordinal = ordinal;
17437    proto$1.preparse = preParsePostFormat;
17438    proto$1.postformat = preParsePostFormat;
17439    proto$1.relativeTime = relativeTime;
17440    proto$1.pastFuture = pastFuture;
17441    proto$1.set = set;
17442    proto$1.eras = localeEras;
17443    proto$1.erasParse = localeErasParse;
17444    proto$1.erasConvertYear = localeErasConvertYear;
17445    proto$1.erasAbbrRegex = erasAbbrRegex;
17446    proto$1.erasNameRegex = erasNameRegex;
17447    proto$1.erasNarrowRegex = erasNarrowRegex;
17448
17449    proto$1.months = localeMonths;
17450    proto$1.monthsShort = localeMonthsShort;
17451    proto$1.monthsParse = localeMonthsParse;
17452    proto$1.monthsRegex = monthsRegex;
17453    proto$1.monthsShortRegex = monthsShortRegex;
17454    proto$1.week = localeWeek;
17455    proto$1.firstDayOfYear = localeFirstDayOfYear;
17456    proto$1.firstDayOfWeek = localeFirstDayOfWeek;
17457
17458    proto$1.weekdays = localeWeekdays;
17459    proto$1.weekdaysMin = localeWeekdaysMin;
17460    proto$1.weekdaysShort = localeWeekdaysShort;
17461    proto$1.weekdaysParse = localeWeekdaysParse;
17462
17463    proto$1.weekdaysRegex = weekdaysRegex;
17464    proto$1.weekdaysShortRegex = weekdaysShortRegex;
17465    proto$1.weekdaysMinRegex = weekdaysMinRegex;
17466
17467    proto$1.isPM = localeIsPM;
17468    proto$1.meridiem = localeMeridiem;
17469
17470    function get$1(format, index, field, setter) {
17471        var locale = getLocale(),
17472            utc = createUTC().set(setter, index);
17473        return locale[field](utc, format);
17474    }
17475
17476    function listMonthsImpl(format, index, field) {
17477        if (isNumber(format)) {
17478            index = format;
17479            format = undefined;
17480        }
17481
17482        format = format || '';
17483
17484        if (index != null) {
17485            return get$1(format, index, field, 'month');
17486        }
17487
17488        var i,
17489            out = [];
17490        for (i = 0; i < 12; i++) {
17491            out[i] = get$1(format, i, field, 'month');
17492        }
17493        return out;
17494    }
17495
17496    // ()
17497    // (5)
17498    // (fmt, 5)
17499    // (fmt)
17500    // (true)
17501    // (true, 5)
17502    // (true, fmt, 5)
17503    // (true, fmt)
17504    function listWeekdaysImpl(localeSorted, format, index, field) {
17505        if (typeof localeSorted === 'boolean') {
17506            if (isNumber(format)) {
17507                index = format;
17508                format = undefined;
17509            }
17510
17511            format = format || '';
17512        } else {
17513            format = localeSorted;
17514            index = format;
17515            localeSorted = false;
17516
17517            if (isNumber(format)) {
17518                index = format;
17519                format = undefined;
17520            }
17521
17522            format = format || '';
17523        }
17524
17525        var locale = getLocale(),
17526            shift = localeSorted ? locale._week.dow : 0,
17527            i,
17528            out = [];
17529
17530        if (index != null) {
17531            return get$1(format, (index + shift) % 7, field, 'day');
17532        }
17533
17534        for (i = 0; i < 7; i++) {
17535            out[i] = get$1(format, (i + shift) % 7, field, 'day');
17536        }
17537        return out;
17538    }
17539
17540    function listMonths(format, index) {
17541        return listMonthsImpl(format, index, 'months');
17542    }
17543
17544    function listMonthsShort(format, index) {
17545        return listMonthsImpl(format, index, 'monthsShort');
17546    }
17547
17548    function listWeekdays(localeSorted, format, index) {
17549        return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
17550    }
17551
17552    function listWeekdaysShort(localeSorted, format, index) {
17553        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
17554    }
17555
17556    function listWeekdaysMin(localeSorted, format, index) {
17557        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
17558    }
17559
17560    getSetGlobalLocale('en', {
17561        eras: [
17562            {
17563                since: '0001-01-01',
17564                until: +Infinity,
17565                offset: 1,
17566                name: 'Anno Domini',
17567                narrow: 'AD',
17568                abbr: 'AD',
17569            },
17570            {
17571                since: '0000-12-31',
17572                until: -Infinity,
17573                offset: 1,
17574                name: 'Before Christ',
17575                narrow: 'BC',
17576                abbr: 'BC',
17577            },
17578        ],
17579        dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
17580        ordinal: function (number) {
17581            var b = number % 10,
17582                output =
17583                    toInt((number % 100) / 10) === 1
17584                        ? 'th'
17585                        : b === 1
17586                        ? 'st'
17587                        : b === 2
17588                        ? 'nd'
17589                        : b === 3
17590                        ? 'rd'
17591                        : 'th';
17592            return number + output;
17593        },
17594    });
17595
17596    // Side effect imports
17597
17598    hooks.lang = deprecate(
17599        'moment.lang is deprecated. Use moment.locale instead.',
17600        getSetGlobalLocale
17601    );
17602    hooks.langData = deprecate(
17603        'moment.langData is deprecated. Use moment.localeData instead.',
17604        getLocale
17605    );
17606
17607    var mathAbs = Math.abs;
17608
17609    function abs() {
17610        var data = this._data;
17611
17612        this._milliseconds = mathAbs(this._milliseconds);
17613        this._days = mathAbs(this._days);
17614        this._months = mathAbs(this._months);
17615
17616        data.milliseconds = mathAbs(data.milliseconds);
17617        data.seconds = mathAbs(data.seconds);
17618        data.minutes = mathAbs(data.minutes);
17619        data.hours = mathAbs(data.hours);
17620        data.months = mathAbs(data.months);
17621        data.years = mathAbs(data.years);
17622
17623        return this;
17624    }
17625
17626    function addSubtract$1(duration, input, value, direction) {
17627        var other = createDuration(input, value);
17628
17629        duration._milliseconds += direction * other._milliseconds;
17630        duration._days += direction * other._days;
17631        duration._months += direction * other._months;
17632
17633        return duration._bubble();
17634    }
17635
17636    // supports only 2.0-style add(1, 's') or add(duration)
17637    function add$1(input, value) {
17638        return addSubtract$1(this, input, value, 1);
17639    }
17640
17641    // supports only 2.0-style subtract(1, 's') or subtract(duration)
17642    function subtract$1(input, value) {
17643        return addSubtract$1(this, input, value, -1);
17644    }
17645
17646    function absCeil(number) {
17647        if (number < 0) {
17648            return Math.floor(number);
17649        } else {
17650            return Math.ceil(number);
17651        }
17652    }
17653
17654    function bubble() {
17655        var milliseconds = this._milliseconds,
17656            days = this._days,
17657            months = this._months,
17658            data = this._data,
17659            seconds,
17660            minutes,
17661            hours,
17662            years,
17663            monthsFromDays;
17664
17665        // if we have a mix of positive and negative values, bubble down first
17666        // check: https://github.com/moment/moment/issues/2166
17667        if (
17668            !(
17669                (milliseconds >= 0 && days >= 0 && months >= 0) ||
17670                (milliseconds <= 0 && days <= 0 && months <= 0)
17671            )
17672        ) {
17673            milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
17674            days = 0;
17675            months = 0;
17676        }
17677
17678        // The following code bubbles up values, see the tests for
17679        // examples of what that means.
17680        data.milliseconds = milliseconds % 1000;
17681
17682        seconds = absFloor(milliseconds / 1000);
17683        data.seconds = seconds % 60;
17684
17685        minutes = absFloor(seconds / 60);
17686        data.minutes = minutes % 60;
17687
17688        hours = absFloor(minutes / 60);
17689        data.hours = hours % 24;
17690
17691        days += absFloor(hours / 24);
17692
17693        // convert days to months
17694        monthsFromDays = absFloor(daysToMonths(days));
17695        months += monthsFromDays;
17696        days -= absCeil(monthsToDays(monthsFromDays));
17697
17698        // 12 months -> 1 year
17699        years = absFloor(months / 12);
17700        months %= 12;
17701
17702        data.days = days;
17703        data.months = months;
17704        data.years = years;
17705
17706        return this;
17707    }
17708
17709    function daysToMonths(days) {
17710        // 400 years have 146097 days (taking into account leap year rules)
17711        // 400 years have 12 months === 4800
17712        return (days * 4800) / 146097;
17713    }
17714
17715    function monthsToDays(months) {
17716        // the reverse of daysToMonths
17717        return (months * 146097) / 4800;
17718    }
17719
17720    function as(units) {
17721        if (!this.isValid()) {
17722            return NaN;
17723        }
17724        var days,
17725            months,
17726            milliseconds = this._milliseconds;
17727
17728        units = normalizeUnits(units);
17729
17730        if (units === 'month' || units === 'quarter' || units === 'year') {
17731            days = this._days + milliseconds / 864e5;
17732            months = this._months + daysToMonths(days);
17733            switch (units) {
17734                case 'month':
17735                    return months;
17736                case 'quarter':
17737                    return months / 3;
17738                case 'year':
17739                    return months / 12;
17740            }
17741        } else {
17742            // handle milliseconds separately because of floating point math errors (issue #1867)
17743            days = this._days + Math.round(monthsToDays(this._months));
17744            switch (units) {
17745                case 'week':
17746                    return days / 7 + milliseconds / 6048e5;
17747                case 'day':
17748                    return days + milliseconds / 864e5;
17749                case 'hour':
17750                    return days * 24 + milliseconds / 36e5;
17751                case 'minute':
17752                    return days * 1440 + milliseconds / 6e4;
17753                case 'second':
17754                    return days * 86400 + milliseconds / 1000;
17755                // Math.floor prevents floating point math errors here
17756                case 'millisecond':
17757                    return Math.floor(days * 864e5) + milliseconds;
17758                default:
17759                    throw new Error('Unknown unit ' + units);
17760            }
17761        }
17762    }
17763
17764    // TODO: Use this.as('ms')?
17765    function valueOf$1() {
17766        if (!this.isValid()) {
17767            return NaN;
17768        }
17769        return (
17770            this._milliseconds +
17771            this._days * 864e5 +
17772            (this._months % 12) * 2592e6 +
17773            toInt(this._months / 12) * 31536e6
17774        );
17775    }
17776
17777    function makeAs(alias) {
17778        return function () {
17779            return this.as(alias);
17780        };
17781    }
17782
17783    var asMilliseconds = makeAs('ms'),
17784        asSeconds = makeAs('s'),
17785        asMinutes = makeAs('m'),
17786        asHours = makeAs('h'),
17787        asDays = makeAs('d'),
17788        asWeeks = makeAs('w'),
17789        asMonths = makeAs('M'),
17790        asQuarters = makeAs('Q'),
17791        asYears = makeAs('y');
17792
17793    function clone$1() {
17794        return createDuration(this);
17795    }
17796
17797    function get$2(units) {
17798        units = normalizeUnits(units);
17799        return this.isValid() ? this[units + 's']() : NaN;
17800    }
17801
17802    function makeGetter(name) {
17803        return function () {
17804            return this.isValid() ? this._data[name] : NaN;
17805        };
17806    }
17807
17808    var milliseconds = makeGetter('milliseconds'),
17809        seconds = makeGetter('seconds'),
17810        minutes = makeGetter('minutes'),
17811        hours = makeGetter('hours'),
17812        days = makeGetter('days'),
17813        months = makeGetter('months'),
17814        years = makeGetter('years');
17815
17816    function weeks() {
17817        return absFloor(this.days() / 7);
17818    }
17819
17820    var round = Math.round,
17821        thresholds = {
17822            ss: 44, // a few seconds to seconds
17823            s: 45, // seconds to minute
17824            m: 45, // minutes to hour
17825            h: 22, // hours to day
17826            d: 26, // days to month/week
17827            w: null, // weeks to month
17828            M: 11, // months to year
17829        };
17830
17831    // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
17832    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
17833        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
17834    }
17835
17836    function relativeTime$1(posNegDuration, withoutSuffix, thresholds, locale) {
17837        var duration = createDuration(posNegDuration).abs(),
17838            seconds = round(duration.as('s')),
17839            minutes = round(duration.as('m')),
17840            hours = round(duration.as('h')),
17841            days = round(duration.as('d')),
17842            months = round(duration.as('M')),
17843            weeks = round(duration.as('w')),
17844            years = round(duration.as('y')),
17845            a =
17846                (seconds <= thresholds.ss && ['s', seconds]) ||
17847                (seconds < thresholds.s && ['ss', seconds]) ||
17848                (minutes <= 1 && ['m']) ||
17849                (minutes < thresholds.m && ['mm', minutes]) ||
17850                (hours <= 1 && ['h']) ||
17851                (hours < thresholds.h && ['hh', hours]) ||
17852                (days <= 1 && ['d']) ||
17853                (days < thresholds.d && ['dd', days]);
17854
17855        if (thresholds.w != null) {
17856            a =
17857                a ||
17858                (weeks <= 1 && ['w']) ||
17859                (weeks < thresholds.w && ['ww', weeks]);
17860        }
17861        a = a ||
17862            (months <= 1 && ['M']) ||
17863            (months < thresholds.M && ['MM', months]) ||
17864            (years <= 1 && ['y']) || ['yy', years];
17865
17866        a[2] = withoutSuffix;
17867        a[3] = +posNegDuration > 0;
17868        a[4] = locale;
17869        return substituteTimeAgo.apply(null, a);
17870    }
17871
17872    // This function allows you to set the rounding function for relative time strings
17873    function getSetRelativeTimeRounding(roundingFunction) {
17874        if (roundingFunction === undefined) {
17875            return round;
17876        }
17877        if (typeof roundingFunction === 'function') {
17878            round = roundingFunction;
17879            return true;
17880        }
17881        return false;
17882    }
17883
17884    // This function allows you to set a threshold for relative time strings
17885    function getSetRelativeTimeThreshold(threshold, limit) {
17886        if (thresholds[threshold] === undefined) {
17887            return false;
17888        }
17889        if (limit === undefined) {
17890            return thresholds[threshold];
17891        }
17892        thresholds[threshold] = limit;
17893        if (threshold === 's') {
17894            thresholds.ss = limit - 1;
17895        }
17896        return true;
17897    }
17898
17899    function humanize(argWithSuffix, argThresholds) {
17900        if (!this.isValid()) {
17901            return this.localeData().invalidDate();
17902        }
17903
17904        var withSuffix = false,
17905            th = thresholds,
17906            locale,
17907            output;
17908
17909        if (typeof argWithSuffix === 'object') {
17910            argThresholds = argWithSuffix;
17911            argWithSuffix = false;
17912        }
17913        if (typeof argWithSuffix === 'boolean') {
17914            withSuffix = argWithSuffix;
17915        }
17916        if (typeof argThresholds === 'object') {
17917            th = Object.assign({}, thresholds, argThresholds);
17918            if (argThresholds.s != null && argThresholds.ss == null) {
17919                th.ss = argThresholds.s - 1;
17920            }
17921        }
17922
17923        locale = this.localeData();
17924        output = relativeTime$1(this, !withSuffix, th, locale);
17925
17926        if (withSuffix) {
17927            output = locale.pastFuture(+this, output);
17928        }
17929
17930        return locale.postformat(output);
17931    }
17932
17933    var abs$1 = Math.abs;
17934
17935    function sign(x) {
17936        return (x > 0) - (x < 0) || +x;
17937    }
17938
17939    function toISOString$1() {
17940        // for ISO strings we do not use the normal bubbling rules:
17941        //  * milliseconds bubble up until they become hours
17942        //  * days do not bubble at all
17943        //  * months bubble up until they become years
17944        // This is because there is no context-free conversion between hours and days
17945        // (think of clock changes)
17946        // and also not between days and months (28-31 days per month)
17947        if (!this.isValid()) {
17948            return this.localeData().invalidDate();
17949        }
17950
17951        var seconds = abs$1(this._milliseconds) / 1000,
17952            days = abs$1(this._days),
17953            months = abs$1(this._months),
17954            minutes,
17955            hours,
17956            years,
17957            s,
17958            total = this.asSeconds(),
17959            totalSign,
17960            ymSign,
17961            daysSign,
17962            hmsSign;
17963
17964        if (!total) {
17965            // this is the same as C#'s (Noda) and python (isodate)...
17966            // but not other JS (goog.date)
17967            return 'P0D';
17968        }
17969
17970        // 3600 seconds -> 60 minutes -> 1 hour
17971        minutes = absFloor(seconds / 60);
17972        hours = absFloor(minutes / 60);
17973        seconds %= 60;
17974        minutes %= 60;
17975
17976        // 12 months -> 1 year
17977        years = absFloor(months / 12);
17978        months %= 12;
17979
17980        // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
17981        s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';
17982
17983        totalSign = total < 0 ? '-' : '';
17984        ymSign = sign(this._months) !== sign(total) ? '-' : '';
17985        daysSign = sign(this._days) !== sign(total) ? '-' : '';
17986        hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';
17987
17988        return (
17989            totalSign +
17990            'P' +
17991            (years ? ymSign + years + 'Y' : '') +
17992            (months ? ymSign + months + 'M' : '') +
17993            (days ? daysSign + days + 'D' : '') +
17994            (hours || minutes || seconds ? 'T' : '') +
17995            (hours ? hmsSign + hours + 'H' : '') +
17996            (minutes ? hmsSign + minutes + 'M' : '') +
17997            (seconds ? hmsSign + s + 'S' : '')
17998        );
17999    }
18000
18001    var proto$2 = Duration.prototype;
18002
18003    proto$2.isValid = isValid$1;
18004    proto$2.abs = abs;
18005    proto$2.add = add$1;
18006    proto$2.subtract = subtract$1;
18007    proto$2.as = as;
18008    proto$2.asMilliseconds = asMilliseconds;
18009    proto$2.asSeconds = asSeconds;
18010    proto$2.asMinutes = asMinutes;
18011    proto$2.asHours = asHours;
18012    proto$2.asDays = asDays;
18013    proto$2.asWeeks = asWeeks;
18014    proto$2.asMonths = asMonths;
18015    proto$2.asQuarters = asQuarters;
18016    proto$2.asYears = asYears;
18017    proto$2.valueOf = valueOf$1;
18018    proto$2._bubble = bubble;
18019    proto$2.clone = clone$1;
18020    proto$2.get = get$2;
18021    proto$2.milliseconds = milliseconds;
18022    proto$2.seconds = seconds;
18023    proto$2.minutes = minutes;
18024    proto$2.hours = hours;
18025    proto$2.days = days;
18026    proto$2.weeks = weeks;
18027    proto$2.months = months;
18028    proto$2.years = years;
18029    proto$2.humanize = humanize;
18030    proto$2.toISOString = toISOString$1;
18031    proto$2.toString = toISOString$1;
18032    proto$2.toJSON = toISOString$1;
18033    proto$2.locale = locale;
18034    proto$2.localeData = localeData;
18035
18036    proto$2.toIsoString = deprecate(
18037        'toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)',
18038        toISOString$1
18039    );
18040    proto$2.lang = lang;
18041
18042    // FORMATTING
18043
18044    addFormatToken('X', 0, 0, 'unix');
18045    addFormatToken('x', 0, 0, 'valueOf');
18046
18047    // PARSING
18048
18049    addRegexToken('x', matchSigned);
18050    addRegexToken('X', matchTimestamp);
18051    addParseToken('X', function (input, array, config) {
18052        config._d = new Date(parseFloat(input) * 1000);
18053    });
18054    addParseToken('x', function (input, array, config) {
18055        config._d = new Date(toInt(input));
18056    });
18057
18058    //! moment.js
18059
18060    hooks.version = '2.29.4';
18061
18062    setHookCallback(createLocal);
18063
18064    hooks.fn = proto;
18065    hooks.min = min;
18066    hooks.max = max;
18067    hooks.now = now;
18068    hooks.utc = createUTC;
18069    hooks.unix = createUnix;
18070    hooks.months = listMonths;
18071    hooks.isDate = isDate;
18072    hooks.locale = getSetGlobalLocale;
18073    hooks.invalid = createInvalid;
18074    hooks.duration = createDuration;
18075    hooks.isMoment = isMoment;
18076    hooks.weekdays = listWeekdays;
18077    hooks.parseZone = createInZone;
18078    hooks.localeData = getLocale;
18079    hooks.isDuration = isDuration;
18080    hooks.monthsShort = listMonthsShort;
18081    hooks.weekdaysMin = listWeekdaysMin;
18082    hooks.defineLocale = defineLocale;
18083    hooks.updateLocale = updateLocale;
18084    hooks.locales = listLocales;
18085    hooks.weekdaysShort = listWeekdaysShort;
18086    hooks.normalizeUnits = normalizeUnits;
18087    hooks.relativeTimeRounding = getSetRelativeTimeRounding;
18088    hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
18089    hooks.calendarFormat = getCalendarFormat;
18090    hooks.prototype = proto;
18091
18092    // currently HTML5 input type only supports 24-hour formats
18093    hooks.HTML5_FMT = {
18094        DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // <input type="datetime-local" />
18095        DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // <input type="datetime-local" step="1" />
18096        DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // <input type="datetime-local" step="0.001" />
18097        DATE: 'YYYY-MM-DD', // <input type="date" />
18098        TIME: 'HH:mm', // <input type="time" />
18099        TIME_SECONDS: 'HH:mm:ss', // <input type="time" step="1" />
18100        TIME_MS: 'HH:mm:ss.SSS', // <input type="time" step="0.001" />
18101        WEEK: 'GGGG-[W]WW', // <input type="week" />
18102        MONTH: 'YYYY-MM', // <input type="month" />
18103    };
18104
18105    return hooks;
18106
18107})));
18108
18109/*
18110 * ADOBE CONFIDENTIAL
18111 *
18112 * Copyright 2017 Adobe Systems Incorporated
18113 * All Rights Reserved.
18114 *
18115 * NOTICE:  All information contained herein is, and remains
18116 * the property of Adobe Systems Incorporated and its suppliers,
18117 * if any.  The intellectual and technical concepts contained
18118 * herein are proprietary to Adobe Systems Incorporated and its
18119 * suppliers and may be covered by U.S. and Foreign Patents,
18120 * patents in process, and are protected by trade secret or copyright law.
18121 * Dissemination of this information or reproduction of this material
18122 * is strictly forbidden unless prior written permission is obtained
18123 * from Adobe Systems Incorporated.
18124 *
18125 */
18126(function(root, factory) {
18127    "use strict";
18128
18129    if (typeof module === "object" && module.exports) {
18130        module.exports = factory(require("moment"));
18131    } else {
18132        factory(root.moment);
18133    }
18134}(this, function(moment) {
18135    "use strict";
18136
18137    function normalizeType(type) {
18138        switch (type) {
18139            case "date":
18140            case "time":
18141            case "datetime":
18142                return type;
18143            default:
18144                return "date";
18145        }
18146    }
18147
18148    function normalizeFormat(format) {
18149        switch (format) {
18150            case "short":
18151            case "medium":
18152            case "long":
18153            case "full":
18154                return format;
18155            default:
18156                return "medium";
18157        }
18158    }
18159
18160    moment.fn.formatWithPreset = function(type, format) {
18161        var localeData = this.localeData();
18162        var actualFormat = localeData._presets[normalizeType(type)][normalizeFormat(format)];
18163
18164        if (typeof actualFormat === "function") {
18165            actualFormat = actualFormat(this);
18166        }
18167
18168        return this.format(actualFormat);
18169    };
18170
18171    return moment;
18172}));
18173
18174//! moment.js locale configuration
18175
18176;(function (global, factory) {
18177   typeof exports === 'object' && typeof module !== 'undefined'
18178       && typeof require === 'function' ? factory(require('../moment')) :
18179   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
18180   factory(global.moment)
18181}(this, (function (moment) { 'use strict';
18182
18183
18184    function processRelativeTime$2(number, withoutSuffix, key, isFuture) {
18185        var format = {
18186            m: ['eine Minute', 'einer Minute'],
18187            h: ['eine Stunde', 'einer Stunde'],
18188            d: ['ein Tag', 'einem Tag'],
18189            dd: [number + ' Tage', number + ' Tagen'],
18190            w: ['eine Woche', 'einer Woche'],
18191            M: ['ein Monat', 'einem Monat'],
18192            MM: [number + ' Monate', number + ' Monaten'],
18193            y: ['ein Jahr', 'einem Jahr'],
18194            yy: [number + ' Jahre', number + ' Jahren'],
18195        };
18196        return withoutSuffix ? format[key][0] : format[key][1];
18197    }
18198
18199    var de = moment.defineLocale('de', {
18200        months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),
18201        monthsShort : 'Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split('_'),
18202        monthsParseExact : true,
18203        weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),
18204        weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),
18205        weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
18206        weekdaysParseExact : true,
18207        longDateFormat : {
18208            LT: 'HH:mm',
18209            LTS: 'HH:mm:ss',
18210            L : 'DD.MM.YYYY',
18211            LL : 'D. MMMM YYYY',
18212            LLL : 'D. MMMM YYYY HH:mm',
18213            LLLL : 'dddd, D. MMMM YYYY HH:mm'
18214        },
18215        calendar : {
18216            sameDay: '[heute um] LT [Uhr]',
18217            sameElse: 'L',
18218            nextDay: '[morgen um] LT [Uhr]',
18219            nextWeek: 'dddd [um] LT [Uhr]',
18220            lastDay: '[gestern um] LT [Uhr]',
18221            lastWeek: '[letzten] dddd [um] LT [Uhr]'
18222        },
18223        relativeTime : {
18224            future: 'in %s',
18225            past: 'vor %s',
18226            s: 'ein paar Sekunden',
18227            ss: '%d Sekunden',
18228            m: processRelativeTime$2,
18229            mm: '%d Minuten',
18230            h: processRelativeTime$2,
18231            hh: '%d Stunden',
18232            d: processRelativeTime$2,
18233            dd: processRelativeTime$2,
18234            w: processRelativeTime$2,
18235            ww: '%d Wochen',
18236            M: processRelativeTime$2,
18237            MM: processRelativeTime$2,
18238            y: processRelativeTime$2,
18239            yy: processRelativeTime$2,
18240        },
18241        dayOfMonthOrdinalParse: /\d{1,2}\./,
18242        ordinal : '%d.',
18243        week : {
18244            dow : 1, // Monday is the first day of the week.
18245            doy : 4  // The week that contains Jan 4th is the first week of the year.
18246        }
18247    });
18248
18249    return de;
18250
18251})));
18252
18253//! moment.js locale configuration
18254
18255;(function (global, factory) {
18256   typeof exports === 'object' && typeof module !== 'undefined'
18257       && typeof require === 'function' ? factory(require('../moment')) :
18258   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
18259   factory(global.moment)
18260}(this, (function (moment) { 'use strict';
18261
18262
18263    var monthsShortDot$3 = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'),
18264        monthsShort$4 = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');
18265
18266    var monthsParse$5 = [/^ene/i, /^feb/i, /^mar/i, /^abr/i, /^may/i, /^jun/i, /^jul/i, /^ago/i, /^sep/i, /^oct/i, /^nov/i, /^dic/i];
18267    var monthsRegex$6 = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i;
18268
18269    var es = moment.defineLocale('es', {
18270        months: 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split(
18271            '_'
18272        ),
18273        monthsShort: function (m, format) {
18274            if (!m) {
18275                return monthsShortDot$3;
18276            } else if (/-MMM-/.test(format)) {
18277                return monthsShort$4[m.month()];
18278            } else {
18279                return monthsShortDot$3[m.month()];
18280            }
18281        },
18282        monthsRegex: monthsRegex$6,
18283        monthsShortRegex: monthsRegex$6,
18284        monthsStrictRegex:
18285            /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,
18286        monthsShortStrictRegex:
18287            /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,
18288        monthsParse: monthsParse$5,
18289        longMonthsParse: monthsParse$5,
18290        shortMonthsParse: monthsParse$5,
18291        weekdays: 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),
18292        weekdaysShort: 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),
18293        weekdaysMin: 'do_lu_ma_mi_ju_vi_sá'.split('_'),
18294        weekdaysParseExact: true,
18295        longDateFormat: {
18296            LT: 'H:mm',
18297            LTS: 'H:mm:ss',
18298            L: 'DD/MM/YYYY',
18299            LL: 'D [de] MMMM [de] YYYY',
18300            LLL: 'D [de] MMMM [de] YYYY H:mm',
18301            LLLL: 'dddd, D [de] MMMM [de] YYYY H:mm',
18302        },
18303        calendar: {
18304            sameDay: function () {
18305                return '[hoy a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
18306            },
18307            nextDay: function () {
18308                return '[mañana a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
18309            },
18310            nextWeek: function () {
18311                return 'dddd [a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
18312            },
18313            lastDay: function () {
18314                return '[ayer a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
18315            },
18316            lastWeek: function () {
18317                return (
18318                    '[el] dddd [pasado a la' +
18319                    (this.hours() !== 1 ? 's' : '') +
18320                    '] LT'
18321                );
18322            },
18323            sameElse: 'L',
18324        },
18325        relativeTime: {
18326            future: 'en %s',
18327            past: 'hace %s',
18328            s: 'unos segundos',
18329            ss: '%d segundos',
18330            m: 'un minuto',
18331            mm: '%d minutos',
18332            h: 'una hora',
18333            hh: '%d horas',
18334            d: 'un día',
18335            dd: '%d días',
18336            w: 'una semana',
18337            ww: '%d semanas',
18338            M: 'un mes',
18339            MM: '%d meses',
18340            y: 'un año',
18341            yy: '%d años',
18342        },
18343        dayOfMonthOrdinalParse: /\d{1,2}º/,
18344        ordinal: '%dº',
18345        week: {
18346            dow: 1, // Monday is the first day of the week.
18347            doy: 4, // The week that contains Jan 4th is the first week of the year.
18348        },
18349        invalidDate: 'Fecha inválida',
18350    });
18351    return es;
18352})));
18353
18354//! moment.js locale configuration
18355
18356;(function (global, factory) {
18357   typeof exports === 'object' && typeof module !== 'undefined'
18358       && typeof require === 'function' ? factory(require('../moment')) :
18359   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
18360   factory(global.moment)
18361}(this, (function (moment) { 'use strict';
18362
18363    var monthsStrictRegex$1 =
18364            /^(janvier|février|mars|avril|mai|juin|juillet|août|septembre|octobre|novembre|décembre)/i,
18365        monthsShortStrictRegex$1 =
18366            /(janv\.?|févr\.?|mars|avr\.?|mai|juin|juil\.?|août|sept\.?|oct\.?|nov\.?|déc\.?)/i,
18367        monthsRegex$7 =
18368            /(janv\.?|févr\.?|mars|avr\.?|mai|juin|juil\.?|août|sept\.?|oct\.?|nov\.?|déc\.?|janvier|février|mars|avril|mai|juin|juillet|août|septembre|octobre|novembre|décembre)/i,
18369        monthsParse$6 = [
18370            /^janv/i,
18371            /^févr/i,
18372            /^mars/i,
18373            /^avr/i,
18374            /^mai/i,
18375            /^juin/i,
18376            /^juil/i,
18377            /^août/i,
18378            /^sept/i,
18379            /^oct/i,
18380            /^nov/i,
18381            /^déc/i,
18382        ];
18383
18384    var fr = moment.defineLocale('fr', {
18385        months: 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split(
18386            '_'
18387        ),
18388        monthsShort:
18389            'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split(
18390                '_'
18391            ),
18392        monthsRegex: monthsRegex$7,
18393        monthsShortRegex: monthsRegex$7,
18394        monthsStrictRegex: monthsStrictRegex$1,
18395        monthsShortStrictRegex: monthsShortStrictRegex$1,
18396        monthsParse: monthsParse$6,
18397        longMonthsParse: monthsParse$6,
18398        shortMonthsParse: monthsParse$6,
18399        weekdays: 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),
18400        weekdaysShort: 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),
18401        weekdaysMin: 'di_lu_ma_me_je_ve_sa'.split('_'),
18402        weekdaysParseExact: true,
18403        longDateFormat: {
18404            LT: 'HH:mm',
18405            LTS: 'HH:mm:ss',
18406            L: 'DD/MM/YYYY',
18407            LL: 'D MMMM YYYY',
18408            LLL: 'D MMMM YYYY HH:mm',
18409            LLLL: 'dddd D MMMM YYYY HH:mm',
18410        },
18411        calendar: {
18412            sameDay: '[Aujourd’hui à] LT',
18413            nextDay: '[Demain à] LT',
18414            nextWeek: 'dddd [à] LT',
18415            lastDay: '[Hier à] LT',
18416            lastWeek: 'dddd [dernier à] LT',
18417            sameElse: 'L',
18418        },
18419        relativeTime: {
18420            future: 'dans %s',
18421            past: 'il y a %s',
18422            s: 'quelques secondes',
18423            ss: '%d secondes',
18424            m: 'une minute',
18425            mm: '%d minutes',
18426            h: 'une heure',
18427            hh: '%d heures',
18428            d: 'un jour',
18429            dd: '%d jours',
18430            w: 'une semaine',
18431            ww: '%d semaines',
18432            M: 'un mois',
18433            MM: '%d mois',
18434            y: 'un an',
18435            yy: '%d ans',
18436        },
18437        dayOfMonthOrdinalParse: /\d{1,2}(er|)/,
18438        ordinal: function (number, period) {
18439            switch (period) {
18440                // TODO: Return 'e' when day of month > 1. Move this case inside
18441                // block for masculine words below.
18442                // See https://github.com/moment/moment/issues/3375
18443                case 'D':
18444                    return number + (number === 1 ? 'er' : '');
18445
18446                // Words with masculine grammatical gender: mois, trimestre, jour
18447                default:
18448                case 'M':
18449                case 'Q':
18450                case 'DDD':
18451                case 'd':
18452                    return number + (number === 1 ? 'er' : 'e');
18453
18454                // Words with feminine grammatical gender: semaine
18455                case 'w':
18456                case 'W':
18457                    return number + (number === 1 ? 're' : 'e');
18458            }
18459        },
18460        week: {
18461            dow: 1, // Monday is the first day of the week.
18462            doy: 4, // The week that contains Jan 4th is the first week of the year.
18463        },
18464    });
18465
18466    return fr;
18467
18468})));
18469
18470//! moment.js locale configuration
18471
18472;(function (global, factory) {
18473   typeof exports === 'object' && typeof module !== 'undefined'
18474       && typeof require === 'function' ? factory(require('../moment')) :
18475   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
18476   factory(global.moment)
18477}(this, (function (moment) { 'use strict';
18478
18479
18480    var it = moment.defineLocale('it', {
18481        months: 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split(
18482            '_'
18483        ),
18484        monthsShort: 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'),
18485        weekdays: 'domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato'.split(
18486            '_'
18487        ),
18488        weekdaysShort: 'dom_lun_mar_mer_gio_ven_sab'.split('_'),
18489        weekdaysMin: 'do_lu_ma_me_gi_ve_sa'.split('_'),
18490        longDateFormat: {
18491            LT: 'HH:mm',
18492            LTS: 'HH:mm:ss',
18493            L: 'DD/MM/YYYY',
18494            LL: 'D MMMM YYYY',
18495            LLL: 'D MMMM YYYY HH:mm',
18496            LLLL: 'dddd D MMMM YYYY HH:mm',
18497        },
18498        calendar: {
18499            sameDay: function () {
18500                return (
18501                    '[Oggi a' +
18502                    (this.hours() > 1 ? 'lle ' : this.hours() === 0 ? ' ' : "ll'") +
18503                    ']LT'
18504                );
18505            },
18506            nextDay: function () {
18507                return (
18508                    '[Domani a' +
18509                    (this.hours() > 1 ? 'lle ' : this.hours() === 0 ? ' ' : "ll'") +
18510                    ']LT'
18511                );
18512            },
18513            nextWeek: function () {
18514                return (
18515                    'dddd [a' +
18516                    (this.hours() > 1 ? 'lle ' : this.hours() === 0 ? ' ' : "ll'") +
18517                    ']LT'
18518                );
18519            },
18520            lastDay: function () {
18521                return (
18522                    '[Ieri a' +
18523                    (this.hours() > 1 ? 'lle ' : this.hours() === 0 ? ' ' : "ll'") +
18524                    ']LT'
18525                );
18526            },
18527            lastWeek: function () {
18528                switch (this.day()) {
18529                    case 0:
18530                        return (
18531                            '[La scorsa] dddd [a' +
18532                            (this.hours() > 1
18533                                ? 'lle '
18534                                : this.hours() === 0
18535                                ? ' '
18536                                : "ll'") +
18537                            ']LT'
18538                        );
18539                    default:
18540                        return (
18541                            '[Lo scorso] dddd [a' +
18542                            (this.hours() > 1
18543                                ? 'lle '
18544                                : this.hours() === 0
18545                                ? ' '
18546                                : "ll'") +
18547                            ']LT'
18548                        );
18549                }
18550            },
18551            sameElse: 'L',
18552        },
18553        relativeTime: {
18554            future: 'tra %s',
18555            past: '%s fa',
18556            s: 'alcuni secondi',
18557            ss: '%d secondi',
18558            m: 'un minuto',
18559            mm: '%d minuti',
18560            h: "un'ora",
18561            hh: '%d ore',
18562            d: 'un giorno',
18563            dd: '%d giorni',
18564            w: 'una settimana',
18565            ww: '%d settimane',
18566            M: 'un mese',
18567            MM: '%d mesi',
18568            y: 'un anno',
18569            yy: '%d anni',
18570        },
18571        dayOfMonthOrdinalParse: /\d{1,2}º/,
18572        ordinal: '%dº',
18573        week: {
18574            dow: 1, // Monday is the first day of the week.
18575            doy: 4, // The week that contains Jan 4th is the first week of the year.
18576        },
18577    });
18578
18579    return it;
18580
18581})));
18582
18583//! moment.js locale configuration
18584
18585;(function (global, factory) {
18586   typeof exports === 'object' && typeof module !== 'undefined'
18587       && typeof require === 'function' ? factory(require('../moment')) :
18588   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
18589   factory(global.moment)
18590}(this, (function (moment) { 'use strict';
18591
18592
18593    var ptBr = moment.defineLocale('pt-br', {
18594        months: 'janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro'.split(
18595            '_'
18596        ),
18597        monthsShort: 'jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez'.split('_'),
18598        weekdays:
18599            'domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado'.split(
18600                '_'
18601            ),
18602        weekdaysShort: 'dom_seg_ter_qua_qui_sex_sáb'.split('_'),
18603        weekdaysMin: 'do_2ª_3ª_4ª_5ª_6ª_sá'.split('_'),
18604        weekdaysParseExact: true,
18605        longDateFormat: {
18606            LT: 'HH:mm',
18607            LTS: 'HH:mm:ss',
18608            L: 'DD/MM/YYYY',
18609            LL: 'D [de] MMMM [de] YYYY',
18610            LLL: 'D [de] MMMM [de] YYYY [às] HH:mm',
18611            LLLL: 'dddd, D [de] MMMM [de] YYYY [às] HH:mm',
18612        },
18613        calendar: {
18614            sameDay: '[Hoje às] LT',
18615            nextDay: '[Amanhã às] LT',
18616            nextWeek: 'dddd [às] LT',
18617            lastDay: '[Ontem às] LT',
18618            lastWeek: function () {
18619                return this.day() === 0 || this.day() === 6
18620                    ? '[Último] dddd [às] LT' // Saturday + Sunday
18621                    : '[Última] dddd [às] LT'; // Monday - Friday
18622            },
18623            sameElse: 'L',
18624        },
18625        relativeTime: {
18626            future: 'em %s',
18627            past: 'há %s',
18628            s: 'poucos segundos',
18629            ss: '%d segundos',
18630            m: 'um minuto',
18631            mm: '%d minutos',
18632            h: 'uma hora',
18633            hh: '%d horas',
18634            d: 'um dia',
18635            dd: '%d dias',
18636            M: 'um mês',
18637            MM: '%d meses',
18638            y: 'um ano',
18639            yy: '%d anos',
18640        },
18641        dayOfMonthOrdinalParse: /\d{1,2}º/,
18642        ordinal: '%dº',
18643        invalidDate: 'Data inválida',
18644    });
18645
18646    return ptBr;
18647
18648})));
18649
18650//! moment.js locale configuration
18651
18652;(function (global, factory) {
18653   typeof exports === 'object' && typeof module !== 'undefined'
18654       && typeof require === 'function' ? factory(require('../moment')) :
18655   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
18656   factory(global.moment)
18657}(this, (function (moment) { 'use strict';
18658
18659
18660    var zhCn = moment.defineLocale('zh-cn', {
18661        months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split(
18662            '_'
18663        ),
18664        monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split(
18665            '_'
18666        ),
18667        weekdays: '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),
18668        weekdaysShort: '周日_周一_周二_周三_周四_周五_周六'.split('_'),
18669        weekdaysMin: '日_一_二_三_四_五_六'.split('_'),
18670        longDateFormat: {
18671            LT: 'HH:mm',
18672            LTS: 'HH:mm:ss',
18673            L: 'YYYY/MM/DD',
18674            LL: 'YYYY年M月D日',
18675            LLL: 'YYYY年M月D日Ah点mm分',
18676            LLLL: 'YYYY年M月D日ddddAh点mm分',
18677            l: 'YYYY/M/D',
18678            ll: 'YYYY年M月D日',
18679            lll: 'YYYY年M月D日 HH:mm',
18680            llll: 'YYYY年M月D日dddd HH:mm',
18681        },
18682        meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
18683        meridiemHour: function (hour, meridiem) {
18684            if (hour === 12) {
18685                hour = 0;
18686            }
18687            if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {
18688                return hour;
18689            } else if (meridiem === '下午' || meridiem === '晚上') {
18690                return hour + 12;
18691            } else {
18692                // '中午'
18693                return hour >= 11 ? hour : hour + 12;
18694            }
18695        },
18696        meridiem: function (hour, minute, isLower) {
18697            var hm = hour * 100 + minute;
18698            if (hm < 600) {
18699                return '凌晨';
18700            } else if (hm < 900) {
18701                return '早上';
18702            } else if (hm < 1130) {
18703                return '上午';
18704            } else if (hm < 1230) {
18705                return '中午';
18706            } else if (hm < 1800) {
18707                return '下午';
18708            } else {
18709                return '晚上';
18710            }
18711        },
18712        calendar: {
18713            sameDay: '[今天]LT',
18714            nextDay: '[明天]LT',
18715            nextWeek: function (now) {
18716                if (now.week() !== this.week()) {
18717                    return '[下]dddLT';
18718                } else {
18719                    return '[本]dddLT';
18720                }
18721            },
18722            lastDay: '[昨天]LT',
18723            lastWeek: function (now) {
18724                if (this.week() !== now.week()) {
18725                    return '[上]dddLT';
18726                } else {
18727                    return '[本]dddLT';
18728                }
18729            },
18730            sameElse: 'L',
18731        },
18732        dayOfMonthOrdinalParse: /\d{1,2}(日|月|周)/,
18733        ordinal: function (number, period) {
18734            switch (period) {
18735                case 'd':
18736                case 'D':
18737                case 'DDD':
18738                    return number + '日';
18739                case 'M':
18740                    return number + '月';
18741                case 'w':
18742                case 'W':
18743                    return number + '周';
18744                default:
18745                    return number;
18746            }
18747        },
18748        relativeTime: {
18749            future: '%s后',
18750            past: '%s前',
18751            s: '几秒',
18752            ss: '%d 秒',
18753            m: '1 分钟',
18754            mm: '%d 分钟',
18755            h: '1 小时',
18756            hh: '%d 小时',
18757            d: '1 天',
18758            dd: '%d 天',
18759            w: '1 周',
18760            ww: '%d 周',
18761            M: '1 个月',
18762            MM: '%d 个月',
18763            y: '1 å¹´',
18764            yy: '%d å¹´',
18765        },
18766        week: {
18767            // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效
18768            dow: 1, // Monday is the first day of the week.
18769            doy: 4, // The week that contains Jan 4th is the first week of the year.
18770        },
18771    });
18772
18773    return zhCn;
18774
18775})));
18776
18777//! moment.js locale configuration
18778
18779;(function (global, factory) {
18780   typeof exports === 'object' && typeof module !== 'undefined'
18781       && typeof require === 'function' ? factory(require('../moment')) :
18782   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
18783   factory(global.moment)
18784}(this, (function (moment) { 'use strict';
18785
18786
18787    var zhTw = moment.defineLocale('zh-tw', {
18788        months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split(
18789            '_'
18790        ),
18791        monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split(
18792            '_'
18793        ),
18794        weekdays: '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),
18795        weekdaysShort: '週日_週一_週二_週三_週四_週五_週六'.split('_'),
18796        weekdaysMin: '日_一_二_三_四_五_六'.split('_'),
18797        longDateFormat: {
18798            LT: 'HH:mm',
18799            LTS: 'HH:mm:ss',
18800            L: 'YYYY/MM/DD',
18801            LL: 'YYYY年M月D日',
18802            LLL: 'YYYY年M月D日 HH:mm',
18803            LLLL: 'YYYY年M月D日dddd HH:mm',
18804            l: 'YYYY/M/D',
18805            ll: 'YYYY年M月D日',
18806            lll: 'YYYY年M月D日 HH:mm',
18807            llll: 'YYYY年M月D日dddd HH:mm',
18808        },
18809        meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
18810        meridiemHour: function (hour, meridiem) {
18811            if (hour === 12) {
18812                hour = 0;
18813            }
18814            if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {
18815                return hour;
18816            } else if (meridiem === '中午') {
18817                return hour >= 11 ? hour : hour + 12;
18818            } else if (meridiem === '下午' || meridiem === '晚上') {
18819                return hour + 12;
18820            }
18821        },
18822        meridiem: function (hour, minute, isLower) {
18823            var hm = hour * 100 + minute;
18824            if (hm < 600) {
18825                return '凌晨';
18826            } else if (hm < 900) {
18827                return '早上';
18828            } else if (hm < 1130) {
18829                return '上午';
18830            } else if (hm < 1230) {
18831                return '中午';
18832            } else if (hm < 1800) {
18833                return '下午';
18834            } else {
18835                return '晚上';
18836            }
18837        },
18838        calendar: {
18839            sameDay: '[今天] LT',
18840            nextDay: '[明天] LT',
18841            nextWeek: '[下]dddd LT',
18842            lastDay: '[昨天] LT',
18843            lastWeek: '[上]dddd LT',
18844            sameElse: 'L
vendor: 5,442 bytes, lines 18844-19024
18844',
18845        },
18846        dayOfMonthOrdinalParse: /\d{1,2}(日|月|週)/,
18847        ordinal: function (number, period) {
18848            switch (period) {
18849                case 'd':
18850                case 'D':
18851                case 'DDD':
18852                    return number + '日';
18853                case 'M':
18854                    return number + '月';
18855                case 'w':
18856                case 'W':
18857                    return number + '週';
18858                default:
18859                    return number;
18860            }
18861        },
18862        relativeTime: {
18863            future: '%s後',
18864            past: '%s前',
18865            s: '幾秒',
18866            ss: '%d 秒',
18867            m: '1 分鐘',
18868            mm: '%d 分鐘',
18869            h: '1 小時',
18870            hh: '%d 小時',
18871            d: '1 天',
18872            dd: '%d 天',
18873            M: '1 個月',
18874            MM: '%d 個月',
18875            y: '1 å¹´',
18876            yy: '%d å¹´',
18877        },
18878    });
18879
18880    return zhTw;
18881
18882})));
18883
18884//! moment.js locale configuration
18885
18886;(function (global, factory) {
18887   typeof exports === 'object' && typeof module !== 'undefined'
18888       && typeof require === 'function' ? factory(require('../moment')) :
18889   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
18890   factory(global.moment)
18891}(this, (function (moment) { 'use strict';
18892
18893
18894    var ja = moment.defineLocale('ja', {
18895        eras: [
18896            {
18897                since: '2019-05-01',
18898                offset: 1,
18899                name: '令和',
18900                narrow: '㋿',
18901                abbr: 'R',
18902            },
18903            {
18904                since: '1989-01-08',
18905                until: '2019-04-30',
18906                offset: 1,
18907                name: '平成',
18908                narrow: '㍻',
18909                abbr: 'H',
18910            },
18911            {
18912                since: '1926-12-25',
18913                until: '1989-01-07',
18914                offset: 1,
18915                name: '昭和',
18916                narrow: '㍼',
18917                abbr: 'S',
18918            },
18919            {
18920                since: '1912-07-30',
18921                until: '1926-12-24',
18922                offset: 1,
18923                name: '大正',
18924                narrow: '㍽',
18925                abbr: 'T',
18926            },
18927            {
18928                since: '1873-01-01',
18929                until: '1912-07-29',
18930                offset: 6,
18931                name: '明治',
18932                narrow: '㍾',
18933                abbr: 'M',
18934            },
18935            {
18936                since: '0001-01-01',
18937                until: '1873-12-31',
18938                offset: 1,
18939                name: '西暦',
18940                narrow: 'AD',
18941                abbr: 'AD',
18942            },
18943            {
18944                since: '0000-12-31',
18945                until: -Infinity,
18946                offset: 1,
18947                name: '紀元前',
18948                narrow: 'BC',
18949                abbr: 'BC',
18950            },
18951        ],
18952        eraYearOrdinalRegex: /(元|\d+)年/,
18953        eraYearOrdinalParse: function (input, match) {
18954            return match[1] === '元' ? 1 : parseInt(match[1] || input, 10);
18955        },
18956        months: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
18957        monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split(
18958            '_'
18959        ),
18960        weekdays: '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'),
18961        weekdaysShort: '日_月_火_水_木_金_土'.split('_'),
18962        weekdaysMin: '日_月_火_水_木_金_土'.split('_'),
18963        longDateFormat: {
18964            LT: 'HH:mm',
18965            LTS: 'HH:mm:ss',
18966            L: 'YYYY/MM/DD',
18967            LL: 'YYYY年M月D日',
18968            LLL: 'YYYY年M月D日 HH:mm',
18969            LLLL: 'YYYY年M月D日 dddd HH:mm',
18970            l: 'YYYY/MM/DD',
18971            ll: 'YYYY年M月D日',
18972            lll: 'YYYY年M月D日 HH:mm',
18973            llll: 'YYYY年M月D日(ddd) HH:mm',
18974        },
18975        meridiemParse: /午前|午後/i,
18976        isPM: function (input) {
18977            return input === '午後';
18978        },
18979        meridiem: function (hour, minute, isLower) {
18980            if (hour < 12) {
18981                return '午前';
18982            } else {
18983                return '午後';
18984            }
18985        },
18986        calendar: {
18987            sameDay: '[今日] LT',
18988            nextDay: '[明日] LT',
18989            nextWeek: function (now) {
18990                if (now.week() !== this.week()) {
18991                    return '[来週]dddd LT';
18992                } else {
18993                    return 'dddd LT';
18994                }
18995            },
18996            lastDay: '[昨日] LT',
18997            lastWeek: function (now) {
18998                if (this.week() !== now.week()) {
18999                    return '[先週]dddd LT';
19000                } else {
19001                    return 'dddd LT';
19002                }
19003            },
19004            sameElse: 'L',
19005        },
19006        dayOfMonthOrdinalParse: /\d{1,2}日/,
19007        ordinal: function (number, period) {
19008            switch (period) {
19009                case 'y':
19010                    return number === 1 ? '元年' : number + '年';
19011                case 'd':
19012                case 'D':
19013                case 'DDD':
19014                    return number + '日';
19015                default:
19016                    return number;
19017            }
19018        },
19019        relativeTime: {
19020            future: '%s後',
19021            past: '%s前',
19022            s: '数秒',
19023            ss: '%d秒',
19024            m: '1分',
19025            mm: '%d分',
19026            h: '1時間',
19027            hh: '%d時間',
19028            d: '1日',
19029            dd: '%d日',
19030            M: '1ヶ月',
19031            MM: '%dヶ月',
19032            y: '1å¹´',
19033            yy: '%då¹´',
19034        },
19035    });
19036
19037    return ja;
19038
19039})));
19040
19041//! moment.js locale configuration
19042
19043;(function (global, factory) {
19044   typeof exports === 'object' && typeof module !== 'undefined'
19045       && typeof require === 'function' ? factory(require('../moment')) :
19046   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
19047   factory(global.moment)
19048}(this, (function (moment) { 'use strict';
19049
19050
19051    var ko = moment.defineLocale('ko', {
19052        months: '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),
19053        monthsShort: '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split(
19054            '_'
19055        ),
19056        weekdays: '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'),
19057        weekdaysShort: '일_월_화_수_목_금_토'.split('_'),
19058        weekdaysMin: '일_월_화_수_목_금_토'.split('_'),
19059        longDateFormat: {
19060            LT: 'A h:mm',
19061            LTS: 'A h:mm:ss',
19062            L: 'YYYY.MM.DD.',
19063            LL: 'YYYY년 MMMM D일',
19064            LLL: 'YYYY년 MMMM D일 A h:mm',
19065            LLLL: 'YYYY년 MMMM D일 dddd A h:mm',
19066            l: 'YYYY.MM.DD.',
19067            ll: 'YYYY년 MMMM D일',
19068            lll: 'YYYY년 MMMM D일 A h:mm',
19069            llll: 'YYYY년 MMMM D일 dddd A h:mm',
19070        },
19071        calendar: {
19072            sameDay: '오늘 LT',
19073            nextDay: '내일 LT',
19074            nextWeek: 'dddd LT',
19075            lastDay: '어제 LT',
19076            lastWeek: '지난주 dddd LT',
19077            sameElse: 'L',
19078        },
19079        relativeTime: {
19080            future: '%s 후',
19081            past: '%s 전',
19082            s: '몇 초',
19083            ss: '%d초',
19084            m: '1분',
19085            mm: '%d분',
19086            h: '한 시간',
19087            hh: '%d시간',
19088            d: '하루',
19089            dd: '%d일',
19090            M: '한 달',
19091            MM: '%d달',
19092            y: '일 년',
19093            yy: '%d년',
19094        },
19095        dayOfMonthOrdinalParse: /\d{1,2}(일|월|주)/,
19096        ordinal: function (number, period) {
19097            switch (period) {
19098                case 'd':
19099                case 'D':
19100                case 'DDD':
19101                    return number + '일';
19102                case 'M':
19103                    return number + '월';
19104                case 'w':
19105                case 'W':
19106                    return number + '주';
19107                default:
19108                    return number;
19109            }
19110        },
19111        meridiemParse: /오전|오후/,
19112        isPM: function (token) {
19113            return token === '오후';
19114        },
19115        meridiem: function (hour, minute, isUpper) {
19116            return hour < 12 ? '오전' : '오후';
19117        },
19118    });
19119
19120    return ko;
19121
19122})));
19123
19124/*
19125 * ADOBE CONFIDENTIAL
19126 *
19127 * Copyright 2017 Adobe Systems Incorporated
19128 * All Rights Reserved.
19129 *
19130 * NOTICE:  All information contained herein is, and remains
19131 * the property of Adobe Systems Incorporated and its suppliers,
19132 * if any.  The intellectual and technical concepts contained
19133 * herein are proprietary to Adobe Systems Incorporated and its
19134 * suppliers and may be covered by U.S. and Foreign Patents,
19135 * patents in process, and are protected by trade secret or copyright law.
19136 * Dissemination of this information or reproduction of this material
19137 * is strictly forbidden unless prior written permission is obtained
19138 * from Adobe Systems Incorporated.
19139 */
19140(function(root, factory) {
19141    "use strict";
19142
19143    if (typeof module === "object" && module.exports) {
19144        module.exports = factory(require("moment"));
19145    } else {
19146        factory(root.moment);
19147    }
19148}(this, function(moment) {
19149    "use strict";
19150
19151    var shortTimeZoneFormat = new Intl.DateTimeFormat("de", { year: "2-digit", timeZoneName: "short" });
19152    var longTimeZoneFormat = new Intl.DateTimeFormat("de", { year: "2-digit", timeZoneName: "long" });
19153
19154    function getShortTimeZone(date) {
19155        var v = shortTimeZoneFormat.format(date);
19156        return v.substring(v.indexOf(" ") + 1);
19157    }
19158
19159    function getLongTimeZone(date) {
19160        var v = longTimeZoneFormat.format(date);
19161        return v.substring(v.indexOf(" ") + 1);
19162    }
19163
19164    // See https://github.com/unicode-cldr/cldr-dates-modern/blob/master/main/de/ca-gregorian.json
19165    moment.updateLocale("de", {
19166        presets: {
19167            date: {
19168                short: "DD.MM.YY",
19169                medium: "DD.MM.Y",
19170                long: "D. MMMM Y",
19171                full: "dddd, D. MMMM Y"
19172            },
19173            time: {
19174                short: "HH:mm",
19175                medium: "HH:mm:ss",
19176                long: function(moment) {
19177                    return "HH:mm:ss [" + getShortTimeZone(moment.toDate()) + "]";
19178                },
19179                full: function(moment) {
19180                    return "HH:mm:ss [" + getLongTimeZone(moment.toDate()) + "]";
19181                }
19182            },
19183            datetime: {
19184                short: "DD.MM.YY, HH:mm",
19185                medium: "DD.MM.Y, HH:mm:ss",
19186                long: function(moment) {
19187                    return "D. MMMM Y [um] HH:mm:ss [" + getShortTimeZone(moment.toDate()) + "]";
19188                },
19189                full: function(moment) {
19190                    return "dddd, D. MMMM Y [um] HH:mm:ss [" + getLongTimeZone(moment.toDate()) + "]";
19191                }
19192            }
19193        }
19194    });
19195}));
19196
19197/*
19198 * ADOBE CONFIDENTIAL
19199 *
19200 * Copyright 2017 Adobe Systems Incorporated
19201 * All Rights Reserved.
19202 *
19203 * NOTICE:  All information contained herein is, and remains
19204 * the property of Adobe Systems Incorporated and its suppliers,
19205 * if any.  The intellectual and technical concepts contained
19206 * herein are proprietary to Adobe Systems Incorporated and its
19207 * suppliers and may be covered by U.S. and Foreign Patents,
19208 * patents in process, and are protected by trade secret or copyright law.
19209 * Dissemination of this information or reproduction of this material
19210 * is strictly forbidden unless prior written permission is obtained
19211 * from Adobe Systems Incorporated.
19212 */
19213(function(root, factory) {
19214    "use strict";
19215
19216    if (typeof module === "object" && module.exports) {
19217        module.exports = factory(require("moment"));
19218    } else {
19219        factory(root.moment);
19220    }
19221}(this, function(moment) {
19222    "use strict";
19223
19224    var shortTimeZoneFormat = new Intl.DateTimeFormat("es", { year: "2-digit", timeZoneName: "short" });
19225    var longTimeZoneFormat = new Intl.DateTimeFormat("es", { year: "2-digit", timeZoneName: "long" });
19226
19227    function getShortTimeZone(date) {
19228        var v = shortTimeZoneFormat.format(date);
19229        return v.substring(v.indexOf(" ") + 1);
19230    }
19231
19232    function getLongTimeZone(date) {
19233        var v = longTimeZoneFormat.format(date);
19234        return v.substring(v.indexOf(" ") + 1);
19235    }
19236
19237    // See https://github.com/unicode-cldr/cldr-dates-modern/blob/master/main/es/ca-gregorian.json
19238    moment.updateLocale("es", {
19239        presets: {
19240            date: {
19241                short: "D/M/YY",
19242                medium: "D MMM Y",
19243                long: "D [de] MMMM [de] Y",
19244                full: "dddd, D [de] MMMM [de] Y"
19245            },
19246            time: {
19247                short: "H:mm",
19248                medium: "H:mm:ss",
19249                long: function(moment) {
19250                    return "H:mm:ss [" + getShortTimeZone(moment.toDate()) + "]";
19251                },
19252                full: function(moment) {
19253                    return "H:mm:ss [(" + getLongTimeZone(moment.toDate()) + ")]";
19254                }
19255            },
19256            datetime: {
19257                short: "D/M/YY H:mm",
19258                medium: "D MMM Y H:mm:ss",
19259                long: function(moment) {
19260                    return "D [de] MMMM [de] Y, H:mm:ss [" + getShortTimeZone(moment.toDate()) + "]";
19261                },
19262                full: function(moment) {
19263                    return "dddd, D [de] MMMM [de] Y, H:mm:ss [(" + getLongTimeZone(moment.toDate()) + ")]";
19264                }
19265            }
19266        }
19267    });
19268}));
19269
19270/*
19271 * ADOBE CONFIDENTIAL
19272 *
19273 * Copyright 2017 Adobe Systems Incorporated
19274 * All Rights Reserved.
19275 *
19276 * NOTICE:  All information contained herein is, and remains
19277 * the property of Adobe Systems Incorporated and its suppliers,
19278 * if any.  The intellectual and technical concepts contained
19279 * herein are proprietary to Adobe Systems Incorporated and its
19280 * suppliers and may be covered by U.S. and Foreign Patents,
19281 * patents in process, and are protected by trade secret or copyright law.
19282 * Dissemination of this information or reproduction of this material
19283 * is strictly forbidden unless prior written permission is obtained
19284 * from Adobe Systems Incorporated.
19285 */
19286(function(root, factory) {
19287    "use strict";
19288
19289    if (typeof module === "object" && module.exports) {
19290        module.exports = factory(require("moment"));
19291    } else {
19292        factory(root.moment);
19293    }
19294}(this, function(moment) {
19295    "use strict";
19296
19297    var shortTimeZoneFormat = new Intl.DateTimeFormat("fr", { year: "2-digit", timeZoneName: "short" });
19298    var longTimeZoneFormat = new Intl.DateTimeFormat("fr", { year: "2-digit", timeZoneName: "long" });
19299
19300    function getShortTimeZone(date) {
19301        var v = shortTimeZoneFormat.format(date);
19302        return v.substring(v.indexOf(" ") + 1);
19303    }
19304
19305    function getLongTimeZone(date) {
19306        var v = longTimeZoneFormat.format(date);
19307        return v.substring(v.indexOf(" ") + 1);
19308    }
19309
19310    moment.updateLocale("fr", {
19311        presets: {
19312            date: {
19313                short: "DD/MM/Y",
19314                medium: "D MMM Y",
19315                long: "D MMMM Y",
19316                full: "dddd D MMMM Y"
19317            },
19318            time: {
19319                short: "HH:mm",
19320                medium: "HH:mm:ss",
19321                long: function(moment) {
19322                    return "HH:mm:ss [" + getShortTimeZone(moment.toDate()) + "]";
19323                },
19324                full: function(moment) {
19325                    return "HH:mm:ss [" + getLongTimeZone(moment.toDate()) + "]";
19326                }
19327            },
19328            datetime: {
19329                short: "DD/MM/Y HH:mm",
19330                medium: "D MMM Y à HH:mm:ss",
19331                long: function(moment) {
19332                    return "D MMMM Y à HH:mm:ss [" + getShortTimeZone(moment.toDate()) + "]";
19333                },
19334                full: function(moment) {
19335                    return "dddd D MMMM Y à HH:mm:ss [" + getLongTimeZone(moment.toDate()) + "]";
19336                }
19337            }
19338        }
19339    });
19340}));
19341
19342/*
19343 * ADOBE CONFIDENTIAL
19344 *
19345 * Copyright 2017 Adobe Systems Incorporated
19346 * All Rights Reserved.
19347 *
19348 * NOTICE:  All information contained herein is, and remains
19349 * the property of Adobe Systems Incorporated and its suppliers,
19350 * if any.  The intellectual and technical concepts contained
19351 * herein are proprietary to Adobe Systems Incorporated and its
19352 * suppliers and may be covered by U.S. and Foreign Patents,
19353 * patents in process, and are protected by trade secret or copyright law.
19354 * Dissemination of this information or reproduction of this material
19355 * is strictly forbidden unless prior written permission is obtained
19356 * from Adobe Systems Incorporated.
19357 */
19358(function(root, factory) {
19359    "use strict";
19360
19361    if (typeof module === "object" && module.exports) {
19362        module.exports = factory(require("moment"));
19363    } else {
19364        factory(root.moment);
19365    }
19366}(this, function(moment) {
19367    "use strict";
19368
19369    var shortTimeZoneFormat = new Intl.DateTimeFormat("it", { year: "2-digit", timeZoneName: "short" });
19370    var longTimeZoneFormat = new Intl.DateTimeFormat("it", { year: "2-digit", timeZoneName: "long" });
19371
19372    function getShortTimeZone(date) {
19373        var v = shortTimeZoneFormat.format(date);
19374        return v.substring(v.indexOf(" ") + 1);
19375    }
19376
19377    function getLongTimeZone(date) {
19378        var v = longTimeZoneFormat.format(date);
19379        return v.substring(v.indexOf(" ") + 1);
19380    }
19381
19382    // See https://github.com/unicode-cldr/cldr-dates-modern/blob/master/main/it/ca-gregorian.json
19383    moment.updateLocale("it", {
19384        presets: {
19385            date: {
19386                short: "DD/MM/YY",
19387                medium: "DD MMM Y",
19388                long: "D MMMM Y",
19389                full: "dddd D MMMM Y"
19390            },
19391            time: {
19392                short: "HH:mm",
19393                medium: "HH:mm:ss",
19394                long: function(moment) {
19395                    return "HH:mm:ss [" + getShortTimeZone(moment.toDate()) + "]";
19396                },
19397                full: function(moment) {
19398                    return "HH:mm:ss [" + getLongTimeZone(moment.toDate()) + "]";
19399                }
19400            },
19401            datetime: {
19402                short: "DD/MM/YY, HH:mm",
19403                medium: "DD MMM Y, HH:mm:ss",
19404                long: function(moment) {
19405                    return "D MMMM Y HH:mm:ss [" + getShortTimeZone(moment.toDate()) + "]";
19406                },
19407                full: function(moment) {
19408                    return "dddd D MMMM Y HH:mm:ss [" + getLongTimeZone(moment.toDate()) + "]";
19409                }
19410            }
19411        }
19412    });
19413}));
19414
19415/*
19416 * ADOBE CONFIDENTIAL
19417 *
19418 * Copyright 2017 Adobe Systems Incorporated
19419 * All Rights Reserved.
19420 *
19421 * NOTICE:  All information contained herein is, and remains
19422 * the property of Adobe Systems Incorporated and its suppliers,
19423 * if any.  The intellectual and technical concepts contained
19424 * herein are proprietary to Adobe Systems Incorporated and its
19425 * suppliers and may be covered by U.S. and Foreign Patents,
19426 * patents in process, and are protected by trade secret or copyright law.
19427 * Dissemination of this information or reproduction of this material
19428 * is strictly forbidden unless prior written permission is obtained
19429 * from Adobe Systems Incorporated.
19430 */
19431(function(root, factory) {
19432    "use strict";
19433
19434    if (typeof module === "object" && module.exports) {
19435        module.exports = factory(require("moment"));
19436    } else {
19437        factory(root.moment);
19438    }
19439}(this, function(moment) {
19440    "use strict";
19441
19442    var shortTimeZoneFormat = new Intl.DateTimeFormat("pt-br", { year: "2-digit", timeZoneName: "short" });
19443    var longTimeZoneFormat = new Intl.DateTimeFormat("pt-br", { year: "2-digit", timeZoneName: "long" });
19444
19445    function getShortTimeZone(date) {
19446        var v = shortTimeZoneFormat.format(date);
19447        return v.substring(v.indexOf(" ") + 1);
19448    }
19449
19450    function getLongTimeZone(date) {
19451        var v = longTimeZoneFormat.format(date);
19452        return v.substring(v.indexOf(" ") + 1);
19453    }
19454
19455    // See https://github.com/unicode-cldr/cldr-dates-modern/blob/master/main/pt/ca-gregorian.json
19456    moment.updateLocale("pt-br", {
19457        presets: {
19458            date: {
19459                short: "DD/MM/Y",
19460                medium: "D [de] MMM [de] Y",
19461                long: "D [de] MMMM [de] Y",
19462                full: "dddd, D [de] MMMM [de] Y"
19463            },
19464            time: {
19465                short: "HH:mm",
19466                medium: "HH:mm:ss",
19467                long: function(moment) {
19468                    return "HH:mm:ss [" + getShortTimeZone(moment.toDate()) + "]";
19469                },
19470                full: function(moment) {
19471                    return "HH:mm:ss [" + getLongTimeZone(moment.toDate()) + "]";
19472                }
19473            },
19474            datetime: {
19475                short: "DD/MM/Y HH:mm",
19476                medium: "D [de] MMM [de] Y HH:mm:ss",
19477                long: function(moment) {
19478                    return "D [de] MMMM [de] Y HH:mm:ss [" + getShortTimeZone(moment.toDate()) + "]";
19479                },
19480                full: function(moment) {
19481                    return "dddd, D [de] MMMM [de] Y HH:mm:ss [" + getLongTimeZone(moment.toDate()) + "]";
19482                }
19483            }
19484        }
19485    });
19486}));
19487
19488/*
19489 * ADOBE CONFIDENTIAL
19490 *
19491 * Copyright 2017 Adobe Systems Incorporated
19492 * All Rights Reserved.
19493 *
19494 * NOTICE:  All information contained herein is, and remains
19495 * the property of Adobe Systems Incorporated and its suppliers,
19496 * if any.  The intellectual and technical concepts contained
19497 * herein are proprietary to Adobe Systems Incorporated and its
19498 * suppliers and may be covered by U.S. and Foreign Patents,
19499 * patents in process, and are protected by trade secret or copyright law.
19500 * Dissemination of this information or reproduction of this material
19501 * is strictly forbidden unless prior written permission is obtained
19502 * from Adobe Systems Incorporated.
19503 */
19504(function(root, factory) {
19505    "use strict";
19506
19507    if (typeof module === "object" && module.exports) {
19508        module.exports = factory(require("moment"));
19509    } else {
19510        factory(root.moment);
19511    }
19512}(this, function(moment) {
19513    "use strict";
19514
19515    var shortTimeZoneFormat = new Intl.DateTimeFormat("zh-cn", { year: "2-digit", timeZoneName: "short" });
19516    var longTimeZoneFormat = new Intl.DateTimeFormat("zh-cn", { year: "2-digit", timeZoneName: "long" });
19517
19518    function getShortTimeZone(date) {
19519        var v = shortTimeZoneFormat.format(date);
19520        return v.substring(v.indexOf(" ") + 1);
19521    }
19522
19523    function getLongTimeZone(date) {
19524        var v = longTimeZoneFormat.format(date);
19525        return v.substring(v.indexOf(" ") + 1);
19526    }
19527
19528    // See https://github.com/unicode-cldr/cldr-dates-modern/blob/master/main/zh/ca-gregorian.json
19529    moment.updateLocale("zh-cn", {
19530        presets: {
19531            date: {
19532                short: "Y/M/D",
19533                medium: "Y年M月D日",
19534                long: "Y年M月D日",
19535                full: "Y年M月D日dddd"
19536            },
19537            time: {
19538                short: "ah:mm",
19539                medium: "ah:mm:ss",
19540                long: function(moment) {
19541                    return "[" + getShortTimeZone(moment.toDate()) + "] ah:mm:ss";
19542                },
19543                full: function(moment) {
19544                    return "[" + getLongTimeZone(moment.toDate()) + "] ah:mm:ss";
19545                }
19546            },
19547            datetime: {
19548                short: "Y/M/D ah:mm",
19549                medium: "Y年M月D日 ah:mm:ss",
19550                long: function(moment) {
19551                    return "Y年M月D日 [" + getShortTimeZone(moment.toDate()) + "] ah:mm:ss";
19552                },
19553                full: function(moment) {
19554                    return "Y年M月D日dddd [" + getLongTimeZone(moment.toDate()) + "] ah:mm:ss";
19555                }
19556            }
19557        }
19558    });
19559}));
19560
19561/*
19562 * ADOBE CONFIDENTIAL
19563 *
19564 * Copyright 2017 Adobe Systems Incorporated
19565 * All Rights Reserved.
19566 *
19567 * NOTICE:  All information contained herein is, and remains
19568 * the property of Adobe Systems Incorporated and its suppliers,
19569 * if any.  The intellectual and technical concepts contained
19570 * herein are proprietary to Adobe Systems Incorporated and its
19571 * suppliers and may be covered by U.S. and Foreign Patents,
19572 * patents in process, and are protected by trade secret or copyright law.
19573 * Dissemination of this information or reproduction of this material
19574 * is strictly forbidden unless prior written permission is obtained
19575 * from Adobe Systems Incorporated.
19576 */
19577(function(root, factory) {
19578    "use strict";
19579
19580    if (typeof module === "object" && module.exports) {
19581        module.exports = factory(require("moment"));
19582    } else {
19583        factory(root.moment);
19584    }
19585}(this, function(moment) {
19586    "use strict";
19587
19588    var shortTimeZoneFormat = new Intl.DateTimeFormat("zh-tw", { year: "2-digit", timeZoneName: "short" });
19589    var longTimeZoneFormat = new Intl.DateTimeFormat("zh-tw", { year: "2-digit", timeZoneName: "long" });
19590
19591    function getShortTimeZone(date) {
19592        var v = shortTimeZoneFormat.format(date);
19593        return v.substring(v.indexOf(" ") + 1);
19594    }
19595
19596    function getLongTimeZone(date) {
19597        var v = longTimeZoneFormat.format(date);
19598        return v.substring(v.indexOf(" ") + 1);
19599    }
19600
19601    // See https://github.com/unicode-cldr/cldr-dates-modern/blob/master/main/zh-Hant/ca-gregorian.json
19602    moment.updateLocale("zh-tw", {
19603        presets: {
19604            date: {
19605                short: "Y/M/D",
19606                medium: "Y年M月D日",
19607                long: "Y年M月D日",
19608                full: "Y年M月D日 dddd"
19609            },
19610            time: {
19611                short: "ah:mm",
19612                medium: "ah:mm:ss",
19613                long: function(moment) {
19614                    return "ah:mm:ss [[" + getShortTimeZone(moment.toDate()) + "]]";
19615                },
19616                full: function(moment) {
19617                    return "ah:mm:ss [[" + getLongTimeZone(moment.toDate()) + "]]";
19618                }
19619            },
19620            datetime: {
19621                short: "Y/M/D ah:mm",
19622                medium: "Y年M月D日 ah:mm:ss",
19623                long: function(moment) {
19624                    return "Y年M月D日 ah:mm:ss [[" + getShortTimeZone(moment.toDate()) + "]]";
19625                },
19626                full: function(moment) {
19627                    return "Y年M月D日 dddd ah:mm:ss [[" + getLongTimeZone(moment.toDate()) + "]]";
19628                }
19629            }
19630        }
19631    });
19632}));
19633
19634/*
19635 * ADOBE CONFIDENTIAL
19636 *
19637 * Copyright 2017 Adobe Systems Incorporated
19638 * All Rights Reserved.
19639 *
19640 * NOTICE:  All information contained herein is, and remains
19641 * the property of Adobe Systems Incorporated and its suppliers,
19642 * if any.  The intellectual and technical concepts contained
19643 * herein are proprietary to Adobe Systems Incorporated and its
19644 * suppliers and may be covered by U.S. and Foreign Patents,
19645 * patents in process, and are protected by trade secret or copyright law.
19646 * Dissemination of this information or reproduction of this material
19647 * is strictly forbidden unless prior written permission is obtained
19648 * from Adobe Systems Incorporated.
19649 */
19650(function(root, factory) {
19651    "use strict";
19652
19653    if (typeof module === "object" && module.exports) {
19654        module.exports = factory(require("moment"));
19655    } else {
19656        factory(root.moment);
19657    }
19658}(this, function(moment) {
19659    "use strict";
19660
19661    var shortTimeZoneFormat = new Intl.DateTimeFormat("ja", { year: "2-digit", timeZoneName: "short" });
19662    var longTimeZoneFormat = new Intl.DateTimeFormat("ja", { year: "2-digit", timeZoneName: "long" });
19663
19664    function getShortTimeZone(date) {
19665        var v = shortTimeZoneFormat.format(date);
19666        return v.substring(v.indexOf(" ") + 1);
19667    }
19668
19669    function getLongTimeZone(date) {
19670        var v = longTimeZoneFormat.format(date);
19671        return v.substring(v.indexOf(" ") + 1);
19672    }
19673
19674    // See https://github.com/unicode-cldr/cldr-dates-modern/blob/master/main/ja/ca-gregorian.json
19675    moment.updateLocale("ja", {
19676        presets: {
19677            date: {
19678                short: "Y/MM/DD",
19679                medium: "Y/MM/DD",
19680                long: "Y年M月D日",
19681                full: "Y年M月D日dddd"
19682            },
19683            time: {
19684                short: "H:mm",
19685                medium: "H:mm:ss",
19686                long: function(moment) {
19687                    return "H:mm:ss [" + getShortTimeZone(moment.toDate()) + "]";
19688                },
19689                full: function(moment) {
19690                    return "H時mm分ss秒 [" + getLongTimeZone(moment.toDate()) + "]";
19691                }
19692            },
19693            datetime: {
19694                short: " Y/MM/DD H:mm",
19695                medium: "Y/MM/DD H:mm:ss",
19696                long: function(moment) {
19697                    return "Y年M月D日 H:mm:ss [" + getShortTimeZone(moment.toDate()) + "]";
19698                },
19699                full: function(moment) {
19700                    return "Y年M月D日dddd H時mm分ss秒 [" + getLongTimeZone(moment.toDate()) + "]";
19701                }
19702            }
19703        }
19704    });
19705}));
19706
19707/*
19708 * ADOBE CONFIDENTIAL
19709 *
19710 * Copyright 2017 Adobe Systems Incorporated
19711 * All Rights Reserved.
19712 *
19713 * NOTICE:  All information contained herein is, and remains
19714 * the property of Adobe Systems Incorporated and its suppliers,
19715 * if any.  The intellectual and technical concepts contained
19716 * herein are proprietary to Adobe Systems Incorporated and its
19717 * suppliers and may be covered by U.S. and Foreign Patents,
19718 * patents in process, and are protected by trade secret or copyright law.
19719 * Dissemination of this information or reproduction of this material
19720 * is strictly forbidden unless prior written permission is obtained
19721 * from Adobe Systems Incorporated.
19722 */
19723(function(root, factory) {
19724    "use strict";
19725
19726    if (typeof module === "object" && module.exports) {
19727        module.exports = factory(require("moment"));
19728    } else {
19729        factory(root.moment);
19730    }
19731}(this, function(moment) {
19732    "use strict";
19733
19734    var shortTimeZoneFormat = new Intl.DateTimeFormat("ko", { year: "2-digit", timeZoneName: "short" });
19735    var longTimeZoneFormat = new Intl.DateTimeFormat("ko", { year: "2-digit", timeZoneName: "long" });
19736
19737    function getShortTimeZone(date) {
19738        var v = shortTimeZoneFormat.format(date);
19739        return v.substring(v.indexOf(" ") + 1);
19740    }
19741
19742    function getLongTimeZone(date) {
19743        var v = longTimeZoneFormat.format(date);
19744        return v.substring(v.indexOf(" ") + 1);
19745    }
19746
19747    // See https://github.com/unicode-cldr/cldr-dates-modern/blob/master/main/ko/ca-gregorian.json
19748    moment.updateLocale("ko", {
19749        presets: {
19750            date: {
19751                short: "YY. M. D.",
19752                medium: "Y. M. D.",
19753                long: "Y년 M월 D일",
19754                full: "Y년 M월 D일 dddd"
19755            },
19756            time: {
19757                short: "a h:mm",
19758                medium: "a h:mm:ss",
19759                long: function(moment) {
19760                    return "a h시 m분 s초 [" + getShortTimeZone(moment.toDate()) + "]";
19761                },
19762                full: function(moment) {
19763                    return "a h시 m분 s초 [" + getLongTimeZone(moment.toDate()) + "]";
19764                }
19765            },
19766            datetime: {
19767                short: "YY. M. D. a h:mm",
19768                medium: "Y. M. D. a h:mm:ss",
19769                long: function(moment) {
19770                    return "Y년 M월 D일 a h시 m분 s초 [" + getShortTimeZone(moment.toDate()) + "]";
19771                },
19772                full: function(moment) {
19773                    return "Y년 M월 D일 dddd a h시 m분 s초 [" + getLongTimeZone(moment.toDate()) + "]";
19774                }
19775            }
19776        }
19777    });
19778}));
19779
19780/*
19781 * ADOBE CONFIDENTIAL
19782 *
19783 * Copyright 2017 Adobe Systems Incorporated
19784 * All Rights Reserved.
19785 *
19786 * NOTICE:  All information contained herein is, and remains
19787 * the property of Adobe Systems Incorporated and its suppliers,
19788 * if any.  The intellectual and technical concepts contained
19789 * herein are proprietary to Adobe Systems Incorporated and its
19790 * suppliers and may be covered by U.S. and Foreign Patents,
19791 * patents in process, and are protected by trade secret or copyright law.
19792 * Dissemination of this information or reproduction of this material
19793 * is strictly forbidden unless prior written permission is obtained
19794 * from Adobe Systems Incorporated.
19795 */
19796(function(root, factory) {
19797    "use strict";
19798
19799    if (typeof module === "object" && module.exports) {
19800        module.exports = factory(require("moment"));
19801    } else {
19802        factory(root.moment);
19803    }
19804}(this, function(moment) {
19805    "use strict";
19806
19807    var shortTimeZoneFormat = new Intl.DateTimeFormat("en", { year: "2-digit", timeZoneName: "short" });
19808    var longTimeZoneFormat = new Intl.DateTimeFormat("en", { year: "2-digit", timeZoneName: "long" });
19809
19810    function getShortTimeZone(date) {
19811        var v = shortTimeZoneFormat.format(date);
19812        return v.substring(v.indexOf(" ") + 1);
19813    }
19814
19815    function getLongTimeZone(date) {
19816        var v = longTimeZoneFormat.format(date);
19817        return v.substring(v.indexOf(" ") + 1);
19818    }
19819
19820    // See https://github.com/unicode-cldr/cldr-dates-modern/blob/master/main/en/ca-gregorian.json
19821    moment.updateLocale("en", {
19822        presets: {
19823            date: {
19824                short: "M/D/YY",
19825                medium: "MMM D, Y",
19826                long: "MMMM D, Y",
19827                full: "dddd, MMMM D, Y"
19828            },
19829            time: {
19830                short: "h:mm A",
19831                medium: "h:mm:ss A",
19832                long: function(moment) {
19833                    return "h:mm:ss A [" + getShortTimeZone(moment.toDate()) + "]";
19834                },
19835                full: function(moment) {
19836                    return "h:mm:ss A [" + getLongTimeZone(moment.toDate()) + "]";
19837                }
19838            },
19839            datetime: {
19840                short: "M/D/YY, h:mm A",
19841                medium: "MMM D, Y, h:mm:ss A",
19842                long: function(moment) {
19843                    return "MMMM D, Y [at] h:mm:ss A [" + getShortTimeZone(moment.toDate()) + "]";
19844                },
19845                full: function(moment) {
19846                    return "dddd, MMMM D, Y [at] h:mm:ss A [" + getLongTimeZone(moment.toDate()) + "]";
19847                }
19848            }
19849        }
19850    });
19851}));
19852
19853/*
19854 *
19855 * ADOBE CONFIDENTIAL
19856 * __________________
19857 *
19858 *  Copyright 2012 Adobe Systems Incorporated
19859 *  All Rights Reserved.
19860 *
19861 * NOTICE:  All information contained herein is, and remains
19862 * the property of Adobe Systems Incorporated and its suppliers,
19863 * if any.  The intellectual and technical concepts contained
19864 * herein are proprietary to Adobe Systems Incorporated and its
19865 * suppliers and are protected by trade secret or copyright law.
19866 * Dissemination of this information or reproduction of this material
19867 * is strictly forbidden unless prior written permission is obtained
19868 * from Adobe Systems Incorporated.
19869 */
19870(function(Backbone, $CQ, _, Handlebars) {
19871    "use strict";
19872    var SCF = {
19873        VERSION: "0.0.1",
19874        Views: {},
19875        Models: {},
19876        Collections: {},
19877        config: {
19878            urlRoot: ""
19879        },
19880        constants: {
19881            SOCIAL_SELECTOR: ".social",
19882            JSON_EXT: ".json",
19883            URL_EXT: ".social.json",
19884            TRANSLATE_URL_EXT: ".social.translate.json",
19885            ANALYTICS_BASE_RESOURCE_TYPE: "social/commons/components/analyticsbase"
19886        },
19887        Components: {},
19888        loadedComponents: {},
19889        templates: {},
19890        fieldManagers: {},
19891        DEBUG: 1,
19892        INFO: 2,
19893        WARN: 3,
19894        ERROR: 4
19895    };
19896    SCF.LOG_LEVEL = SCF.INFO;
19897    var _logger = {
19898        debug: function() {
19899            if (SCF.LOG_LEVEL <= SCF.DEBUG) {
19900                window.console.debug.apply(window.console, arguments);
19901            }
19902        },
19903        info: function() {
19904            if (SCF.LOG_LEVEL <= SCF.INFO) {
19905                window.console.info.apply(window.console, arguments);
19906            }
19907        },
19908        warn: function() {
19909            if (SCF.LOG_LEVEL <= SCF.WARN) {
19910                window.console.warn.apply(window.console, arguments);
19911            }
19912        },
19913        error: function() {
19914            if (SCF.LOG_LEVEL <= SCF.ERROR) {
19915                window.console.error.apply(window.console, arguments);
19916            }
19917        }
19918    };
19919    var deepCommentSearch = function(node, regex) {
19920        var child = node.firstChild;
19921        var foundNode = null;
19922        while (child) {
19923            switch (child.nodeType) {
19924                case 1:
19925                    foundNode = deepCommentSearch(child, regex);
19926                    break;
19927                case 8:
19928                    if (child.nodeValue.match(regex)) {
19929                        return child;
19930                    }
19931                    break;
19932            }
19933            if (foundNode !== null) {
19934                break;
19935            }
19936            child = child.nextSibling;
19937        }
19938        return foundNode;
19939    };
19940    SCF.Router = new Backbone.Router();
19941    if (!Backbone.History.started) {
19942        Backbone.history.start({
19943            pushState: true,
19944            hashChange: false
19945        });
19946    }
19947    SCF.View = Backbone.View.extend({
19948        initialize: function() {
19949            this._rendered = false;
19950            this._childViews = {};
19951            this._parentView = undefined;
19952            this._modelReady = false;
19953            this._sessionReady = false;
19954            this._renderedChildren = [];
19955            this._replacementTarget = null;
19956            this._destroyed = false;
19957            if (this.$el.html() !== "") {
19958                this.bindView();
19959                this._rendered = true;
19960            }
19961            this.listenTo(this.model, "model:loaded", function() {
19962                this._modelReady = true;
19963                this.render();
19964            });
19965            this.listenTo(this.model, "model:cacheFixed", function() {
19966                this.render();
19967            });
19968            if (this.requiresSession && !SCF.Session.isReady()) {
19969                //SCF.log.debug("%s waiting for session to be ready.", this.cid);
19970                this.listenTo(SCF.Session, "model:loaded", function(data) {
19971                    if (!this._sessionReady) {
19972                        //SCF.log.debug("View: %s got Session ready.", this.cid);
19973                        this._sessionReady = true;
19974                        this.render();
19975                    }
19976                });
19977            }
19978            this._sessionReady = SCF.Session.isReady();
19979            if (_.isFunction(this.init)) {
19980                this.init.apply(this, arguments);
19981            }
19982            if (SCF.Session.isReady()) {
19983                this.initContext();
19984            } else {
19985                SCF.Session.on("model:loaded", _.bind(this.initContext, this));
19986            }
19987        },
19988        initContext: function() {
19989            if (_.isUndefined(SCF.Context)) {
19990                SCF.Context = {};
19991                var groupNavbarSel = ".scf-js-group-navbar";
19992
19993                // get site path to be written into SCF.Context and recorded for analytics
19994                var sitePath = $(".scf-js-site-title").attr("href");
19995                sitePath = _.isUndefined(sitePath) ? "" : sitePath.substring(0, sitePath.lastIndexOf(".html"));
19996                this.sitePath = sitePath;
19997                /*
19998                 * Populate page level component information into SCF.Context
19999                 * to be sent with analytics calls. It is particularly important
20000                 * for events such as post (SCFCreate) or votes (SCFVote) originated
20001                 * in nested coments or replies (not top level) that do not have
20002                 * direct access to this information
20003                 */
20004                SCF.Context.siteTitle = $(".scf-js-site-title").length !== 0 ? $(".scf-js-site-title").text() : "";
20005                SCF.Context.sitePath = this.sitePath;
20006                SCF.Context.groupTitle = $(groupNavbarSel).length !== 0 && !_.isUndefined($(groupNavbarSel).attr("data-group-title")) ? $(groupNavbarSel).data("group-title") : "";
20007                SCF.Context.groupPath = $(groupNavbarSel).length !== 0 && !_.isUndefined($(groupNavbarSel).attr("data-group-path")) ? $(groupNavbarSel).data("group-
20007path") : "";
20008                SCF.Context.user = SCF.Session.get("authorizableId");
20009            }
20010            if (_.isFunction(this.initAnalytics)) {
20011                this.initAnalytics.apply(this, arguments);
20012            }
20013        },
20014        getContextForTemplate: function() {
20015            var context = (this.model !== undefined) ? this.model.toJSON() : this.context;
20016            return this.getMergedContexts(context);
20017        },
20018        getMergedContexts: function(context) {
20019            if (!_.isObject(context)) {
20020                context = {};
20021            }
20022            context.loggedInUser = SCF.Session.toJSON();
20023            context.environment = {};
20024            context.environment.client = true;
20025            return context;
20026        },
20027        appendTo: function(parentElement) {
20028            if (!this._rendered) {
20029                this.render();
20030            }
20031            $CQ(parentElement).append(this.el);
20032            this.trigger("view:ready", {
20033                view: this
20034            });
20035        },
20036        replaceElement: function(replacedElement) {
20037            if (!this._rendered) {
20038                this.render();
20039            }
20040            if (this._rendered) {
20041                $CQ(replacedElement).replaceWith(this.$el);
20042                this._replacementTarget = null;
20043                this.trigger("view:ready", {
20044                    view: this
20045                });
20046            } else {
20047                //SCF.log.debug("Attaching replacementTarget: %s", this.cid);
20048                this._replacementTarget = replacedElement;
20049            }
20050        },
20051        render: function() {
20052            if (this._destroyed) {
20053                return;
20054            }
20055            var that = this;
20056            if (!(this._modelReady || this.model._isReady) || (this.requiresSession && !this._sessionReady)) {
20057                /*
20058                if (!(this._modelReady || this.model._isReady)) {
20059                    SCF.log.debug("Skipping render due to Model not ready %s : %s", this.cid, this.model.attributes.resourceType);
20060                }
20061                if (this.requiresSession && !this._sessionReady) {
20062                    SCF.log.debug("Skipping render due to Session not ready %s : %s", this.cid, this.model.attributes.resourceType);
20063                }
20064                */
20065                return this;
20066            }
20067            //SCF.log.debug("Rendering %s : %s", this.cid, this.model.attributes.resourceType);
20068            this.unbindDataFields();
20069            for (var viewName in this._childViews) {
20070                this._childViews[viewName].destroy();
20071                delete this._childViews[viewName];
20072            }
20073            this._renderedChildren = [];
20074            var element = $CQ(this.template(this.getContextForTemplate(), {
20075                data: {
20076                    parentView: this
20077                }
20078            }));
20079            //Check if its attached to DOM or rendered
20080            if (this._rendered || this.$el.parent().length > 0) {
20081                this.$el.html(element.html());
20082            } else {
20083                this.setElement(element);
20084            }
20085            //render children
20086            _.each(this._childViews, function(child) {
20087                that.renderChildView(child);
20088            });
20089
20090            var finishRendering = _.bind(function() {
20091                this.bindView();
20092                this._rendered = true;
20093                if (this.afterRender) {
20094                    this.afterRender();
20095                }
20096                this.trigger("view:rendered", {
20097                    view: this
20098                });
20099
20100            }, this);
20101            //wait for children to finish rendering and then complete binding the view
20102            $CQ.when(this._renderedChildren).done(finishRendering);
20103            if (this._replacementTarget !== null) {
20104                this.replaceElement(this._replacementTarget);
20105            }
20106            return this;
20107        },
20108        bindView: function() {
20109            var that = this;
20110            this.unbindDataFields();
20111            this.$("[evt]").not(this.$("[data-scf-component] [evt]")).each(function(idx, trigger) {
20112                SCF.View.bindEvents(that, $CQ(trigger));
20113            });
20114            this.$("[data-attrib]").not(this.$("[data-scf-component] [data-attrib]")).each(function(idx, element) {
20115                SCF.View.bindDataFields(that, $CQ(element));
20116            });
20117            this.$("[data-form]").not(this.$("[data-scf-component] [data-form]")).each(function(idx, element) {
20118                SCF.View.bindDataForms(that, $CQ(element));
20119            });
20120        },
20121        addChildView: function(childView) {
20122            //SCF.log.debug("Adding Child View: %s", childView.cid);
20123            this._childViews[childView.cid] = childView;
20124            var deferred = $CQ.Deferred();
20125            this._renderedChildren[childView.cid] = deferred.promise();
20126            this.listenTo(childView, "view:rendered", function() {
20127                deferred.resolve();
20128            });
20129            this.listenTo(childView, "view:destroyed", function(event) {
20130                //SCF.log.debug("Parent getting destory command for child view: %s", event.view.cid);
20131                this.removeChildView(event.view.cid);
20132            });
20133            return this;
20134        },
20135        getChildView: function(childViewID) {
20136            return this._childViews[childViewID];
20137        },
20138        removeChildView: function(childViewID) {
20139            if (this._renderedChildren.hasOwnProperty(childViewID)) {
20140                this._renderedChildren[childViewID].fail();
20141            }
20142            if (this._childViews.hasOwnProperty(childViewID)) {
20143                var childView = this._childViews[childViewID];
20144                childView.stopListening();
20145                this.stopListening(childView, "view:rendered");
20146                this._childViews[childViewID] = undefined;
20147                delete this._childViews[childViewID];
20148            }
20149            return this;
20150        },
20151        getChildViews: function() {
20152            return this._childViews;
20153        },
20154        setParent: function(parentView) {
20155            this._parentView = parentView;
20156            parentView.addChildView(this);
20157            return this;
20158        },
20159        renderChildView: function(view) {
20160            //SCF.log.debug("Rendering child view: %s", view.cid);
20161            view.render();
20162            var parent = this;
20163            if (parent.el === null) {
20164                return;
20165            }
20166            var el = null;
20167            var currentNode = null;
20168            var targetView = new RegExp("\s*?data-view='" + view.cid + "'");
20169            if (document.createNodeIterator && NodeFilter && NodeFilter.SHOW_COMMENT) {
20170                var iter = document.createNodeIterator(parent.el, NodeFilter.SHOW_COMMENT,
20171                    function(node) {
20172                        if (node.data.match(targetView)) {
20173                            return NodeFilter.FILTER_ACCEPT;
20174                        }
20175                    },
20176                    false
20177                );
20178                currentNode = iter.nextNode();
20179                while (currentNode !== null) {
20180                    el = currentNode;
20181                    currentNode = iter.nextNode();
20182                    break;
20183                }
20184                view.replaceElement(el);
20185            } else {
20186                el = deepCommentSearch(parent.el, targetView);
20187                view.replaceElement(el);
20188            }
20189        },
20190        getField: function(field) {
20191            var element = this._fields[field];
20192            if (element) {
20193                return element.val();
20194            }
20195            return "";
20196        },
20197        setField: function(field, data) {
20198            var element = this._fields[field];
20199            if (!element) {
20200                return;
20201            }
20202            element.val(data);
20203        },
20204        focus: function(field) {
20205            var element = this._fields[field];
20206            if (!element) {
20207                return;
20208            }
20209            element.focus();
20210        },
20211        getForm: function(form) {
20212            if (typeof this._forms === 'undefined') {
20213                return null;
20214            } else {
20215                return this._forms[form];
20216            }
20217        },
20218        destroy: function() {
20219            this.undelegateEvents();
20220            this.unbindDataFields();
20221            this.stopListening();
20222            this.trigger("view:destroyed", {
20223                view: this
20224            });
20225            this._destroyed = true;
20226            //SCF.log.debug("DESTORYING %s : %s", this.cid, this.model.attributes.resourceType);
20227        },
20228        unbindDataFields: function() {
20229            for (var prop in this._fields) {
20230                if (this._fields.hasOwnProperty(prop)) {
20231                    if (_.isFunction(this._fields[prop].destroy)) {
20232                        this._fields[prop].destroy();
20233                    }
20234                }
20235            }
20236            this._fields = {};
20237        },
20238        log: _logger
20239    });
20240    SCF.View.extend = function() {
20241        var child = Backbone.View.extend.apply(this, arguments);
20242        var viewName = arguments[0].viewName;
20243        SCF.Views[viewName] = child;
20244        return child;
20245    };
20246
20247    SCF.Model = Backbone.Model.extend({
20248        _cachedModels: {},
20249        _hasLoadedChildren: false,
20250        parse: function(response) {
20251            this._parseRelations(response);
20252            return response;
20253        },
20254        addEncoding: function(data) {
20255            if ((window.FormData) && (data instanceof window.FormData)) {
20256                data.append("_charset_", "UTF-8");
20257            }
20258            if (!data.hasOwnProperty("_charset_")) {
20259                data._charset_ = "UTF-8";
20260            }
20261            return data;
20262        },
20263        reload: function(callback) {
20264            this._isReady = false;
20265            var url = "";
20266            var urlFn;
20267            if (_.isFunction(this.url)) {
20268                //Need to do this since model.clear will clear the id that is used to construct the url
20269                url = this.url();
20270                urlFn = this.url;
20271            } else {
20272                //seen code that sets the param as a hardcoded string
20273                url = this.url;
20274            }
20275            this.clear();
20276            //This.clear clears the id resulting in bad URL so setting the URL for fetch to happen
20277            if (!_.isEmpty(url)) {
20278                this.url = url;
20279            }
20280            var that = this;
20281            this.fetch({
20282                dataType: "json",
20283                cache: false,
20284                xhrFields: {
20285                    withCredentials: true
20286                },
20287                error: function(model, response) {
20288                    SCF.log.error("Error fetching model");
20289                    SCF.log.error(response);
20290                    model.clear();
20291                    model._isReady = true;
20292                    model.trigger("model:loaded", model);
20293                    if (callback && typeof(callback.error) === "function") {
20294                        callback.error();
20295                    }
20296                },
20297                success: function(model) {
20298                    if (urlFn !== undefined) {
20299                        //resetting the url back to function
20300                        model.url = urlFn;
20301                    }
20302                    model._isReady = true;
20303                    model.trigger("model:loaded", model);
20304                    if (callback && typeof(callback.success) === "function") {
20305                        callback.success();
20306                    }
20307                }
20308            });
20309        },
20310        reset: function(attributes, options) {
20311            this.clear().set(_.clone(this.defaults));
20312            var attr = this._parseRelations(attributes);
20313            this.set(attr, options);
20314            return this;
20315        },
20316        initialize: function(attributes) {
20317            this.listenTo(SCF.Session, "logout:success", function() {
20318                this.reload();
20319            });
20320            this.listenTo(SCF.Session, "login:success", function() {
20321                this.reload();
20322            });
20323        },
20324        constructor: function(attributes, options) {
20325            if(typeof(attributes) !== "object") {
20326                attributes = JSON.parse(attributes);
20327            }
20328            var attr = this._parseRelations(attributes);
20329            Backbone.Model.apply(this, [attr, options]);
20330        },
20331        url: function() {
20332            var u;
20333            if (this.urlRoot) {
20334                u = this.urlRoot + this.id + SCF.constants.URL_EXT;
20335            } else if (SCF.config.urlRoot) {
20336                u = SCF.config.urlRoot + this.id + SCF.constants.URL_EXT;
20337            } else {
20338                u = this.id + SCF.constants.URL_EXT;
20339            }
20340            return u;
20341        },
20342        _parseRelations: function(attributes) {
20343            if(typeof(attributes) !== "object") {
20344                attributes = JSON.parse(attributes);
20345            }
20346            var makeRelation = _.bind(function(data, key) {
20347                if (!attributes[key] && !data.path) {
20348                    attributes[key] = [];
20349                }
20350                if (attributes[key] || data.path) {
20351                    var relative = attributes[key];
20352                    var ModelKlass, model;
20353                    if (_.isArray(relative)) {
20354                        var modelArray = [],
20355                            idArray = [];
20356                        _.each(relative, function(rel) {
20357                            if (_.isObject(rel)) {
20358                                ModelKlass = !_.isUndefined(SCF.Models[data.model]) ? SCF.Models[data.model] : SCF.Components[rel.resourceType].Model;
20359                                model = ModelKlass.findLocal(rel.id);
20360                                if (!model) {
20361                                    model = ModelKlass.createLocally(rel);
20362                                } else {
20363                                    model.reset(rel);
20364                                }
20365                                modelArray.push(model);
20366                            } else if (!_.isEmpty(rel)) {
20367                                var idFromUrl = rel.substr(SCF.config.urlRoot.length);
20368                                idFromUrl = idFromUrl.substr(0, idFromUrl.lastIndexOf(SCF.constants.URL_EXT));
20369                                ModelKlass = SCF.Models[data.model];
20370                                model = ModelKlass.findLocal("idFromUrl");
20371                                if (!model) {
20372                                    model = data.autofetch ? ModelKlass.find(idFromUrl) : new ModelKlass({
20373                                        url: rel
20374                                    });
20375                                }
20376                                ModelKlass.prototype._cachedModels[idFromUrl] = model;
20377                                modelArray.push(model);
20378                            }
20379                        });
20380                        var CollectionKlass = SCF.Collections[data.collection] || Backbone.Collection;
20381                        var collection = new CollectionKlass();
20382                        collection.model = ModelKlass;
20383                        collection.parent = this;
20384                        collection.set(modelArray, {
20385                            silent: true
20386                        });
20387                        attributes[key] = collection;
20388                    } else if (_.isObject(relative)) {
20389                        if (_.isUndefined(SCF.Models[data.model]) && _.isUndefined(SCF.Components[relative.resourceType])) {
20390                            this.log.error("A relation key %s requested model %s but it is not available nor is the component type: %s", key, data.model, relative.resourceType);
20391                            return;
20392                        }
20393                        ModelKlass = SCF.Models[data.model] || SCF.Components[relative.resourceType].Model;
20394                        model = ModelKlass.findLocal(relative.id) || ModelKlass.createLocally(relative);
20395                        attributes[key] = model;
20396                    } else {
20397                        var url = relative;
20398                        if (!url) {
20399                            if (data.path) {
20400                                if (data.path.substr(0, 1) === "/") {
20401                                    url = data.path;
20402                                } else {
20403                                    url = SCF.config.urlRoot + attributes.id + "/" + data.path + SCF.constants.URL_EXT;
20404                                }
20405                            } else {
20406                                return;
20407                            }
20408                        }
20409                        ModelKlass = SCF.Models[data.model];
20410                        if (data.autofetch) {
20411                            model = ModelKlass.find(url, undefined, true);
20412                        } else {
20413                            model = ModelKlass.findLocal(url, true) || new ModelKlass({
20414                                "url": url
20415                            });
20416                        }
20417                        attributes[key] = model;
20418                    }
20419                }
20420            }, this);
20421            _.each(this.relationships, makeRelation);
20422            return attributes;
20423        },
20424        toJSON: function() {
20425            var json = Backbone.Model.prototype.toJSON.apply(this);
20426            _.each(this.relationships, function(config, relation) {
20427
20428                var relative = json[relation];
20429                if (relative.length <= 0) {
20430                    delete json[relation];
20431                    return;
20432                }
20433                if (_.isArray(relative)) {
20434                    var jsonArray = [];
20435                    _.each(relative, function(rel) {
20436                        if (rel instanceof Backbone.Model)
20437                            jsonArray.push(rel.toJSON());
20438                        else
20439                            jsonArray.push(rel);
20440                    });
20441                    json[relation] = jsonArray;
20442                } else if (relative instanceof Backbone.Collection) {
20443                    json[relation] = relative.toJSON();
20444                } else if (relative instanceof Backbone.Model) {
20445                    json[relation] = relative.toJSON();
20446                }
20447
20448            });
20449            return json;
20450        },
20451        log: _logger
20452    });
20453    SCF.Model.extend = function() {
20454        var child = Backbone.Model.extend.apply(this, arguments);
20455        var modelName = arguments[0].modelName;
20456        SCF.Models[modelName] = child;
20457        return child;
20458    };
20459    SCF.View.bindEvents = function(view, eventTrigger) {
20460        var eventString = eventTrigger.attr("evt");
20461        _.each(eventString.split(","), function(value) {
20462            var parts = value.split("=");
20463            var evt = $CQ.trim(parts[0]);
20464            var func = $CQ.trim(parts[1]);
20465            if (view[func]) {
20466                var eventHandler = _.bind(view[func], view);
20467                eventTrigger.off(evt);
20468                eventTrigger.on(evt, eventHandler);
20469            }
20470        });
20471    };
20472    SCF.View.bindDataFields = function(view, element) {
20473        var field = element.attr("data-attrib");
20474        if (!view._fields) {
20475            view._fields = {};
20476        }
20477        if (!_.isUndefined(view._fields[field])) {
20478            return;
20479        }
20480        var fieldType = element.attr("data-field-type");
20481        var ManagerKlass = (_.isUndefined(SCF.fieldManagers[fieldType])) ? DefaultFieldType : SCF.fieldManagers[fieldType];
20482        var manager = new ManagerKlass(element, {}, view.model);
20483        view._fields[field] = (function() {
20484            return {
20485                val: function() {
20486                    if (arguments.length === 0)
20487                        return manager.getValue();
20488                    else
20489                        return manager.setValue(arguments[0]);
20490                },
20491                focus: function() {
20492                    return manager.focus();
20493                },
20494                destroy: function() {
20495                    if (_.isFunction(manager.destroy)) {
20496                        manager.destroy();
20497                    }
20498                }
20499            };
20500        })();
20501    };
20502    SCF.View.bindDataForms = function(view, element) {
20503        var form = element.attr("data-form");
20504        if (!view._forms) {
20505            view._forms = {};
20506        }
20507        view._forms[form] = new SCFValidator($(element), false);
20508    };
20509    SCF.Model.findLocal = function(mid, isUrl) {
20510        var id = isUrl ? mid.substr(SCF.config.urlRoot.length) : mid;
20511        if (this.prototype._cachedModels && this.prototype._cachedModels[id]) {
20512            return this.prototype._cachedModels[id];
20513        }
20514    };
20515    SCF.Model.createLocally = function(attributes) {
20516        var modelObj = new this.prototype.constructor(attributes);
20517        modelObj._isReady = true;
20518        this.prototype._cachedModels[modelObj.get("id")] = modelObj;
20519        return modelObj;
20520    };
20521    SCF.Model.prototype.load = function(mid) {
20522        if (mid) {
20523            this.set({
20524                "id": mid
20525            }, {
20526                silent: true
20527            });
20528        }
20529        this.fetch({
20530            success: function(model) {
20531                model._isReady = true;
20532                model.trigger("model:loaded", model);
20533            },
20534            xhrFields: {
20535                withCredentials: true
20536            }
20537        });
20538    };
20539    SCF.Model.prototype.getConfigValue = function(key) {
20540        var config = this.get("configuration");
20541        if (!_.isEmpty(config)) {
20542            return config[key];
20543        }
20544        return null;
20545    };
20546    SCF.Model.prototype.destroy = function(options) {
20547        var model = this;
20548        this.constructor.prototype._cachedModels[model.get("id")] = undefined;
20549        model.trigger("destroy", model, model.collection, options);
20550    };
20551
20552    SCF.Model.prototype.parseServerError = function(jqxhr, text, error) {
20553        var errorDetails = $CQ.parseJSON(jqxhr.responseText);
20554        if (errorDetails.hasOwnProperty("status.code")) {
20555            errorDetails.status = errorDetails.status || {};
20556            errorDetails.status.code = errorDetails["status.code"];
20557            delete errorDetails["status.code"];
20558        }
20559        if (errorDetails.hasOwnProperty("status.message")) {
20560            errorDetails.status = errorDetails.status || {};
20561            errorDetails.status.message = errorDetails["status.message"];
20562            delete errorDetails["status.message"];
20563        }
20564        return {
20565            "error": error,
20566            "details": errorDetails
20567        };
20568    };
20569
20570    SCF.Model.find = function(mid, callback, isUrl) {
20571        var that = this;
20572        if (this.prototype._cachedModels && this.prototype._cachedModels[mid]) {
20573            var model = this.prototype._cachedModels[mid];
20574            if (_.isFunction(callback)) {
20575                callback(model);
20576            }
20577            return model;
20578        } else {
20579            var newModel = new this.prototype.constructor({
20580                id: mid
20581            });
20582            if (isUrl) {
20583                newModel.url = mid;
20584            }
20585            //TODO figure out caching mechanism
20586            this.prototype._cachedModels[mid] = newModel;
20587            newModel.fetch({
20588                dataType: "json",
20589                xhrFields: {
20590                    withCredentials: true
20591                },
20592                error: function(model, response) {
20593                    if (response.status === 204 || response.status === 404) {
20594                        SCF.log.debug("non existing resource");
20595                        model._isReady = true;
20596                        model.trigger("model:loaded", model);
20597                        if (_.isFunction(callback)) {
20598                            callback(model);
20599                        }
20600                    } else {
20601                        SCF.log.error("Error fetching model");
20602                        SCF.log.error(response);
20603                        that.prototype._cachedModels[mid] = undefined;
20604                    }
20605
20606                },
20607                success: function(model) {
20608                    model._isReady = true;
20609                    model.trigger("model:loaded", model);
20610                    if (_.isFunction(callback)) {
20611                        callback(model);
20612                    }
20613                }
20614            });
20615            return newModel;
20616        }
20617    };
20618    SCF.Collection = Backbone.Collection.extend({});
20619    SCF.Collection.extend = function() {
20620        var child = Backbone.Collection.extend.apply(this, arguments);
20621        var collectioName = arguments[0].collectioName;
20622        SCF.Collections[collectioName] = child;
20623        return child;
20624    };
20625
20626    SCF.registerComponent = function(componentName, modelKlass, viewKlass) {
20627        SCF.Components[componentName] = {
20628            Model: modelKlass,
20629            View: viewKlass,
20630            name: componentName
20631        };
20632    };
20633
20634    SCF.addLoadedComponent = function(resourceType, model, view) {
20635        if (!SCF.Components[resourceType]) {
20636            return;
20637        }
20638        if (!SCF.loadedComponents[resourceType]) {
20639            SCF.loadedComponents[resourceType] = {};
20640        }
20641        SCF.loadedComponents[resourceType][model.id] = {
20642            "model": model,
20643            "view": view
20644        };
20645        return SCF.loadedComponents[resourceType][model.id];
20646    };
20647    SCF.findTemplate = function(resourceId, templateName, resourceType) {
20648        if (arguments.length == 2) {
20649            resourceType = templateName;
20650            templateName = "";
20651        }
20652        var templateKey = resourceType + "/" + templateName;
20653        if (SCF.templates[templateKey]) {
20654            return SCF.templates[templateKey];
20655        }
20656        var template;
20657        $CQ.ajax({
20658            async: false,
20659            // xhrFields: {
20660            //  withCredentials: true
20661            // },
20662            url: SCF.config.urlRoot + "/services/social/templates" + "?resourceType=" + resourceType + "&ext=hbs&selector=" + templateName
20663        }).done(function(data, status) {
20664            if (status == "success") {
20665                template = Handlebars.compile(data);
20666                SCF.templates[templateKey] = template;
20667            }
20668        });
20669        return template;
20670    };
20671
20672    SCF.log = _logger;
20673
20674    SCF.registerFieldType = function(fieldType, fieldTypeManager) {
20675        if (!(_.isFunction(fieldTypeManager.prototype.setValue))) {
20676            this.log.error("%s does not implement required method, \"setValue\"", fieldType);
20677            return;
20678        }
20679        if (!(_.isFunction(fieldTypeManager.prototype.getValue))) {
20680            this.log.error("%s does not implement required method, \"getValue\"", fieldType);
20681            return;
20682        }
20683        if (!(_.isFunction(fieldTypeManager.prototype.focus))) {
20684            this.log.error("%s does not implement required method, \"focus\"", fieldType);
20685            return;
20686        }
20687        if (!(_.isFunction(fieldTypeManager.prototype.destroy))) {
20688            this.log.error("%s does not implement required method, \"destroy\"", fieldType);
20689            return;
20690        }
20691        this.fieldManagers[fieldType] = fieldTypeManager;
20692    };
20693
20694    var DefaultFieldType = function(element, config, model) {
20695        this.$el = element;
20696    };
20697
20698    DefaultFieldType.prototype.setValue = function(val) {
20699        return this.$el.val(val);
20700    };
20701    DefaultFieldType.prototype.getValue = function() {
20702        return this.$el.val();
20703    };
20704    DefaultFieldType.prototype.focus = function() {
20705        this.$el.focus();
20706    };
20707    DefaultFieldType.prototype.destroy = function() {};
20708
20709    SCF.View.prototype.launchModal = function(element, header, closeCallBack) {
20710        var modalScreen = $CQ("<div class=\"scf scf-modal-screen\"></div>");
20711        var modalDialog = $CQ("<div class=\"scf scf-modal-dialog\" style=\"display:none;\">" +
20712            "<h2 class=\"scf-modal-header\">" + header +
20713            "</h2><div class=\"scf-modal-close\" tabindex=\"0\" role=\"button\" aria-pressed=\"false\">X</div></div>");
20714        var el = element;
20715        var parent = el.parent();
20716        modalDialog.append(el);
20717        el.show();
20718        var close = function(e) {
20719            if (SCF.Util.mayCall(e, "preventDefault")) {
20720                e.preventDefault();
20721            }
20722            el.hide();
20723            parent.append(el);
20724            modalScreen.remove();
20725            modalDialog.remove();
20726            if (_.isFunction(closeCallBack)) {
20727                closeCallBack();
20728            }
20729        };
20730
20731        var closeByEnter = function(e) {
20732            if(e.which == 13) {
20733                if (SCF.Util.mayCall(e, "preventDefault")) {
20734                    e.preventDefault();
20735                }
20736                el.hide();
20737                parent.append(el);
20738                modalScreen.remove();
20739                modalDialog.remove();
20740                if (_.isFunction(closeCallBack)) {
20741                    closeCallBack();
20742                }
20743            }
20744        };
20745
20746        modalDialog.find(".scf-modal-close").keypress(closeByEnter);
20747        modalDialog.find(".scf-modal-close").click(close);
20748        modalDialog.find(".scf-js-modal-close").click(close);
20749
20750        $CQ("body").append(modalScreen);
20751        $CQ("body").append(modalDialog);
20752        var width = (window.innerWidth - modalDialog.innerWidth()) / 2;
20753        var height = (window.innerHeight - modalDialog.innerHeight()) / 2;
20754        modalDialog.css({
20755            "top": height,
20756            "left": width
20757        });
20758        modalDialog.show();
20759        SCF.Util.addTabbingInDialog(modalDialog) ;
20760        return close;
20761    };
20762
20763    SCF.View.prototype.overlayTemplate = "<div class=\"scf-overlay\">" +
20764        "<div class=\"scf-overlay-header btn-toolbar\">" +
20765        "<button class=\"btn btn-primary scf-ovelay-back-button\" title=\"{{i18n \"Back\"}}\">" +
20766        "<span class=\"scf-icon-left\"></span>" +
20767        "</button>" +
20768        "<h3>{{header}}</h3>" +
20769        "</div>" +
20770        "</div>";
20771    SCF.View.prototype.loadOverlay = function(element, parent, header, closeCallback) {
20772        var template = Handlebars.compile(this.overlayTemplate);
20773        var overlay = $CQ(template({
20774            'header': header
20775        }));
20776        var close = function() {
20777            overlay.remove();
20778            parent.find(".scf-is-overlay-hidden").each(function() {
20779                $CQ(this).removeClass("scf-is-overlay-hidden");
20780            });
20781            if (closeCallback && _.isFunction(closeCallBack)) {
20782                closeCallBack();
20783            }
20784        };
20785        parent.children().each(function() {
20786            $CQ(this).addClass("scf-is-overlay-hidden");
20787        });
20788        overlay.append(element);
20789        parent.append(overlay);
20790        overlay.find(".scf-ovelay-back-button").click(close);
20791        return close;
20792    };
20793    SCF.View.prototype.errorTemplate = "<h3>{{details.status.message}}</h3>";
20794    SCF.View.prototype.addErrorMessage = function(element, error) {
20795        var template = Handlebars.compile(this.errorTemplate);
20796        var $el = $CQ(element);
20797        var $errorElement = $CQ(template(error));
20798        $errorElement.addClass("scf-js-error-message");
20799        $el.before($errorElement);
20800    };
20801    SCF.View.prototype.compileTemplate = function(hbsMarkup) {
20802        return Handlebars.compile(hbsMarkup);
20803    };
20804    SCF.View.prototype.clearErrorMessages = function(element, error) {
20805        this.$el.find(".scf-js-error-message").remove();
20806        this.$el.find(".scf-error").removeClass("scf-error");
20807    };
20808
20809    SCF.ChildView = SCF.View.extend({
20810        bindView: function() {},
20811        bindDataForms: function() {},
20812        bindDataFields: function() {},
20813        bindEvents: function() {},
20814        viewName: "ChildView"
20815    });
20816
20817    SCF.Util = {
20818        // Allows you to pass in an object and see if the funcName is avaiable ot be called,
20819        // this only does a shallow check for now.
20820        "mayCall": function(obj, funcName) {
20821            if (_.isUndefined(obj) || _.isNull(obj)) {
20822                return false;
20823            }
20824            return (obj.hasOwnProperty(funcName) || obj[funcName] !== null) && _.isFunction(obj[funcName]);
20825        },
20826        "announce": function(channel, data) {
20827            $CQ(document).trigger(channel, data);
20828        },
20829        "listenTo": function(channel, listener) {
20830            $CQ(document).on(channel, function(e, data) {
20831                listener(data);
20832                e.stopImmediatePropagation();
20833            });
20834        },
20835        "startsWith": function(sourceString, searchString) {
20836            return sourceString.substr(0, searchString.length) === searchString;
20837        },
20838        "getContextPath": function() {
20839            var URL = CQ.shared.HTTP.getPath();
20840            var pageExtension = CQ.shared.HTTP.getExtension();
20841            var urlSplit = URL.split(pageExtension);
20842            if (urlSplit && urlSplit !== undefined) {
20843                if (urlSplit.length > 1) {
20844                    return urlSplit[1];
20845                } else {
20846                    return urlSplit[0];
20847                }
20848            }
20849            return "";
20850        },
20851        "addTabbingInDialog": function(e) {
20852            var inputs = e.find('select, input, textarea, button, a,div').filter(':visible');
20853            var firstInput = inputs.first();
20854            var lastInput = inputs.last();
20855            firstInput.focus();
20856            lastInput.on('keydown', function(e) {
20857                if ((e.which === 9 && !e.shiftKey)) {
20858                    e.preventDefault();
20859                    firstInput.focus();
20860                }
20861            });
20862            /*redirect first shift+tab to last input*/
20863            firstInput.on('keydown', function(e) {
20864                if ((e.which === 9 && e.shiftKey)) {
20865                    e.preventDefault();
20866                    lastInput.focus();
20867                }
20868            });
20869            return close;
20870        }
20871    };
20872    window.SCF = SCF;
20873
20874})(Backbone, $CQ, _, Handlebars);
20875
20876/*
20877 *
20878 * ADOBE CONFIDENTIAL
20879 * __________________
20880 *
20881 *  Copyright 2012 Adobe Systems Incorporated
20882 *  All Rights Reserved.
20883 *
20884 * NOTICE:  All information contained herein is, and remains
20885 * the property of Adobe Systems Incorporated and its suppliers,
20886 * if any.  The intellectual and technical concepts contained
20887 * herein are proprietary to Adobe Systems Incorporated and its
20888 * suppliers and are protected by trade secret or copyright law.
20889 * Dissemination of this information or reproduction of this material
20890 * is strictly forbidden unless prior written permission is obtained
20891 * from Adobe Systems Incorporated.
20892 */
20893(function(Handlebars, moment, SCF, $CQ, _, CQ) {
20894    "use strict";
20895
20896    var slingInclude = function(path, templateName, resourceType) {
20897        var html = "";
20898        var params = {
20899            resourcePath: path
20900        };
20901        if (resourceType) {
20902            SCF.log.warn("Forcing resource type is not supported when sling including on the client side");
20903        }
20904        if (templateName) {
20905            params.selector = templateName;
20906        }
20907        var urlToFetch = SCF.config.urlRoot + path;
20908        urlToFetch += templateName ? "." + templateName + ".html" : ".html";
20909        $CQ.ajax({
20910            async: false,
20911            // xhrFields: {
20912            //  withCredentials: true
20913            // },
20914            url: urlToFetch
20915        }).done(function(data, status) {
20916            if (status == "success") {
20917                html = data;
20918            }
20919        });
20920        return new Handlebars.SafeString(html);
20921    };
20922    Handlebars.registerHelper("include", function(context, options) {
20923
20924
20925        if (arguments.length === 1) {
20926            options = context;
20927            context = undefined;
20928        }
20929        var parentView = options.data.parentView;
20930        var getModelName = function(viewName) {
20931            if (!viewName) {
20932                return undefined;
20933            }
20934            var idx = viewName.lastIndexOf("View");
20935            if (idx !== -1) {
20936                return viewName.substr(0, idx) + "Model";
20937            } else {
20938                return viewName + "Model";
20939            }
20940        };
20941        var bindModelView = _.isUndefined(options.hash.bind) ? true : options.hash.bind;
20942        var viewName = options.hash.view;
20943        var templateName = options.hash.template;
20944        var resourceType = options.hash.resourceType;
20945        var path = options.hash.path;
20946        var modelName = options.hash.model || getModelName(viewName);
20947        var viewObj, modelObj, ViewKlass, ModelKlass, id, component;
20948
20949
20950        if (_.isObject(context)) {
20951            resourceType = resourceType || context.resourceType;
20952            component = SCF.Components[resourceType];
20953            if ((_.isUndefined(component)) && (resourceType.match(/^(\/apps)|(\/libs)/))) {
20954                var baseType = resourceType.substring(6);
20955                component = SCF.Components[baseType];
20956            }
20957            var cTemplate;
20958
20959            id = context.id;
20960            if (!id) {
20961                var url = context.url;
20962                if (!url) {
20963                    SCF.log.warn("No resource id found for context: ");
20964                    SCF.log.warn(context);
20965                }
20966                var idFromUrl = url.substr(SCF.config.urlRoot.length);
20967                idFromUrl = idFromUrl.substr(0, idFromUrl.lastIndexOf(SCF.constants.URL_EXT));
20968                id = idFromUrl;
20969            }
20970
20971            if (templateName) {
20972                cTemplate = SCF.findTemplate(id, templateName, resourceType);
20973            } else {
20974                cTemplate = SCF.findTemplate(id, resourceType);
20975            }
20976
20977            var getViewKlass = function() {
20978                //use an SCF.ChildView if the template being included belongs to the same component and rendering the same resource
20979                if (parentView.model.get("resourceType") === resourceType && parentView.model.id === id) {
20980                    return SCF.ChildView;
20981                }
20982                return component ? component.View : undefined;
20983            };
20984
20985            ViewKlass = viewName ? SCF.Views[viewName] : getViewKlass();
20986            ViewKlass = bindModelView ? ViewKlass : undefined;
20987            ModelKlass = modelName ? SCF.Models[modelName] : component ? component.Model : undefined;
20988            ModelKlass = bindModelView ? ModelKlass : undefined;
20989
20990            if (!ViewKlass && !cTemplate) {
20991                if (id) {
20992                    return slingInclude(id, templateName, resourceType);
20993                }
20994                SCF.log.error("No view or template found for " + resourceType + " and template " + templateName);
20995                return "";
20996            }
20997
20998
20999            if (!ViewKlass && cTemplate) {
21000                return new Handlebars.SafeString(cTemplate(SCF.View.prototype.getMergedContexts(context)));
21001            }
21002
21003
21004            if (ViewKlass && !cTemplate) {
21005                SCF.log.error("No template found for " + resourceType + " and template " + templateName);
21006                return "";
21007            }
21008
21009            if (!ModelKlass || !id) {
21010                viewObj = new ViewKlass({
21011                    "context": context
21012                });
21013            } else {
21014                modelObj = ModelKlass.findLocal(id);
21015                if (!modelObj) {
21016                    modelObj = ModelKlass.createLocally(context);
21017                }
21018                if (modelObj.isNew()) {
21019                    modelObj.load(id);
21020                }
21021                viewObj = new ViewKlass({
21022                    model: modelObj
21023                });
21024
21025            }
21026            if (templateName && cTemplate) {
21027                viewObj.template = cTemplate;
21028            } else if (cTemplate) {
21029                ViewKlass.prototype.template = cTemplate;
21030            }
21031
21032        } else {
21033
21034            var isPathAbsolute = path ? path.slice(0, 1) === "/" : false;
21035            if (!context && !isPathAbsolute) {
21036                SCF.log.error("Must provide context path when including " + resourceType);
21037                return "";
21038            }
21039
21040            id = isPathAbsolute ? path : context + "/" + path;
21041
21042            if (resourceType) {
21043                component = SCF.Components[resourceType];
21044            }
21045            if (bindModelView && (component || (viewName && modelName))) {
21046                ViewKlass = !component ? SCF.Views[viewName] : component.View;
21047                ModelKlass = !component ? SCF.Models[modelName] : component.Model;
21048            }
21049
21050            if (ViewKlass && ModelKlass) {
21051                var isUrl = id.indexOf("http://") === 0;
21052                modelObj = ModelKlass.find(id, undefined, isUrl);
21053                viewObj = new ViewKlass({
21054                    "model": modelObj
21055                });
21056                if (templateName) {
21057                    viewObj.template = SCF.findTemplate(id, templateName, resourceType);
21058                } else if (typeof viewObj.template === "undefined") {
21059                    SCF.log.info("Getting default template for " + resourceType);
21060                    viewObj.template = SCF.findTemplate(id, resourceType, resourceType);
21061                }
21062            } else {
21063                return slingInclude(id, templateName, resourceType);
21064            }
21065        }
21066        viewObj.setParent(parentView);
21067        if (!ViewKlass.prototype.template && viewObj.template && ViewKlass != SCF.ChildView) {
21068            ViewKlass.prototype.template = SCF.findTemplate(modelObj.get("id"), resourceType);
21069
21070        }
21071        viewObj.templateName = templateName || "default";
21072        viewObj.resource = id;
21073        return new Handlebars.SafeString("<!-- data-view='" + viewObj.cid + "'-->");
21074    });
21075
21076    Handlebars.registerHelper("equals", function(lvalue, rvalue, options) {
21077        if (arguments.length < 3)
21078            throw new Error("Handlebars Helper equal needs 2 parameters");
21079        if (lvalue != rvalue) {
21080            return options.inverse(this);
21081        } else {
21082            return options.fn(this);
21083        }
21084    });
21085
21086    Handlebars.registerHelper('lt', function(a, b) {
21087        var next =  arguments[arguments.length - 1];
21088        return (a < b) ? next.fn(this) : next.inverse(this);
21089    });
21090
21091    Handlebars.registerHelper("lastPath", function(context, options) {
21092        var idx = context.lastIndexOf("/");
21093        return context.slice(idx + 1);
21094    });
21095
21096    Handlebars.registerHelper("getComponentName", function(context, options) {
21097        return context.split('/')[1];
21098    });
21099
21100    Handlebars.registerHelper("pretty-time", function(context, options) {
21101        if (!context) {
21102            return "";
21103        }
21104        var time = new Date(context);
21105        var now = new Date();
21106        var diff = now.getTime() - time.getTime();
21107        var second = 1000;
21108        var minute = second * 60;
21109        var hour = minute * 60;
21110        var day = hour * 24;
21111        moment.locale(CQ.shared.I18n.getLocale());
21112        // max days ago before switching to actual date. If not passed in then hardcoding as 60.
21113        var days_cutoff = options.hash.daysCutoff ? options.hash.daysCutoff : 60;
21114        if (diff < minute) {
21115            time = Math.round(diff / second) + "";
21116            if (time == 1) {
21117                return new Handlebars.SafeString(CQ.I18n.get("{0} second ago", time));
21118            }
21119            return new Handlebars.SafeString(CQ.I18n.get("{0} seconds ago", time));
21120        } else if (diff < hour) {
21121            time = Math.round(diff / minute);
21122            if (time == 1) {
21123                return new Handlebars.SafeString(CQ.I18n.get("{0} minute ago", time));
21124            }
21125            return new Handlebars.SafeString(CQ.I18n.get("{0} minutes ago", time));
21126        } else if (diff < day) {
21127            time = Math.round(diff / hour);
21128            if (time == 1) {
21129                return new Handlebars.SafeString(CQ.I18n.get("{0} hour ago", time));
21130            }
21131            return new Handlebars.SafeString(CQ.I18n.get("{0} hours ago", time));
21132        } else if (diff < day * days_cutoff) {
21133            time = Math.round(diff / day);
21134            if (time == 1) {
21135                return new Handlebars.SafeString(CQ.I18n.get("{0} day ago", time));
21136            }
21137            return new Handlebars.SafeString(CQ.I18n.get("{0} days ago", time));
21138        } else {
21139            return new Handlebars.SafeString(moment(time).format(CQ.I18n.get("MMM DD YYYY, h:mm A", null, "moment.js, communities moderation")));
21140        }
21141    });
21142
21143    Handlebars.registerHelper("pages", function(context, options) {
21144        var pageInfo = context;
21145
21146        if (pageInfo.hasOwnProperty("selectedPage") && pageInfo.hasOwnProperty("totalPages") && pageInfo.hasOwnProperty("pageSize") && pageInfo.hasOwnProperty("basePageURL")) {
21147            var output = "";
21148            if (pageInfo.totalPages <= 1) {
21149                return output;
21150            }
21151            var pageSize = Math.abs(pageInfo.pageSize);
21152            var pageSign = (pageInfo.orderReversed) ? "-" : "";
21153            var currentPage = pageInfo.selectedPage;
21154
21155            var leftLimit = currentPage;
21156            if ((leftLimit - 2) > 0 && pageInfo.totalPages > 5) {
21157                leftLimit = leftLimit - 2;
21158            } else if (leftLimit == 2 && pageInfo.totalPages > 5) {
21159                //for  https://jira.corp.adobe.com/browse/NPR-30827
21160                leftLimit = 1;
21161            }
21162
21163            if (pageInfo.totalPages <= 5) {
21164                leftLimit = 1;
21165            } else {
21166                if (pageInfo.totalPages - currentPage < 2) {
21167                    leftLimit = pageInfo.totalPages - 4;
21168                }
21169            }
21170            var rightLimit = leftLimit + 5;
21171            if (rightLimit > pageInfo.totalPages) {
21172                rightLimit = pageInfo.totalPages + 1;
21173            }
21174
21175            for (var i = leftLimit; i < rightLimit; i++) {
21176                pageInfo.pageNumber = i;
21177                pageInfo.currentPageUrl = pageInfo.basePageURL + "." + ((i - 1) * pageSize) + "." + pageSign + pageSize + ".html";
21178                pageInfo.currentPage = i == pageInfo.selectedPage;
21179                pageInfo.suffix = ((i - 1) * pageSize) + "." + pageSign + pageSize;
21180                output += options.fn(pageInfo);
21181            }
21182            return output;
21183        } else {
21184            return "";
21185        }
21186    });
21187
21188    Handlebars.registerHelper("loadmore", function(context, options) {
21189        var pageInfo = context.pageInfo;
21190        var items = context.items;
21191        if (!context.totalSize || !pageInfo) {
21192            return "";
21193        }
21194        if (!(!_.isUndefined(pageInfo.selectedPage) && context.totalSize && pageInfo.pageSize)) {
21195            return "";
21196        }
21197        if (context.totalSize <= 0) {
21198            return "";
21199        }
21200        var info = {};
21201        info.suffix = pageInfo.nextSuffix;
21202        var remaining = this.totalSize;
21203        if (!_.isUndefined(items)) {
21204            remaining = remaining - items.length;
21205        }
21206        if (remaining === 0) {
21207            return "";
21208        }
21209        var url = pageInfo.nextPageURL;
21210        if (!_.isUndefined(url) && url.indexOf(".json", url.length - 5) !== -1) {
21211            url = url.substr(0, url.length - 5);
21212            url += ".html";
21213        }
21214        info.remaining = remaining;
21215        info.moreURL = url;
21216        return options.fn(info);
21217    });
21218
21219    Handlebars.registerHelper("dateUtil", function(context, options) {
21220        var date = context;
21221        var format = options.hash.format;
21222        var timezone = options.hash.timezone;
21223        if (!date || typeof date != "number") {
21224            date = new Date().getTime();
21225        } else {
21226            date = new Date(date);
21227        }
21228        format = format.replace(/y/g, "Y"); // replace java "yyyy" with moment "YYYY"
21229        format = format.replace(/\bdd\b/gi, "DD"); // replace java "dd" with moment "DD"
21230        format = format.replace(/\bd\b/gi, "D"); // replace java "d" with moment "D"
21231        format = format.replace(/\bEEEE\b/gi, "dddd");
21232        moment.locale(CQ.shared.I18n.getLocale());
21233
21234        if (timezone && moment.tz) {
21235            return new Handlebars.SafeString(moment.tz(date, timezone).format(format));
21236        }
21237
21238        return new Handlebars.SafeString(moment(date).format(format));
21239    });
21240
21241    Handlebars.registerHelper("i18n", function(context, options) {
21242        if (arguments.length > 1) {
21243            var i18nArgs = _.rest(arguments);
21244            return CQ.I18n.get(context, i18nArgs);
21245        } else {
21246            return CQ.I18n.get(context);
21247        }
21248    });
21249
21250    Handlebars.registerHelper("xss-htmlAttr", function(context, options) {
21251        //encodeForHTMLAttr
21252        var $div = $CQ("div");
21253        $div.attr("data-xss", context);
21254        var cleaned = $div.attr("data-xss");
21255        return CQ.shared.XSS.getXSSValue(cleaned);
21256        // if (!context) {
21257        //     return "";
21258        // }
21259        // return new Handlebars.SafeString(context.toString().replace(/\./g, '-'));
21260    });
21261    Handlebars.registerHelper("xss-jsString", function(context, options) {
21262        //encodeForJSString
21263        return CQ.shared.XSS.getXSSValue(context);
21264    });
21265    Handlebars.registerHelper("xss-html", function(context, options) {
21266        //encodeForHTML
21267        return $CQ("<div></div>").text(context).html();
21268    });
21269    Handlebars.registerHelper("xss-validHref", function(context, options) {
21270        //getValidHref
21271        return encodeURI(context);
21272    });
21273    Handlebars.registerHelper("dom-id", function(context, options) {
21274        if (!context) {
21275            return "";
21276        }
21277        var domId = $CQ.trim(context);
21278        domId = domId.replace(/\./g, "-");
21279        domId = domId.replace(/\//g, "-");
21280        domId = domId.replace(/:/g, "-");
21281        return domId;
21282    });
21283    Handlebars.registerHelper("abbreviate", function(context, options) {
21284
21285        if (!context) {
21286            return "";
21287        }
21288        var maxWords = options.hash.maxWords;
21289        var maxLength = options.hash.maxLength;
21290        var safeString = options.hash.safeString;
21291        var ctx = $CQ.trim(context);
21292        var initialLength = ctx.length;
21293
21294        var words = ctx.substring(0, maxLength).split(" ");
21295        var abb = words.slice(0, words.length > maxWords ? maxWords : words.length).join(" ");
21296        var abbContent = initialLength != abb.length && options.fn ? options.fn(this) : "";
21297        if (safeString) {
21298            return new Handlebars.SafeString(abb) + abbContent;
21299        }
21300        return abb + abbContent;
21301    });
21302
21303    Handlebars.registerHelper("includeClientLib", function(context, options) {
21304        // This helper only works on the server side.
21305        return "";
21306    });
21307
21308    Handlebars.registerHelper("if-wcm-mode", function(context, options) {
21309        // This helper only works on the server side.
21310        return "";
21311    });
21312
21313    Handlebars.registerHelper("getContextPath", function(context, options) {
21314        var contextPath = "";
21315        if (Granite && Granite.HTTP.getContextPath()) {
21316            contextPath = Granite.HTTP.getContextPath();
21317        }
21318        return contextPath;
21319    });
21320
21321})(Handlebars, moment, SCF, $CQ, _, CQ);
21322
21323/*
21324 *
21325 * ADOBE CONFIDENTIAL
21326 * __________________
21327 *
21328 *  Copyright 2012 Adobe Systems Incorporated
21329 *  All Rights Reserved.
21330 *
21331 * NOTICE:  All information contained herein is, and remains
21332 * the property of Adobe Systems Incorporated and its suppliers,
21333 * if any.  The intellectual and technical concepts contained
21334 * herein are proprietary to Adobe Systems Incorporated and its
21335 * suppliers and are protected by trade secret or copyright law.
21336 * Dissemination of this information or reproduction of this material
21337 * is strictly forbidden unless prior written permission is obtained
21338 * from Adobe Systems Incorporated.
21339 */
21340(function($CQ, SCF, _, CQ, Granite) {
21341    "use strict";
21342    var LoginView = SCF.View.extend({
21343        viewName: "Login",
21344        tagName: "div",
21345        className: "scf-login",
21346        init: function() {
21347            this._isReady = false;
21348            this.listenTo(this.model, this.model.events.LOGGED_IN_SUCCESS, this.render);
21349            this.listenTo(this.model, this.model.events.LOGGED_OUT, this.render);
21350        },
21351        loginAction: function() {
21352            if (this.model.get("loggedIn")) {
21353                this.$el.children(".login-dialog").hide();
21354                this.logout();
21355            } else {
21356                var loginDialog = this.$el.children(".login-dialog").toggle();
21357                loginDialog.find("input:first").focus();
21358            }
21359        },
21360        logout: function() {
21361            this.model.logout();
21362        },
21363        login: function() {
21364            var username = this.getField("username");
21365            var password = this.getField("password");
21366            if (username === "" || password === "") {
21367                return;
21368            }
21369            this.model.login(username, password);
21370        }
21371    });
21372    var LoginModel = SCF.Model.extend({
21373        moderatorCheckAttribute: "moderatorCheck",
21374        events: {
21375            LOGGED_IN_SUCCESS: "login:success",
21376            LOGGED_IN_FAIL: "login:failed",
21377            LOGGED_OUT: "logout:success"
21378        },
21379        initialize: function(attributes, options) {
21380            this._isReady = false;
21381            if (CQ.shared.User.data === undefined || CQ.shared.User.data === null) {
21382                //Dont call the currentuser.json if data is available
21383                this.initUser(options);
21384            } else {
21385                this.getLoggedInUser(options);
21386            }
21387        },
21388        defaults: {
21389            "loggedIn": false
21390        },
21391        isReady: function() {
21392            return this._isReady;
21393        },
21394        checkIfModeratorFor: function(resource) {
21395            var componentList = this.attributes.hasOwnProperty(this.moderatorCheckAttribute) ?
21396                this.attributes[this.moderatorCheckAttribute] : [];
21397            return this.attributes.loggedIn && _.contains(componentList, resource);
21398        },
21399        checkIfUserCanPost: function(resource) {
21400            var componentList = this.attributes.hasOwnProperty("mayPost") ?
21401                this.attributes.mayPost : [];
21402            return this.attributes.loggedIn && _.contains(componentList, resource);
21403        },
21404        setLanguage: function(data) {
21405            var langFromPreferences = data.preferences &&
21406                data.preferences.language ?
21407                data.preferences.language :
21408                "en";
21409            var language = document.documentElement.lang || langFromPreferences;
21410            CQ.shared.I18n.setLocale(language);
21411        },
21412        initUser: function(options) {
21413            var CURRENT_USER_URL = CQ.shared.HTTP.externalize("/libs/granite/security/currentuser" + CQ.shared.HTTP.EXTENSION_JSON + "?props=preferences/language");
21414            CURRENT_USER_URL = CQ.shared.HTTP.noCaching(CURRENT_USER_URL);
21415            var that = this;
21416            $CQ.ajax({
21417                url: CURRENT_USER_URL,
21418                type: "GET",
21419                success: function(result) {
21420                    that.getLoggedInUser(options, result.home);
21421                    that.setLanguage(result);
21422                },
21423                async: false
21424            });
21425        },
21426        getLoggedInUser: function(options, userPath) {
21427            var that = this;
21428            var moderationCheckParameter;
21429            if (options.hasOwnProperty(LoginModel.moderatorCheckAttribute)) {
21430                moderationCheckParameter = "?" + LoginModel.moderatorCheckAttribute + "=";
21431                _.each(options[LoginModel.moderatorCheckAttribute], function(item) {
21432                    moderationCheckParameter += item + ",";
21433                });
21434                moderationCheckParameter = moderationCheckParameter.substring(0, moderationCheckParameter.length - 1);
21435            }
21436            var userHomePath = "";
21437            if (userPath !== undefined) {
21438                userHomePath = userPath;
21439            } else if (CQ.shared.User.initialized) {
21440                userHomePath = CQ.shared.User.data.home;
21441            } else {
21442                // AEM user not initialized force it:
21443                var f = CQ.shared.User.init();
21444                userHomePath = CQ.shared.User.data.home;
21445            }
21446
21447            $CQ.ajax({
21448                url: SCF.config.urlRoot + "/services/social/getLoggedInUser" + moderationCheckParameter + "&h=" + userHomePath,
21449                xhrFields: {
21450                    withCredentials: true
21451                },
21452                type: "GET"
21453            }).done(function(user) {
21454                if (user.name) {
21455                    that.set({
21456                        "loggedIn": true
21457                    });
21458                    that.set(user);
21459                }
21460                that._isReady = true;
21461                if (typeof options !== "undefined" && options.silent) {
21462                    that.trigger("model:loaded", {
21463                        model: that,
21464                        silent: true
21465                    });
21466                } else {
21467                    that.trigger("model:loaded", {
21468                        model: that,
21469                        silent: false
21470                    });
21471                }
21472            });
21473        },
21474        logout: function() {
21475            var that = this;
21476            $CQ.ajax({
21477                url: SCF.config.urlRoot + "/services/social/logout",
21478                xhrFields: {
21479                    withCredentials: true
21480                },
21481                type: "GET"
21482            }).always(function() {
21483                that.clear();
21484                that.trigger(that.events.LOGGED_OUT);
21485            });
21486        },
21487        login: function(username, password) {
21488            var that = this;
21489            $CQ.ajax({
21490                url: SCF.config.urlRoot + "/libs/login.html/j_security_check",
21491                xhrFields: {
21492                    withCredentials: true
21493                },
21494                data: {
21495                    j_username: username,
21496                    j_password: password,
21497                    j_validate: "true"
21498                },
21499                type: "POST"
21500            }).success(function(loginResult, textStatus, jqXHR, id) {
21501                var amIAuthenticated = jqXHR.getResponseHeader("Set-Cookie") 
21501=== null || jqXHR.getResponseHeader("Set-Cookie") !== "";
21502                if (!amIAuthenticated) {
21503                    this.trigger(this.events.LOGGED_IN_FAIL, {
21504                        "user": username
21505                    });
21506                } else {
21507                    that.getLoggedInUser();
21508                    that.trigger(that.events.LOGGED_IN_SUCCESS, {
21509                        "user": username
21510                    });
21511                }
21512            });
21513        }
21514    });
21515    LoginModel.moderatorCheckAttribute = "moderatorCheck";
21516    SCF.LoginView = LoginView;
21517    SCF.LoginModel = LoginModel;
21518
21519    SCF.registerComponent("login", SCF.LoginModel, SCF.LoginView);
21520
21521})($CQ, SCF, _, CQ, Granite);
21522
21523/*
21524 *
21525 * ADOBE CONFIDENTIAL
21526 * __________________
21527 *
21528 *  Copyright 2012 Adobe Systems Incorporated
21529 *  All Rights Reserved.
21530 *
21531 * NOTICE:  All information contained herein is, and remains
21532 * the property of Adobe Systems Incorporated and its suppliers,
21533 * if any.  The intellectual and technical concepts contained
21534 * herein are proprietary to Adobe Systems Incorporated and its
21535 * suppliers and are protected by trade secret or copyright law.
21536 * Dissemination of this information or reproduction of this material
21537 * is strictly forbidden unless prior written permission is obtained
21538 * from Adobe Systems Incorporated.
21539 */
21540//file: bootstrap.js
21541(function(_, $CQ, Backbone, Handlebars, SCF) {
21542    "use strict";
21543    var contextPath = CQ.shared.HTTP.getContextPath();
21544    SCF.events = SCF.events || {};
21545    SCF.events.BOOTSTRAP_REQUEST = "scf-bootstrap-request";
21546
21547    SCF.config.urlRoot = window.location.protocol + "//" + window.location.host;
21548    if (contextPath !== null && contextPath.length > 0) {
21549        SCF.config.urlRoot += contextPath;
21550    }
21551    var addView = function(component) {
21552        var model = component.model;
21553        //If the component type isn't registered do nothing
21554        if (SCF.Components[component.type]) {
21555            var templateUsed = component.template ?
21556                SCF.findTemplate(component.id, component.template, component.type) :
21557                SCF.findTemplate(component.id, component.type);
21558            var view = new SCF.Components[component.type].View({
21559                "model": model,
21560                el: component.el
21561            });
21562            if (component.template) {
21563                view.template = templateUsed;
21564            } else {
21565                SCF.Components[component.type].View.prototype.template = templateUsed;
21566            }
21567            view.templateName = component.template || "default";
21568            view.resource = component.id;
21569            // Bootstrap was not determining parent views at all which broke updates
21570            _.each(SCF.loadedComponents, function(typeObject) {
21571                _.each(typeObject, function(type, id) {
21572                    if (model.attributes.hasOwnProperty("parentId")) {
21573                        if (id === model.attributes.parentId) {
21574                            view.setParent(type.view);
21575                        }
21576                    } else if (view._parentView === undefined || view._parentView === null) {
21577                        // If there isn't a parent ID in the data wire it up via the dom
21578                        // Search for a parent to this el that is an SCF component, meaning it has
21579                        // both and ID and a resource type.
21580                        var $parentEl = view.$el.parents("[data-component-id][data-scf-component]");
21581                        if ($parentEl && $parentEl.length === 1) {
21582                            var domParentId = $parentEl.attr("data-component-id");
21583                            var resourceType = $parentEl.attr("data-scf-component");
21584                            var parentSCFComponentByResource = SCF.loadedComponents[resourceType];
21585                            // Check to make sure a component is registered for this type.
21586                            if (parentSCFComponentByResource !== undefined) {
21587                                var parentSCFComponent = parentSCFComponentByResource[domParentId];
21588                                // Make sure the id is registered and it really does have a view.
21589                                if (parentSCFComponent !== undefined && parentSCFComponent.hasOwnProperty("view")) {
21590                                    view.setParent(parentSCFComponent.view);
21591                                }
21592                            }
21593                        }
21594                    }
21595                });
21596            });
21597            if (model.cacheFixed) {
21598                view.render();
21599            }
21600            component.view = view;
21601        }
21602    };
21603
21604    var addModel = function(component) {
21605        //If the component type isn't registered do nothing
21606        if (SCF.Components[component.type]) {
21607            var model;
21608            var modelHolder = component.modelHolder;
21609            var ModelKlass = SCF.Components[component.type].Model;
21610            if (modelHolder.length > 0) {
21611                var modelText = $CQ(modelHolder[0]).text();
21612                if (modelText === "") {
21613                    modelText = modelHolder[0].text;
21614                }
21615                var modelJSON = $CQ.parseJSON(modelText);
21616                component.id = modelJSON.id;
21617                model = ModelKlass.findLocal(component.id);
21618                if (!model) {
21619                    model = SCF.Components[component.type].Model.createLocally(modelJSON);
21620                }
21621            } else {
21622                model = ModelKlass.findLocal(component.id);
21623                if (!model) {
21624                    // if we didn't find the model load it based on the ID which is the path to the component.
21625                    model = SCF.Components[component.type].Model.find(component.id);
21626                }
21627            }
21628            component.model = model;
21629        }
21630    };
21631
21632    // Creates a component based on the scf ID the resource type and an optional template.
21633    var createComponent = function(id, type, template, $el) {
21634        // Find the json model on the page.
21635        var modelHolder = $CQ("script[type='application/json'][id='" + id + "']");
21636        var component = {
21637            id: id,
21638            type: type,
21639            template: template,
21640            modelHolder: modelHolder,
21641            el: $el
21642        };
21643        var model = addModel(component);
21644        var view = addView(component);
21645        return SCF.addLoadedComponent(type, model, view);
21646    };
21647    // A helper method for inspecting a scf component piece of markup and extract some data from it.
21648    var extractComponentFromElement = function($el) {
21649        var component = {
21650            id: $el.attr("data-component-id"),
21651            type: $el.data("scf-component"),
21652            template: $el.data("scf-template"),
21653            modelHolder: $CQ("script[type='application/json'][id='" + $el.attr("data-component-id") + "']"),
21654            el: $el
21655        };
21656
21657        return component;
21658    };
21659
21660    var fullBootstrap = function() {
21661        var $CQcomponents = $CQ("[data-scf-component]");
21662        var allComponents = [],
21663            componentsToBoostrap = [];
21664        // for each component on the page get the meta data.
21665        $CQcomponents.each(function(idx, el) {
21666            var component = extractComponentFromElement($(el));
21667            if (!SCF.loadedComponents[component.type] || !SCF.loadedComponents[component.type][component.id]) {
21668                componentsToBoostrap.push(component);
21669            }
21670            allComponents.push(component);
21671        });
21672
21673        // If there were components startup the user model. This gives the user model a bit of head start and reduces flicker on the screen.
21674        // Allow newly added components to reinvoke the Session model for all the components to ensure
21675        // The session has alll the component's moderator attributes set correctly. (even thought they
21676        // live at a page level.)
21677        if (componentsToBoostrap.length > 0) {
21678            var options = {};
21679            options.silent = true;
21680            options[SCF.LoginModel.moderatorCheckAttribute] = _.map(allComponents, function(item) {
21681                var dataObj;
21682                if (item.id.indexOf("/content/usergenerated") === -1) {
21683                    // If the component itself isn't in usergenerated then we should check it for moderators
21684                    return item.id;
21685                }
21686                try {
21687                    dataObj = JSON.parse(item.modelHolder.text());
21688                } catch (e) {
21689                    // If the component's data can't be turned in JSON just skip it, something
21690                    // is probably wrong if this is happening.
21691                    return false;
21692                }
21693                if (!(dataObj.hasOwnProperty("sourceComponentId"))) {
21694                    // If the component doesn't have a sourceComponentId then it's not moderatable,
21695                    // any tallies for example.
21696                    return false;
21697                }
21698                if (dataObj.sourceComponentId.indexOf("/content/usergenerated") !== -1) {
21699                    // If the source component is also in user generated then we shouldn't need to check it as the
21700                    // content parent is where configuration for moderation lives.
21701                    return false;
21702                }
21703                return dataObj.sourceComponentId;
21704
21705            });
21706            options[SCF.LoginModel.moderatorCheckAttribute] = _.compact(options[SCF.LoginModel.moderatorCheckAttribute]);
21707            if (SCF.Session) {
21708                SCF.Session.getLoggedInUser(options, undefined);
21709            } else {
21710                var log = new SCF.LoginModel({}, options);
21711                SCF.Session = log;
21712            }
21713        }
21714
21715
21716        _.each(componentsToBoostrap, function(component) {
21717            addModel(component);
21718        });
21719        _.each(componentsToBoostrap, function(component) {
21720            addView(component);
21721            SCF.addLoadedComponent(component.type, component.model, component.view);
21722        });
21723    };
21724
21725    $CQ(document).ready(fullBootstrap);
21726    //Sometimes this script could be loaded multiple times
21727    if (!Backbone.History.started) {
21728        Backbone.history.start({
21729            pushState: true,
21730            hasChange: false
21731        });
21732    }
21733    $(document).on(SCF.events.BOOTSTRAP_REQUEST, fullBootstrap);
21734    SCF.addComponent = function(el) {
21735        var $el = $(el);
21736        if ($el.length === 0) {
21737            throw "Could not find requested element on page.";
21738        }
21739        var component = extractComponentFromElement($el);
21740        if (component === null) {
21741            throw "Component is already loaded.";
21742        }
21743        if (!component.id) {
21744            throw "Component does not have a data-component-id attribute, which is required";
21745        }
21746        if (!component.type) {
21747            throw "Component does not have a data-scf-component attribute, which is required.";
21748        }
21749        return createComponent(component.id, component.type, component.template, component.el);
21750    };
21751
21752    SCF.unloadComponent = function(id, type) {
21753        var typeList = SCF.loadedComponents[type];
21754        if (typeList === null) {
21755            throw "Type " + type + " is not registered with SCF.";
21756        }
21757        var component = SCF.loadedComponents[type][id];
21758        if (component === null || component === undefined) {
21759            throw "Could not find component with ID: " + id;
21760        }
21761        component.view.destroy();
21762        component.model = null;
21763        delete SCF.loadedComponents[type][id];
21764    };
21765})(_, $CQ, Backbone, Handlebars, SCF);
21766
21767/*
21768 *
21769 * ADOBE CONFIDENTIAL
21770 * __________________
21771 *
21772 *  Copyright 2012 Adobe Systems Incorporated
21773 *  All Rights Reserved.
21774 *
21775 * NOTICE:  All information contained herein is, and remains
21776 * the property of Adobe Systems Incorporated and its suppliers,
21777 * if any.  The intellectual and technical concepts contained
21778 * herein are proprietary to Adobe Systems Incorporated and its
21779 * suppliers and are protected by trade secret or copyright law.
21780 * Dissemination of this information or reproduction of this material
21781 * is strictly forbidden unless prior written permission is obtained
21782 * from Adobe Systems Incorporated.
21783 */
21784(function(Backbone, $CQ, _, Handlebars) {
21785    "use strict";
21786
21787    var CKRte = function(element, config, model, view) {
21788        var rteConfig = {};
21789        rteConfig = _.extend(config, rteConfig);
21790        rteConfig = _.extend(this.config, rteConfig);
21791        var el = element.get()[0];
21792        if (_.isUndefined(window.CKEDITOR)) {
21793            SCF.log.error("Rich text editor requested but unable to find CKEDITOR please include client library category: \"%s\" or disable RTE", "ckeditor");
21794            return;
21795        }
21796        this.$el = element;
21797        var height = this.$el.data("editorheight");
21798        var uploadUrl = SCF.config.urlRoot + model.get("id") + SCF.constants.URL_EXT;
21799        var modelConfigAttachmentAllowed = model.get("configuration");
21800        modelConfigAttachmentAllowed = modelConfigAttachmentAllowed && modelConfigAttachmentAllowed.isAttachmentAllowed;
21801
21802
21803        if (rteConfig.extraPlugins === undefined) {
21804            rteConfig.extraPlugins = (window.CKEDITOR.config.extraPlugins) ? window.CKEDITOR.config.extraPlugins +
21805                "," : undefined;
21806        }
21807
21808        // Mentions support
21809        // We have embedded the mentions plugin in ckeditor - so no need to add it as an extra plugin (will be beneficial for performance)
21810        // Just check here if mentions is enabled for the component and then make the necessary configuration for the mentions support
21811        if (model.attributes && model.attributes.configuration && model.attributes.configuration.enableMentions) {
21812
21813            rteConfig.extraAllowedContent = 'a[*]'; // This is to enable hyperlinks to mentioned user's profiles in ckeditor
21814
21815            // This defines how you will see the users in the mentions drop down list
21816            var mentionsDropDownTemplate = '<li data-id="{id}"><img src="{avatarUrl}" alt="{name}">{name}</li>';
21817
21818            // This defines how the mentioned user will look once we select them while writing the post .
21819            // Howeer when viewing the published post/comment mentions user will be dsiplayed as defined by UIMentionsPattern design property for that component
21820            var mentionsOutputTemplate = '<a href = "{friendlyUrl}" class = "social-mention" data-social-mention-authorizableid = "{authorizableId}">{name}</a>';
21821
21822            var minCharsToTriggerMentionsFeed = 4; //should we make this configurable via a design property ? OR would it be an overkill ?
21823
21824            var maxLimitForMentionsDropDown = 20; //same thought ? should we make this configurable via a design property ? OR would it be an overkill ?
21825
21826            rteConfig.mentions = [{feed: function(options, callback) {
21827                        var searchFor = options.query;
21828                        var userListNodePath = model.attributes.sourceComponentId ? model.attributes.sourceComponentId : model.attributes.id;
21829                        var dataUrl = window.location.origin + userListNodePath + '/userlist.social.0.20.json' +
21830                            '?type=users&filter=[{"operation":"CONTAINS","./@rep:principalName":"' +
21831                            searchFor + '"},{"operation":"CONTAINS","./@rep:principalName":"' +
21832                            searchFor + "*" + '"},{"operation":"CONTAINS","profile/@givenName":"' +
21833                            searchFor + "*" + '"},{"operation":"CONTAINS","profile/@familyName":"' +
21834                            searchFor + "*" + '"}]&fromPublisher=true&_charset_=utf-8';
21835                        $.ajax({
21836                            async: false,
21837                            url: Granite.HTTP.externalize(dataUrl),
21838                            type: 'GET',
21839                            success: function(resp) {
21840                                if(resp.items != undefined) {
21841                                    callback(JSON.parse(JSON.stringify(resp.items)));
21842                                }
21843                            }
21844                        });
21845                    },minChars: minCharsToTriggerMentionsFeed,itemsLimit: maxLimitForMentionsDropDown,itemTemplate: mentionsDropDownTemplate, outputTemplate: mentionsOutputTemplate}];
21846        }
21847
21848        var toolbarArr = rteConfig.toolbar[0].items;
21849        var index;
21850        // Add oEmbed plugin by default for Blogs Articles and Calendar Events
21851        if (model.get("resourceType") === "social/journal/components/hbs/journal" ||
21852            model.get("resourceType") === "social/calendar/components/hbs/calendar" ||
21853            model.get("resourceType") === "social/ideation/components/hbs/ideation" ||
21854            model.get("resourceType") === "social/ideation/components/hbs/idea" ||
21855            (model.get("resourceType") === "social/calendar/components/hbs/event" ||
21856                model.get("resourceType") === "social/journal/components/hbs/entry_topic") &&
21857            element[0].dataset.rteType !== 'comment') {
21858
21859            // Add the oembed Icon to toolbar
21860            index = toolbarArr.indexOf("oembed");
21861            if (index === -1) {
21862                rteConfig.toolbar[0].items.push("oembed");
21863            }
21864
21865            if (rteConfig.extraPlugins === undefined) {
21866                rteConfig.extraPlugins = "oembed";
21867            } else if (rteConfig.extraPlugins.length > 0 && rteConfig.extraPlugins.indexOf("oembed") === -1) {
21868                rteConfig.extraPlugins = rteConfig.extraPlugins.concat(",oembed");
21869            }
21870        } else { // Need to remove the oembed plugin for the Blog Comment
21871            index = toolbarArr.indexOf("oembed");
21872            if (index > 0) {
21873                toolbarArr.splice(index, 1);
21874            }
21875        }
21876
21877        if (modelConfigAttachmentAllowed) {
21878            rteConfig.filebrowserUploadUrl = uploadUrl;
21879            rteConfig.uploadUrl = uploadUrl;
21880
21881            // Add the Image Icon to toolbar
21882            index = toolbarArr.indexOf("Image");
21883            if (index === -1) {
21884                rteConfig.toolbar[0].items.push("Image");
21885            }
21886
21887            if (rteConfig.extraPlugins === undefined) {
21888                rteConfig.extraPlugins = "image2,uploadimage";
21889            } else if (rteConfig.extraPlugins.length > 0 && rteConfig.extraPlugins.indexOf("image2,uploadimage") === -1) {
21890                rteConfig.extraPlugins = rteConfig.extraPlugins.concat(",image2,uploadimage");
21891            }
21892        } else {
21893            // Add the Image Icon to toolbar
21894            index = toolbarArr.indexOf("Image");
21895            if (index === -1) {
21896                rteConfig.toolbar[0].items.push("Image");
21897            }
21898
21899            if (rteConfig.extraPlugins === undefined) {
21900                rteConfig.extraPlugins = "image2";
21901            } else if (rteConfig.extraPlugins.length > 0 && rteConfig.extraPlugins.indexOf("image2") === -1) {
21902                rteConfig.extraPlugins = rteConfig.extraPlugins.concat(",image2");
21903            }
21904        }
21905
21906        var domElementName = $CQ(el).attr("name");
21907        if (_.isEmpty(domElementName)) {
21908            var modelId = model.get("id");
21909            var idx = modelId.lastIndexOf("/");
21910            modelId = modelId.slice(idx + 1);
21911            var attribName = $CQ(el).data("attrib");
21912            modelId = attribName + "-" + modelId;
21913            $CQ(el).attr("name", modelId);
21914            domElementName = modelId;
21915        }
21916        var resizeEnabled = this.$el.data("editorresize");
21917        if (resizeEnabled) {
21918            rteConfig.resize_enabled = true;
21919        }
21920
21921        if (_.isNumber(height)) {
21922            rteConfig.height = height;
21923        }
21924
21925        if (!window.CKEDITOR.instances[domElementName]) {
21926            this.editor = window.CKEDITOR.replace(el, rteConfig);
21927        } else {
21928            if (this.editor === undefined) {
21929                this.editor = window.CKEDITOR.instances[domElementName];
21930            }
21931        }
21932        /*if (_.isNumber(height)) {
21933            delete this.config.height;
21934        }
21935        if (resizeEnabled) {
21936            delete this.config.resize_enabled;
21937        }*/
21938        this.model = model;
21939        if (modelConfigAttachmentAllowed) {
21940            this.editor.on("fileUploadRequest", this.attachFileFromDragAndDrop);
21941            this.editor.on("fileUploadResponse", this.handleFileUploadResponse);
21942            this.changeImagePluginDialog();
21943        }
21944    };
21945
21946    CKRte.prototype.destroy = function() {
21947        if (this.editor) {
21948            try {
21949                if (this.editor.filter && this.editor.window && this.editor.window.getFrame()) {
21950                    this.editor.destroy(true);
21951                    this.editor.removeAllListeners();
21952                } else {
21953                    this.editor.removeAllListeners();
21954                    window.CKEDITOR.remove(this.editor);
21955                    window.CKEDITOR.fire("instanceDestroyed", null, this.editor);
21956                }
21957            } catch (e) {
21958                SCF.log.error("Couldn't destroy editor: %o", e);
21959            }
21960        }
21961        delete this.editor;
21962        return;
21963    };
21964
21965
21966    CKRte.prototype.getFileIFrameFromDialog = function(definition) {
21967        var dialogDefinition = definition;
21968        var contents = dialogDefinition.contents;
21969        for (var i = 0; i < contents.length; i++) {
21970            var contentObject = contents[i];
21971            var contentObjectId = contentObject.id;
21972            // Code specific to image plugin. They have give the ID as Upload
21973            if (contentObjectId == "Upload") {
21974                var elements = contentObject.elements;
21975                for (var j = 0; j < elements.length; j++) {
21976                    var element = elements[j];
21977                    var elementId = element.id;
21978                    if (elementId == "uploadButton") {
21979                        // set the custom Function
21980                        element.onClick = this.setCustomFileButtonClick;
21981                        element["for"] = ["Upload", "file"];
21982                    }
21983                    if (elementId == "upload") {
21984                        element.id = "file";
21985                    }
21986                }
21987            }
21988        }
21989    };
21990
21991    CKRte.prototype.setCustomFileButtonClick = function(evt) {
21992        var target = evt.sender["for"];
21993        var dialog = evt.data.dialog;
21994        var fileElement = dialog.getContentElement(target[0], target[1]);
21995        var fileIframe = $CQ("#" + fileElement.domId + " iframe");
21996        //set additional parameters for the upload to happen
21997        var fileIframeForm = fileIframe.contents().find("form");
21998        var success = _.bind(function(response) {
21999            var responseObj;
22000            if(typeof(response.response) !== "object") {
22001                responseObj = JSON.parse(response.response);
22002            } else {
22003                responseObj = response.response;
22004            }
22005            var location = responseObj.url;
22006            location = CQ.shared.HTTP.encodePath(location);
22007            dialog.getContentElement("info", "src").setValue(location);
22008            dialog.selectPage("info");
22009            if ($CQ(".cke_dialog_ui_input_text").length !== 0) {
22010                $CQ(".cke_dialog_ui_input_text").focus();
22011            }
22012        }, this);
22013        var error = _.bind(function(response) {
22014            SCF.log.error("Failed to upload file" + response);
22015            alert("Failed to upload file " + response.responseJSON.error.message);
22016        }, this);
22017        var postData;
22018        var formFiles = fileIframeForm.find("input:file");
22019        var files = formFiles[0].files;
22020        var hasAttachment = (typeof files != "undefined");
22021        if (hasAttachment) {
22022            // Create a formdata object and add the files
22023            var url = fileIframeForm.attr("action");
22024            CKRte.prototype.attachFile.call(this, files, url, success, error);
22025        }
22026        evt.stop();
22027        return false;
22028    };
22029
22030    CKRte.prototype.handleFileUploadResponse = function(evt) {
22031        evt.stop();
22032        var data = evt.data;
22033        var xhr = data.fileLoader.xhr;
22034        var response = xhr.responseText;
22035        response = JSON.parse(response);
22036        if(typeof(response.response) !== "object") {
22037            response.response = JSON.parse(response.response);
22038        }
22039        if (xhr.status == 200) {
22040            data.uploaded = 1;
22041            data.url = CQ.shared.HTTP.encodePath(response.response.url);
22042            data.name = response.response.properties.name;
22043        }
22044    };
22045
22046    CKRte.prototype.attachFileFromDragAndDrop = function(evt) {
22047        var fileLoader = evt.data.fileLoader;
22048        var xhr = fileLoader.xhr;
22049        var postData;
22050        if (window.FormData) {
22051            postData = new FormData();
22052        }
22053        if (postData) {
22054            postData.append("file", fileLoader.file);
22055            postData.append("id", "nobot");
22056            postData.append(":operation", "social:uploadImage");
22057            postData.append("_charset_", "UTF-8");
22058            xhr.open("POST", fileLoader.uploadUrl, true);
22059            xhr.setRequestHeader("Accept", "application/json");
22060            xhr.withCredentials = true;
22061            xhr.send(postData);
22062        }
22063        evt.stop();
22064    };
22065
22066    CKRte.prototype.attachFile = function(files, url, success, error) {
22067        var postData;
22068        if (window.FormData) {
22069            postData = new FormData();
22070        }
22071        if (postData) {
22072            $CQ.each(files, function(key, value) {
22073                postData.append("file", value);
22074            });
22075            postData.append("id", "nobot");
22076            postData.append(":operation", "social:uploadImage");
22077            postData.append("_charset_", "UTF-8");
22078            $CQ.ajax(url, {
22079                dataType: "json",
22080                type: "POST",
22081                processData: false,
22082                contentType: false,
22083                xhrFields: {
22084                    withCredentials: true
22085                },
22086                data: postData,
22087                "success": success,
22088                "error": error
22089            });
22090        }
22091    };
22092    CKRte.prototype.changeImagePluginDialog = function() {
22093        // List of things being done
22094        // Get the dialog defintion of the image2 plugin
22095        // Setting a custom onClick function to the file input button in the dialog
22096        // Getting the iframe that loads the server response after an image is uploaded
22097        // Set addition params specific to upload operation
22098        // Add an onload event listener to the iframe
22099        // The iframe onload event listener updates the field that has image URL
22100        if (!CKRte.isImageDialogDefinitionChanged) {
22101            CKRte.isImageDialogDefinitionChanged = true;
22102            var that = this;
22103            window.CKEDITOR.on("dialogDefinition", function(ev) {
22104                var dialogName = ev.data.name;
22105                if (dialogName == "image2") {
22106                    that.getFileIFrameFromDialog(ev.data.definition);
22107                }
22108            });
22109        }
22110    };
22111
22112    CKRte.prototype.config = {
22113        toolbar: [{
22114            name: "basicstyles",
22115            items: ["Bold", "Italic", "Underline", "NumberedList", "BulletedList", "Outdent", "Indent", "JustifyLeft", "JustifyCenter", "JustifyRight", "JustifyBlock", "TextColor"]
22116        }],
22117        autoParagraph: false,
22118        autoUpdateElement: false,
22119        removePlugins: "elementspath",
22120        resize_enabled: false
22121    };
22122    CKRte.prototype.setValue = function(val) {
22123        this.editor.setData(val);
22124    };
22125    CKRte.prototype.getValue = function() {
22126        return this.editor.getData();
22127    };
22128    CKRte.prototype.focus = function() {
22129        return this.editor.focus();
22130    };
22131
22132    CKRte.isImageDialogDefinitionChanged = false;
22133
22134    SCF.registerFieldType("ckeditor", CKRte);
22135    SCF.registerFieldType("rte", CKRte);
22136})(Backbone, $CQ, _, Handlebars);
22137
22138/*
22139 *
22140 * ADOBE CONFIDENTIAL
22141 * __________________
22142 *
22143 *  Copyright 2012 Adobe Systems Incorporated
22144 *  All Rights Reserved.
22145 *
22146 * NOTICE:  All information contained herein is, and remains
22147 * the property of Adobe Systems Incorporated and its suppliers,
22148 * if any.  The intellectual and technical concepts contained
22149 * herein are proprietary to Adobe Systems Incorporated and its
22150 * suppliers and are protected by trade secret or copyright law.
22151 * Dissemination of this information or reproduction of this material
22152 * is strictly forbidden unless prior written permission is obtained
22153 * from Adobe Systems Incorporated.
22154 */
22155(function(_, $CQ, Backbone, Handlebars, SCF) {
22156    "use strict";
22157
22158    var SmartTagManager = function(tagField, config, model) {
22159        this.containerEl = tagField;
22160        var filterVal = $CQ(tagField).data("tag-filter");
22161        var filterLimit = $CQ(tagField).data("tag-limit");
22162        $CQ(tagField).tagit({
22163            fieldName: name,
22164            allowSpaces: false,
22165            placeholderText: CQ.I18n.getMessage("Add a tag"),
22166            animate: false,
22167            minLength: 2,
22168            removeConfirmation: true,
22169            showAutocompleteOnFocus: false,
22170            tagSource: function(request, response) {
22171                $CQ.ajax({
22172                    url: SCF.config.urlRoot + "/services/tagfilter",
22173                    data: {
22174                        term: request.term,
22175                        tagfilter: filterVal,
22176                        tagFilterLimit: filterLimit,
22177                        pagePath: CQ.shared.HTTP.getPath(),
22178                        _charset_: "UTF-8"
22179                    },
22180                    dataType: "json",
22181                    success: function(data) {
22182                        response($CQ.map(data, function(item) {
22183                            return {
22184                                label: item.label,
22185                                value: item.value,
22186                                id: item.tagid
22187                            };
22188                        }));
22189                    }
22190                });
22191            }
22192        });
22193
22194        if (!_.isEmpty(model.get("tags"))) {
22195            $CQ.each(model.get("tags"), function(index, item) {
22196                $CQ(tagField).tagit("createTag", item.title, item.tagId, item.value);
22197
22198            });
22199        }
22200    };
22201    SmartTagManager.prototype.getValue = function() {
22202        var tags = [];
22203
22204        $CQ(this.containerEl).find('li').each(function() {
22205            var _liObj = $(this);
22206            var _value = _liObj.find("input").attr("value");
22207            if (!_.isEmpty(_value)) {
22208                tags.push(_value);
22209            }
22210        });
22211
22212        return tags;
22213    };
22214    SmartTagManager.prototype.setValue = function() {};
22215    SmartTagManager.prototype.focus = function() {
22216        $CQ(this.el).focus();
22217    };
22218    SmartTagManager.prototype.destroy = function() {};
22219
22220
22221
22222    var TagManager = function(tagField, config, model) {
22223        var compileTemplates = function(sourceMap) {
22224            var compiledTemplates = {};
22225            for (var key in sourceMap) {
22226                compiledTemplates[key] = Handlebars.compile(sourceMap[key]);
22227            }
22228            return compiledTemplates;
22229        };
22230        this.modelTags = model.get("tags");
22231        this.templatesSource = this.defaultTemplates;
22232        if (config && config.hasOwnProperty("templates")) {
22233            this.templatesSource = _.extend(this.defaultTemplates, config.templates);
22234        }
22235        this.compiledTemplates = compileTemplates(this.templatesSource);
22236        var el = tagField.get()[0];
22237        var filterVal = $CQ(el).data("tag-filter");
22238        var filterLimit = $CQ(el).data("tag-limit");
22239        var tags = TagManager.tagsByFilterVal[filterVal];
22240        if (!tags) {
22241            var that = this;
22242            $CQ.ajax({
22243                url: SCF.config.urlRoot + "/services/tagfilter",
22244                data: {
22245                    tagfilter: filterVal,
22246                    tagFilterLimit: filterLimit
22247                },
22248                // xhrFields: {
22249                //     withCredentials: true
22250                // },
22251                dataType: "json",
22252                async: false,
22253                success: function(data) {
22254                    tags = data;
22255                    TagManager.tagsByFilterVal[filterVal] = tags;
22256                    that.initTagFields(tags, el);
22257                }
22258            });
22259        } else {
22260            this.initTagFields(tags, el);
22261        }
22262    };
22263
22264    TagManager.prototype.initTagFields = function(tags, field) {
22265        var tagSelector = $CQ(this.compiledTemplates.inputField(tags));
22266        this.selectedTags = {};
22267        var that = this;
22268        var $field = $CQ(field);
22269        $field.after(tagSelector);
22270        var attributes = $field.prop("attributes");
22271        $CQ.each(attributes, function() {
22272            tagSelector.attr(this.name, this.value);
22273        });
22274        tagSelector.removeAttr("data-attrib");
22275        var selectedTags = $CQ(this.compiledTemplates.tagsContainer(this.modelTags));
22276
22277        if (!_.isUndefined(this.modelTags) && this.modelTags !== null && this.modelTags.hasOwnProperty("length")) {
22278            for (var i = 0; i < this.modelTags.length; i++) {
22279                this.selectedTags[this.modelTags[i].tagId] = this.modelTags[i];
22280            }
22281        }
22282        tagSelector.after(selectedTags);
22283        selectedTags.find(".scf-js-remove-tag").click(function(e) {
22284            var targetTag = $CQ(e.target).closest("[data-attrib]");
22285            delete that.selectedTags[targetTag.attr("data-attrib")];
22286            targetTag.remove();
22287        });
22288        $field.remove();
22289        tagSelector.change(function() {
22290            $CQ(tagSelector).find("option:selected").each(function() {
22291                var tag = $CQ(this).text();
22292                var tagId = $CQ(this).val();
22293                $CQ(this).removeAttr("selected");
22294                if (tagId in that.selectedTags) {
22295                    return;
22296                }
22297                var selectedTag = $CQ(that.compiledTemplates.tag({
22298                    "tagid": tagId,
22299                    "label": tag
22300                }));
22301                selectedTags.append(selectedTag);
22302                that.selectedTags[tagId] = tag;
22303                selectedTag.find(".scf-js-remove-tag").click(function() {
22304                    selectedTag.remove();
22305                    delete that.selectedTags[tagId];
22306                });
22307            });
22308            $CQ($CQ(this).find("option[disabled]")[0]).removeAttr("disabled").attr("selected", "selected").attr("disabled", "disabled");
22309        });
22310    };
22311
22312    TagManager.prototype.getValue = function() {
22313        var tags = [];
22314        for (var tagId in this.selectedTags) {
22315            tags.push(tagId);
22316        }
22317        return tags;
22318    };
22319    TagManager.prototype.setValue = function() {
22320        if (tags instanceof Array) {
22321            for (var i; i < tags.length; i++) {
22322                var tag = tags[i];
22323                this.selectedTags[tag.tagId] = tag.title;
22324            }
22325        }
22326    };
22327    TagManager.prototype.focus = function() {
22328        $CQ(this.el).focus();
22329    };
22330    TagManager.prototype.destroy = function() {};
22331
22332    TagManager.prototype.defaultTemplates = {
22333        "inputField": "<select size=\"1\"><option disabled selected>add a tag</option>{{#each this}}<option value=\"{{tagid}}\">{{label}}</option>{{/each}}</select>",
22334        "tagsContainer": "<ul class=\"scf-horizontal-tag-list\">{{#each this}}<li class=\"scf-selected-tag \" data-attrib=\"{{tagId}}\"><span class=\"scf-js-remove-tag scf-remove-tag\"></span> {{title}}</li>{{/each}}</div>",
22335        "tag": "<li class=\"scf-selected-tag \"><span class=\"scf-js-remove-tag scf-remove-tag\"></span> {{label}}</li>"
22336    };
22337
22338    TagManager.tagsByFilterVal = {};
22339
22340    SCF.registerFieldType("tags", TagManager);
22341    SCF.registerFieldType("smarttags", SmartTagManager);
22342    // Maybe this export can be removed when we transition over totally to SCF
22343    SCF.TagManager = TagManager;
22344    SCF.SmartTagManager = SmartTagManager;
22345
22346})(_, $CQ, Backbone, Handlebars, SCF);
22347
22348/*
22349 *
22350 * ADOBE CONFIDENTIAL
22351 * __________________
22352 *
22353 *  Copyright 2012 Adobe Systems Incorporated
22354 *  All Rights Reserved.
22355 *
22356 * NOTICE:  All information contained herein is, and remains
22357 * the property of Adobe Systems Incorporated and its suppliers,
22358 * if any.  The intellectual and technical concepts contained
22359 * herein are proprietary to Adobe Systems Incorporated and its
22360 * suppliers and are protected by trade secret or copyright law.
22361 * Dissemination of this information or reproduction of this material
22362 * is strictly forbidden unless prior written permission is obtained
22363 * from Adobe Systems Incorporated.
22364 */
22365(function(_, $CQ, Backbone, Handlebars, SCF) {
22366    "use strict";
22367
22368    // select user
22369    var initUserSelector = function(el_selector, path, dropDown) {
22370        var $el = $CQ(el_selector);
22371        // userlist node needs to be next to ugc node
22372        var base_url = path;
22373        $el.autocomplete({
22374            source: function(request, response) {
22375                var searchString = $CQ(el_selector).val();
22376                var filterObject = {
22377                    "operation": "CONTAINS",
22378                    "./@rep:principalName": searchString
22379                };
22380                filterObject = [filterObject];
22381                var filterGivenName = {
22382                    "operation": "like",
22383                    "profile/@givenName": searchString
22384                };
22385                filterObject.push(filterGivenName);
22386                var filterFamilyName = {
22387                    "operation": "like",
22388                    "profile/@familyName": searchString
22389                };
22390                filterObject.push(filterFamilyName);
22391                filterObject = JSON.stringify(filterObject);
22392
22393                var sitePath = SCF.Context.sitePath + "/configuration.social.0.20.json";
22394                $CQ.ajax({
22395                    url: sitePath,
22396                    type: "GET",
22397                    success: function(siteJson) {
22398                        var url = base_url + ".social.0.20.json";
22399                        url = CQ.shared.HTTP.addParameter(url, "filter", filterObject);
22400                        url = CQ.shared.HTTP.addParameter(url, "type", "users");
22401                        url = CQ.shared.HTTP.addParameter(url, "fromPublisher", "true");
22402                        url = CQ.shared.HTTP.addParameter(url, "_charset_", "utf-8");
22403                        url = CQ.shared.HTTP.addParameter(url, "groupId", "community-" + siteJson.siteId + "-members");
22404                        $.get(url, function(data) {
22405                            var users = data.items;
22406                            $el.data("lastQueryResult", users);
22407                            response(users);
22408                        });
22409                    }
22410                });
22411            },
22412            minLength: 3,
22413            change: function(event, ui) {
22414                dropDown.model.set("composedForValid", dropDown.validateUser($el.val()));
22415            },
22416            select: function(event, ui) {
22417                dropDown.model.set("composedForValid", true);
22418                $CQ(this).val(ui.item.authorizableId);
22419                return false;
22420            },
22421            setvalue: function(value) {
22422                this.element.val(value);
22423                this.input.val(value);
22424                $CQ(this).val(value);
22425            }
22426        }).data("uiAutocomplete")._renderItem = function(ul, item) {
22427            if (item.avatarUrl) {
22428                return $CQ("<li></li>").append(
22429                        "<a><img src='" + item.avatarUrl + "' width='30' height='30'/>&nbsp;" + item.name + "</a>")
22430                    .data("item.autocomplete", item).appendTo(ul);
22431            } else {
22432                return $CQ("<li></li>").append("<a>" + item.name + "</a>").data("item.autocomplete", item).appendTo(ul);
22433            }
22434        };
22435    };
22436
22437    var UserDropDown = function(inputEl, config, model) {
22438        this.$el = $CQ(inputEl);
22439        this.model = model;
22440        this.config = config;
22441        this.modelId = this.model.get("forumId");
22442        if (_.isEmpty(this.modelId)) {
22443            this.modelId = this.model.get("id");
22444        }
22445        initUserSelector($CQ(inputEl), this.modelId + "/userlist", this);
22446    };
22447
22448    var isUserInList = function(userList, userName) {
22449        for (var user in userList) {
22450            if (userList[user].authorizableId === userName) {
22451                return true;
22452            }
22453        }
22454        return false;
22455    };
22456
22457    UserDropDown.prototype.validateUser = function(userName) {
22458        var isValid = false;
22459
22460        // Check to see if the user is blank
22461        if (userName.trim().length === 0)
22462            return true;
22463
22464        // First, check last (cached) search, if it exists
22465        if (this.$el.data("lastQueryResult")) {
22466            if (isUserInList(this.$el.data("lastQueryResult"), userName)) {
22467                isValid = true;
22468            }
22469        }
22470        // Next, perform a query and check to see if we find a match
22471        if (!isValid) {
22472            var users = this.searchUsers(userName);
22473            isValid = isUserInList(users, userName);
22474        }
22475        return isValid;
22476    };
22477
22478    UserDropDown.prototype.searchUsers = function(userName) {
22479        var base_url = this.modelId + "/userlist";
22480        var url = base_url + ".social.0.20.json?search=" + userName + "&showUsers=true";
22481        var users;
22482        $.get(url, function(data) {
22483            users = data.items;
22484        });
22485        users = users || [];
22486        return users;
22487    };
22488
22489    UserDropDown.prototype.getValue = function() {
22490        return this.$el.val();
22491    };
22492
22493    UserDropDown.prototype.setValue = function() {
22494        // Some model prop
22495        this.$el.autocomplete().setValue(this.model.get("author").id);
22496    };
22497
22498    UserDropDown.prototype.focus = function() {
22499        $CQ(this.el).focus();
22500    };
22501
22502    UserDropDown.prototype.destroy = function() {
22503        if (this.$el.data('autocomplete') || this.$el.data('lastQueryResult')) {
22504            this.$el.autocomplete("destroy");
22505        }
22506    };
22507
22508    SCF.registerFieldType("userdropdown", UserDropDown);
22509    SCF.UserDropDown = UserDropDown;
22510})(_, $CQ, Backbone, Handlebars, SCF);
22511
22512/*******************************************************************************
22513 * Copyright 2018 Adobe
22514 *
22515 * Licensed under the Apache License, Version 2.0 (the "License");
22516 * you may not use this file except in compliance with the License.
22517 * You may obtain a copy of the License at
22518 *
22519 *     http://www.apache.org/licenses/LICENSE2.0
22520 *
22521 * Unless required by applicable law or agreed to in writing, software
22522 * distributed under the License is distributed on an "AS IS" BASIS,
22523 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22524 * See the License for the specific language governing permissions and
22525 * limitations under the License.
22526 ******************************************************************************/
22527
22528/**
22529 * Element.matches()
22530 * https://developer.mozilla.org/enUS/docs/Web/API/Element/matches#Polyfill
22531 */
22532if (!Element.prototype.matches) {
22533    Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
22534}
22535
22536// eslint-disable-next-line valid-jsdoc
22537/**
22538 * Element.closest()
22539 * https://developer.mozilla.org/enUS/docs/Web/API/Element/closest#Polyfill
22540 */
22541if (!Element.prototype.closest) {
22542    Element.prototype.closest = function(s) {
22543        "use strict";
22544        var el = this;
22545        if (!document.documentElement.contains(el)) {
22546            return null;
22547        }
22548        do {
22549            if (el.matches(s)) {
22550                return el;
22551            }
22552            el = el.parentElement || el.parentNode;
22553        } while (el !== null && el.nodeType === 1);
22554        return null;
22555    };
22556}
22557
22558/*******************************************************************************
22559 * Copyright 2018 Adobe
22560 *
22561 * Licensed under the Apache License, Version 2.0 (the "License");
22562 * you may not use this file except in compliance with the License.
22563 * You may obtain a copy of the License at
22564 *
22565 *     http://www.apache.org/licenses/LICENSE-2.0
22566 *
22567 * Unless required by applicable law or agreed to in writing, software
22568 * distributed under the License is distributed on an "AS IS" BASIS,
22569 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22570 * See the License for the specific language governing permissions and
22571 * limitations under the License.
22572 ******************************************************************************/
22573/* global
22574    CQ
22575 */
22576(function() {
22577    "use strict";
22578
22579    var containerUtils = window.CQ && window.CQ.CoreComponents && window.CQ.CoreComponents.c
22579ontainer && window.CQ.CoreComponents.container.utils ? window.CQ.CoreComponents.container.utils : undefined;
22580    if (!containerUtils) {
22581        // eslint-disable-next-line no-console
22582        console.warn("Tabs: container utilities at window.CQ.CoreComponents.container.utils are not available. This can lead to missing features. Ensure the core.wcm.components.commons.site.container client library is included on the page.");
22583    }
22584    var dataLayerEnabled;
22585    var dataLayer;
22586
22587    var NS = "cmp";
22588    var IS = "tabs";
22589
22590    var keyCodes = {
22591        END: 35,
22592        HOME: 36,
22593        ARROW_LEFT: 37,
22594        ARROW_UP: 38,
22595        ARROW_RIGHT: 39,
22596        ARROW_DOWN: 40
22597    };
22598
22599    var selectors = {
22600        self: "[data-" + NS + '-is="' + IS + '"]',
22601        active: {
22602            tab: "cmp-tabs__tab--active",
22603            tabpanel: "cmp-tabs__tabpanel--active"
22604        }
22605    };
22606
22607    /**
22608     * Tabs Configuration
22609     *
22610     * @typedef {Object} TabsConfig Represents a Tabs configuration
22611     * @property {HTMLElement} element The HTMLElement representing the Tabs
22612     * @property {Object} options The Tabs options
22613     */
22614
22615    /**
22616     * Tabs
22617     *
22618     * @class Tabs
22619     * @classdesc An interactive Tabs component for navigating a list of tabs
22620     * @param {TabsConfig} config The Tabs configuration
22621     */
22622    function Tabs(config) {
22623        var that = this;
22624
22625        if (config && config.element) {
22626            init(config);
22627        }
22628
22629        /**
22630         * Initializes the Tabs
22631         *
22632         * @private
22633         * @param {TabsConfig} config The Tabs configuration
22634         */
22635        function init(config) {
22636            that._config = config;
22637
22638            // prevents multiple initialization
22639            config.element.removeAttribute("data-" + NS + "-is");
22640
22641            cacheElements(config.element);
22642            that._active = getActiveIndex(that._elements["tab"]);
22643
22644            if (that._elements.tabpanel) {
22645                refreshActive();
22646                bindEvents();
22647                scrollToDeepLinkIdInTabs();
22648            }
22649
22650            if (window.Granite && window.Granite.author && window.Granite.author.MessageChannel) {
22651                /*
22652                 * Editor message handling:
22653                 * - subscribe to "cmp.panelcontainer" message requests sent by the editor frame
22654                 * - check that the message data panel container type is correct and that the id (path) matches this specific Tabs component
22655                 * - if so, route the "navigate" operation to enact a navigation of the Tabs based on index data
22656                 */
22657                CQ.CoreComponents.MESSAGE_CHANNEL = CQ.CoreComponents.MESSAGE_CHANNEL || new window.Granite.author.MessageChannel("cqauthor", window);
22658                CQ.CoreComponents.MESSAGE_CHANNEL.subscribeRequestMessage("cmp.panelcontainer", function(message) {
22659                    if (message.data && message.data.type === "cmp-tabs" && message.data.id === that._elements.self.dataset["cmpPanelcontainerId"]) {
22660                        if (message.data.operation === "navigate") {
22661                            navigate(message.data.index);
22662                        }
22663                    }
22664                });
22665            }
22666        }
22667
22668        /**
22669         * Displays the panel containing the element that corresponds to the deep link in the URI fragment
22670         * and scrolls the browser to this element.
22671         */
22672        function scrollToDeepLinkIdInTabs() {
22673            if (containerUtils) {
22674                var deepLinkItemIdx = containerUtils.getDeepLinkItemIdx(that, "tab", "tabpanel");
22675                if (deepLinkItemIdx > -1) {
22676                    var deepLinkItem = that._elements["tab"][deepLinkItemIdx];
22677                    if (deepLinkItem && that._elements["tab"][that._active].id !== deepLinkItem.id) {
22678                        navigateAndFocusTab(deepLinkItemIdx, true);
22679                    }
22680                    var hashId = window.location.hash.substring(1);
22681                    if (hashId) {
22682                        var hashItem = document.querySelector("[id='" + hashId + "']");
22683                        if (hashItem) {
22684                            hashItem.scrollIntoView();
22685                        }
22686                    }
22687                }
22688            }
22689        }
22690
22691        /**
22692         * Returns the index of the active tab, if no tab is active returns 0
22693         *
22694         * @param {Array} tabs Tab elements
22695         * @returns {Number} Index of the active tab, 0 if none is active
22696         */
22697        function getActiveIndex(tabs) {
22698            if (tabs) {
22699                for (var i = 0; i < tabs.length; i++) {
22700                    if (tabs[i].classList.contains(selectors.active.tab)) {
22701                        return i;
22702                    }
22703                }
22704            }
22705            return 0;
22706        }
22707
22708        /**
22709         * Caches the Tabs elements as defined via the {@code data-tabs-hook="ELEMENT_NAME"} markup API
22710         *
22711         * @private
22712         * @param {HTMLElement} wrapper The Tabs wrapper element
22713         */
22714        function cacheElements(wrapper) {
22715            that._elements = {};
22716            that._elements.self = wrapper;
22717            var hooks = that._elements.self.querySelectorAll("[data-" + NS + "-hook-" + IS + "]");
22718
22719            for (var i = 0; i < hooks.length; i++) {
22720                var hook = hooks[i];
22721                if (hook.closest("." + NS + "-" + IS) === that._elements.self) { // only process own tab elements
22722                    var capitalized = IS;
22723                    capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
22724                    var key = hook.dataset[NS + "Hook" + capitalized];
22725                    if (that._elements[key]) {
22726                        if (!Array.isArray(that._elements[key])) {
22727                            var tmp = that._elements[key];
22728                            that._elements[key] = [tmp];
22729                        }
22730                        that._elements[key].push(hook);
22731                    } else {
22732                        that._elements[key] = hook;
22733                    }
22734                }
22735            }
22736        }
22737
22738        /**
22739         * Binds Tabs event handling
22740         *
22741         * @private
22742         */
22743        function bindEvents() {
22744            window.addEventListener("hashchange", scrollToDeepLinkIdInTabs, false);
22745            var tabs = that._elements["tab"];
22746            if (tabs) {
22747                for (var i = 0; i < tabs.length; i++) {
22748                    (function(index) {
22749                        tabs[i].addEventListener("click", function(event) {
22750                            navigateAndFocusTab(index);
22751                        });
22752                        tabs[i].addEventListener("keydown", function(event) {
22753                            onKeyDown(event);
22754                        });
22755                    })(i);
22756                }
22757            }
22758        }
22759
22760        /**
22761         * Handles tab keydown events
22762         *
22763         * @private
22764         * @param {Object} event The keydown event
22765         */
22766        function onKeyDown(event) {
22767            var index = that._active;
22768            var lastIndex = that._elements["tab"].length - 1;
22769
22770            switch (event.keyCode) {
22771                case keyCodes.ARROW_LEFT:
22772                case keyCodes.ARROW_UP:
22773                    event.preventDefault();
22774                    if (index > 0) {
22775                        navigateAndFocusTab(index - 1);
22776                    }
22777                    break;
22778                case keyCodes.ARROW_RIGHT:
22779                case keyCodes.ARROW_DOWN:
22780                    event.preventDefault();
22781                    if (index < lastIndex) {
22782                        navigateAndFocusTab(index + 1);
22783                    }
22784                    break;
22785                case keyCodes.HOME:
22786                    event.preventDefault();
22787                    navigateAndFocusTab(0);
22788                    break;
22789                case keyCodes.END:
22790                    event.preventDefault();
22791                    navigateAndFocusTab(lastIndex);
22792                    break;
22793                default:
22794                    return;
22795            }
22796        }
22797
22798        /**
22799         * Refreshes the tab markup based on the current {@code Tabs#_active} index
22800         *
22801         * @private
22802         */
22803        function refreshActive() {
22804            var tabpanels = that._elements["tabpanel"];
22805            var tabs = that._elements["tab"];
22806
22807            if (tabpanels) {
22808                if (Array.isArray(tabpanels)) {
22809                    for (var i = 0; i < tabpanels.length; i++) {
22810                        if (i === parseInt(that._active)) {
22811                            tabpanels[i].classList.add(selectors.active.tabpanel);
22812                            tabpanels[i].removeAttribute("aria-hidden");
22813                            tabs[i].classList.add(selectors.active.tab);
22814                            tabs[i].setAttribute("aria-selected", true);
22815                            tabs[i].setAttribute("tabindex", "0");
22816                        } else {
22817                            tabpanels[i].classList.remove(selectors.active.tabpanel);
22818                            tabpanels[i].setAttribute("aria-hidden", true);
22819                            tabs[i].classList.remove(selectors.active.tab);
22820                            tabs[i].setAttribute("aria-selected", false);
22821                            tabs[i].setAttribute("tabindex", "-1");
22822                        }
22823                    }
22824                } else {
22825                    // only one tab
22826                    tabpanels.classList.add(selectors.active.tabpanel);
22827                    tabs.classList.add(selectors.active.tab);
22828                }
22829            }
22830        }
22831
22832        /**
22833         * Focuses the element and prevents scrolling the element into view
22834         *
22835         * @param {HTMLElement} element Element to focus
22836         */
22837        function focusWithoutScroll(element) {
22838            var x = window.scrollX || window.pageXOffset;
22839            var y = window.scrollY || window.pageYOffset;
22840            element.focus();
22841            window.scrollTo(x, y);
22842        }
22843
22844        /**
22845         * Navigates to the tab at the provided index
22846         *
22847         * @private
22848         * @param {Number} index The index of the tab to navigate to
22849         */
22850        function navigate(index) {
22851            that._active = index;
22852            refreshActive();
22853        }
22854
22855        /**
22856         * Navigates to the item at the provided index and ensures the active tab gains focus
22857         *
22858         * @private
22859         * @param {Number} index The index of the item to navigate to
22860         * @param {Boolean} keepHash true to keep the hash in the URL, false to update it
22861         */
22862        function navigateAndFocusTab(index, keepHash) {
22863            var exActive = that._active;
22864            if (!keepHash && containerUtils) {
22865                containerUtils.updateUrlHash(that, "tab", index);
22866            }
22867            navigate(index);
22868            focusWithoutScroll(that._elements["tab"][index]);
22869
22870            if (dataLayerEnabled) {
22871
22872                var activeItem = getDataLayerId(that._elements.tabpanel[index]);
22873                var exActiveItem = getDataLayerId(that._elements.tabpanel[exActive]);
22874
22875                dataLayer.push({
22876                    event: "cmp:show",
22877                    eventInfo: {
22878                        path: "component." + activeItem
22879                    }
22880                });
22881
22882                dataLayer.push({
22883                    event: "cmp:hide",
22884                    eventInfo: {
22885                        path: "component." + exActiveItem
22886                    }
22887                });
22888
22889                var tabsId = that._elements.self.id;
22890                var uploadPayload = { component: {} };
22891                uploadPayload.component[tabsId] = { shownItems: [activeItem] };
22892
22893                var removePayload = { component: {} };
22894                removePayload.component[tabsId] = { shownItems: undefined };
22895
22896                dataLayer.push(removePayload);
22897                dataLayer.push(uploadPayload);
22898            }
22899        }
22900    }
22901
22902    /**
22903     * Reads options data from the Tabs wrapper element, defined via {@code data-cmp-*} data attributes
22904     *
22905     * @private
22906     * @param {HTMLElement} element The Tabs element to read options data from
22907     * @returns {Object} The options read from the component data attributes
22908     */
22909    function readData(element) {
22910        var data = element.dataset;
22911        var options = [];
22912        var capitalized = IS;
22913        capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
22914        var reserved = ["is", "hook" + capitalized];
22915
22916        for (var key in data) {
22917            if (Object.prototype.hasOwnProperty.call(data, key)) {
22918                var value = data[key];
22919
22920                if (key.indexOf(NS) === 0) {
22921                    key = key.slice(NS.length);
22922                    key = key.charAt(0).toLowerCase() + key.substring(1);
22923
22924                    if (reserved.indexOf(key) === -1) {
22925                        options[key] = value;
22926                    }
22927                }
22928            }
22929        }
22930
22931        return options;
22932    }
22933
22934    /**
22935     * Parses the dataLayer string and returns the ID
22936     *
22937     * @private
22938     * @param {HTMLElement} item the accordion item
22939     * @returns {String} dataLayerId or undefined
22940     */
22941    function getDataLayerId(item) {
22942        if (item) {
22943            if (item.dataset.cmpDataLayer) {
22944                return Object.keys(JSON.parse(item.dataset.cmpDataLayer))[0];
22945            } else {
22946                return item.id;
22947            }
22948        }
22949        return null;
22950    }
22951
22952    /**
22953     * Document ready handler and DOM mutation observers. Initializes Tabs components as necessary.
22954     *
22955     * @private
22956     */
22957    function onDocumentReady() {
22958        dataLayerEnabled = document.body.hasAttribute("data-cmp-data-layer-enabled");
22959        dataLayer = (dataLayerEnabled) ? window.adobeDataLayer = window.adobeDataLayer || [] : undefined;
22960
22961        var elements = document.querySelectorAll(selectors.self);
22962        for (var i = 0; i < elements.length; i++) {
22963            new Tabs({ element: elements[i], options: readData(elements[i]) });
22964        }
22965
22966        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
22967        var body = document.querySelector("body");
22968        var observer = new MutationObserver(function(mutations) {
22969            mutations.forEach(function(mutation) {
22970                // needed for IE
22971                var nodesArray = [].slice.call(mutation.addedNodes);
22972                if (nodesArray.length > 0) {
22973                    nodesArray.forEach(function(addedNode) {
22974                        if (addedNode.querySelectorAll) {
22975                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
22976                            elementsArray.forEach(function(element) {
22977                                new Tabs({ element: element, options: readData(element) });
22978                            });
22979                        }
22980                    });
22981                }
22982            });
22983        });
22984
22985        observer.observe(body, {
22986            subtree: true,
22987            childList: true,
22988            characterData: true
22989        });
22990    }
22991
22992    if (document.readyState !== "loading") {
22993        onDocumentReady();
22994    } else {
22995        document.addEventListener("DOMContentLoaded", onDocumentReady);
22996    }
22997
22998    if (containerUtils) {
22999        window.addEventListener("load", containerUtils.scrollToAnchor, false);
23000    }
23001
23002}());
23003
23004/*******************************************************************************
23005 * Copyright 2018 Adobe
23006 *
23007 * Licensed under the Apache License, Version 2.0 (the "License");
23008 * you may not use this file except in compliance with the License.
23009 * You may obtain a copy of the License at
23010 *
23011 *     http://www.apache.org/licenses/LICENSE-2.0
23012 *
23013 * Unless required by applicable law or agreed to in writing, software
23014 * distributed under the License is distributed on an "AS IS" BASIS,
23015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23016 * See the License for the specific language governing permissions and
23017 * limitations under the License.
23018 ******************************************************************************/
23019(function() {
23020    "use strict";
23021
23022    var containerUtils = window.CQ && window.CQ.CoreComponents && window.CQ.CoreComponents.c
23022ontainer && window.CQ.CoreComponents.container.utils ? window.CQ.CoreComponents.container.utils : undefined;
23023    if (!containerUtils) {
23024        // eslint-disable-next-line no-console
23025        console.warn("Tabs: container utilities at window.CQ.CoreComponents.container.utils are not available. This can lead to missing features. Ensure the core.wcm.components.commons.site.container client library is included on the page.");
23026    }
23027    var dataLayerEnabled;
23028    var dataLayer;
23029
23030    var NS = "cmp";
23031    var IS = "carousel";
23032
23033    var keyCodes = {
23034        SPACE: 32,
23035        END: 35,
23036        HOME: 36,
23037        ARROW_LEFT: 37,
23038        ARROW_UP: 38,
23039        ARROW_RIGHT: 39,
23040        ARROW_DOWN: 40
23041    };
23042
23043    var selectors = {
23044        self: "[data-" + NS + '-is="' + IS + '"]'
23045    };
23046
23047    var properties = {
23048        /**
23049         * Determines whether the Carousel will automatically transition between slides
23050         *
23051         * @memberof Carousel
23052         * @type {Boolean}
23053         * @default false
23054         */
23055        "autoplay": {
23056            "default": false,
23057            "transform": function(value) {
23058                return !(value === null || typeof value === "undefined");
23059            }
23060        },
23061        /**
23062         * Duration (in milliseconds) before automatically transitioning to the next slide
23063         *
23064         * @memberof Carousel
23065         * @type {Number}
23066         * @default 5000
23067         */
23068        "delay": {
23069            "default": 5000,
23070            "transform": function(value) {
23071                value = parseFloat(value);
23072                return !isNaN(value) ? value : null;
23073            }
23074        },
23075        /**
23076         * Determines whether automatic pause on hovering the carousel is disabled
23077         *
23078         * @memberof Carousel
23079         * @type {Boolean}
23080         * @default false
23081         */
23082        "autopauseDisabled": {
23083            "default": false,
23084            "transform": function(value) {
23085                return !(value === null || typeof value === "undefined");
23086            }
23087        }
23088    };
23089
23090    /**
23091     * Carousel Configuration
23092     *
23093     * @typedef {Object} CarouselConfig Represents a Carousel configuration
23094     * @property {HTMLElement} element The HTMLElement representing the Carousel
23095     * @property {*[]} options The Carousel options
23096     */
23097
23098    /**
23099     * Carousel
23100     *
23101     * @class Carousel
23102     * @classdesc An interactive Carousel component for navigating a list of generic items
23103     * @param {CarouselConfig} config The Carousel configuration
23104     */
23105    function Carousel(config) {
23106        var that = this;
23107
23108        if (config && config.element) {
23109            init(config);
23110        }
23111
23112        /**
23113         * Initializes the Carousel
23114         *
23115         * @private
23116         * @param {CarouselConfig} config The Carousel configuration
23117         */
23118        function init(config) {
23119            that._config = config;
23120
23121            // prevents multiple initialization
23122            config.element.removeAttribute("data-" + NS + "-is");
23123
23124            setupProperties(config.options);
23125            cacheElements(config.element);
23126
23127            that._active = 0;
23128            that._paused = false;
23129
23130            if (that._elements.item) {
23131                initializeActive();
23132                bindEvents();
23133                resetAutoplayInterval();
23134                refreshPlayPauseActions();
23135                scrollToDeepLinkIdInCarousel();
23136            }
23137
23138            // TODO: This section is only relevant in edit mode and should move to the editor clientLib
23139            if (window.Granite && window.Granite.author && window.Granite.author.MessageChannel) {
23140                /*
23141                 * Editor message handling:
23142                 * - subscribe to "cmp.panelcontainer" message requests sent by the editor frame
23143                 * - check that the message data panel container type is correct and that the id (path) matches this specific Carousel component
23144                 * - if so, route the "navigate" operation to enact a navigation of the Carousel based on index data
23145                 */
23146                window.CQ = window.CQ || {};
23147                window.CQ.CoreComponents = window.CQ.CoreComponents || {};
23148                window.CQ.CoreComponents.MESSAGE_CHANNEL = window.CQ.CoreComponents.MESSAGE_CHANNEL || new window.Granite.author.MessageChannel("cqauthor", window);
23149                window.CQ.CoreComponents.MESSAGE_CHANNEL.subscribeRequestMessage("cmp.panelcontainer", function(message) {
23150                    if (message.data && message.data.type === "cmp-carousel" && message.data.id === that._elements.self.dataset["cmpPanelcontainerId"]) {
23151                        if (message.data.operation === "navigate") {
23152                            navigate(message.data.index);
23153                        }
23154                    }
23155                });
23156            }
23157        }
23158
23159        /**
23160         * Displays the slide containing the element that corresponds to the deep link in the URI fragment
23161         * and scrolls the browser to this element.
23162         */
23163        function scrollToDeepLinkIdInCarousel() {
23164            if (containerUtils) {
23165                var deepLinkItemIdx = containerUtils.getDeepLinkItemIdx(that, "item", "item");
23166                if (deepLinkItemIdx > -1) {
23167                    var deepLinkItem = that._elements["item"][deepLinkItemIdx];
23168                    if (deepLinkItem && that._elements["item"][that._active].id !== deepLinkItem.id) {
23169                        navigateAndFocusIndicator(deepLinkItemIdx, true);
23170                        // pause the carousel auto-rotation
23171                        pause();
23172                    }
23173                    var hashId = window.location.hash.substring(1);
23174                    if (hashId) {
23175                        var hashItem = document.querySelector("[id='" + hashId + "']");
23176                        if (hashItem) {
23177                            hashItem.scrollIntoView();
23178                        }
23179                    }
23180                }
23181            }
23182        }
23183
23184        /**
23185         * Caches the Carousel elements as defined via the {@code data-carousel-hook="ELEMENT_NAME"} markup API
23186         *
23187         * @private
23188         * @param {HTMLElement} wrapper The Carousel wrapper element
23189         */
23190        function cacheElements(wrapper) {
23191            that._elements = {};
23192            that._elements.self = wrapper;
23193            var hooks = that._elements.self.querySelectorAll("[data-" + NS + "-hook-" + IS + "]");
23194
23195            for (var i = 0; i < hooks.length; i++) {
23196                var hook = hooks[i];
23197                var capitalized = IS;
23198                capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
23199                var key = hook.dataset[NS + "Hook" + capitalized];
23200                if (that._elements[key]) {
23201                    if (!Array.isArray(that._elements[key])) {
23202                        var tmp = that._elements[key];
23203                        that._elements[key] = [tmp];
23204                    }
23205                    that._elements[key].push(hook);
23206                } else {
23207                    that._elements[key] = hook;
23208                }
23209            }
23210        }
23211
23212        /**
23213         * Sets up properties for the Carousel based on the passed options.
23214         *
23215         * @private
23216         * @param {Object} options The Carousel options
23217         */
23218        function setupProperties(options) {
23219            that._properties = {};
23220
23221            for (var key in properties) {
23222                if (Object.prototype.hasOwnProperty.call(properties, key)) {
23223                    var property = properties[key];
23224                    var value = null;
23225
23226                    if (options && options[key] != null) {
23227                        value = options[key];
23228
23229                        // transform the provided option
23230                        if (property && typeof property.transform === "function") {
23231                            value = property.transform(value);
23232                        }
23233                    }
23234
23235                    if (value === null) {
23236                        // value still null, take the property default
23237                        value = properties[key]["default"];
23238                    }
23239
23240                    that._properties[key] = value;
23241                }
23242            }
23243        }
23244
23245        /**
23246         * Binds Carousel event handling
23247         *
23248         * @private
23249         */
23250        function bindEvents() {
23251            window.addEventListener("hashchange", scrollToDeepLinkIdInCarousel, false);
23252            if (that._elements["previous"]) {
23253                that._elements["previous"].addEventListener("click", function() {
23254                    var index = getPreviousIndex();
23255                    navigate(index);
23256                    if (dataLayerEnabled) {
23257                        dataLayer.push({
23258                            event: "cmp:show",
23259                            eventInfo: {
23260                                path: "component." + getDataLayerId(that._elements.item[index])
23261                            }
23262                        });
23263                    }
23264                });
23265            }
23266
23267            if (that._elements["next"]) {
23268                that._elements["next"].addEventListener("click", function() {
23269                    var index = getNextIndex();
23270                    navigate(index);
23271                    if (dataLayerEnabled) {
23272                        dataLayer.push({
23273                            event: "cmp:show",
23274                            eventInfo: {
23275                                path: "component." + getDataLayerId(that._elements.item[index])
23276                            }
23277                        });
23278                    }
23279                });
23280            }
23281
23282            var indicators = that._elements["indicator"];
23283            if (indicators) {
23284                for (var i = 0; i < indicators.length; i++) {
23285                    (function(index) {
23286                        indicators[i].addEventListener("click", function(event) {
23287                            navigateAndFocusIndicator(index);
23288                            // pause the carousel auto-rotation
23289                            pause();
23290                        });
23291                    })(i);
23292                }
23293            }
23294
23295            if (that._elements["pause"]) {
23296                if (that._properties.autoplay) {
23297                    that._elements["pause"].addEventListener("click", onPauseClick);
23298                }
23299            }
23300
23301            if (that._elements["play"]) {
23302                if (that._properties.autoplay) {
23303                    that._elements["play"].addEventListener("click", onPlayClick);
23304                }
23305            }
23306
23307            that._elements.self.addEventListener("keydown", onKeyDown);
23308
23309            if (!that._properties.autopauseDisabled) {
23310                that._elements.self.addEventListener("mouseenter", onMouseEnter);
23311                that._elements.self.addEventListener("mouseleave", onMouseLeave);
23312            }
23313
23314            // for accessibility we pause animation when a element get focused
23315            var items = that._elements["item"];
23316            if (items) {
23317                for (var j = 0; j < items.length; j++) {
23318                    items[j].addEventListener("focusin", onMouseEnter);
23319                    items[j].addEventListener("focusout", onMouseLeave);
23320                }
23321            }
23322        }
23323
23324        /**
23325         * Handles carousel keydown events
23326         *
23327         * @private
23328         * @param {Object} event The keydown event
23329         */
23330        function onKeyDown(event) {
23331            var index = that._active;
23332            var lastIndex = that._elements["indicator"].length - 1;
23333
23334            switch (event.keyCode) {
23335                case keyCodes.ARROW_LEFT:
23336                case keyCodes.ARROW_UP:
23337                    event.preventDefault();
23338                    if (index > 0) {
23339                        navigateAndFocusIndicator(index - 1);
23340                    }
23341                    break;
23342                case keyCodes.ARROW_RIGHT:
23343                case keyCodes.ARROW_DOWN:
23344                    event.preventDefault();
23345                    if (index < lastIndex) {
23346                        navigateAndFocusIndicator(index + 1);
23347                    }
23348                    break;
23349                case keyCodes.HOME:
23350                    event.preventDefault();
23351                    navigateAndFocusIndicator(0);
23352                    break;
23353                case keyCodes.END:
23354                    event.preventDefault();
23355                    navigateAndFocusIndicator(lastIndex);
23356                    break;
23357                case keyCodes.SPACE:
23358                    if (that._properties.autoplay && (event.target !== that._elements["previous"] && event.target !== that._elements["next"])) {
23359                        event.preventDefault();
23360                        if (!that._paused) {
23361                            pause();
23362                        } else {
23363                            play();
23364                        }
23365                    }
23366                    if (event.target === that._elements["pause"]) {
23367                        that._elements["play"].focus();
23368                    }
23369                    if (event.target === that._elements["play"]) {
23370                        that._elements["pause"].focus();
23371                    }
23372                    break;
23373                default:
23374                    return;
23375            }
23376        }
23377
23378        /**
23379         * Handles carousel mouseenter events
23380         *
23381         * @private
23382         * @param {Object} event The mouseenter event
23383         */
23384        function onMouseEnter(event) {
23385            clearAutoplayInterval();
23386        }
23387
23388        /**
23389         * Handles carousel mouseleave events
23390         *
23391         * @private
23392         * @param {Object} event The mouseleave event
23393         */
23394        function onMouseLeave(event) {
23395            resetAutoplayInterval();
23396        }
23397
23398        /**
23399         * Handles pause element click events
23400         *
23401         * @private
23402         * @param {Object} event The click event
23403         */
23404        function onPauseClick(event) {
23405            pause();
23406            that._elements["play"].focus();
23407        }
23408
23409        /**
23410         * Handles play element click events
23411         *
23412         * @private
23413         * @param {Object} event The click event
23414         */
23415        function onPlayClick() {
23416            play();
23417            that._elements["pause"].focus();
23418        }
23419
23420        /**
23421         * Pauses the playing of the Carousel. Sets {@code Carousel#_paused} marker.
23422         * Only relevant when autoplay is enabled
23423         *
23424         * @private
23425         */
23426        function pause() {
23427            that._paused = true;
23428            clearAutoplayInterval();
23429            refreshPlayPauseActions();
23430        }
23431
23432        /**
23433         * Enables the playing of the Carousel. Sets {@code Carousel#_paused} marker.
23434         * Only relevant when autoplay is enabled
23435         *
23436         * @private
23437         */
23438        function play() {
23439            that._paused = false;
23440
23441            // If the Carousel is hovered, don't begin auto transitioning until the next mouse leave event
23442            var hovered = false;
23443            if (that._elements.self.parentElement) {
23444                hovered = that._elements.self.parentElement.querySelector(":hover") === that._elements.self;
23445            }
23446            if (that._properties.autopauseDisabled || !hovered) {
23447                resetAutoplayInterval();
23448            }
23449
23450            refreshPlayPauseActions();
23451        }
23452
23453        /**
23454         * Refreshes the play/pause action markup based on the {@code Carousel#_paused} state
23455         *
23456         * @private
23457         */
23458        function refreshPlayPauseActions() {
23459            setActionDisabled(that._elements["pause"], that._paused);
23460            setActionDisabled(that._elements["play"], !that._paused);
23461        }
23462
23463        /**
23464         * Initialize {@code Carousel#_active} based on the active item of the carousel.
23465         */
23466        function initializeActive() {
23467            var items = that._elements["item"];
23468            if (items && Array.isArray(items)) {
23469                for (var i = 0; i < items.length; i++) {
23470                    if (items[i].classList.contains("cmp-carousel__item--active")) {
23471                        that._active = i;
23472                        break;
23473                    }
23474                }
23475            }
23476        }
23477
23478        /**
23479         * Refreshes the item markup based on the current {@code Carousel#_active} index
23480         *
23481         * @private
23482         */
23483        function refreshActive() {
23484            var items = that._elements["item"];
23485            var indicators = that._elements["indicator"];
23486
23487            if (items) {
23488                if (Array.isArray(items)) {
23489                    for (var i = 0; i < items.length; i++) {
23490                        if (i === parseInt(that._active)) {
23491                            items[i].classList.add("cmp-carousel__item--active");
23492                            items[i].removeAttribute("aria-hidden");
23493                            indicators[i].classList.add("cmp-carousel__indicator--active");
23494                            indicators[i].setAttribute("aria-selected", true);
23495                            indicators[i].setAttribute("tabindex", "0");
23496                        } else {
23497                            items[i].classList.remove("cmp-carousel__item--active");
23498                            items[i].setAttribute("aria-hidden", true);
23499                            indicators[i].classList.remove("cmp-carousel__indicator--active");
23500                            indicators[i].setAttribute("aria-selected", false);
23501                            indicators[i].setAttribute("tabindex", "-1");
23502                        }
23503                    }
23504                } else {
23505                    // only one item
23506                    items.classList.add("cmp-carousel__item--active");
23507                    indicators.classList.add("cmp-carousel__indicator--active");
23508                }
23509            }
23510        }
23511
23512        /**
23513         * Focuses the element and prevents scrolling the element into view
23514         *
23515         * @param {HTMLElement} element Element to focus
23516         */
23517        function focusWithoutScroll(element) {
23518            var x = window.scrollX || window.pageXOffset;
23519            var y = window.scrollY || window.pageYOffset;
23520            element.focus();
23521            window.scrollTo(x, y);
23522        }
23523
23524        /**
23525         * Retrieves the next active index, with looping
23526         *
23527         * @private
23528         * @returns {Number} Index of the next carousel item
23529         */
23530        function getNextIndex() {
23531            return that._active === (that._elements["item"].length - 1) ? 0 : that._active + 1;
23532        }
23533
23534        /**
23535         * Retrieves the previous active index, with looping
23536         *
23537         * @private
23538         * @returns {Number} Index of the previous carousel item
23539         */
23540        function getPreviousIndex() {
23541            return that._active === 0 ? (that._elements["item"].length - 1) : that._active - 1;
23542        }
23543
23544        /**
23545         * Navigates to the item at the provided index
23546         *
23547         * @private
23548         * @param {Number} index The index of the item to navigate to
23549         * @param {Boolean} keepHash true to keep the hash in the URL, false to update it
23550         */
23551        function navigate(index, keepHash) {
23552            if (index < 0 || index > (that._elements["item"].length - 1)) {
23553                return;
23554            }
23555
23556            that._active = index;
23557            refreshActive();
23558
23559            if (!keepHash && containerUtils) {
23560                containerUtils.updateUrlHash(that, "item", index);
23561            }
23562
23563            if (dataLayerEnabled) {
23564                var carouselId = that._elements.self.id;
23565                var activeItem = getDataLayerId(that._elements.item[index]);
23566                var updatePayload = { component: {} };
23567                updatePayload.component[carouselId] = { shownItems: [activeItem] };
23568
23569                var removePayload = { component: {} };
23570                removePayload.component[carouselId] = { shownItems: undefined };
23571
23572                dataLayer.push(removePayload);
23573                dataLayer.push(updatePayload);
23574            }
23575
23576            // reset the autoplay transition interval following navigation, if not already hovering the carousel
23577            if (that._elements.self.parentElement) {
23578                if (that._elements.self.parentElement.querySelector(":hover") !== that._elements.self) {
23579                    resetAutoplayInterval();
23580                }
23581            }
23582        }
23583
23584        /**
23585         * Navigates to the item at the provided index and ensures the active indicator gains focus
23586         *
23587         * @private
23588         * @param {Number} index The index of the item to navigate to
23589         * @param {Boolean} keepHash true to keep the hash in the URL, false to update it
23590         */
23591        function navigateAndFocusIndicator(index, keepHash) {
23592            navigate(index, keepHash);
23593            focusWithoutScroll(that._elements["indicator"][index]);
23594
23595            if (dataLayerEnabled) {
23596                dataLayer.push({
23597                    event: "cmp:show",
23598                    eventInfo: {
23599                        path: "component." + getDataLayerId(that._elements.item[index])
23600                    }
23601                });
23602            }
23603        }
23604
23605        /**
23606         * Starts/resets automatic slide transition interval
23607         *
23608         * @private
23609         */
23610        function resetAutoplayInterval() {
23611            if (that._paused || !that._properties.autoplay) {
23612                return;
23613            }
23614            clearAutoplayInterval();
23615            that._autoplayIntervalId = window.setInterval(function() {
23616                if (document.visibilityState && document.hidden) {
23617                    return;
23618                }
23619                var indicators = that._elements["indicators"];
23620                if (indicators !== document.activeElement && indicators.contains(document.activeElement)) {
23621                    // if an indicator has focus, ensure we switch focus following navigation
23622                    navigateAndFocusIndicator(getNextIndex(), true);
23623                } else {
23624                    navigate(getNextIndex(), true);
23625                }
23626            }, that._properties.delay);
23627        }
23628
23629        /**
23630         * Clears/pauses automatic slide transition interval
23631         *
23632         * @private
23633         */
23634        function clearAutoplayInterval() {
23635            window.clearInterval(that._autoplayIntervalId);
23636            that._autoplayIntervalId = null;
23637        }
23638
23639        /**
23640         * Sets the disabled state for an action and toggles the appropriate CSS classes
23641         *
23642         * @private
23643         * @param {HTMLElement} action Action to disable
23644         * @param {Boolean} [disable] {@code true} to disable, {@code false} to enable
23645         */
23646        function setActionDisabled(action, disable) {
23647            if (!action) {
23648                return;
23649            }
23650            if (disable !== false) {
23651                action.disabled = true;
23652                action.classList.add("cmp-carousel__action--disabled");
23653            } else {
23654                action.disabled = false;
23655                action.classList.remove("cmp-carousel__action--disabled");
23656            }
23657        }
23658    }
23659
23660    /**
23661     * Parses the dataLayer string and returns the ID
23662     *
23663     * @private
23664     * @param {HTMLElement} item the accordion item
23665     * @returns {String} dataLayerId or undefined
23666     */
23667    function getDataLayerId(item) {
23668        if (item) {
23669            if (item.dataset.cmpDataLayer) {
23670                return Object.keys(JSON.parse(item.dataset.cmpDataLayer))[0];
23671            } else {
23672                return item.id;
23673            }
23674        }
23675        return null;
23676    }
23677
23678    /**
23679     * Document ready handler and DOM mutation observers. Initializes Carousel components as necessary.
23680     *
23681     * @private
23682     */
23683    function onDocumentReady() {
23684        dataLayerEnabled = document.body.hasAttribute("data-cmp-data-layer-enabled");
23685        dataLayer = (dataLayerEnabled) ? window.adobeDataLayer = window.adobeDataLayer || [] : undefined;
23686
23687        var elements = document.querySelectorAll(selectors.self);
23688        for (var i = 0; i < elements.length; i++) {
23689            new Carousel({ element: elements[i], options: CMP.utils.readData(elements[i], IS) });
23690        }
23691
23692        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
23693        var body = document.querySelector("body");
23694        var observer = new MutationObserver(function(mutations) {
23695            mutations.forEach(function(mutation) {
23696                // needed for IE
23697                var nodesArray = [].slice.call(mutation.addedNodes);
23698                if (nodesArray.length > 0) {
23699                    nodesArray.forEach(function(addedNode) {
23700                        if (addedNode.querySelectorAll) {
23701                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
23702                            elementsArray.forEach(function(element) {
23703                                new Carousel({ element: element, options: CMP.utils.readData(element, IS) });
23704                            });
23705                        }
23706                    });
23707                }
23708            });
23709        });
23710
23711        observer.observe(body, {
23712            subtree: true,
23713            childList: true,
23714            characterData: true
23715        });
23716    }
23717
23718    var documentReady = document.readyState !== "loading" ? Promise.resolve() : new Promise(function(resolve) {
23719        document.addEventListener("DOMContentLoaded", resolve);
23720    });
23721    var utilsReady = (window.CMP && window.CMP.utils) ? Promise.resolve() : new Promise(function(resolve) {
23722        document.addEventListener("core.wcm.components.commons.site.utils.loaded", resolve);
23723    });
23724    Promise.all([documentReady, utilsReady]).then(onDocumentReady);
23725
23726    if (containerUtils) {
23727        window.addEventListener("load", containerUtils.scrollToAnchor, false);
23728    }
23729
23730}());
23731
23732/*
23733 *
23734 * ADOBE CONFIDENTIAL
23735 * __________________
23736 *
23737 *  Copyright 2014 Adobe Systems Incorporated
23738 *  All Rights Reserved.
23739 *
23740 * NOTICE:  All information contained herein is, and remains
23741 * the property of Adobe Systems Incorporated and its suppliers,
23742 * if any.  The intellectual and technical concepts contained
23743 * herein are proprietary to Adobe Systems Incorporated and its
23744 * suppliers and are protected by trade secret or copyright law.
23745 * Dissemination of this information or reproduction of this material
23746 * is strictly forbidden unless prior written permission is obtained
23747 * from Adobe Systems Incorporated.
23748 */
23749$CQ(document).ready(function() {
23750    var initQuicksearch = function(el_selector) {
23751        var $el = $(el_selector);
23752        $el.autocomplete({
23753            source: function(request, response) {
23754                $.get(getUrl("*" + $CQ(el_selector).val() + "*"), function(data) {
23755                    var results = data.items;
23756                    response(results);
23757                });
23758            },
23759            minLength: 3,
23760            appendTo: ".scf-quicksearch-form-group",
23761            position: {
23762                my: "right top",
23763                at: "right bottom"
23764            },
23765            focus: function(event, ui) {
23766                event.preventDefault();
23767                $(this).val(getTitle(ui.item));
23768            },
23769            change: function(event, ui) {},
23770            select: function(event, ui) {
23771                var keycode = (event.keyCode ? event.keyCode : event.which);
23772                if (keycode === 13) {
23773                    window.location.replace(ui.item.friendlyUrl);
23774                }
23775            },
23776            setvalue: function(value) {}
23777        }).data("uiAutocomplete")._renderItem = function(ul, item) {
23778            return $CQ("<li class='scf-quicksearch-item-container'></li>").append("<a href='" + item.friendlyUrl + "'><span class='glyphicon scf-icon-" + getIconClassName(item.resourceType) + "' aria-hidden='true'></span><span class='scf-quicksearch-item'>" + getTitle(item) + "</span><span class='small scf-quicksearch-item-url'>" + item.friendlyUrl + "</span></a>").data("item.autocomplete", item).appendTo(ul);
23779        };
23780        $("#scf-js-quicksearch-input-inline").keypress(function(event) {
23781            var keycode = (event.keyCode ? event.keyCode : event.which);
23782            if (keycode === 13) {
23783                event.preventDefault();
23784                var currentPage = window.location.href;
23785                // Add current url to backbone history without navigating - to aid proper functioning of browser's back button.
23786                SCF.Router.navigate(currentPage, {
23787                    trigger: false
23788                });
23789                var form = $("#form-search-input-inline");
23790                var resultPage = form.find(".scf-js-seach-resultPage").val();
23791                var filter = getFilter($CQ(this).val(), true);
23792                var contextPath = CQ.shared.HTTP.getContextPath();
23793                var url = resultPage + ".html?tzOffset=" + (new Date().getTimezoneOffset()) + "&" + filter;
23794                window.location.replace(url);
23795            }
23796        });
23797    };
23798    var getTitle = function(itemObj) {
23799        /*
23800         * Most resource types have their title stored in subject property.
23801         * Folder has it in name property.
23802         * Replies, comments, answers don't have title - for now display last of resource type.
23803         */
23804        var title = (itemObj.subject && itemObj.subject.length > 0) ? itemObj.subject : (itemObj.name && itemObj.name.length > 0) ? itemObj.name : itemObj.resourceType.split("/")[itemObj.resourceType.split("/").length - 1];
23805        return title;
23806    };
23807    var getIconClassName = function(str) {
23808        return str.replace(/\//g, "-");
23809    };
23810    var getUrl = function(value) {
23811        var url = $CQ(".scf-js-search-endpoint").val() + ".social.json?" + getFilter(value);
23812        return url;
23813    };
23814    var getFilter = function(value, isRegularSearch) {
23815        var filter = "";
23816        var paths = $CQ(".scf-js-searchform").data("paths");
23817        var searchPaths;
23818        if (typeof(paths) !== 'undefined' && paths !== null && paths.length > 0) {
23819            paths = paths.substring(1, paths.length - 1); // remove '[' and ']'
23820            searchPaths = paths.split(',');
23821        }
23822        value = value.trim();
23823        //value = value.replace(/,/gi, '\\,');
23824        //value = value.replace('*', '\\*');
23825        if (value && value.length > 0) {
23826            filter = "filter=jcr:title like '" + encodeURIComponent(value) + "'";
23827            filter += (filter.length > 0) ? ", " : "filter=";
23828            filter += "author_display_name like '" + encodeURIComponent(value) + "'";
23829
23830            // when focusing in search filed and pressing Enter (not quikcsearch mode)
23831            // need to also search on tag and description
23832            if (isRegularSearch) {
23833                filter += ", jcr:description like '" + encodeURIComponent(value) + "'";
23834                filter += ", tag like '" + encodeURIComponent(value) + "'";
23835            }
23836            filter += "&expLanguage=" + "default";
23837            filter += "&searchText=" + encodeURIComponent(value);
23838        }
23839        if (typeof(searchPaths) != 'undefined') {
23840            for (i = 0; i < searchPaths.length; i++) {
23841                filter += "&path=" + searchPaths[i].trim();
23842            }
23843        }
23844        var contextPath = CQ.shared.HTTP.getContextPath();
23845        contextPath = (contextPath !== null && contextPath.length > 0) ? contextPath : CQ.shared.HTTP.getPath();
23846        filter += "&_charset_=utf-8";
23847        return filter;
23848    };
23849    if ($CQ("#scf-js-quicksearch-input-inline").length !== 0) {
23850        initQuicksearch($CQ("#scf-js-quicksearch-input-inline"));
23851    }
23852});
23853
23854/*******************************************************************************
23855 * Copyright 2016 Adobe
23856 *
23857 * Licensed under the Apache License, Version 2.0 (the "License");
23858 * you may not use this file except in compliance with the License.
23859 * You may obtain a copy of the License at
23860 *
23861 *     http://www.apache.org/licenses/LICENSE-2.0
23862 *
23863 * Unless required by applicable law or agreed to in writing, software
23864 * distributed under the License is distributed on an "AS IS" BASIS,
23865 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23866 * See the License for the specific language governing permissions and
23867 * limitations under the License.
23868 ******************************************************************************/
23869(function() {
23870    "use strict";
23871
23872    var NS = "cmp";
23873    var IS = "formText";
23874    var IS_DASH = "form-text";
23875
23876    var selectors = {
23877        self: "[data-" + NS + '-is="' + IS + '"]'
23878    };
23879
23880    var properties = {
23881        /**
23882         * A validation message to display if there is a type mismatch between the user input and expected input.
23883         *
23884         * @type {String}
23885         */
23886        constraintMessage: "",
23887        /**
23888         * A validation message to display if no input is supplied, but input is expected for the field.
23889         *
23890         * @type {String}
23891         */
23892        requiredMessage: ""
23893    };
23894
23895    function readData(element) {
23896        var data = element.dataset;
23897        var options = [];
23898        var capitalized = IS;
23899        capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
23900        var reserved = ["is", "hook" + capitalized];
23901
23902        for (var key in data) {
23903            if (Object.prototype.hasOwnProperty.call(data, key)) {
23904                var value = data[key];
23905
23906                if (key.indexOf(NS) === 0) {
23907                    key = key.slice(NS.length);
23908                    key = key.charAt(0).toLowerCase() + key.substring(1);
23909
23910                    if (reserved.indexOf(key) === -1) {
23911                        options[key] = value;
23912                    }
23913                }
23914            }
23915        }
23916
23917        return options;
23918    }
23919
23920    function FormText(config) {
23921        if (config.element) {
23922            // prevents multiple initialization
23923            config.element.removeAttribute("data-" + NS + "-is");
23924        }
23925
23926        this._cacheElements(config.element);
23927        this._setupProperties(config.options);
23928
23929        this._elements.input.addEventListener("invalid", this._onInvalid.bind(this));
23930        this._elements.input.addEventListener("input", this._onInput.bind(this));
23931    }
23932
23933    FormText.prototype._onInvalid = function(event) {
23934        event.target.setCustomValidity("");
23935        if (event.target.validity.typeMismatch) {
23936            if (this._properties.constraintMessage) {
23937                event.target.setCustomValidity(this._properties.constraintMessage);
23938            }
23939        } else if (event.target.validity.valueMissing) {
23940            if (this._properties.requiredMessage) {
23941                event.target.setCustomValidity(this._properties.requiredMessage);
23942            }
23943        }
23944    };
23945
23946    FormText.prototype._onInput = function(event) {
23947        event.target.setCustomValidity("");
23948    };
23949
23950    FormText.prototype._cacheElements = function(wrapper) {
23951        this._elements = {};
23952        this._elements.self = wrapper;
23953        var hooks = this._elements.self.querySelectorAll("[data-" + NS + "-hook-" + IS_DASH + "]");
23954        for (var i = 0; i < hooks.length; i++) {
23955            var hook = hooks[i];
23956            var capitalized = IS;
23957            capitalized = capitalized.charAt(0).toUpperCase() + capitalized.slice(1);
23958            var key = hook.dataset[NS + "Hook" + capitalized];
23959            this._elements[key] = hook;
23960        }
23961    };
23962
23963    FormText.prototype._setupProperties = function(options) {
23964        this._properties = {};
23965
23966        for (var key in properties) {
23967            if (Object.prototype.hasOwnProperty.call(properties, key)) {
23968                var property = properties[key];
23969                if (options && options[key] != null) {
23970                    if (property && typeof property.transform === "function") {
23971                        this._properties[key] = property.transform(options[key]);
23972                    } else {
23973                        this._properties[key] = options[key];
23974                    }
23975                } else {
23976                    this._properties[key] = properties[key]["default"];
23977                }
23978            }
23979        }
23980    };
23981
23982    function onDocumentReady() {
23983        var elements = document.querySelectorAll(selectors.self);
23984        for (var i = 0; i < elements.length; i++) {
23985            new FormText({ element: elements[i], options: readData(elements[i]) });
23986        }
23987
23988        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
23989        var body = document.querySelector("body");
23990        var observer = new MutationObserver(function(mutations) {
23991            mutations.forEach(function(mutation) {
23992                // needed for IE
23993                var nodesArray = [].slice.call(mutation.addedNodes);
23994                if (nodesArray.length > 0) {
23995                    nodesArray.forEach(function(addedNode) {
23996                        if (addedNode.querySelectorAll) {
23997                            var elementsArray = [].slice.call(addedNode.querySelectorAll(selectors.self));
23998                            elementsArray.forEach(function(element) {
23999                                new FormText({ element: element, options: readData(element) });
24000                            });
24001                        }
24002                    });
24003                }
24004            });
24005        });
24006
24007        observer.observe(body, {
24008            subtree: true,
24009            childList: true,
24010            characterData: true
24011        });
24012    }
24013
24014    if (document.readyState !== "loading") {
24015        onDocumentReady();
24016    } else {
24017        document.addEventListener("DOMContentLoaded", onDocumentReady);
24018    }
24019
24020})();
24021
24022/**
24023 * ...
24024 *
24025 * @module search-trip-recent-searches
24026 * @version 1.0.0
24027 * @since Fri Jan 08 2016
24028 */
24029'use strict';
24030
24031//dependencies
24032var registerComponent = require('com/register/register-component');
24033var jQuery = require('jQuery');
24034var isFunction = require('lodash.isfunction');
24035var createSearchQuery = require('common/search-trip/clientlibs/search-trip-query-helper').createQuery;
24036var forEach = require('lodash.foreach');
24037
24038exports = module.exports = createSearchTripsRecentSearchesInstance;
24039
24040/**
24041 * The definition of the component. Each DOM element will
24042 * define the elements class with this string.
24043 * @type {String}
24044 */
24045exports.componentReference = 'am-js__search-trip-recent-searches';
24046
24047/**
24048 * The style definition of the component.
24049 * @type {String}
24050 */
24051exports.styleDefinition = 'search-trip-recent-searches';
24052
24053/**
24054 * Factory method to create an instance. Linked to an html element.
24055 *
24056 * @return {object} Component instance.
24057 */
24058function createSearchTripsRecentSearchesInstance() {
24059    /**
24060     * Component instance.
24061     * @type {Object}
24062     */
24063    var instance = {};
24064
24065    /**
24066     * @type {object}
24067     */
24068    var $buttons;
24069
24070    /**
24071     * The DOM Element was added to the DOM.
24072     */
24073    instance.attached = function () {
24074        init();
24075    };
24076
24077    /**
24078     * The DOM Element was removed from the DOM.
24079     */
24080    instance.detached = function () {
24081        dispose();
24082    };
24083
24084    /**
24085     * DOM Element and component is ready.
24086     */
24087    function init() {
24088        addListeners();
24089    }
24090
24091    /**
24092     * Append listeners to the element.
24093     */
24094    function addListeners() {
24095        addListenersToRecentSearches();
24096    }
24097
24098    /**
24099     * Add listeners to recent-search buttons.
24100     */
24101    function addListenersToRecentSearches() {
24102        $buttons = jQuery(instance.element).find('.' + exports.styleDefinition + '__container__list_item_btn');
24103        $buttons.on('click', onRecentSearchClickListener);
24104    }
24105
24106    /**
24107     * Handles click event on a recent search item.
24108     *
24109     * @param  {Object} event
24110     */
24111    function onRecentSearchClickListener(event) {
24112        if (!isFunction(instance.params.recentSearchSelected)) {
24113            return;
24114        }
24115        var button = jQuery(event.target);
24116        var searchParams = button.data();
24117        var stations = {
24118            from: searchParams.fromStation,
24119            to: searchParams.toStation
24120        };
24121        var dates = {
24122            from: searchParams.fromDate,
24123            to: searchParams.toDate
24124        };
24125        var travelers = createTypeObject(searchParams, 'traveler');
24126        var discounts = createTypeObject(searchParams, 'discounts');
24127
24128        instance.params.recentSearchSelected(createSearchQuery(searchParams.mode, stations, dates, travelers, discounts));
24129    }
24130
24131    /**
24132     * Itearates the `searchParams` object and create a new object using keys
24133     * that are matching the critera of `match`.
24134     *
24135     * @param  {object} searchParams
24136     * @param  {string} match
24137     * @return {object}
24138     */
24139    function createTypeObject(searchParams, match) {
24140        var result = {};
24141        forEach(searchParams, function (value, key) {
24142            if (!inString(key, match)) {
24143                return;
24144            }
24145            key = removeAllMatches(key, match).toLowerCase();
24146            result[key] = value;
24147        });
24148        return result;
24149    }
24150
24151    /**
24152     * Checks for a `match` in `string`.
24153     *
24154     * @param  {string} string
24155     * @param  {string} match
24156     * @return {boolean}
24157     */
24158    function inString(string, match) {
24159        return string.indexOf(match) > -1;
24160    }
24161
24162    /**
24163     * Removes all matching words from `string`.
24164     *
24165     * @param  {string} string
24166     * @param  {string} match
24167     * @return {string}        [description]
24168     */
24169    function removeAllMatches(string, match) {
24170        var regEx = new RegExp(match, 'g');
24171        return string.replace(regEx, '');
24172    }
24173
24174    /**
24175     * Dealloc variables and removes any added listeners.
24176     */
24177    function dispose() {
24178        $buttons.off('click', onRecentSearchClickListener);
24179    }
24180
24181    return instance;
24182}
24183
24184registerComponent(exports.componentReference, createSearchTripsRecentSearchesInstance);
24185
24186/**
24187 * ...
24188 *
24189 * @module search-trip-mobile-intro
24190 * @version 1.0.0
24191 * @since Tue Dec 08 2015
24192 */
24193"use strict";
24194
24195//dependencies
24196var first = require('lodash.first');
24197var registerComponent = require('com/register/register-component');
24198var jQuery = require('jQuery');
24199var isFunction = require('lodash.isfunction');
24200var searchStationField = require('search-station-field/clientlibs');
24201
24202exports = module.exports = createSearchTripMobileIntroInstance;
24203
24204/**
24205 * The definition of the component. Each DOM element will
24206 * define the elements class with this string.
24207 * @type {String}
24208 */
24209exports.componentReference = 'am-js__search-trip-mobile-intro';
24210
24211/**
24212 * The style definition of the component.
24213 * @type {String}
24214 */
24215exports.styleDefinition = 'search-trip-mobile-intro';
24216
24217/**
24218 * Factory method to create an instance. Linked to an html element.
24219 *
24220 * @return {object} Component instance.
24221 */
24222function createSearchTripMobileIntroInstance() {
24223    /**
24224     * Component instance.
24225     * @type {Object}
24226     */
24227    var instance = {};
24228
24229    /**
24230     * jQuery instance of the component element
24231     */
24232    var $element;
24233
24234    /**
24235     * Mobile search input
24236     * @type {Object}
24237     */
24238    var $mobileSearchInput;
24239
24240    /**
24241     * Cancel search button
24242     * @type {Object}
24243     */
24244    var $cancelSearchButton;
24245
24246    /**
24247     * Search station field instance
24248     * @type {Object}
24249     */
24250    var searchStationFieldInstance;
24251
24252    /**
24253     * State to track if the mobile input is active
24254     * @type {Boolean}
24255     */
24256    var isMobileInputActive;
24257
24258    /**
24259     * The DOM Element was added to the DOM.
24260     */
24261    instance.attached = function () {
24262        init();
24263    };
24264
24265    /**
24266     * The DOM Element was removed from the DOM.
24267     */
24268    instance.detached = function () {
24269        dispose();
24270    };
24271
24272    /**
24273     * The DOM Element was removed from the DOM.
24274     */
24275    function init() {
24276        $element = jQuery(instance.element);
24277        $cancelSearchButton = $element.find('.' + exports.styleDefinition + '__clear-btn');
24278        $mobileSearchInput = $element.find('.search-station-field__inp');
24279        searchStationFieldInstance = first(instance.getInstancesOf(searchStationField.componentReference));
24280        jQuery(document).ready(setFocusState.bind(null, false));
24281        addListeners();
24282    }
24283
24284    /**
24285     * Append listeners to the element.
24286     */
24287    function addListeners() {
24288        $mobileSearchInput.focus(onMobileInputFocusListener);
24289        $cancelSearchButton.click(onCancelClickListener);
24290        searchStationFieldInstance.addChangeListener(onSearchStationFieldSelectedListener);
24291    }
24292
24293    /**
24294     * Click listener to handle `focus` event on mobile input
24295     */
24296    function onMobileInputFocusListener() {
24297        if (!isMobileInputActive) {
24298            if (isFunction(instance.params.onInputFocusListener)) {
24299                instance.params.onInputFocusListener();
24300            }
24301            changeMobileInputActiveState(true);
24302            isMobileInputActive = true;
24303        }
24304    }
24305
24306    /**
24307     * Click listener to handle `click` event on Cancel button
24308     */
24309    function onCancelClickListener() {
24310        changeMobileInputActiveState(false);
24311        if (isFunction(instance.params.onCancelMobileInputClickListener)) {
24312            instance.params.onCancelMobileInputClickListener();
24313        }
24314        isMobileInputActive = false;
24315    }
24316
24317    /**
24318     * Adds/removes focus state on the mobile search input
24319     * @param {Boolean} isFocussed whether the focus should be set or not.
24320     */
24321    function setFocusState(isFocussed) {
24322        if (isFocussed) {
24323            $mobileSearchInput.focus();
24324        } else {
24325            $mobileSearchInput.blur();
24326        }
24327    }
24328
24329    /**
24330     * Focus/Blur listener for the mobile input
24331     */
24332    function changeMobileInputActiveState(isActive) {
24333        if (isActive) {
24334            $element.addClass('is-active').removeClass('is-inactive');
24335        } else {
24336            $element.addClass('is-inactive').removeClass('is-active');
24337        }
24338    }
24339
24340    /**
24341     * Listener to handle search-station-field selection
24342     */
24343    function onSearchStationFieldSelectedListener() {
24344        //Open the search modal and populate the selected destination in TO field.
24345        if (isFunction(instance.params.onSearchStationFieldSelectedListener)) {
24346            instance.params.onSearchStationFieldSelectedListener(searchStationFieldInstance.getCurrentCode());
24347        }
24348    }
24349
24350    /**
24351     * The DOM Element was removed from the DOM.
24352     */
24353    function dispose() {
24354        $mobileSearchInput.off('focus');
24355        $cancelSearchButton.off('click');
24356    }
24357
24358    return instance;
24359}
24360
24361registerComponent(exports.componentReference, createSearchTripMobileIntroInstance);
24362

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.