PageSourceSearch

https://jacktime.ru/js/build.min.js

js jacktime.ru collected 2026-10-08 14:30:07 UTC 190,503 bytes, 4,117 lines download raw bytes

1/*!
2* jquery.inputmask.js
3* http://github.com/RobinHerbots/jquery.inputmask
4* Copyright (c) 2010 - 2014 Robin Herbots
5* Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
6* Version: 3.1.49
7*/
8!function(factory) {
9    "function" == typeof define && define.amd ? define([ "jquery" ], factory) : factory(jQuery);
10}(function($) {
11    function isInputEventSupported(eventName) {
12        var el = document.createElement("input"), evName = "on" + eventName, isSupported = evName in el;
13        return isSupported || (el.setAttribute(evName, "return;"), isSupported = "function" == typeof el[evName]),
14        el = null, isSupported;
15    }
16    function isInputTypeSupported(inputType) {
17        var isSupported = "text" == inputType || "tel" == inputType;
18        if (!isSupported) {
19            var el = document.createElement("input");
20            el.setAttribute("type", inputType), isSupported = "text" === el.type, el = null;
21        }
22        return isSupported;
23    }
24    function resolveAlias(aliasStr, options, opts) {
25        var aliasDefinition = opts.aliases[aliasStr];
26        return aliasDefinition ? (aliasDefinition.alias && resolveAlias(aliasDefinition.alias, void 0, opts),
27        $.extend(!0, opts, aliasDefinition), $.extend(!0, opts, options), !0) : !1;
28    }
29    function generateMaskSet(opts) {
30        function analyseMask(mask) {
31            function maskToken(isGroup, isOptional, isQuantifier, isAlternator) {
32                this.matches = [], this.isGroup = isGroup || !1, this.isOptional = isOptional || !1,
33                this.isQuantifier = isQuantifier || !1, this.isAlternator = isAlternator || !1,
34                this.quantifier = {
35                    min: 1,
36                    max: 1
37                };
38            }
39            function insertTestDefinition(mtoken, element, position) {
40                var maskdef = opts.definitions[element], newBlockMarker = 0 == mtoken.matches.length;
41                if (position = void 0 != position ? position : mtoken.matches.length, maskdef && !escaped) {
42                    maskdef.placeholder = $.isFunction(maskdef.placeholder) ? maskdef.placeholder.call(this, opts) : maskdef.placeholder;
43                    for (var prevalidators = maskdef.prevalidator, prevalidatorsL = prevalidators ? prevalidators.length : 0, i = 1; i < maskdef.cardinality; i++) {
44                        var prevalidator = prevalidatorsL >= i ? prevalidators[i - 1] : [], validator = prevalidator.validator, cardinality = prevalidator.cardinality;
45                        mtoken.matches.splice(position++, 0, {
46                            fn: validator ? "string" == typeof validator ? new RegExp(validator) : new function() {
47                                this.test = validator;
48                            }() : new RegExp("."),
49                            cardinality: cardinality ? cardinality : 1,
50                            optionality: mtoken.isOptional,
51                            newBlockMarker: newBlockMarker,
52                            casing: maskdef.casing,
53                            def: maskdef.definitionSymbol || element,
54                            placeholder: maskdef.placeholder,
55                            mask: element
56                        });
57                    }
58                    mtoken.matches.splice(position++, 0, {
59                        fn: maskdef.validator ? "string" == typeof maskdef.validator ? new RegExp(maskdef.validator) : new function() {
60                            this.test = maskdef.validator;
61                        }() : new RegExp("."),
62                        cardinality: maskdef.cardinality,
63                        optionality: mtoken.isOptional,
64                        newBlockMarker: newBlockMarker,
65                        casing: maskdef.casing,
66                        def: maskdef.definitionSymbol || element,
67                        placeholder: maskdef.placeholder,
68                        mask: element
69                    });
70                } else mtoken.matches.splice(position++, 0, {
71                    fn: null,
72                    cardinality: 0,
73                    optionality: mtoken.isOptional,
74                    newBlockMarker: newBlockMarker,
75                    casing: null,
76                    def: element,
77                    placeholder: void 0,
78                    mask: element
79                }), escaped = !1;
80            }
81            for (var match, m, openingToken, currentOpeningToken, alternator, lastMatch, tokenizer = /(?:[?*+]|\{[0-9\+\*]+(?:,[0-9\+\*]*)?\})\??|[^.?*+^${[]()|\\]+|./g, escaped = !1, currentToken = new maskToken(), openenings = [], maskTokens = []; match = tokenizer.exec(mask); ) switch (m = match[0],
82            m.charAt(0)) {
83              case opts.optionalmarker.end:
84              case opts.groupmarker.end:
85                if (openingToken = openenings.pop(), openenings.length > 0) {
86                    if (currentOpeningToken = openenings[openenings.length - 1], currentOpeningToken.matches.push(openingToken),
87                    currentOpeningToken.isAlternator) {
88                        alternator = openenings.pop();
89                        for (var mndx = 0; mndx < alternator.matches.length; mndx++) alternator.matches[mndx].isGroup = !1;
90                        openenings.length > 0 ? (currentOpeningToken = openenings[openenings.length - 1],
91                        currentOpeningToken.matches.push(alternator)) : currentToken.matches.push(alternator);
92                    }
93                } else currentToken.matches.push(openingToken);
94                break;
95
96              case opts.optionalmarker.start:
97                openenings.push(new maskToken(!1, !0));
98                break;
99
100              case opts.groupmarker.start:
101                openenings.push(new maskToken(!0));
102                break;
103
104              case opts.quantifiermarker.start:
105                var quantifier = new maskToken(!1, !1, !0);
106                m = m.replace(/[{}]/g, "");
107                var mq = m.split(","), mq0 = isNaN(mq[0]) ? mq[0] : parseInt(mq[0]), mq1 = 1 == mq.length ? mq0 : isNaN(mq[1]) ? mq[1] : parseInt(mq[1]);
108                if (("*" == mq1 || "+" == mq1) && (mq0 = "*" == mq1 ? 0 : 1), quantifier.quantifier = {
109                    min: mq0,
110                    max: mq1
111                }, openenings.length > 0) {
112                    var matches = openenings[openenings.length - 1].matches;
113                    if (match = matches.pop(), !match.isGroup) {
114                        var groupToken = new maskToken(!0);
115                        groupToken.matches.push(match), match = groupToken;
116                    }
117                    matches.push(match), matches.push(quantifier);
118                } else {
119                    if (match = currentToken.matches.pop(), !match.isGroup) {
120                        var groupToken = new maskToken(!0);
121                        groupToken.matches.push(match), match = groupToken;
122                    }
123                    currentToken.matches.push(match), currentToken.matches.push(quantifier);
124                }
125                break;
126
127              case opts.escapeChar:
128                escaped = !0;
129                break;
130
131              case opts.alternatormarker:
132                openenings.length > 0 ? (currentOpeningToken = openenings[openenings.length - 1],
133                lastMatch = currentOpeningToken.matches.pop()) : lastMatch = currentToken.matches.pop(),
134                lastMatch.isAlternator ? openenings.push(lastMatch) : (alternator = new maskToken(!1, !1, !1, !0),
135                alternator.matches.push(lastMatch), openenings.push(alternator));
136                break;
137
138              default:
139                if (openenings.length > 0) {
140                    if (currentOpeningToken = openenings[openenings.length - 1], currentOpeningToken.matches.length > 0 && (lastMatch = currentOpeningToken.matches[currentOpeningToken.matches.length - 1],
141                    lastMatch.isGroup && (lastMatch.isGroup = !1, insertTestDefinition(lastMatch, opts.groupmarker.start, 0),
142                    insertTestDefinition(lastMatch, opts.groupmarker.end))), insertTestDefinition(currentOpeningToken, m),
143                    currentOpeningToken.isAlternator) {
144                        alternator = openenings.pop();
145                        for (var mndx = 0; mndx < alternator.matches.length; mndx++) alternator.matches[mndx].isGroup = !1;
146                        openenings.length > 0 ? (currentOpeningToken = openenings[openenings.length - 1],
147                        currentOpeningToken.matches.push(alternator)) : currentToken.matches.push(alternator);
148                    }
149                } else currentToken.matches.length > 0 && (lastMatch = currentToken.matches[currentToken.matches.length - 1],
150                lastMatch.isGroup && (lastMatch.isGroup = !1, insertTestDefinition(lastMatch, opts.groupmarker.start, 0),
151                insertTestDefinition(lastMatch, opts.groupmarker.end))), insertTestDefinition(currentToken, m);
152            }
153            return currentToken.matches.length > 0 && (lastMatch = currentToken.matches[currentToken.matches.length - 1],
154            lastMatch.isGroup && (lastMatch.isGroup = !1, insertTestDefinition(lastMatch, opts.groupmarker.start, 0),
155            insertTestDefinition(lastMatch, opts.groupmarker.end)), maskTokens.push(currentToken)),
156            maskTokens;
157        }
158        function generateMask(mask, metadata) {
159            if (void 0 == mask || "" == mask) return void 0;
160            if (1 == mask.length && 0 == opts.greedy && 0 != opts.repeat && (opts.placeholder = ""),
161            opts.repeat >
161 0 || "*" == opts.repeat || "+" == opts.repeat) {
162                var repeatStart = "*" == opts.repeat ? 0 : "+" == opts.repeat ? 1 : opts.repeat;
163                mask = opts.groupmarker.start + mask + opts.groupmarker.end + opts.quantifiermarker.start + repeatStart + "," + opts.repeat + opts.quantifiermarker.end;
164            }
165            return void 0 == $.inputmask.masksCache[mask] && ($.inputmask.masksCache[mask] = {
166                mask: mask,
167                maskToken: analyseMask(mask),
168                validPositions: {},
169                _buffer: void 0,
170                buffer: void 0,
171                tests: {},
172                metadata: metadata
173            }), $.extend(!0, {}, $.inputmask.masksCache[mask]);
174        }
175        function preProcessMask(mask) {
176            if (mask = mask.toString(), opts.numericInput) {
177                mask = mask.split("").reverse();
178                for (var ndx = 0; ndx < mask.length; ndx++) mask[ndx] == opts.optionalmarker.start ? mask[ndx] = opts.optionalmarker.end : mask[ndx] == opts.optionalmarker.end ? mask[ndx] = opts.optionalmarker.start : mask[ndx] == opts.groupmarker.start ? mask[ndx] = opts.groupmarker.end : mask[ndx] == opts.groupmarker.end && (mask[ndx] = opts.groupmarker.start);
179                mask = mask.join("");
180            }
181            return mask;
182        }
183        var ms = void 0;
184        if ($.isFunction(opts.mask) && (opts.mask = opts.mask.call(this, opts)), $.isArray(opts.mask)) {
185            if (opts.mask.length > 1) {
186                opts.keepStatic = void 0 == opts.keepStatic ? !0 : opts.keepStatic;
187                var altMask = "(";
188                return $.each(opts.mask, function(ndx, msk) {
189                    altMask.length > 1 && (altMask += ")|("), altMask += preProcessMask(void 0 == msk.mask || $.isFunction(msk.mask) ? msk : msk.mask);
190                }), altMask += ")", generateMask(altMask, opts.mask);
191            }
192            opts.mask = opts.mask.pop();
193        }
194        return opts.mask && (ms = void 0 == opts.mask.mask || $.isFunction(opts.mask.mask) ? generateMask(preProcessMask(opts.mask), opts.mask) : generateMask(preProcessMask(opts.mask.mask), opts.mask)),
195        ms;
196    }
197    function maskScope(actionObj, maskset, opts) {
198        function getMaskTemplate(baseOnInput, minimalPos, includeInput) {
199            minimalPos = minimalPos || 0;
200            var ndxIntlzr, test, testPos, maskTemplate = [], pos = 0;
201            do {
202                if (baseOnInput === !0 && getMaskSet().validPositions[pos]) {
203                    var validPos = getMaskSet().validPositions[pos];
204                    test = validPos.match, ndxIntlzr = validPos.locator.slice(), maskTemplate.push(includeInput === !0 ? validPos.input : getPlaceholder(pos, test));
205                } else {
206                    if (minimalPos > pos) {
207                        var testPositions = getTests(pos, ndxIntlzr, pos - 1);
208                        testPos = testPositions[0];
209                    } else testPos = getTestTemplate(pos, ndxIntlzr, pos - 1);
210                    test = testPos.match, ndxIntlzr = testPos.locator.slice(), maskTemplate.push(getPlaceholder(pos, test));
211                }
212                pos++;
213            } while ((void 0 == maxLength || maxLength > pos - 1) && null != test.fn || null == test.fn && "" != test.def || minimalPos >= pos);
214            return maskTemplate.pop(), maskTemplate;
215        }
216        function getMaskSet() {
217            return maskset;
218        }
219        function resetMaskSet(soft) {
220            var maskset = getMaskSet();
221            maskset.buffer = void 0, maskset.tests = {}, soft !== !0 && (maskset._buffer = void 0,
222            maskset.validPositions = {}, maskset.p = 0);
223        }
224        function getLastValidPosition(closestTo) {
225            var maskset = getMaskSet(), lastValidPosition = -1, valids = maskset.validPositions;
226            void 0 == closestTo && (closestTo = -1);
227            var before = lastValidPosition, after = lastValidPosition;
228            for (var posNdx in valids) {
229                var psNdx = parseInt(posNdx);
230                (-1 == closestTo || null != valids[psNdx].match.fn) && (closestTo >= psNdx && (before = psNdx),
231                psNdx >= closestTo && (after = psNdx));
232            }
233            return lastValidPosition = -1 != before && closestTo - before > 1 || closestTo > after ? before : after;
234        }
235        function setValidPosition(pos, validTest, fromSetValid) {
236            if (opts.insertMode && void 0 != getMaskSet().validPositions[pos] && void 0 == fromSetValid) {
237                var i, positionsClone = $.extend(!0, {}, getMaskSet().validPositions), lvp = getLastValidPosition();
238                for (i = pos; lvp >= i; i++) delete getMaskSet().validPositions[i];
239                getMaskSet().validPositions[pos] = validTest;
240                var j, valid = !0;
241                for (i = pos; lvp >= i; i++) {
242                    var t = positionsClone[i];
243                    if (void 0 != t) {
244                        var vps = getMaskSet().validPositions;
245                        j = !opts.keepStatic && vps[i] && (void 0 != vps[i + 1] && getTests(i + 1, vps[i].locator.slice(), i).length > 1 || void 0 != vps[i].alternation) ? i + 1 : seekNext(i),
246                        valid = positionCanMatchDefinition(j, t.match.def) ? valid && isValid(j, t.input, !0, !0) !== !1 : null == t.match.fn;
247                    }
248                    if (!valid) break;
249                }
250                if (!valid) return getMaskSet().validPositions = $.extend(!0, {}, positionsClone),
251                !1;
252            } else getMaskSet().validPositions[pos] = validTest;
253            return !0;
254        }
255        function stripValidPositions(start, end) {
256            var i, startPos = start;
257            for (void 0 != getMaskSet().validPositions[start] && getMaskSet().validPositions[start].input == opts.radixPoint && (end++,
258            startPos++), i = startPos; end > i; i++) void 0 != getMaskSet().validPositions[i] && 0 != opts.canClearPosition(getMaskSet(), i, getLastValidPosition(), opts) && delete getMaskSet().validPositions[i];
259            for (i = end; i <= getLastValidPosition(); ) {
260                var t = getMaskSet().validPositions[i], s = getMaskSet().validPositions[startPos];
261                void 0 != t && void 0 == s ? (positionCanMatchDefinition(startPos, t.match.def) && isValid(startPos, t.input, !0) !== !1 && (delete getMaskSet().validPositions[i],
262                i++), startPos++) : i++;
263            }
264            var lvp = getLastValidPosition();
265            lvp >= start && void 0 != getMaskSet().validPositions[lvp] && getMaskSet().validPositions[lvp].input == opts.radixPoint && delete getMaskSet().validPositions[lvp],
266            resetMaskSet(!0);
267        }
268        function getTestTemplate(pos, ndxIntlzr, tstPs) {
269            for (var testPos, testPositions = getTests(pos, ndxIntlzr, tstPs), lvp = getLastValidPosition(), lvTest = getMaskSet().validPositions[lvp] || getTests(0)[0], lvTestAltArr = void 0 != lvTest.alternation ? lvTest.locator[lvTest.alternation].split(",") : [], ndx = 0; ndx < testPositions.length && (testPos = testPositions[ndx],
270            !(opts.greedy || testPos.match && (testPos.match.optionality === !1 || testPos.match.newBlockMarker === !1) && testPos.match.optionalQuantifier !== !0 && (void 0 == lvTest.alternation || void 0 != testPos.locator[lvTest.alternation] && checkAlternationMatch(testPos.locator[lvTest.alternation].toString().split(","), lvTestAltArr)))); ndx++) ;
271            return testPos;
272        }
273        function getTest(pos) {
274            return getMaskSet().validPositions[pos] ? getMaskSet().validPositions[pos].match : getTests(pos)[0].match;
275        }
276        function positionCanMatchDefinition(pos, def) {
277            for (var valid = !1, tests = getTests(pos), tndx = 0; tndx < tests.length; tndx++) if (tests[tndx].match && tests[tndx].match.def == def) {
278                valid = !0;
279                break;
280            }
281            return valid;
282        }
283        function getTests(pos, ndxIntlzr, tstPs) {
284            function ResolveTestFromToken(maskToken, ndxInitializer, loopNdx, quantifierRecurse) {
285                function handleMatch(match, loopNdx, quantifierRecurse) {
286                    if (testPos > 1e4) return alert("jquery.inputmask: There is probably an error in your mask definition or in the code. Create an issue on github with an example of the mask you are using. " + getMaskSet().mask),
287                    !0;
288                    if (testPos == pos && void 0 == match.matches) return matches.push({
289                        match: match,
290                        locator: loopNdx.reverse()
291                    }), !0;
292                    if (void 0 != match.matches) {
293                        if (match.isGroup && quantifierRecurse !== !0) {
294                            if (match = handleMatch(maskToken.matches[tndx + 1], loopNdx)) return !0;
295                        } else if (match.isOptional) {
296                            var optionalToken = match;
297                            if (match = ResolveTestFromToken(match, ndxInitializer, loopNdx, quantifierRecurse)) {
298                                var latestMatch = matches[matches.length - 1].match, isFirstMatch = 0 == $.inArray(latestMatch, optionalToken.matches);
299                                isFirstMatch && (insertStop = !0), testPos = pos;
300                            }
301                        } else if (match.isAlternator) {
302                            var maltMatches, alternateToken = match, malternateMatches = [], currentMatches = matches.slice(), loopNdxCnt = loopNdx.length, altIndex = ndxInitializer.length > 0 ? ndxInitializer.shift() : -1;
303                            if (-1 == altIndex || "string" == typeof altIndex) {
304                                var altIndexArr, currentPos = testPos, ndxInitializerClone = ndxInitializer.slice();
305                                "string" == typeof altIndex && (altIndexArr = altIndex.split(","));
306                                for (var amndx = 0;
306 amndx < alternateToken.matches.length; amndx++) {
307                                    matches = [], match = handleMatch(alternateToken.matches[amndx], [ amndx ].concat(loopNdx), quantifierRecurse) || match,
308                                    maltMatches = matches.slice(), testPos = currentPos, matches = [];
309                                    for (var i = 0; i < ndxInitializerClone.length; i++) ndxInitializer[i] = ndxInitializerClone[i];
310                                    for (var ndx1 = 0; ndx1 < maltMatches.length; ndx1++) for (var altMatch = maltMatches[ndx1], ndx2 = 0; ndx2 < malternateMatches.length; ndx2++) {
311                                        var altMatch2 = malternateMatches[ndx2];
312                                        if (altMatch.match.mask == altMatch2.match.mask && ("string" != typeof altIndex || -1 != $.inArray(altMatch.locator[loopNdxCnt].toString(), altIndexArr))) {
313                                            maltMatches.splice(ndx1, 1), altMatch2.locator[loopNdxCnt] = altMatch2.locator[loopNdxCnt] + "," + altMatch.locator[loopNdxCnt],
314                                            altMatch2.alternation = loopNdxCnt;
315                                            break;
316                                        }
317                                    }
318                                    malternateMatches = malternateMatches.concat(maltMatches);
319                                }
320                                "string" == typeof altIndex && (malternateMatches = $.map(malternateMatches, function(lmnt, ndx) {
321                                    if (isFinite(ndx)) {
322                                        var mamatch, altLocArr = lmnt.locator[loopNdxCnt].toString().split(",");
323                                        lmnt.locator[loopNdxCnt] = void 0, lmnt.alternation = void 0;
324                                        for (var alndx = 0; alndx < altLocArr.length; alndx++) mamatch = -1 != $.inArray(altLocArr[alndx], altIndexArr),
325                                        mamatch && (void 0 != lmnt.locator[loopNdxCnt] ? (lmnt.locator[loopNdxCnt] += ",",
326                                        lmnt.alternation = loopNdxCnt, lmnt.locator[loopNdxCnt] += altLocArr[alndx]) : lmnt.locator[loopNdxCnt] = parseInt(altLocArr[alndx]));
327                                        if (void 0 != lmnt.locator[loopNdxCnt]) return lmnt;
328                                    }
329                                })), matches = currentMatches.concat(malternateMatches), insertStop = !0;
330                            } else match = handleMatch(alternateToken.matches[altIndex], [ altIndex ].concat(loopNdx), quantifierRecurse);
331                            if (match) return !0;
332                        } else if (match.isQuantifier && quantifierRecurse !== !0) {
333                            var qt = match;
334                            opts.greedy = opts.greedy && isFinite(qt.quantifier.max);
335                            for (var qndx = ndxInitializer.length > 0 && quantifierRecurse !== !0 ? ndxInitializer.shift() : 0; qndx < (isNaN(qt.quantifier.max) ? qndx + 1 : qt.quantifier.max) && pos >= testPos; qndx++) {
336                                var tokenGroup = maskToken.matches[$.inArray(qt, maskToken.matches) - 1];
337                                if (match = handleMatch(tokenGroup, [ qndx ].concat(loopNdx), !0)) {
338                                    var latestMatch = matches[matches.length - 1].match;
339                                    latestMatch.optionalQuantifier = qndx > qt.quantifier.min - 1;
340                                    var isFirstMatch = 0 == $.inArray(latestMatch, tokenGroup.matches);
341                                    if (isFirstMatch) {
342                                        if (qndx > qt.quantifier.min - 1) {
343                                            insertStop = !0, testPos = pos;
344                                            break;
345                                        }
346                                        return !0;
347                                    }
348                                    return !0;
349                                }
350                            }
351                        } else if (match = ResolveTestFromToken(match, ndxInitializer, loopNdx, quantifierRecurse)) return !0;
352                    } else testPos++;
353                }
354                for (var tndx = ndxInitializer.length > 0 ? ndxInitializer.shift() : 0; tndx < maskToken.matches.length; tndx++) if (maskToken.matches[tndx].isQuantifier !== !0) {
355                    var match = handleMatch(maskToken.matches[tndx], [ tndx ].concat(loopNdx), quantifierRecurse);
356                    if (match && testPos == pos) return match;
357                    if (testPos > pos) break;
358                }
359            }
360            var maskTokens = getMaskSet().maskToken, testPos = ndxIntlzr ? tstPs : 0, ndxInitializer = ndxIntlzr || [ 0 ], matches = [], insertStop = !1;
361            if (void 0 == ndxIntlzr) {
362                for (var test, previousPos = pos - 1; void 0 == (test = getMaskSet().validPositions[previousPos]) && previousPos > -1; ) previousPos--;
363                if (void 0 != test && previousPos > -1) testPos = previousPos, ndxInitializer = test.locator.slice(); else {
364                    for (previousPos = pos - 1; void 0 == (test = getMaskSet().tests[previousPos]) && previousPos > -1; ) previousPos--;
365                    void 0 != test && previousPos > -1 && (testPos = previousPos, ndxInitializer = test[0].locator.slice());
366                }
367            }
368            for (var mtndx = ndxInitializer.shift(); mtndx < maskTokens.length; mtndx++) {
369                var match = ResolveTestFromToken(maskTokens[mtndx], ndxInitializer, [ mtndx ]);
370                if (match && testPos == pos || testPos > pos) break;
371            }
372            return (0 == matches.length || insertStop) && matches.push({
373                match: {
374                    fn: null,
375                    cardinality: 0,
376                    optionality: !0,
377                    casing: null,
378                    def: ""
379                },
380                locator: []
381            }), getMaskSet().tests[pos] = $.extend(!0, [], matches), getMaskSet().tests[pos];
382        }
383        function getBufferTemplate() {
384            return void 0 == getMaskSet()._buffer && (getMaskSet()._buffer = getMaskTemplate(!1, 1)),
385            getMaskSet()._buffer;
386        }
387        function getBuffer() {
388            return void 0 == getMaskSet().buffer && (getMaskSet().buffer = getMaskTemplate(!0, getLastValidPosition(), !0)),
389            getMaskSet().buffer;
390        }
391        function refreshFromBuffer(start, end, buffer) {
392            if (buffer = buffer || getBuffer().slice(), start === !0) resetMaskSet(), start = 0,
393            end = buffer.length; else for (var i = start; end > i; i++) delete getMaskSet().validPositions[i],
394            delete getMaskSet().tests[i];
395            for (var i = start; end > i; i++) buffer[i] != opts.skipOptionalPartCharacter && isValid(i, buffer[i], !0, !0);
396        }
397        function casing(elem, test) {
398            switch (test.casing) {
399              case "upper":
400                elem = elem.toUpperCase();
401                break;
402
403              case "lower":
404                elem = elem.toLowerCase();
405            }
406            return elem;
407        }
408        function checkAlternationMatch(altArr1, altArr2) {
409            for (var altArrC = opts.greedy ? altArr2 : altArr2.slice(0, 1), isMatch = !1, alndx = 0; alndx < altArr1.length;
409 alndx++) if (-1 != $.inArray(altArr1[alndx], altArrC)) {
410                isMatch = !0;
411                break;
412            }
413            return isMatch;
414        }
415        function isValid(pos, c, strict, fromSetValid) {
416            function _isValid(position, c, strict, fromSetValid) {
417                var rslt = !1;
418                return $.each(getTests(position), function(ndx, tst) {
419                    for (var test = tst.match, loopend = c ? 1 : 0, chrs = "", i = (getBuffer(), test.cardinality); i > loopend; i--) chrs += getBufferElement(position - (i - 1));
420                    if (c && (chrs += c), rslt = null != test.fn ? test.fn.test(chrs, getMaskSet(), position, strict, opts) : c != test.def && c != opts.skipOptionalPartCharacter || "" == test.def ? !1 : {
421                        c: test.def,
422                        pos: position
423                    }, rslt !== !1) {
424                        var elem = void 0 != rslt.c ? rslt.c : c;
425                        elem = elem == opts.skipOptionalPartCharacter && null === test.fn ? test.def : elem;
426                        var validatedPos = position;
427                        if (void 0 != rslt.remove && stripValidPositions(rslt.remove, rslt.remove + 1),
428                        rslt.refreshFromBuffer) {
429                            var refresh = rslt.refreshFromBuffer;
430                            if (strict = !0, refreshFromBuffer(refresh === !0 ? refresh : refresh.start, refresh.end),
431                            void 0 == rslt.pos && void 0 == rslt.c) return rslt.pos = getLastValidPosition(),
432                            !1;
433                            if (validatedPos = void 0 != rslt.pos ? rslt.pos : position, validatedPos != position) return rslt = $.extend(rslt, isValid(validatedPos, elem, !0)),
434                            !1;
435                        } else if (rslt !== !0 && void 0 != rslt.pos && rslt.pos != position && (validatedPos = rslt.pos,
436                        refreshFromBuffer(position, validatedPos), validatedPos != position)) return rslt = $.extend(rslt, isValid(validatedPos, elem, !0)),
437                        !1;
438                        return 1 != rslt && void 0 == rslt.pos && void 0 == rslt.c ? !1 : (ndx > 0 && resetMaskSet(!0),
439                        setValidPosition(validatedPos, $.extend({}, tst, {
440                            input: casing(elem, test)
441                        }), fromSetValid) || (rslt = !1), !1);
442                    }
443                }), rslt;
444            }
445            function alternate(pos, c, strict, fromSetValid) {
446                var lastAlt, alternation, validPsClone = $.extend(!0, {}, getMaskSet().validPositions);
447                for (lastAlt = getLastValidPosition(); lastAlt >= 0; lastAlt--) if (getMaskSet().validPositions[lastAlt] && void 0 != getMaskSet().validPositions[lastAlt].alternation) {
448                    alternation = getMaskSet().validPositions[lastAlt].alternation;
449                    break;
450                }
451                if (void 0 != alternation) for (var decisionPos in getMaskSet().validPositions) if (parseInt(decisionPos) > parseInt(lastAlt) && void 0 === getMaskSet().validPositions[decisionPos].alternation) {
452                    for (var altPos = getMaskSet().validPositions[decisionPos], decisionTaker = altPos.locator[alternation], altNdxs = getMaskSet().validPositions[lastAlt].locator[alternation].split(","), mndx = 0; mndx < altNdxs.length; mndx++) if (decisionTaker < altNdxs[mndx]) {
453                        for (var possibilityPos, possibilities, dp = decisionPos - 1; dp >= 0; dp--) if (possibilityPos = getMaskSet().validPositions[dp],
454                        void 0 != possibilityPos) {
455                            possibilities = possibilityPos.locator[alternation], possibilityPos.locator[alternation] = altNdxs[mndx];
456                            break;
457                        }
458                        if (decisionTaker != possibilityPos.locator[alternation]) {
459                            for (var buffer = getBuffer().slice(), i = decisionPos; i < getLastValidPosition() + 1; i++) delete getMaskSet().validPositions[i],
460                            delete getMaskSet().tests[i];
461                            resetMaskSet(!0), opts.keepStatic = !opts.keepStatic;
462                            for (var i = decisionPos; i < buffer.length; i++) buffer[i] != opts.skipOptionalPartCharacter && isValid(getLastValidPosition() + 1, buffer[i], !1, !0);
463                            possibilityPos.locator[alternation] = possibilities;
464                            var isValidRslt = isValid(pos, c, strict, fromSetValid);
465                            if (opts.keepStatic = !opts.keepStatic, isValidRslt) return isValidRslt;
466                            resetMaskSet(), getMaskSet().validPositions = $.extend(!0, {}, validPsClone);
467                        }
468                    }
469                    break;
470                }
471                return !1;
472            }
473            function trackbackAlternations(originalPos, newPos) {
474                for (var vp = getMaskSet().validPositions[newPos], targetL
474ocator = vp.locator, tll = targetLocator.length, ps = originalPos; newPos > ps; ps++) if (!isMask(ps)) {
475                    var tests = getTests(ps), bestMatch = tests[0], equality = -1;
476                    $.each(tests, function(ndx, tst) {
477                        for (var i = 0; tll > i; i++) tst.locator[i] && checkAlternationMatch(tst.locator[i].toString().split(","), targetLocator[i].toString().split(",")) && i > equality && (equality = i,
478                        bestMatch = tst);
479                    }), setValidPosition(ps, $.extend({}, bestMatch, {
480                        input: bestMatch.match.def
481                    }), !0);
482                }
483            }
484            strict = strict === !0;
485            for (var buffer = getBuffer(), pndx = pos - 1; pndx > -1 && !getMaskSet().validPositions[pndx]; pndx--) ;
486            for (pndx++; pos > pndx; pndx++) void 0 == getMaskSet().validPositions[pndx] && ((!isMask(pndx) || buffer[pndx] != getPlaceholder(pndx)) && getTests(pndx).length > 1 || buffer[pndx] == opts.radixPoint || "0" == buffer[pndx] && $.inArray(opts.radixPoint, buffer) < pndx) && _isValid(pndx, buffer[pndx], !0);
487            var maskPos = pos, result = !1;
488            if (fromSetValid && maskPos >= getMaskLength() && resetMaskSet(!0), maskPos < getMaskLength() && (result = _isValid(maskPos, c, strict, fromSetValid),
489            !strict && result === !1)) {
490                var currentPosValid = getMaskSet().validPositions[maskPos];
491                if (!currentPosValid || null != currentPosValid.match.fn || currentPosValid.match.def != c && c != opts.skipOptionalPartCharacter) {
492                    if ((opts.insertMode || void 0 == getMaskSet().validPositions[seekNext(maskPos)]) && !isMask(maskPos)) for (var nPos = maskPos + 1, snPos = seekNext(maskPos); snPos >= nPos; nPos++) if (result = _isValid(nPos, c, strict, fromSetValid),
493                    result !== !1) {
494                        trackbackAlternations(maskPos, nPos), maskPos = nPos;
495                        break;
496                    }
497                } else result = {
498                    caret: seekNext(maskPos)
499                };
500            }
501            return result === !1 && opts.keepStatic && isComplete(buffer) && (result = alternate(pos, c, strict, fromSetValid)),
502            result === !0 && (result = {
503                pos: maskPos
504            }), result;
505        }
506        function isMask(pos) {
507            var test = getTest(pos);
508            return null != test.fn ? test.fn : !1;
509        }
510        function getMaskLength() {
511            var maskLength;
512            if (maxLength = $el.prop("maxLength"), -1 == maxLength && (maxLength = void 0),
513            0 == opts.greedy) {
514                var pos, lvp = getLastValidPosition(), testPos = getMaskSet().validPositions[lvp], ndxIntlzr = void 0 != testPos ? testPos.locator.slice() : void 0;
515                for (pos = lvp + 1; void 0 == testPos || null != testPos.match.fn || null == testPos.match.fn && "" != testPos.match.def; pos++) testPos = getTestTemplate(pos, ndxIntlzr, pos - 1),
516                ndxIntlzr = testPos.locator.slice();
517                maskLength = pos;
518            } else maskLength = getBuffer().length;
519            return void 0 == maxLength || maxLength > maskLength ? maskLength : maxLength;
520        }
521        function seekNext(pos) {
522            var maskL = getMaskLength();
523            if (pos >= maskL) return maskL;
524            for (var position = pos; ++position < maskL && !isMask(position) && (opts.nojumps !== !0 || opts.nojumpsThreshold > position); ) ;
525            return position;
526        }
527        function seekPrevious(pos) {
528            var position = pos;
529            if (0 >= position) return 0;
530            for (;--position > 0 && !isMask(position); ) ;
531            return position;
532        }
533        function getBufferElement(position) {
534            return void 0 == getMaskSet().validPositions[position] ? getPlaceholder(position) : getMaskSet().validPositions[position].input;
535        }
536        function writeBuffer(input, buffer, caretPos, event, triggerInputEvent) {
537            if (event && $.isFunction(opts.onBeforeWrite)) {
538                var result = opts.onBeforeWrite.call(input, event, buffer, caretPos, opts);
539                if (result && result.refreshFromBuffer) {
540                    var refresh = result.refreshFromBuffer;
541                    refreshFromBuffer(refresh === !0 ? refresh : refresh.start, refresh.end, result.buffer),
542                    resetMaskSet(!0), caretPos = result.caret || caretPos;
543                }
544            }
545            input._valueSet(buffer.join("")), void 0 != caretPos && caret(input, caretPos),
546            triggerInputEvent === !0 && (skipInputEvent = !0, $(input).trigger("input"));
547        }
548        function getPlaceholder(pos, test) {
549            return test = test || getTest(pos), void 0 != test.placeholder ? test.placeholder : null == test.fn ? test.def : opts.placeholder.charAt(pos % opts.placeholder.length);
550        }
551        function checkVal(input, writeOut, strict, nptvl) {
552            function isTemplateMatch() {
553                var isMatch = !1, charCodeNdx = getBufferTemplate().slice(initialNdx, seekNext(initialNdx)).join("").indexOf(charCodes);
554                if (-1 != charCodeNdx && !isMask(initialNdx)) {
555                    isMatch = !0;
556                    for (var bufferTemplateArr = getBufferTemplate().slice(initialNdx, initialNdx + charCodeNdx), i = 0; i < bufferTemplateArr.length; i++) if (" " != bufferTemplateArr[i]) {
557                        isMatch = !1;
558                        break;
559                    }
560                }
561                return isMatch;
562            }
563            var inputValue = void 0 != nptvl ? nptvl.slice() : input._valueGet().split("");
564            resetMaskSet(), getMaskSet().p = seekNext(-1), writeOut && input._valueSet("");
565            var staticInput = getBufferTemplate().slice(0, seekNext(-1)).join(""), matches = inputValue.join("").match(new RegExp(escapeRegex(staticInput), "g"));
566            matches && matches.length > 0 && inputValue.splice(0, staticInput.length * matches.length);
567            var charCodes = "", initialNdx = 0;
568            $.each(inputValue, function(ndx, charCode) {
569                var keypress = $.Event("keypress");
570                keypress.which = charCode.charCodeAt(0), charCodes += charCode;
571                var lvp = getLastValidPosition(), lvTest = getMaskSet().validPositions[lvp], nextTest = getTestTemplate(lvp + 1, lvTest ? lvTest.locator.slice() : void 0, lvp);
572                if (!isTemplateMatch() || strict) {
573                    var pos = strict ? ndx : null == nextTest.match.fn && nextTest.match.optionality && lvp + 1 < getMaskSet().p ? lvp + 1 : getMaskSet().p;
574                    keypressEvent.call(input, keypress, !0, !1, strict, pos), initialNdx = pos + 1,
575                    charCodes = "";
576                } else keypressEvent.call(input, keypress, !0, !1, !0, lvp + 1);
577            }), writeOut && writeBuffer(input, getBuffer(), $(input).is(":focus") ? seekNext(getLastValidPosition(0)) : void 0, $.Event("checkval"));
578        }
579        function escapeRegex(str) {
580            return $.inputmask.escapeRegex.call(this, str);
581        }
582        function unmaskedvalue($input) {
583            if ($input.data("_inputmask") && !$input.hasClass("hasDatepicker")) {
584                var umValue = [], vps = getMaskSet().validPositions;
585                for (var pndx in vps) vps[pndx].match && null != vps[pndx].match.fn && umValue.push(vps[pndx].input);
586                var unmaskedValue = (isRTL ? umValue.reverse() : umValue).join(""), bufferValue = (isRTL ? getBuffer().slice().reverse() : getBuffer()).join("");
587                return $.isFunction(opts.onUnMask) && (unmaskedValue = opts.onUnMask.call($input, bufferValue, unmaskedValue, opts) || unmaskedValue),
588                unmaskedValue;
589            }
590            return $input[0]._valueGet();
591        }
592        function TranslatePosition(pos) {
593            if (isRTL && "number" == typeof pos && (!opts.greedy || "" != opts.placeholder)) {
594                var bffrLght = getBuffer().length;
595                pos = bffrLght - pos;
596            }
597            return pos;
598        }
599        function caret(input, begin, end) {
600            var range, npt = input.jquery && input.length > 0 ? input[0] : input;
601            if ("number" != typeof begin) return npt.setSelectionRange ? (begin = npt.selectionStart,
602            end = npt.selectionEnd) : document.selection && document.selection.createRange && (range = document.selection.createRange(),
603            begin = 0 - range.duplicate().moveStart("character", -1e5), end = begin + range.text.length),
604            {
605                begin: TranslatePosition(begin),
606                end: TranslatePosition(end)
607            };
608            if (begin = TranslatePosition(begin), end = TranslatePosition(end), end = "number" == typeof end ? end : begin,
609            $(npt).is(":visible")) {
610                var scrollCalc = $(npt).css("font-size").replace("px", "") * end;
611                npt.scrollLeft = scrollCalc > npt.scrollWidth ? scrollCalc : 0, 0 == opts.insertMode && begin == end && end++,
612                npt.setSelectionRange ? (npt.selectionStart = begin, npt.selectionEnd = end) : npt.createTextRange && (range = npt.createTextRange(),
613                range.collapse(!0), range.moveEnd("character", end), range.moveStart("character", begin),
614                range.select());
615            }
616        }
617        function determineLastRequiredPosition(returnDefinition) {
618            var pos, testPos, buffer = getBuffer(), bl = buffer.length, lvp = getLastValidPosition(), positions = {}, lvTest = getMaskSet().validPositions[lvp], ndxIntlzr = void 0 != lvTest ? lvTest.locator.slice() : void 0;
619            for (pos = lvp + 1; pos < buffer.length; pos++) testPos = getTestTemplate(pos, ndxIntlzr, pos - 1),
620            ndxIntlzr = testPos.locator.slice(), positions[pos] = $.extend(!0, {}, testPos);
621            var lvTestAltArr = lvTest && void 0 != lvTest.alternation ? lvTest.locator[lvTest.alternation].split(",") : [];
622            for (pos = bl - 1; pos > lvp && (testPos = positions[pos].match, (testPos.optionality || testPos.optionalQuantifier || lvTest && void 0 != lvTest.alternation && void 0 != positions[pos].locator[lvTest.alternation] && -1 != $.inArray(positions[pos].locator[lvTest.alternation].toString(), lvTestAltArr)) && buffer[pos] == getPlaceholder(pos, testPos)); pos--) bl--;
623            return returnDefinition ? {
624                l: bl,
625                def: positions[bl] ? positions[bl].match : void 0
626            } : bl;
627        }
628        function clearOptionalTail(buffer) {
629            for (var rl = determineLastRequiredPosition(), lmib = buffer.length - 1; lmib > rl && !isMask(lmib); lmib--) ;
630            buffer.splice(rl, lmib + 1 - rl);
631        }
632        function isComplete(buffer) {
633            if ($.isFunction(opts.isComplete)) return opts.isComplete.call($el, buffer, opts);
634            if ("*" == opts.repeat) return void 0;
635            var complete = !1, lrp = determineLastRequiredPosition(!0), aml = seekPrevious(lrp.l), lvp = getLastValidPosition();
636            if (lvp == aml && (void 0 == lrp.def || lrp.def.newBlockMarker || lrp.def.optionalQuantifier)) {
637                complete = !0;
638                for (var i = 0; aml >= i; i++) {
639                    var mask = isMask(i);
640                    if (mask && (void 0 == buffer[i] || buffer[i] == getPlaceholder(i)) || !mask && buffer[i] != getPlaceholder(i)) {
641                        complete = !1;
642                        break;
643                    }
644                }
645            }
646            return complete;
647        }
648        function isSelection(begin, end) {
649            return isRTL ? begin - end > 1 || begin - end == 1 && opts.insertMode : end - begin > 1 || end - begin == 1 && opts.insertMode;
650        }
651        function installEventRuler(npt) {
652            var events = $._data(npt).events;
653            $.each(events, function(eventType, eventHandlers) {
654                $.each(eventHandlers, function(ndx, eventHandler) {
655                    if ("inputmask" == eventHandler.namespace && "setvalue" != eventHandler.type) {
656                        var handler = eventHandler.handler;
657                        eventHandler.handler = function(e) {
658                            if (!this.disabled && (!this.readOnly || "keydown" == e.type && e.ctrlKey && 67 == e.keyCode)) {
659                                switch (e.type) {
660                                  case "input":
661                                    if (skipInputEvent === !0) return skipInputEvent = !1, e.preventDefault();
662                                    break;
663
664                                  case "keydown":
665                                    skipKeyPressEvent = !1;
666                                    break;
667
668                                  case "keypress":
669                                    if (skipKeyPressEvent === !0) return e.preventDefault();
670                                    skipKeyPressEvent = !0;
671                                    break;
672
673                                  case "compositionstart":
674                                    break;
675
676                                  case "compositionupdate":
677                                    skipInputEvent = !0;
678                                    break;
679
680                                  case "compositionend":                                }
681                                return handler.apply(this, arguments);
682                            }
683                            e.preventDefault();
684                        };
685                    }
686                });
687            });
688        }
689        function patchValueProperty(npt) {
690            function PatchValhook(type) {
691                if (void 0 == $.valHooks[type] || 1 != $.valHooks[type].inputmaskpatch) {
692                    var valhookGet = $.valHooks[type] && $.valHooks[type].get ? $.valHooks[type].get : function(elem) {
693                        return elem.value;
694                    }, valhookSet = $.valHooks[type] && $.valHooks[type].set ? $.valHooks[type].set : function(elem, value) {
695                        return elem.value = value, elem;
696                    };
697                    $.valHooks[type] = {
698                        get: function(elem) {
699                            var $elem = $(elem);
700                            if ($elem.data("_inputmask")) {
701                                if ($elem.data("_inputmask").opts.autoUnmask) return $elem.inputmask("unmaskedvalue");
702                                var result = valhookGet(elem), inputData = $elem.data("_inputmask"), maskset = inputData.maskset, bufferTemplate = maskset._buffer;
703                                return bufferTemplate = bufferTemplate ? bufferTemplate.join("") : "", result != bufferTemplate ? result : "";
704                            }
705                            return valhookGet(elem);
706                        },
707                        set: function(elem, value) {
708                            var result, $elem = $(elem), inputData = $elem.data("_inputmask");
709                            return inputData ? (result = valhookSet(elem, $.isFunction(inputData.opts.onBeforeMask) ? inputData.opts.onBeforeMask.call(el, value, inputData.opts) || value : value),
710                            $elem.triggerHandler("setvalue.inputmask")) : result = valhookSet(elem, value),
711                            result;
712                        },
713                        inputmaskpatch: !0
714                    };
715                }
716            }
717            function getter() {
718                var $self = $(this), inputData = $(this).data("_inputmask");
719                return inputData ? inputData.opts.autoUnmask ? $self.inputmask("unmaskedvalue") : valueGet.call(this) != getBufferTemplate().join("") ? valueGet.call(this) : "" : valueGet.call(this);
720            }
721            function setter(value) {
722                var inputData = $(this).data("_inputmask");
723                inputData ? (valueSet.call(this, $.isFunction(inputData.opts.onBeforeMask) ? inputData.opts.onBeforeMask.call(el, value, inputData.opts) || value : value),
724                $(this).triggerHandler("setvalue.inputmask")) : valueSet.call(this, value);
725            }
726            function InstallNativeValueSetFallback(npt) {
727                $(npt).bind("mouseenter.inputmask", function() {
728                    var $input = $(this), input = this, value = input._valueGet();
729                    "" != value && value != getBuffer().join("") && (this._valueSet($.is
729Function(opts.onBeforeMask) ? opts.onBeforeMask.call(el, value, opts) || value : value),
730                    $input.triggerHandler("setvalue.inputmask"));
731                });
732                //!! the bound handlers are executed in the order they where bound
733                var events = $._data(npt).events, handlers = events.mouseover;
734                if (handlers) {
735                    for (var ourHandler = handlers[handlers.length - 1], i = handlers.length - 1; i > 0; i--) handlers[i] = handlers[i - 1];
736                    handlers[0] = ourHandler;
737                }
738            }
739            var valueGet, valueSet;
740            if (!npt._valueGet) {
741                if (Object.getOwnPropertyDescriptor) {
742                    Object.getOwnPropertyDescriptor(npt, "value");
743                }
744                document.__lookupGetter__ && npt.__lookupGetter__("value") ? (valueGet = npt.__lookupGetter__("value"),
745                valueSet = npt.__lookupSetter__("value"), npt.__defineGetter__("value", getter),
746                npt.__defineSetter__("value", setter)) : (valueGet = function() {
747                    return npt.value;
748                }, valueSet = function(value) {
749                    npt.value = value;
750                }, PatchValhook(npt.type), InstallNativeValueSetFallback(npt)), npt._valueGet = function(overruleRTL) {
751                    return isRTL && overruleRTL !== !0 ? valueGet.call(this).split("").reverse().join("") : valueGet.call(this);
752                }, npt._valueSet = function(value) {
753                    valueSet.call(this, isRTL ? value.split("").reverse().join("") : value);
754                };
755            }
756        }
757        function handleRemove(input, k, pos) {
758            function generalize() {
759                if (opts.keepStatic) {
760                    resetMaskSet(!0);
761                    var lastAlt, validInputs = [];
762                    for (lastAlt = getLastValidPosition(); lastAlt >= 0; lastAlt--) if (getMaskSet().validPositions[lastAlt]) {
763                        if (void 0 != getMaskSet().validPositions[lastAlt].alternation) break;
764                        validInputs.push(getMaskSet().validPositions[lastAlt].input), delete getMaskSet().validPositions[lastAlt];
765                    }
766                    if (lastAlt > 0) for (;validInputs.length > 0; ) {
767                        getMaskSet().p = seekNext(getLastValidPosition());
768                        var keypress = $.Event("keypress");
769                        keypress.which = validInputs.pop().charCodeAt(0), keypressEvent.call(input, keypress, !0, !1, !1, getMaskSet().p);
770                    }
771                }
772            }
773            if ((opts.numericInput || isRTL) && (k == $.inputmask.keyCode.BACKSPACE ? k = $.inputmask.keyCode.DELETE : k == $.inputmask.keyCode.DELETE && (k = $.inputmask.keyCode.BACKSPACE),
774            isRTL)) {
775                var pend = pos.end;
776                pos.end = pos.begin, pos.begin = pend;
777            }
778            k == $.inputmask.keyCode.BACKSPACE && pos.end - pos.begin <= 1 ? pos.begin = seekPrevious(pos.begin) : k == $.inputmask.keyCode.DELETE && pos.begin == pos.end && pos.end++,
779            stripValidPositions(pos.begin, pos.end), generalize();
780            var firstMaskedPos = getLastValidPosition(pos.begin);
781            firstMaskedPos < pos.begin ? (-1 == firstMaskedPos && resetMaskSet(), getMaskSet().p = seekNext(firstMaskedPos)) : getMaskSet().p = pos.begin;
782        }
783        function keydownEvent(e) {
784            var input = this, $input = $(input), k = e.keyCode, pos = caret(input);
785            k == $.inputmask.keyCode.BACKSPACE || k == $.inputmask.keyCode.DELETE || iphone && 127 == k || e.ctrlKey && 88 == k && !isInputEventSupported("cut") ? (e.preventDefault(),
786            88 == k && (undoValue = getBuffer().join("")), handleRemove(input, k, pos), writeBuffer(input, getBuffer(), getMaskSet().p, e, undoValue != getBuffer().join("")),
787            input._valueGet() == getBufferTemplate().join("") && $input.trigger("cleared"),
788            opts.showTooltip && $input.prop("title", getMaskSet().mask)) : k == $.inputmask.keyCode.END || k == $.inputmask.keyCode.PAGE_DOWN ? setTimeout(function() {
789                var caretPos = seekNext(getLastValidPosition());
790                opts.insertMode || caretPos != getMaskLength() || e.shiftKey || caretPos--, caret(input, e.shiftKey ? pos.begin : caretPos, caretPos);
791            }, 0) : k == $.inputmask.keyCode.HOME && !e.shiftKey || k == $.inputmask.keyCode.PAGE_UP ? caret(input, 0, e.shiftKey ? pos.begin : 0) : opts.undoOnEscape && k == $.inputmask.keyCode.ESCAPE || 90 == k && e.ctrlKey ? (checkVal(input, !0, !1, undoValue.split("")),
792            $input.click()) : k != $.inputmask.keyCode.INSERT || e.shiftKey || e.ctrlKey ? 0 != opts.insertMode || e.shiftKey || (k == $.inputmask.keyCode.RIGHT ? setTimeout(function() {
793                var caretPos = caret(input);
794                caret(input, caretPos.begin);
795            }, 0) : k == $.inputmask.keyCode.LEFT && setTimeout(function() {
796                var caretPos = caret(input);
797                caret(input, isRTL ? caretPos.begin + 1 : caretPos.begin - 1);
798            }, 0)) : (opts.insertMode = !opts.insertMode, caret(input, opts.insertMode || pos.begin != getMaskLength() ? pos.begin : pos.begin - 1)),
799            ignorable = -1 != $.inArray(k, opts.ignorables);
800        }
801        function keypressEvent(e, checkval, writeOut, strict, ndx) {
802            var input = this, $input = $(input), k = e.which || e.charCode || e.keyCode;
803            if (!(checkval === !0 || e.ctrlKey && e.altKey) && (e.ctrlKey || e.metaKey || ignorable)) return !0;
804            if (k) {
805                46 == k && 0 == e.shiftKey && "," == opts.radixPoint && (k = 44);
806                var forwardPosition, pos = checkval ? {
807                    begin: ndx,
808                    end: ndx
809                } : caret(input), c = String.fromCharCode(k), isSlctn = isSelection(pos.begin, pos.end);
810                isSlctn && (getMaskSet().undoPositions = $.extend(!0, {}, getMaskSet().validPositions),
811                handleRemove(input, $.inputmask.keyCode.DELETE, pos), opts.insertMode || (opts.insertMode = !opts.insertMode,
812                setValidPosition(pos.begin, strict), opts.insertMode = !opts.insertMode), isSlctn = !opts.multi),
813                getMaskSet().writeOutBuffer = !0;
814                var p = isRTL && !isSlctn ? pos.end : pos.begin, valResult = isValid(p, c, strict);
815                if (valResult !== !1) {
816                    if (valResult !== !0 && (p = void 0 != valResult.pos ? valResult.pos : p, c = void 0 != valResult.c ? valResult.c : c),
817                    resetMaskSet(!0), void 0 != valResult.caret) forwardPosition = valResult.caret; else {
818                        var vps = getMaskSet().validPositions;
819                        forwardPosition = !opts.keepStatic && (void 0 != vps[p + 1] && getTests(p + 1, vps[p].locator.slice(), p).length > 1 || void 0 != vps[p].alternation) ? p + 1 : seekNext(p);
820                    }
821                    getMaskSet().p = forwardPosition;
822                }
823                if (writeOut !== !1) {
824                    var self = this;
825                    if (setTimeout(function() {
826                        opts.onKeyValidation.call(self, valResult, opts);
827                    }, 0), getMaskSet().writeOutBuffer && valResult !== !1) {
828                        var buffer = getBuffer();
829                        writeBuffer(input, buffer, checkval ? void 0 : opts.numericInput ? seekPrevious(forwardPosition) : forwardPosition, e, checkval !== !0),
830                        checkval !== !0 && setTimeout(function() {
831                            isComplete(buffer) === !0 && $input.trigger("complete");
832                        }, 0);
833                    } else isSlctn && (getMaskSet().buffer = void 0, getMaskSet().validPositions = getMaskSet().undoPositions);
834                } else isSlctn && (getMaskSet().buffer = void 0, getMaskSet().validPositions = getMaskSet().undoPositions);
835                if (opts.showTooltip && $input.prop("title", getMaskSet().mask), checkval && $.isFunction(opts.onBeforeWrite)) {
836                    var result = opts.onBeforeWrite.call(this, e, getBuffer(), forwardPosition, opts);
837                    if (result && result.refreshFromBuffer) {
838                        var refresh = result.refreshFromBuffer;
839                        refreshFromBuffer(refresh === !0 ? refresh : refresh.start, refresh.end, result.buffer),
840                        resetMaskSet(!0), result.caret && (getMaskSet().p = result.caret);
841                    }
842                }
843                e.preventDefault();
844            }
845        }
846        function keyupEvent(e) {
847            var buffer = ($(this), e.keyCode, getBuffer());
848            opts.onKeyUp.call(this, e, buffer, opts);
849        }
850        function pasteEvent(e) {
851            var input = this, $input = $(input), inputValue = input._valueGet(!0), caretPos = caret(input);
852            if ("propertychange" == e.type && input._valueGet().length <= getMaskLength()) return !0;
853            if ("paste" == e.type) {
854                var valueBeforeCaret = inputValue.substr(0, caretPos.begin), valueAfterCaret = inputValue.substr(caretPos.end, inputValue.length);
855                valueBeforeCaret == getBufferTemplate().slice(0, caretPos.begin).join("") && (valueBeforeCaret = ""),
856                valueAfterCaret == getBufferTemplate().slice(caretPos.end).join("") && (valueAfterCaret = ""),
857                window.clipboardData && window.clipboardData.getData ? inputValue = valueBeforeCaret + window.clipboardData.getData("Text") + valueAfterCaret : e.originalEvent && e.originalEvent.clipboardData && e.originalEvent.clipboardData.getData && (inputValue = valueBeforeCaret + e.originalEvent.clipboardData.getData("text/plain") + valueAfterCaret);
858            }
859            var pasteValue = $.isFunction(opts.onBeforePaste) ? opts.onBeforePaste.call(input, inputValue, opts) || inputValue : inputValue;
860            return checkVal(input, !0, !1, isRTL ? pasteValue.split("").reverse() : pasteValue.split("")),
861            $input.click(), isComplete(getBuffer()) === !0 && $input.trigger("complete"), !1;
862        }
863        function inputFallBackEvent(e) {
864            var input = this;
865            checkVal(input, !0, !1), isComplete(getBuffer()) === !0 && $(input).trigger("complete"),
866            e.preventDefault();
867        }
868        function compositionStartEvent(e) {
869            var input = this;
870            undoValue = getBuffer().join(""), ("" == compositionData || 0 != e.originalEvent.data.indexOf(compositionData)) && (compositionCaretPos = caret(input));
871        }
872        function compositionUpdateEvent(e) {
873            var input = this, caretPos = compositionCaretPos || caret(input);
874            0 == e.originalEvent.data.indexOf(compositionData) && (resetMaskSet(), caretPos = {
875                begin: 0,
876                end: 0
877            });
878            var newData = e.originalEvent.data;
879            caret(input, caretPos.begin, caretPos.end);
880            for (var i = 0; i < newData.length; i++) {
881                var keypress = $.Event("keypress");
882                keypress.which = newData.charCodeAt(i), skipKeyPressEvent = !1, ignorable = !1,
883                keypressEvent.call(input, keypress);
884            }
885            setTimeout(function() {
886                var forwardPosition = getMaskSet().p;
887                writeBuffer(input, getBuffer(), opts.numericInput ? seekPrevious(forwardPosition) : forwardPosition);
888            }, 0), compositionData = e.originalEvent.data;
889        }
890        function compositionEndEvent() {}
891        function mask(el) {
892            if ($el = $(el), $el.is(":input") && isInputTypeSupported($el.attr("type"))) {
893                if ($el.data("_inputmask", {
894                    maskset: maskset,
895                    opts: opts,
896                    isRTL: !1
897                }), opts.showTooltip && $el.prop("title", getMaskSet().mask), ("rtl" == el.dir || opts.rightAlign) && $el.css("text-align", "right"),
898                "rtl" == el.dir || opts.numericInput) {
899                    el.dir = "ltr", $el.removeAttr("dir");
900                    var inputData = $el.data("_inputmask");
901                    inputData.isRTL = !0, $el.data("_inputmask", inputData), isRTL = !0;
902                }
903                $el.unbind(".inputmask"), $el.closest("form").bind("submit", function() {
904                    undoValue != getBuffer().join("") && $el.change(), $el[0]._valueGet && $el[0]._valueGet() == getBufferTemplate().join("") && $el[0]._valueSet(""),
905                    opts.removeMaskOnSubmit && $el.inputmask("remove");
906                }).bind("reset", function() {
907                    setTimeout(function() {
908                        $el.triggerHandler("setvalue.inputmask");
909                    }, 0);
910                }), $el.bind("mouseenter.inputmask", function() {
911                    var $input = $(this), input = this;
912                    !$input.is(":focus") && opts.showMaskOnHover && input._valueGet() != getBuffer().join("") && writeBuffer(input, getBuffer());
913                }).bind("blur.inputmask", function(e) {
914                    var $input = $(this), input = this;
915                    if ($input.data("_inputmask")) {
916                        var nptValue = input._valueGet(), buffer = getBuffer().slice();
917                        firstClick = !0, undoValue != buffer.join("") && ($input.change(), undoValue = buffer.join("")),
918                        "" != nptValue && (opts.clearMaskOnLostFocus && (nptValue == getBufferTemplate().join("") ? buffer = [] : clearOptionalTail(buffer)),
919                        isComplete(buffer) === !1 && ($input.trigger("incomplete"), opts.clearIncomplete && (resetMaskSet(),
920                        buffer = opts.clearMaskOnLostFocus ? [] : getBufferTemplate().slice())), writeBuffer(input, buffer, void 0, e));
921                    }
922                }).bind("focus.inputmask", function() {
923                    var input = ($(this), this), nptValue = input._valueGet();
924                    opts.showMaskOnFocus && (!opts.showMaskOnHover || opts.showMaskOnHover && "" == nptValue) && input._valueGet() != getBuffer().join("") && writeBuffer(input, getBuffer(), seekNext(getLastValidPosition())),
925                    undoValue = getBuffer().join("");
926                }).bind("mouseleave.inputmask", function() {
927                    var $input = $(this), input = this;
928                    if (opts.clearMaskOnLostFocus) {
929                        var buffer = getBuffer().slice(), nptValue = input._valueGet();
930                        $input.is(":focus") || nptValue == $input.attr("placeholder") || "" == nptValue || (nptValue == getBufferTemplate().join("") ? buffer = [] : clearOptionalTail(buffer),
931                        writeBuffer(input, buffer));
932                    }
933                }).bind("click.inputmask", function() {
934                    var $input = $(this), input = this;
935                    if ($input.is(":focus")) {
936                        var selectedCaret = caret(input);
937                        if (selectedCaret.begin == selectedCaret.end) if (opts.radixFocus && "" != opts.radixPoint && -1 != $.inArray(opts.radixPoint, getBuffer()) && (firstClick || getBuffer().join("") == getBufferTemplate().join(""))) caret(input, $.inArray(opts.radixPoint, getBuffer())),
938                        firstClick = !1; else {
939                            var clickPosition = isRTL ? TranslatePosition(selectedCaret.begin) : selectedCaret.begin, lastPosition = seekNext(getLastValidPosition(clickPosition));
940                            lastPosition > clickPosition ? caret(input, isMask(clickPosition) ? clickPosition : seekNext(clickPosition)) : caret(input, lastPosition);
941                        }
942                    }
943                }).bind("dblclick.inputmask", function() {
944                    var input = this;
945                    setTimeout(function() {
946                        caret(input, 0, seekNext(getLastValidPosition()));
947                    }, 0);
948                }).bind(PasteEventType + ".inputmask dragdrop.inputmask drop.inputmask", pasteEvent).bind("setvalue.inputmask", function() {
949                    var input = this;
950                    checkVal(input, !0, !1), undoValue = getBuffer().join(""), (opts.clearMaskOnLostFocus || op
950ts.clearIncomplete) && input._valueGet() == getBufferTemplate().join("") && input._valueSet("");
951                }).bind("cut.inputmask", function(e) {
952                    skipInputEvent = !0;
953                    var input = this, $input = $(input), pos = caret(input);
954                    handleRemove(input, $.inputmask.keyCode.DELETE, pos), writeBuffer(input, getBuffer(), getMaskSet().p, e, undoValue != getBuffer().join("")),
955                    input._valueGet() == getBufferTemplate().join("") && $input.trigger("cleared"),
956                    opts.showTooltip && $input.prop("title", getMaskSet().mask);
957                }).bind("complete.inputmask", opts.oncomplete).bind("incomplete.inputmask", opts.onincomplete).bind("cleared.inputmask", opts.oncleared),
958                $el.bind("keydown.inputmask", keydownEvent).bind("keypress.inputmask", keypressEvent).bind("keyup.inputmask", keyupEvent),
959                androidfirefox || $el.bind("compositionstart.inputmask", compositionStartEvent).bind("compositionupdate.inputmask", compositionUpdateEvent).bind("compositionend.inputmask", compositionEndEvent),
960                "paste" === PasteEventType && $el.bind("input.inputmask", inputFallBackEvent), patchValueProperty(el);
961                var initialValue = $.isFunction(opts.onBeforeMask) ? opts.onBeforeMask.call(el, el._valueGet(), opts) || el._valueGet() : el._valueGet();
962                checkVal(el, !0, !1, initialValue.split(""));
963                var buffer = getBuffer().slice();
964                undoValue = buffer.join("");
965                var activeElement;
966                try {
967                    activeElement = document.activeElement;
968                } catch (e) {}
969                isComplete(buffer) === !1 && opts.clearIncomplete && resetMaskSet(), opts.clearMaskOnLostFocus && (buffer.join("") == getBufferTemplate().join("") ? buffer = [] : clearOptionalTail(buffer)),
970                writeBuffer(el, buffer), activeElement === el && caret(el, seekNext(getLastValidPosition())),
971                installEventRuler(el);
972            }
973        }
974        var undoValue, compositionCaretPos, compositionData, $el, maxLength, isRTL = !1, skipKeyPressEvent = !1, skipInputEvent = !1, ignorable = !1, firstClick = !0;
975        if (void 0 != actionObj) switch (actionObj.action) {
976          case "isComplete":
977            return $el = $(actionObj.el), maskset = $el.data("_inputmask").maskset, opts = $el.data("_inputmask").opts,
978            isComplete(actionObj.buffer);
979
980          case "unmaskedvalue":
981            return $el = actionObj.$input, maskset = $el.data("_inputmask").maskset, opts = $el.data("_inputmask").opts,
982            isRTL = actionObj.$input.data("_inputmask").isRTL, unmaskedvalue(actionObj.$input);
983
984          case "mask":
985            undoValue = getBuffer().join(""), mask(actionObj.el);
986            break;
987
988          case "format":
989            $el = $({}), $el.data("_inputmask", {
990                maskset: maskset,
991                opts: opts,
992                isRTL: opts.numericInput
993            }), opts.numericInput && (isRTL = !0);
994            var valueBuffer = ($.isFunction(opts.onBeforeMask) ? opts.onBeforeMask.call($el, actionObj.value, opts) || actionObj.value : actionObj.value).split("");
995            return checkVal($el, !1, !1, isRTL ? valueBuffer.reverse() : valueBuffer), $.isFunction(opts.onBeforeWrite) && opts.onBeforeWrite.call(this, void 0, getBuffer(), 0, opts),
996            actionObj.metadata ? {
997                value: isRTL ? getBuffer().slice().reverse().join("") : getBuffer().join(""),
998                metadata: $el.inputmask("getmetadata")
999            } : isRTL ? getBuffer().slice().reverse().join("") : getBuffer().join("");
1000
1001          case "isValid":
1002            $el = $({}), $el.data("_inputmask", {
1003                maskset: maskset,
1004                opts: opts,
1005                isRTL: opts.numericInput
1006            }), opts.numericInput && (isRTL = !0);
1007            var valueBuffer = actionObj.value.split("");
1008            checkVal($el, !1, !0, isRTL ? valueBuffer.reverse() : valueBuffer);
1009            for (var buffer = getBuffer(), rl = determineLastRequiredPosition(), lmib = buffer.length - 1; lmib > rl && !isMask(lmib); lmib--) ;
1010            return buffer.splice(rl, lmib + 1 - rl), isComplete(buffer) && actionObj.value == buffer.join("");
1011
1012          case "getemptymask":
1013            return $el = $(actionObj.el), maskset = $el.data("_inputmask").maskset, opts = $el.data("_inputmask").opts,
1014            getBufferTemplate();
1015
1016          case "remove":
1017            var el = actionObj.el;
1018            $el = $(el), maskset = $el.data("_inputmask").maskset, opts = $el.data("_inputmask").opts,
1019            el._valueSet(unmaskedvalue($el)), $el.unbind(".inputmask"), $el.removeData("_inputmask");
1020            var valueProperty;
1021            Object.getOwnPropertyDescriptor && (valueProperty = Object.getOwnPropertyDescriptor(el, "value")),
1022            valueProperty && valueProperty.get ? el._valueGet && Object.defineProperty(el, "value", {
1023                get: el._valueGet,
1024                set: el._valueSet
1025            }) : document.__lookupGetter__ && el.__lookupGetter__("value") && el._valueGet && (el.__defineGetter__("value", el._valueGet),
1026            el.__defineSetter__("value", el._valueSet));
1027            try {
1028                delete el._valueGet, delete el._valueSet;
1029            } catch (e) {
1030                el._valueGet = void 0, el._valueSet = void 0;
1031            }
1032            break;
1033
1034          case "getmetadata":
1035            if ($el = $(actionObj.el), maskset = $el.data("_inputmask").maskset, opts = $el.data("_inputmask").opts,
1036            $.isArray(maskset.metadata)) {
1037                for (var alternation, lvp = getLastValidPosition(), firstAlt = lvp; firstAlt >= 0; firstAlt--) if (getMaskSet().validPositions[firstAlt] && void 0 != getMaskSet().validPositions[firstAlt].alternation) {
1038                    alternation = getMaskSet().validPositions[firstAlt].alternation;
1039                    break;
1040                }
1041                return void 0 != alternation ? maskset.metadata[getMaskSet().validPositions[lvp].locator[alternation]] : maskset.metadata[0];
1042            }
1043            return maskset.metadata;
1044        }
1045    }
1046    if (void 0 === $.fn.inputmask) {
1047        var ua = navigator.userAgent, iphone = null !== ua.match(new RegExp("iphone", "i")), androidfirefox = (null !== ua.match(new RegExp("android.*safari.*", "i")),
1048        null !== ua.match(new RegExp("android.*chrome.*", "i")), null !== ua.match(new RegExp("android.*firefox.*", "i"))), PasteEventType = (/Kindle/i.test(ua) || /Silk/i.test(ua) || /KFTT/i.test(ua) || /KFOT/i.test(ua) || /KFJWA/i.test(ua) || /KFJWI/i.test(ua) || /KFSOWI/i.test(ua) || /KFTHWA/i.test(ua) || /KFTHWI/i.test(ua) || /KFAPWA/i.test(ua) || /KFAPWI/i.test(ua),
1049        isInputEventSupported("paste") ? "paste" : isInputEventSupported("input") ? "input" : "propertychange");
1050        $.inputmask = {
1051            defaults: {
1052                placeholder: "_",
1053                optionalmarker: {
1054                    start: "[",
1055                    end: "]"
1056                },
1057                quantifiermarker: {
1058                    start: "{",
1059                    end: "}"
1060                },
1061                groupmarker: {
1062                    start: "(",
1063                    end: ")"
1064                },
1065                alternatormarker: "|",
1066                escapeChar: "\\",
1067                mask: null,
1068                oncomplete: $.noop,
1069                onincomplete: $.noop,
1070                oncleared: $.noop,
1071                repeat: 0,
1072                greedy: !0,
1073                autoUnmask: !1,
1074                removeMaskOnSubmit: !1,
1075                clearMaskOnLostFocus: !0,
1076                insertMode: !0,
1077                clearIncomplete: !1,
1078                aliases: {},
1079                alias: null,
1080                onKeyUp: $.noop,
1081                onBeforeMask: void 0,
1082                onBeforePaste: void 0,
1083                onBeforeWrite: void 0,
1084                onUnMask: void 0,
1085                showMaskOnFocus: !0,
1086                showMaskOnHover: !0,
1087                onKeyValidation: $.noop,
1088                skipOptionalPartCharacter: " ",
1089                showTooltip: !1,
1090                numericInput: !1,
1091                rightAlign: !1,
1092                undoOnEscape: !0,
1093                radixPoint: "",
1094                radixFocus: !1,
1095                nojumps: !1,
1096                nojumpsThreshold: 0,
1097                keepStatic: void 0,
1098                definitions: {
1099                    "9": {
1100                        validator: "[0-9]",
1101                        cardinality: 1,
1102                        definitionSymbol: "*"
1103                    },
1104                    a: {
1105                        validator: "[A-Za-z\u0410-\u044f\u0401\u0451\xc0-\xff\xb5]",
1106                        cardinality: 1,
1107                        definitionSymbol: "*"
1108                    },
1109                    "*": {
1110                        validator: "[0-9A-Za-z\u0410-\u044f\u0401\u0451\xc0-\xff\xb5]",
1111                        cardinality: 1
1112                    }
1113                },
1114                ignorables: [ 8, 9, 13, 19, 27, 33, 34, 35, 36, 37, 38, 39, 40, 45, 46, 93, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123 ],
1115                isComplete: void 0,
1116                canClearPosition: $.noop
1117            },
1118            keyCode: {
1119                ALT: 18,
1120                BACKSPACE: 8,
1121                CAPS_LOCK: 20,
1122                COMMA: 188,
1123                COMMAND: 91,
1124                COMMAND_LEFT: 91,
1125                COMMAND_RIGHT: 93,
1126                CONTROL: 17,
1127                DELETE: 46,
1128                DOWN: 40,
1129                END: 35,
1130                ENTER: 13,
1131                ESCAPE: 27,
1132                HOME: 36,
1133                INSERT: 45,
1134                LEFT: 37,
1135                MENU: 93,
1136                NUMPAD_ADD: 107,
1137                NUMPAD_DECIMAL: 110,
1138                NUMPAD_DIVIDE: 111,
1139                NUMPAD_ENTER: 108,
1140                NUMPAD_MULTIPLY: 106,
1141                NUMPAD_SUBTRACT: 109,
1142                PAGE_DOWN: 34,
1143                PAGE_UP: 33,
1144                PERIOD: 190,
1145                RIGHT: 39,
1146                SHIFT: 16,
1147                SPACE: 32,
1148                TAB: 9,
1149                UP: 38,
1150                WINDOWS: 91
1151            },
1152            masksCache: {},
1153            escapeRegex: function(str) {
1154                var specials = [ "/", ".", "*", "+", "?", "|", "(", ")", "[", "]", "{", "}", "\\" ];
1155                return str.replace(new RegExp("(\\" + specials.join("|\\") + ")", "gim"), "\\$1");
1156            },
1157            format: function(value, options, metadata) {
1158                var opts = $.extend(!0, {}, $.inputmask.defaults, options);
1159                return resolveAlias(opts.alias, options, opts), maskScope({
1160                    action: "format",
1161                    value: value,
1162                    metadata: metadata
1163                }, generateMaskSet(opts), opts);
1164            },
1165            isValid: function(value, options) {
1166                var opts = $.extend(!0, {}, $.inputmask.defaults, options);
1167                return resolveAlias(opts.alias, options, opts), maskScope({
1168                    action: "isValid",
1169                    value: value
1170                }, generateMaskSet(opts), opts);
1171            }
1172        }, $.fn.inputmask = function(fn, options) {
1173            function importAttributeOptions(npt, opts, importedOptionsContainer) {
1174                var $npt = $(npt);
1175                $npt.data("inputmask-alias") && resolveAlias($npt.data("inputmask-alias"), {}, opts);
1176                for (var option in opts) {
1177                    var optionData = $npt.data("inputmask-" + option.toLowerCase());
1178                    void 0 != optionData && ("mask" == option && 0 == optionData.indexOf("[") ? (opts[option] = optionData.replace(/[\s[\]]/g, "").split("','"),
1179                    opts[option][0] = opts[option][0].replace("'", ""), opts[option][opts[option].length - 1] = opts[option][opts[option].length - 1].replace("'", "")) : opts[option] = "boolean" == typeof optionData ? optionData : optionData.toString(),
1180                    importedOptionsContainer && (importedOptionsContainer[option] = opts[option]));
1181                }
1182                return opts;
1183            }
1184            var maskset, opts = $.extend(!0, {}, $.inputmask.defaults, options);
1185            if ("string" == typeof fn) switch (fn) {
1186              case "mask":
1187                return resolveAlias(opts.alias, options, opts), maskset = generateMaskSet(opts),
1188                void 0 == maskset ? this : this.each(function() {
1189                    maskScope({
1190                        action: "mask",
1191                        el: this
1192                    }, $.extend(!0, {}, maskset), importAttributeOptions(this, opts));
1193                });
1194
1195              case "unmaskedvalue":
1196                var $input = $(this);
1197                return $input.data("_inputmask") ? maskScope({
1198                    action: "unmaskedvalue",
1199                    $input: $input
1200                }) : $input.val();
1201
1202              case "remove":
1203                return this.each(function() {
1204                    var $input = $(this);
1205                    $input.data("_inputmask") && maskScope({
1206                        action: "remove",
1207                        el: this
1208                    });
1209                });
1210
1211              case "getemptymask":
1212                return this.data("_inputmask") ? maskScope({
1213                    action: "getemptymask",
1214                    el: this
1215                }) : "";
1216
1217              case "hasMaskedValue":
1218                return this.data("_inputmask") ? !this.data("_inputmask").opts.autoUnmask : !1;
1219
1220              case "isComplete":
1221                return this.data("_inputmask") ? maskScope({
1222                    action: "isComplete",
1223                    buffer: this[0]._valueGet().split(""),
1224                    el: this
1225                }) : !0;
1226
1227              case "getmetadata":
1228                return this.data("_inputmask") ? maskScope({
1229                    action: "getmetadata",
1230                    el: this
1231                }) : void 0;
1232
1233              default:
1234                return resolveAlias(opts.alias, options, opts), resolveAlias(fn, options, opts) || (opts.mask = fn),
1235                maskset = generateMaskSet(opts), void 0 == maskset ? this : this.each(function() {
1236                    maskScope({
1237                        action: "mask",
1238                        el: this
1239                    }, $.extend(!0, {}, maskset), importAttributeOptions(this, opts));
1240                });
1241            } else {
1242                if ("object" == typeof fn) return opts = $.extend(!0, {}, $.inputmask.defaults, fn),
1243                resolveAlias(opts.alias, fn, opts), maskset = generateMaskSet(opts), void 0 == maskset ? this : this.each(function() {
1244                    maskScope({
1245                        action: "mask",
1246                        el: this
1247                    }, $.extend(!0, {}, maskset), importAttributeOptions(this, opts));
1248                });
1249                if (void 0 == fn) return this.each(function() {
1250                    var attrOptions = $(this).attr("data-inputmask");
1251                    if (attrOptions && "" != attrOptions) try {
1252                        attrOptions = attrOptions.replace(new RegExp("'", "g"), '"');
1253                        var dataoptions = $.parseJSON("{" + attrOptions + "}");
1254                        $.extend(!0, dataoptions, options), opts = $.extend(!0, {}, $.inputmask.defaults, dataoptions),
1255                        opts = importAttributeOptions(this, opts), resolveAlias(opts.alias, dataoptions, opts),
1256                        opts.alias = void 0, $(this).inputmask("mask", opts);
1257                    } catch (ex) {}
1258                    if ($(this).attr("data-inputmask-mask") || $(this).attr("data-inputmask-alias")) {
1259                        opts = $.extend(!0, {}, $.inputmask.defaults, {});
1260                        var dataOptions = {};
1261                        opts = importAttributeOptions(this, opts, dataOptions), resolveAlias(opts.alias, dataOptions, opts),
1262                        opts.alias = void 0, $(this).inputmask("mask", opts);
1263                    }
1264                });
1265            }
1266        };
1267    }
1268    return $.fn.inputmask;
1269});
1270
1271/*! http://mths.be/placehold
1271er v2.0.7 by @mathias */
1272;(function(window, document, $) {
1273
1274    // Opera Mini v7 doesn’t support placeholder although its DOM seems to indicate so
1275    var isOperaMini = Object.prototype.toString.call(window.operamini) == '[object OperaMini]';
1276    var isInputSupported = 'placeholder' in document.createElement('input') && !isOperaMini;
1277    var isTextareaSupported = 'placeholder' in document.createElement('textarea') && !isOperaMini;
1278    var prototype = $.fn;
1279    var valHooks = $.valHooks;
1280    var propHooks = $.propHooks;
1281    var hooks;
1282    var placeholder;
1283
1284    if (isInputSupported && isTextareaSupported) {
1285
1286        placeholder = prototype.placeholder = function() {
1287            return this;
1288        };
1289
1290        placeholder.input = placeholder.textarea = true;
1291
1292    } else {
1293
1294        placeholder = prototype.placeholder = function() {
1295            var $this = this;
1296            $this
1297                .filter((isInputSupported ? 'textarea' : ':input') + '[placeholder]')
1298                .not('.placeholder')
1299                .bind({
1300                    'focus.placeholder': clearPlaceholder,
1301                    'blur.placeholder': setPlaceholder
1302                })
1303                .data('placeholder-enabled', true)
1304                .trigger('blur.placeholder');
1305            return $this;
1306        };
1307
1308        placeholder.input = isInputSupported;
1309        placeholder.textarea = isTextareaSupported;
1310
1311        hooks = {
1312            'get': function(element) {
1313                var $element = $(element);
1314
1315                var $passwordInput = $element.data('placeholder-password');
1316                if ($passwordInput) {
1317                    return $passwordInput[0].value;
1318                }
1319
1320                return $element.data('placeholder-enabled') && $element.hasClass('placeholder') ? '' : element.value;
1321            },
1322            'set': function(element, value) {
1323                var $element = $(element);
1324
1325                var $passwordInput = $element.data('placeholder-password');
1326                if ($passwordInput) {
1327                    return $passwordInput[0].value = value;
1328                }
1329
1330                if (!$element.data('placeholder-enabled')) {
1331                    return element.value = value;
1332                }
1333                if (value == '') {
1334                    element.value = value;
1335                    // Issue #56: Setting the placeholder causes problems if the element continues to have focus.
1336                    if (element != safeActiveElement()) {
1337                        // We can't use `triggerHandler` here because of dummy text/password inputs :(
1338                        setPlaceholder.call(element);
1339                    }
1340                } else if ($element.hasClass('placeholder')) {
1341                    clearPlaceholder.call(element, true, value) || (element.value = value);
1342                } else {
1343                    element.value = value;
1344                }
1345                // `set` can not return `undefined`; see http://jsapi.info/jquery/1.7.1/val#L2363
1346                return $element;
1347            }
1348        };
1349
1350        if (!isInputSupported) {
1351            valHooks.input = hooks;
1352            propHooks.value = hooks;
1353        }
1354        if (!isTextareaSupported) {
1355            valHooks.textarea = hooks;
1356            propHooks.value = hooks;
1357        }
1358
1359        $(function() {
1360            // Look for forms
1361            $(document).delegate('form', 'submit.placeholder', function() {
1362                // Clear the placeholder values so they don't get submitted
1363                var $inputs = $('.placeholder', this).each(clearPlaceholder);
1364                setTimeout(function() {
1365                    $inputs.each(setPlaceholder);
1366                }, 10);
1367            });
1368        });
1369
1370        // Clear placeholder values upon page reload
1371        $(window).bind('beforeunload.placeholder', function() {
1372            $('.placeholder').each(function() {
1373                this.value = '';
1374            });
1375        });
1376
1377    }
1378
1379    function args(elem) {
1380        // Return an object of element attributes
1381        var newAttrs = {};
1382        var rinlinejQuery = /^jQuery\d+$/;
1383        $.each(elem.attributes, function(i, attr) {
1384            if (attr.specified && !rinlinejQuery.test(attr.name)) {
1385                newAttrs[attr.name] = attr.value;
1386            }
1387        });
1388        return newAttrs;
1389    }
1390
1391    function clearPlaceholder(event, value) {
1392        var input = this;
1393        var $input = $(input);
1394        if (input.value == $input.attr('placeholder') && $input.hasClass('placeholder')) {
1395            if ($input.data('placeholder-password')) {
1396                $input = $input.hide().next().show().attr('id', $input.removeAttr('id').data('placeholder-id'));
1397                // If `clearPlaceholder` was called from `$.valHooks.input.set`
1398                if (event === true) {
1399                    return $input[0].value = value;
1400                }
1401                $input.focus();
1402            } else {
1403                input.value = '';
1404                $input.removeClass('placeholder');
1405                input == safeActiveElement() && input.select();
1406            }
1407        }
1408    }
1409
1410    function setPlaceholder() {
1411        var $replacement;
1412        var input = this;
1413        var $input = $(input);
1414        var id = this.id;
1415        if (input.value == '') {
1416            if (input.type == 'password') {
1417                if (!$input.data('placeholder-textinput')) {
1418                    try {
1419                        $replacement = $input.clone().attr({ 'type': 'text' });
1420                    } catch(e) {
1421                        $replacement = $('<input>').attr($.extend(args(this), { 'type': 'text' }));
1422                    }
1423                    $replacement
1424                        .removeAttr('name')
1425                        .data({
1426                            'placeholder-password': $input,
1427                            'placeholder-id': id
1428                        })
1429                        .bind('focus.placeholder', clearPlaceholder);
1430                    $input
1431                        .data({
1432                            'placeholder-textinput': $replacement,
1433                            'placeholder-id': id
1434                        })
1435                        .before($replacement);
1436                }
1437                $input = $input.removeAttr('id').hide().prev().attr('id', id).show();
1438                // Note: `$input[0] != input` now!
1439            }
1440            $input.addClass('placeholder');
1441            $input[0].value = $input.attr('placeholder');
1442        } else {
1443            $input.removeClass('placeholder');
1444        }
1445    }
1446
1447    function safeActiveElement() {
1448        // Avoid IE9 `document.activeElement` of death
1449        // https://github.com/mathiasbynens/jquery-placeholder/pull/99
1450        try {
1451            return document.activeElement;
1452        } catch (err) {}
1453    }
1454
1455}(this, document, jQuery));
1456
1457/* ------------------------------------------------------------------------
1458    Class: prettyPhoto
1459    Use: Lightbox clone for jQuery
1460    Author: Stephane Caron (http://www.no-margin-for-errors.com)
1461    Version: 3.1.3
1462------------------------------------------------------------------------- */
1463(function($) {
1464    $.prettyPhoto = {version: '3.1.3'};
1465
1466    $.fn.prettyPhoto = function(pp_settings) {
1467        pp_settings = jQuery.extend({
1468            animation_speed: 'fast', /* fast/slow/normal */
1469            slideshow: 2000, /* false OR interval time in ms */
1470            autoplay_slideshow: false, /* true/false */
1471            opacity:.5, /* Value between 0 and 1 */
1472            show_title: true, /* true/false */
1473            allow_resize: true, /* Resize the photos bigger than viewport. true/false */
1474            default_width: 500,
1475            default_height: 344,
1476            counter_separator_label: '/', /* The separator for the gallery counter 1 "of" 2 */
1477            theme: 'pp_default', /* light_rounded / dark_rounded / light_square / dark_square / facebook */
1478            horizontal_padding: 20, /* The padding on each side of the picture */
1479            hideflash: false, /* Hides all the flash object on a page, set to TRUE if flash appears over prettyPhoto */
1480            wmode: 'opaque', /* Set the flash wmode attribute */
1481            autoplay: true, /* Automatically start videos: True/False */
1482            modal: false, /* If set to true, only the close button will close the window */
1483            deeplinking: true, /* Allow prettyPhoto to update the url to enable deeplinking. */
1484            overlay_gallery: true, /* If set to true, a gallery will overlay the fullscreen image on mouse over */
1485            keyboard_shortcuts: true, /* Set to false if you open forms inside prettyPhoto */
1486            changepicturecallback: function(){}, /* Called everytime an item is shown/changed */
1487            callback: function(){}, /* Called when prettyPhoto is closed */
1488            ie6_fallback: true,
1489            markup: '<div class="pp_pic_holder"> \
1490                        <div class="ppt">&nbsp;</div> \
1491                        <div class="pp_top"> \
1492                            <div class="pp_left"></div> \
1493                            <div class="pp_middle"></div> \
1494                            <div class="pp_right"></div> \
1495                        </div> \
1496                        <div class="pp_content_container"> \
1497                            <div class="pp_left"> \
1498                            <div class="pp_right"> \
1499                                <div class="pp_content"> \
1500                                    <div class="pp_loaderIcon"></div> \
1501                                    <div class="pp_fade"> \
1502                                        <a href="#" class="pp_expand" title="Увеличить изображение">Expand</a> \
1503                                        <div class="pp_hoverContainer"> \
1504                                            <a class="pp_next" href="#">next</a> \
1505                                            <a class="pp_previous" href="#">previous</a> \
1506                                        </div> \
1507                                        <div id="pp_full_res"></div> \
1508                                        <div class="pp_details"> \
1509                                            <div class="pp_nav"> \
1510                                                <a href="#" class="pp_arrow_previous">Previous</a> \
1511                                                <p class="currentTextHolder">0/0</p> \
1512                                                <a href="#" class="pp_arrow_next">Next</a> \
1513                                            </div> \
1514                                            <p class="pp_description"></p> \
1515                                            <div class="pp_social">{pp_social}</div> \
1516                                            <a class="pp_close" href="#">Close</a> \
1517                                        </div> \
1518                                    </div> \
1519                                </div> \
1520                            </div> \
1521                            </div> \
1522                        </div> \
1523                        <div class="pp_bottom"> \
1524                            <div class="pp_left"></div> \
1525                            <div class="pp_middle"></div> \
1526                            <div class="pp_right"></div> \
1527                        </div> \
1528                    </div> \
1529                    <div class="pp_overlay"></div>',
1530            gallery_markup: '<div class="pp_gallery"> \
1531                                <a href="#" class="pp_arrow_previous">Previous</a> \
1532                                <div> \
1533                                    <ul> \
1534                                        {gallery} \
1535                                    </ul> \
1536                                </div> \
1537                                <a href="#" class="pp_arrow_next">Next</a> \
1538                            </div>',
1539            image_markup: '<img id="fullResImage" src="{path}" />',
1540            flash_markup: '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="{width}" height="{height}"><param name="wmode" value="{wmode}" /><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="{path}" /><embed src="{path}" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="{width}" height="{height}" wmode="{wmode}"></embed></object>',
1541            quicktime_markup: '<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab" height="{height}" width="{width}"><param name="src" value="{path}"><param name="autoplay" value="{autoplay}"><param name="type" value="video/quicktime"><embed src="{path}" height="{height}" width="{width}" autoplay="{autoplay}" type="video/quicktime" pluginspage="http://www.apple.com/quicktime/download/"></embed></object>',
1542            iframe_markup: '<iframe src ="{path}" width="{width}" height="{height}" frameborder="no"></iframe>',
1543            inline_markup: '<div class="pp_inline">{content}</div>',
1544            custom_markup: '',
1545            social_tools: '<div class="twitter"><a href="http://twitter.com/share" class="twitter-share-button" data-count="none">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><div class="facebook"><iframe src="http://www.facebook.com/plugins/like.php?locale=en_US&href={location_href}&amp;layout=button_count&amp;show_faces=true&amp;width=500&amp;action=like&amp;font&amp;colorscheme=light&amp;height=23" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:500px; height:23px;" allowTransparency="true"></iframe></div>' /* html or false to disable */
1546        }, pp_settings);
1547
1548        // Global variables accessible only by prettyPhoto
1549        var matchedObjects = this, percentBased = false, pp_dimensions, pp_open,
1550
1551        // prettyPhoto container specific
1552        pp_contentHeight, pp_contentWidth, pp_containerHeight, pp_containerWidth,
1553
1554        // Window size
1555        windowHeight = $(window).height(), windowWidth = $(window).width(),
1556
1557        // Global elements
1558        pp_slideshow;
1559
1560        doresize = true, scroll_pos = _get_scroll();
1561
1562        // Window/Keyboard events
1563        $(window).unbind('resize.prettyphoto').bind('resize.prettyphoto',function(){ _center_overlay(); _resize_overlay(); });
1564
1565        if(pp_settings.keyboard_shortcuts) {
1566            $(document).unbind('keydown.prettyphoto').bind('keydown.prettyphoto',function(e){
1567                if(typeof $pp_pic_holder != 'undefined'){
1568                    if($pp_pic_holder.is(':visible')){
1569                        switch(e.keyCode){
1570                            case 37:
1571                                $.prettyPhoto.changePage('previous');
1572                                e.preventDefault();
1573                                break;
1574                            case 39:
1575                                $.prettyPhoto.changePage('next');
1576                                e.preventDefault();
1577                                break;
1578                            case 27:
1579                                if(!settings.modal)
1580                                $.prettyPhoto.close();
1581                                e.preventDefault();
1582                                break;
1583                        };
1584                        // return false;
1585                    };
1586                };
1587            });
1588        };
1589
1590        /**
1591        * Initialize prettyPhoto.
1592        */
1593        $.prettyPhoto.initialize = function() {
1594
1595            settings = pp_settings;
1596
1597            if(settings.theme == 'pp_default') settings.horizontal_padding = 16;
1598            if(settings.ie6_fallback && $.browser.msie && parseInt($.browser.version) == 6) settings.theme = "light_square"; // Fallback to a supported theme for IE6
1599
1600            // Find out if the picture is part of a set
1601            theRel = $(this).attr('rel');
1602            galleryRegExp = /\[(?:.*)\]/;
1603            isSet = (galleryRegExp.exec(theRel)) ? true : false;
1604
1605            // Put the SRCs, TITLEs, ALTs into an array.
1606            pp_images = (isSet) ? jQuery.map(matchedObjects, function(n, i){ if($(n).attr('rel').indexOf(theRel) != -1) return $(n).attr('href'); }) : $.makeArray($(this).attr('href'));
1607            pp_titles = (isSet) ? jQuery.map(matchedObjects, function(n, i){ if($(n).attr('rel').indexOf(theRel) != -1) return ($(n).find('img').attr('alt')) ? $(n).find('img').attr('alt') : ""; }) : $.makeArray($(this).find('img').attr('alt'));
1608            pp_descriptions = (isSet) ? jQuery.map(matchedObjects, function(n, i){ if($(n).attr('rel').indexOf(theRel) != -1) return ($(n).attr('title')) ? $(n).attr('title') : ""; }) : $.makeArray($(this).attr('title'));
1609
1610            if(pp_images.length > 30) settings.overlay_gallery = false;
1611
1612            set_position = jQuery.inArray($(this).attr('href'), pp_images); // Define where in the array the clicked item is positionned
1613            rel_index = (isSet) ? set_position : $("a[rel^='"+theRel+"']").index($(this));
1614
1615            _build_overlay(this); // Build the overlay {this} being the caller
1616
1617            if(settings.allow_resize)
1618                $(window).bind('scroll.prettyphoto',function(){ _center_overlay(); });
1619
1620
1621            $.prettyPhoto.open();
1622
1623            return false;
1624        }
1625
1626
1627        /**
1628        * Opens the prettyPhoto modal box.
1629        * @param image {String,Array} Full path to the image to be open, can also be an array containing full images paths.
1630        * @param title {String,Array} The title to be displayed with the picture, can also be an array containing all the titles.
1631        * @param description {String,Array} The description to be displayed with the picture, can also be an array containing all the descriptions.
1632        */
1633        $.prettyPhoto.open = function(event) {
1634            if(typeof settings == "undefined"){ // Means it's an API call, need to manually get the settings and set the variables
1635                settings = pp_settings;
1636                if($.browser.msie && $.browser.version == 6) settings.theme = "light_square"; // Fallback to a supported theme for IE6
1637                pp_images = $.makeArray(arguments[0]);
1638                pp_titles = (arguments[1]) ? $.makeArray(arguments[1]) : $.makeArray("");
1639                pp_descriptions = (arguments[2]) ? $.makeArray(arguments[2]) : $.makeArray("");
1640                isSet = (pp_images.length > 1) ? true : false;
1641                set_position = 0;
1642                _build_overlay(event.target); // Build the overlay {this} being the caller
1643            }
1644
1645            if($.browser.msie && $.browser.version == 6) $('select').css('visibility','hidden'); // To fix the bug with IE select boxes
1646
1647            if(settings.hideflash) $('object,embed,iframe[src*=youtube],iframe[src*=vimeo]').css('visibility','hidden'); // Hide the flash
1648
1649            _checkPosition($(pp_images).size()); // Hide the next/previous links if on first or last images.
1650
1651            $('.pp_loaderIcon').show();
1652
1653            if(settings.deeplinking)
1654                setHashtag();
1655
1656            // Rebuild Facebook Like Button with updated href
1657            if(settings.social_tools){
1658                facebook_like_link = settings.social_tools.replace('{location_href}', encodeURIComponent(location.href));
1659                $pp_pic_holder.find('.pp_social').html(facebook_like_link);
1660            }
1661
1662            // Fade the content in
1663            if($ppt.is(':hidden')) $ppt.css('opacity',0).show();
1664            $pp_overlay.show().fadeTo(settings.animation_speed,settings.opacity);
1665
1666            // Display the current position
1667            $pp_pic_holder.find('.currentTextHolder').text((set_position+1) + settings.counter_separator_label + $(pp_images).size());
1668
1669            // Set the description
1670            if(pp_descriptions[set_position] != ""){
1671                $pp_pic_holder.find('.pp_description').show().html(unescape(pp_descriptions[set_position]));
1672            }else{
1673                $pp_pic_holder.find('.pp_description').hide();
1674            }
1675
1676            // Get the dimensions
1677            movie_width = ( parseFloat(getParam('width',pp_images[set_position])) ) ? getParam('width',pp_images[set_position]) : settings.default_width.toString();
1678            movie_height = ( parseFloat(getParam('height',pp_images[set_position])) ) ? getParam('height',pp_images[set_position]) : settings.default_height.toString();
1679
1680            // If the size is % based, calculate according to window dimensions
1681            percentBased=false;
1682            if(movie_height.indexOf('%') != -1) { movie_height = parseFloat(($(window).height() * parseFloat(movie_height) / 100) - 150); percentBased = true; }
1683            if(movie_width.indexOf('%') != -1) { movie_width = parseFloat(($(window).width() * parseFloat(movie_width) / 100) - 150); percentBased = true; }
1684
1685            // Fade the holder
1686            $pp_pic_holder.fadeIn(function(){
1687                // Set the title
1688                (settings.show_title && pp_titles[set_position] != "" && typeof pp_titles[set_position] != "undefined") ? $ppt.html(unescape(pp_titles[set_position])) : $ppt.html('&nbsp;');
1689
1690                imgPreloader = "";
1691                skipInjection = false;
1692
1693                // Inject the proper content
1694                switch(_getFileType(pp_images[set_position])){
1695                    case 'image':
1696                        imgPreloader = new Image();
1697
1698                        // Preload the neighbour images
1699                        nextImage = new Image();
1700                        if(isSet && set_position < $(pp_images).size() -1) nextImage.src = pp_images[set_position + 1];
1701                        prevImage = new Image();
1702                        if(isSet && pp_images[set_position - 1]) prevImage.src = pp_images[set_position - 1];
1703
1704                        $pp_pic_holder.find('#pp_full_res')[0].innerHTML = settings.image_markup.replace(/{path}/g,pp_images[set_position]);
1705
1706                        imgPreloader.onload = function(){
1707                            // Fit item to viewport
1708                            pp_dimensions = _fitToViewport(imgPreloader.width,imgPreloader.height);
1709
1710                            _showContent();
1711                        };
1712
1713                        imgPreloader.onerror = function(){
1714                            alert('Image cannot be loaded. Make sure the path is correct and image exist.');
1715                            $.prettyPhoto.close();
1716                        };
1717
1718                        imgPreloader.src = pp_images[set_position];
1719                    break;
1720
1721                    case 'youtube':
1722                        pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
1723
1724                        // Regular youtube link
1725                        movie_id = getParam('v',pp_images[set_position]);
1726
1727                        // youtu.be link
1728                        if(movie_id == ""){
1729                            movie_id = pp_images[set_position].split('youtu.be/');
1730                            movie_id = movie_id[1];
1731                            if(movie_id.indexOf('?') > 0)
1732                                movie_id = movie_id.substr(0,movie_id.indexOf('?')); // Strip anything after the ?
1733
1734                            if(movie_id.indexOf('&') > 0)
1735                                movie_id = movie_id.substr(0,movie_id.indexOf('&')); // Strip anything after the &
1736                        }
1737
1738                        movie = 'http://www.youtube.com/embed/'+movie_id;
1739                        (getParam('rel',pp_images[set_position])) ? movie+="?rel="+getParam('rel',pp_images[set_position]) : movie+="?rel=1";
1740
1741                        if(settings.autoplay) movie += "&autoplay=1";
1742
1743                        toInject = settings.iframe_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,movie);
1744                    break;
1745
1746                    case 'vimeo':
1747                        pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
1748
1749                        movie_id = pp_images[set_position];
1750                        var regExp = /http:\/\/(www\.)?vimeo.com\/(\d+)/;
1751                        var match = movie_id.match(regExp);
1752
1753                        movie = 'http://player.vimeo.com/video/'+ match[2] +'?title=0&amp;byline=0&amp;portrait=0';
1754                        if(settings.autoplay) movie += "&autoplay=1;";
1755
1756                        vimeo_width = pp_dimensions['width'] + '/embed/?moog_width='+ pp_dimensions['width'];
1757
1758                        toInject = settings.iframe_markup.replace(/{width}/g,vimeo_width).replace(/{height}/g,pp_dimensions['height']).replace(/{path}/g,movie);
1759                    break;
1760
1761                    case 'quicktime':
1762                        pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
1763                        pp_dimensions['height']+=15; pp_dimensions['contentHeight']+=15; pp_dimensions['containerHeight']+=15; // Add space for the control bar
1764
1765                        toInject = settings.quicktime_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}
1765/g,pp_images[set_position]).replace(/{autoplay}/g,settings.autoplay);
1766                    break;
1767
1768                    case 'flash':
1769                        pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
1770
1771                        flash_vars = pp_images[set_position];
1772                        flash_vars = flash_vars.substring(pp_images[set_position].indexOf('flashvars') + 10,pp_images[set_position].length);
1773
1774                        filename = pp_images[set_position];
1775                        filename = filename.substring(0,filename.indexOf('?'));
1776
1777                        toInject =  settings.flash_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,filename+'?'+flash_vars);
1778                    break;
1779
1780                    case 'iframe':
1781                        pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
1782
1783                        frame_url = pp_images[set_position];
1784                        frame_url = frame_url.substr(0,frame_url.indexOf('iframe')-1);
1785
1786                        toInject = settings.iframe_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{path}/g,frame_url);
1787                    break;
1788
1789                    case 'ajax':
1790                        doresize = false; // Make sure the dimensions are not resized.
1791                        pp_dimensions = _fitToViewport(movie_width,movie_height);
1792                        doresize = true; // Reset the dimensions
1793
1794                        skipInjection = true;
1795                        $.get(pp_images[set_position],function(responseHTML){
1796                            toInject = settings.inline_markup.replace(/{content}/g,responseHTML);
1797                            $pp_pic_holder.find('#pp_full_res')[0].innerHTML = toInject;
1798                            _showContent();
1799                        });
1800
1801                    break;
1802
1803                    case 'custom':
1804                        pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
1805
1806                        toInject = settings.custom_markup;
1807                    break;
1808
1809                    case 'inline':
1810                        // to get the item height clone it, apply default width, wrap it in the prettyPhoto containers , then delete
1811                        myClone = $(pp_images[set_position]).clone().append('<br clear="all" />').css({'width':settings.default_width}).wrapInner('<div id="pp_full_res"><div class="pp_inline"></div></div>').appendTo($('body')).show();
1812                        doresize = false; // Make sure the dimensions are not resized.
1813                        pp_dimensions = _fitToViewport($(myClone).width(),$(myClone).height());
1814                        doresize = true; // Reset the dimensions
1815                        $(myClone).remove();
1816                        toInject = settings.inline_markup.replace(/{content}/g,$(pp_images[set_position]).html());
1817                    break;
1818                };
1819
1820                if(!imgPreloader && !skipInjection){
1821                    $pp_pic_holder.find('#pp_full_res')[0].innerHTML = toInject;
1822
1823                    // Show content
1824                    _showContent();
1825                };
1826            });
1827
1828            return false;
1829        };
1830
1831
1832        /**
1833        * Change page in the prettyPhoto modal box
1834        * @param direction {String} Direction of the paging, previous or next.
1835        */
1836        $.prettyPhoto.changePage = function(direction){
1837            currentGalleryPage = 0;
1838
1839            if(direction == 'previous') {
1840                set_position--;
1841                if (set_position < 0) set_position = $(pp_images).size()-1;
1842            }else if(direction == 'next'){
1843                set_position++;
1844                if(set_position > $(pp_images).size()-1) set_position = 0;
1845            }else{
1846                set_position=direction;
1847            };
1848
1849            rel_index = set_position;
1850
1851            if(!doresize) doresize = true; // Allow the resizing of the images
1852            $('.pp_contract').removeClass('pp_contract').addClass('pp_expand');
1853
1854            _hideContent(function(){ $.prettyPhoto.open(); });
1855        };
1856
1857
1858        /**
1859        * Change gallery page in the prettyPhoto modal box
1860        * @param direction {String} Direction of the paging, previous or next.
1861        */
1862        $.prettyPhoto.changeGalleryPage = function(direction){
1863            if(direction=='next'){
1864                currentGalleryPage ++;
1865
1866                if(currentGalleryPage > totalPage) currentGalleryPage = 0;
1867            }else if(direction=='previous'){
1868                currentGalleryPage --;
1869
1870                if(currentGalleryPage < 0) currentGalleryPage = totalPage;
1871            }else{
1872                currentGalleryPage = direction;
1873            };
1874
1875            slide_speed = (direction == 'next' || direction == 'previous') ? settings.animation_speed : 0;
1876
1877            slide_to = currentGalleryPage * (itemsPerPage * itemWidth);
1878
1879            $pp_gallery.find('ul').animate({left:-slide_to},slide_speed);
1880        };
1881
1882
1883        /**
1884        * Start the slideshow...
1885        */
1886        $.prettyPhoto.startSlideshow = function(){
1887            if(typeof pp_slideshow == 'undefined'){
1888                $pp_pic_holder.find('.pp_play').unbind('click').removeClass('pp_play').addClass('pp_pause').click(function(){
1889                    $.prettyPhoto.stopSlideshow();
1890                    return false;
1891                });
1892                pp_slideshow = setInterval($.prettyPhoto.startSlideshow,settings.slideshow);
1893            }else{
1894                $.prettyPhoto.changePage('next');
1895            };
1896        }
1897
1898
1899        /**
1900        * Stop the slideshow...
1901        */
1902        $.prettyPhoto.stopSlideshow = function(){
1903            $pp_pic_holder.find('.pp_pause').unbind('click').removeClass('pp_pause').addClass('pp_play').click(function(){
1904                $.prettyPhoto.startSlideshow();
1905                return false;
1906            });
1907            clearInterval(pp_slideshow);
1908            pp_slideshow=undefined;
1909        }
1910
1911
1912        /**
1913        * Closes prettyPhoto.
1914        */
1915        $.prettyPhoto.close = function(){
1916            if($pp_overlay.is(":animated")) return;
1917
1918            $.prettyPhoto.stopSlideshow();
1919
1920            $pp_pic_holder.stop().find('object,embed').css('visibility','hidden');
1921
1922            $('div.pp_pic_holder,div.ppt,.pp_fade').fadeOut(settings.animation_speed,function(){ $(this).remove(); });
1923
1924            $pp_overlay.fadeOut(settings.animation_speed, function(){
1925                if($.browser.msie && $.browser.version == 6) $('select').css('visibility','visible'); // To fix the bug with IE select boxes
1926
1927                if(settings.hideflash) $('object,embed,iframe[src*=youtube],iframe[src*=vimeo]').css('visibility','visible'); // Show the flash
1928
1929                $(this).remove(); // No more need for the prettyPhoto markup
1930
1931                $(window).unbind('scroll.prettyphoto');
1932
1933                clearHashtag();
1934
1935                settings.callback();
1936
1937                doresize = true;
1938
1939                pp_open = false;
1940
1941                delete settings;
1942            });
1943        };
1944
1945        /**
1946        * Set the proper sizes on the containers and animate the content in.
1947        */
1948        function _showContent(){
1949            $('.pp_loaderIcon').hide();
1950
1951            // Calculate the opened top position of the pic holder
1952            projectedTop = scroll_pos['scrollTop'] + ((windowHeight/2) - (pp_dimensions['containerHeight']/2));
1953            if(projectedTop < 0) projectedTop = 0;
1954
1955            $ppt.fadeTo(settings.animation_speed,1);
1956
1957            // Resize the content holder
1958            $pp_pic_holder.find('.pp_content')
1959                .animate({
1960                    height:pp_dimensions['contentHeight'],
1961                    width:pp_dimensions['contentWidth']
1962                },settings.animation_speed);
1963
1964            // Resize picture the holder
1965            $pp_pic_holder.animate({
1966                'top': projectedTop,
1967                'left': (windowWidth/2) - (pp_dimensions['containerWidth']/2),
1968                width:pp_dimensions['containerWidth']
1969            },settings.animation_speed,function(){
1970                $pp_pic_holder.find('.pp_hoverContainer,#fullResImage').height(pp_dimensions['height']).width(pp_dimensions['width']);
1971
1972                $pp_pic_holder.find('.pp_fade').fadeIn(settings.animation_speed); // Fade the new content
1973
1974                // Show the nav
1975                if(isSet && _getFileType(pp_images[set_position])=="image") { $pp_pic_holder.find('.pp_hoverContainer').show(); }else{ $pp_pic_holder.find('.pp_hoverContainer').hide(); }
1976
1977                if(pp_dimensions['resized']){ // Fade the resizing link if the image is resized
1978                    $('a.pp_expand,a.pp_contract').show();
1979                }else{
1980                    $('a.pp_expand').hide();
1981                }
1982
1983                if(settings.autoplay_slideshow && !pp_slideshow && !pp_open) $.prettyPhoto.startSlideshow();
1984
1985                settings.changepicturecallback(); // Callback!
1986
1987                pp_open = true;
1988            });
1989
1990            _insert_gallery();
1991        };
1992
1993        /**
1994        * Hide the content...DUH!
1995        */
1996        function _hideContent(callback){
1997            // Fade out the current picture
1998            $pp_pic_holder.find('#pp_full_res object,#pp_full_res embed').css('visibility','hidden');
1999            $pp_pic_holder.find('.pp_fade').fadeOut(settings.animation_speed,function(){
2000                $('.pp_loaderIcon').show();
2001
2002                callback();
2003            });
2004        };
2005
2006        /**
2007        * Check the item position in the gallery array, hide or show the navigation links
2008        * @param setCount {integer} The total number of items in the set
2009        */
2010        function _checkPosition(setCount){
2011            (setCount > 1) ? $('.pp_nav').show() : $('.pp_nav').hide(); // Hide the bottom nav if it's not a set.
2012        };
2013
2014        /**
2015        * Resize the item dimensions if it's bigger than the viewport
2016        * @param width {integer} Width of the item to be opened
2017        * @param height {integer} Height of the item to be opened
2018        * @return An array containin the "fitted" dimensions
2019        */
2020        function _fitToViewport(width,height){
2021            resized = false;
2022
2023            _getDimensions(width,height);
2024
2025            // Define them in case there's no resize needed
2026            imageWidth = width, imageHeight = height;
2027
2028            if( ((pp_containerWidth > windowWidth) || (pp_containerHeight > windowHeight)) && doresize && settings.allow_resize && !percentBased) {
2029                resized = true, fitting = false;
2030
2031                while (!fitting){
2032                    if((pp_containerWidth > windowWidth)){
2033                        imageWidth = (windowWidth - 200);
2034                        imageHeight = (height/width) * imageWidth;
2035                    }else if((pp_containerHeight > windowHeight)){
2036                        imageHeight = (windowHeight - 200);
2037                        imageWidth = (width/height) * imageHeight;
2038                    }else{
2039                        fitting = true;
2040                    };
2041
2042                    pp_containerHeight = imageHeight, pp_containerWidth = imageWidth;
2043                };
2044
2045                _getDimensions(imageWidth,imageHeight);
2046
2047                if((pp_containerWidth > windowWidth) || (pp_containerHeight > windowHeight)){
2048                    _fitToViewport(pp_containerWidth,pp_containerHeight)
2049                };
2050            };
2051
2052            return {
2053                width:Math.floor(imageWidth),
2054                height:Math.floor(imageHeight),
2055                containerHeight:Math.floor(pp_containerHeight),
2056                containerWidth:Math.floor(pp_containerWidth) + (settings.horizontal_padding * 2),
2057                contentHeight:Math.floor(pp_contentHeight),
2058                contentWidth:Math.floor(pp_contentWidth),
2059                resized:resized
2060            };
2061        };
2062
2063        /**
2064        * Get the containers dimensions according to the item size
2065        * @param width {integer} Width of the item to be opened
2066        * @param height {integer} Height of the item to be opened
2067        */
2068        function _getDimensions(width,height){
2069            width = parseFloat(width);
2070            height = parseFloat(height);
2071
2072            // Get the details height, to do so, I need to clone it since it's invisible
2073            $pp_details = $pp_pic_holder.find('.pp_details');
2074            $pp_details.width(width);
2075            detailsHeight = parseFloat($pp_details.css('marginTop')) + parseFloat($pp_details.css('marginBottom'));
2076
2077            $pp_details = $pp_details.clone().addClass(settings.theme).width(width).appendTo($('body')).css({
2078                'position':'absolute',
2079                'top':-10000
2080            });
2081            detailsHeight += $pp_details.height();
2082            detailsHeight = (detailsHeight <= 34) ? 36 : detailsHeight; // Min-height for the details
2083            if($.browser.msie && $.browser.version==7) detailsHeight+=8;
2084            $pp_details.remove();
2085
2086            // Get the titles height, to do so, I need to clone it since it's invisible
2087            $pp_title = $pp_pic_holder.find('.ppt');
2088            $pp_title.width(width);
2089            titleHeight = parseFloat($pp_title.css('marginTop')) + parseFloat($pp_title.css('marginBottom'));
2090            $pp_title = $pp_title.clone().appendTo($('body')).css({
2091                'position':'absolute',
2092                'top':-10000
2093            });
2094            titleHeight += $pp_title.height();
2095            $pp_title.remove();
2096
2097            // Get the container size, to resize the holder to the right dimensions
2098            pp_contentHeight = height + detailsHeight;
2099            pp_contentWidth = width;
2100            pp_containerHeight = pp_contentHeight + titleHeight + $pp_pic_holder.find('.pp_top').height() + $pp_pic_holder.find('.pp_bottom').height();
2101            pp_containerWidth = width;
2102        }
2103
2104        function _getFileType(itemSrc){
2105            if (itemSrc.match(/youtube\.com\/watch/i) || itemSrc.match(/youtu\.be/i)) {
2106                return 'youtube';
2107            }else if (itemSrc.match(/vimeo\.com/i)) {
2108                return 'vimeo';
2109            }else if(itemSrc.match(/\b.mov\b/i)){
2110                return 'quicktime';
2111            }else if(itemSrc.match(/\b.swf\b/i)){
2112                return 'flash';
2113            }else if(itemSrc.match(/\biframe=true\b/i)){
2114                return 'iframe';
2115            }else if(itemSrc.match(/\bajax=true\b/i)){
2116                return 'ajax';
2117            }else if(itemSrc.match(/\bcustom=true\b/i)){
2118                return 'custom';
2119            }else if(itemSrc.substr(0,1) == '#'){
2120                return 'inline';
2121            }else{
2122                return 'image';
2123            };
2124        };
2125
2126        function _center_overlay(){
2127            if(doresize && typeof $pp_pic_holder != 'undefined') {
2128                scroll_pos = _get_scroll();
2129                contentHeight = $pp_pic_holder.height(), contentwidth = $pp_pic_holder.width();
2130
2131                projectedTop = (windowHeight/2) + scroll_pos['scrollTop'] - (contentHeight/2);
2132                if(projectedTop < 0) projectedTop = 0;
2133
2134                if(contentHeight > windowHeight)
2135                    return;
2136
2137                $pp_pic_holder.css({
2138                    'top': projectedTop,
2139                    'left': (windowWidth/2) + scroll_pos['scrollLeft'] - (contentwidth/2)
2140                });
2141            };
2142        };
2143
2144        function _get_scroll(){
2145            if (self.pageYOffset) {
2146                return {scrollTop:self.pageYOffset,scrollLeft:self.pageXOffset};
2147            } else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict
2148                return {scrollTop:document.documentElement.scrollTop,scrollLeft:document.documentElement.scrollLeft};
2149            } else if (document.body) {// all other Explorers
2150                return {scrollTop:document.body.scrollTop,scrollLeft:document.body.scrollLeft};
2151            };
2152        };
2153
2154        function _resize_overlay() {
2155            windowHeight = $(window).height(), windowWidth = (window.innerWidth > 0) ? window.innerWidth : screen.width;
2156
2157            if(typeof $pp_overlay != "undefined") $pp_overlay.height($(document).height()).width(windowWidth);
2158        };
2159
2160        function _insert_gallery(){
2161            if(isSet && settings.overlay_gallery && _getFileType(pp_images[set_position])=="image" && (sett
2161ings.ie6_fallback && !($.browser.msie && parseInt($.browser.version) == 6))) {
2162                itemWidth = 72+5; // 52 beign the thumb width, 5 being the right margin.
2163                navWidth = (settings.theme == "facebook" || settings.theme == "pp_default") ? 50 : 30; // Define the arrow width depending on the theme
2164
2165                itemsPerPage = Math.floor((pp_dimensions['containerWidth'] - 100 - navWidth) / itemWidth);
2166                itemsPerPage = (itemsPerPage < pp_images.length) ? itemsPerPage : pp_images.length;
2167                totalPage = Math.ceil(pp_images.length / itemsPerPage) - 1;
2168
2169                // Hide the nav in the case there's no need for links
2170                if(totalPage == 0){
2171                    navWidth = 0; // No nav means no width!
2172                    $pp_gallery.find('.pp_arrow_next,.pp_arrow_previous').hide();
2173                }else{
2174                    $pp_gallery.find('.pp_arrow_next,.pp_arrow_previous').show();
2175                };
2176
2177                galleryWidth = itemsPerPage * itemWidth;
2178                fullGalleryWidth = pp_images.length * itemWidth;
2179
2180                // Set the proper width to the gallery items
2181                $pp_gallery
2182                    .css('margin-left',-((galleryWidth/2) + (navWidth/2)))
2183                    .find('div:first').width(galleryWidth+5)
2184                    .find('ul').width(fullGalleryWidth)
2185                    .find('li.selected').removeClass('selected');
2186
2187                goToPage = (Math.floor(set_position/itemsPerPage) < totalPage) ? Math.floor(set_position/itemsPerPage) : totalPage;
2188
2189                $.prettyPhoto.changeGalleryPage(goToPage);
2190
2191                $pp_gallery_li.filter(':eq('+set_position+')').addClass('selected');
2192            }else{
2193                $pp_pic_holder.find('.pp_content').unbind('mouseenter mouseleave');
2194                // $pp_gallery.hide();
2195            }
2196        }
2197
2198        function _build_overlay(caller){
2199            // Inject Social Tool markup into General markup
2200            if(settings.social_tools)
2201                facebook_like_link = settings.social_tools.replace('{location_href}', encodeURIComponent(location.href));
2202
2203            settings.markup=settings.markup.replace('{pp_social}',(settings.social_tools)?facebook_like_link:'');
2204
2205            $('body').append(settings.markup); // Inject the markup
2206
2207            $pp_pic_holder = $('.pp_pic_holder') , $ppt = $('.ppt'), $pp_overlay 
2207= $('div.pp_overlay'); // Set my global selectors
2208
2209            // Inject the inline gallery!
2210            if(isSet && settings.overlay_gallery) {
2211                currentGalleryPage = 0;
2212                toInject = "";
2213                for (var i=0; i < pp_images.length; i++) {
2214                    if(!pp_images[i].match(/\b(jpg|jpeg|png|gif)\b/gi)){
2215                        classname = 'default';
2216                        img_src = '';
2217                    }else{
2218                        classname = '';
2219                        img_src = pp_images[i];
2220                    }
2221                    toInject += "<li class='"+classname+"'><a href='#'><img src='" + img_src + "' width='70' width='70' alt='' /></a></li>";
2222                };
2223
2224                toInject = settings.gallery_markup.replace(/{gallery}/g,toInject);
2225
2226                $pp_pic_holder.find('#pp_full_res').after(toInject);
2227
2228                $pp_gallery = $('.pp_pic_holder .pp_gallery'), $pp_gallery_li = $pp_gallery.find('li'); // Set the gallery selectors
2229
2230                $pp_gallery.find('.pp_arrow_next').click(function(){
2231                    $.prettyPhoto.changeGalleryPage('next');
2232                    $.prettyPhoto.stopSlideshow();
2233                    return false;
2234                });
2235
2236                $pp_gallery.find('.pp_arrow_previous').click(function(){
2237                    $.prettyPhoto.changeGalleryPage('previous');
2238                    $.prettyPhoto.stopSlideshow();
2239                    return false;
2240                });
2241
2242                $pp_pic_holder.find('.pp_content').hover(
2243                    function(){
2244                        $pp_pic_holder.find('.pp_gallery:not(.disabled)').fadeIn();
2245                    },
2246                    function(){
2247                        $pp_pic_holder.find('.pp_gallery:not(.disabled)').fadeOut();
2248                    });
2249
2250                itemWidth = 52+5; // 52 beign the thumb width, 5 being the right margin.
2251                $pp_gallery_li.each(function(i){
2252                    $(this)
2253                        .find('a')
2254                        .click(function(){
2255                            $.prettyPhoto.changePage(i);
2256                            $.prettyPhoto.stopSlideshow();
2257                            return false;
2258                        });
2259                });
2260            };
2261
2262
2263            // Inject the play/pause if it's a slideshow
2264            if(settings.slideshow){
2265                $pp_pic_holder.find('.pp_nav').prepend('<a href="#" class="pp_play">Play</a>')
2266                $pp_pic_holder.find('.pp_nav .pp_play').click(function(){
2267                    $.prettyPhoto.startSlideshow();
2268                    return false;
2269                });
2270            }
2271
2272            $pp_pic_holder.attr('class','pp_pic_holder ' + settings.theme); // Set the proper theme
2273
2274            $pp_overlay
2275                .css({
2276                    'opacity':0,
2277                    'height':$(document).height(),
2278                    'width':(window.innerWidth > 0) ? window.innerWidth : screen.width
2279                    })
2280                .bind('click',function(){
2281                    if(!settings.modal) $.prettyPhoto.close();
2282                });
2283
2284            $('a.pp_close').bind('click',function(){ $.prettyPhoto.close(); return false; });
2285
2286            $('a.pp_expand').bind('click',function(e){
2287                // Expand the image
2288                if($(this).hasClass('pp_expand')){
2289                    $(this).removeClass('pp_expand').addClass('pp_contract');
2290                    doresize = false;
2291                }else{
2292                    $(this).removeClass('pp_contract').addClass('pp_expand');
2293                    doresize = true;
2294                };
2295
2296                _hideContent(function(){ $.prettyPhoto.open(); });
2297
2298                return false;
2299            });
2300
2301            $pp_pic_holder.find('.pp_previous, .pp_nav .pp_arrow_previous').bind('click',function(){
2302                $.prettyPhoto.changePage('previous');
2303                $.prettyPhoto.stopSlideshow();
2304                return false;
2305            });
2306
2307            $pp_pic_holder.find('.pp_next, .pp_nav .pp_arrow_next').bind('click',function(){
2308                $.prettyPhoto.changePage('next');
2309                $.prettyPhoto.stopSlideshow();
2310                return false;
2311            });
2312
2313            _center_overlay(); // Center it
2314        };
2315
2316        if(!pp_alreadyInitialized && getHashtag()){
2317            pp_alreadyInitialized = true;
2318
2319            // Grab the rel index to trigger the click on the correct element
2320            hashIndex = getHashtag();
2321            hashRel = hashIndex;
2322            hashIndex = hashIndex.substring(hashIndex.indexOf('/')+1,hashIndex.length-1);
2323            hashRel = hashRel.substring(0,hashRel.indexOf('/'));
2324
2325            // Little timeout to make sure all the prettyPhoto initialize scripts has been run.
2326            // Useful in the event the page contain several init scripts.
2327            setTimeout(function(){ $("a[rel^='"+hashRel+"']:eq("+hashIndex+")").trigger('click'); },50);
2328        }
2329
2330        return this.unbind('click.prettyphoto').bind('click.prettyphoto',$.prettyPhoto.initialize); // Return the jQuery object for chaining. The unbind method is used to avoid click conflict when the plugin is called more than once
2331    };
2332
2333    function getHashtag(){
2334        url = location.href;
2335        hashtag = (url.indexOf('#!') != -1) ? decodeURI(url.substring(url.indexOf('#!')+2,url.length)) : false;
2336        return hashtag;
2337    };
2338
2339    function setHashtag(){
2340        if(typeof theRel == 'undefined') return; // theRel is set on normal calls, it's impossible to deeplink using the API
2341        location.hash = '!' + theRel + '/'+rel_index+'/';
2342    };
2343
2344    function clearHashtag(){
2345        // Clear the hashtag only if it was set by prettyPhoto
2346        url = location.href;
2347        hashtag = (url.indexOf('#!prettyPhoto')) ? true : false;
2348        //if(hashtag) location.hash = "!prettyPhoto";
2349    }
2350
2351    function getParam(name,url){
2352      name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
2353      var regexS = "[\\?&]"+name+"=([^&#]*)";
2354      var regex = new RegExp( regexS );
2355      var results = regex.exec( url );
2356      return ( results == null ) ? "" : results[1];
2357    }
2358
2359})(jQuery);
2360
2361var pp_alreadyInitialized = false; // Used for the deep linking to make sure not to call the same function several times.
2362$(function()
2363{
2364  $('.menu-fade').delay(0).fadeIn(0);
2365  $('.offer-fade').delay(0).fadeIn(0);
2366    $('.banner-fade').delay(1000).fadeIn(1000);
2367    $('.banner-fade-2').delay(2000).fadeIn(1000);
2368//$('.menu').delay(100).slideDown(800);
2369//$('.offer').delay(100).slideDown(800);
2370});
2371
2372
2373
2374function sentGetAJAX(obj, successDiv, completeDivs)
2375{
2376    if (obj.attr('rel'))
2377    {
2378        fromURL = obj.attr('rel');
2379    } else {
2380        fromURL = successDiv.attr('rel');
2381    }
2382
2383    $.ajax({
2384        url:fromURL,
2385
2386        success:function(data, textStatus)
2387        {
2388            if (successDiv)
2389            {
2390                successDiv.html(data);
2391            }
2392        },
2393
2394        beforeSend:function(XMLHttpRequest)
2395        {
2396        },
2397
2398        complete:function(XMLHttpRequest, textStatus)
2399        {
2400            for (var i in completeDivs)
2401            {
2402                sentGetAJAX(completeDivs[i], completeDivs[i]);
2403            }
2404        },
2405    });
2406}
2407
2408
2409function sentPostAJAX(obj, form, successDiv, completeDivs)
2410{
2411    if (obj.attr('rel'))
2412    {
2413        fromURL = obj.attr('rel');
2414    } else {
2415        fromURL = successDiv.attr('rel');
2416    }
2417
2418    $.ajax({
2419        url:fromURL,
2420        type:'POST',
2421        dataType:'html',
2422        data:form.serialize(),
2423
2424        success:function(data, textStatus)
2425        {
2426            if (successDiv)
2427            {
2428                successDiv.html(data);
2429            }
2430        },
2431
2432        beforeSend:function(XMLHttpRequest)
2433        {
2434        },
2435
2436        complete:function(XMLHttpRequest, textStatus)
2437        {
2438            for (var i in completeDivs)
2439            {
2440                sentGetAJAX(completeDivs[i], completeDivs[i]);
2441            }
2442        },
2443    });
2444}
2445
2446// Get url patameters
2447(function($)
2448{
2449    $.QueryString = (function(query)
2450    {
2451        if (query == "") return {};
2452        var value = {};
2453        for (var i = 0; i < query.length; ++i)
2454        {
2455            var param = query[i].split('=');
2456            if (param.length != 2) continue;
2457            value[param[0]] = decodeURIComponent(param[1].replace(/\+/g, " "));
2458        }
2459
2460        return value;
2461
2462    })(window.location.search.substr(1).split('&'))
2463})(jQuery);
2464
2465
2466$(function()
2467{
2468    $("a[rel^='prettyPhoto']").prettyPhoto();
2469    $(".gallery a[rel^='prettyPhoto']").prettyPhoto({animation_speed:'normal', slideshow:10000, hideflash: false, social_tools:false, show_title:false, theme:'pp_default', deeplinking:false});
2470
2471    // Register global hook
2472    $(document).ajaxComplete(function(event, request, settings)
2473    {
2474    //   alert(settings);
2475    });
2476});
2477var _swfFlashvars = {
2478    l1:"/",
2479    l2:"/page/order/",
2480    l3:"/page/pay/",
2481    l4:"/page/delivery/",
2482    l5:"/page/skidki/",
2483    l6:"/page/sale/",
2484    l7:"/page/garantii/",
2485    l8:"/page/nash-magazin/",
2486    l9:"#",
2487    l10:"/page/map/",
2488    l11:"/faq/"
2489};
2490
2491var _swfParams = {
2492    menu:"false",
2493    wmode:"opaque"
2494};
2495
2496var _swfAttributes = {};
2497
2498swfobject.embedSWF("/swf/header.swf", "header-back", "100%", "319", "9.0.0", "/swf/header.swf", _swfFlashvars, _swfParams, _swfAttributes);
2499var Flashvars = {};
2500
2501var Params = {
2502    menu:"false",
2503    wmode:"opaque"
2504};
2505
2506var Attributes = {};
2507
2508swfobject.embedSWF("/swf/banner.swf", "banner-center", "100%", "85", "9.0.0", "/swf/banner.swf", Flashvars, Params, Attributes);
2509var activePopup = false;
2510
2511
2512function initPopup(popupName)
2513{
2514    var _overlay = $('<div id="popup-overlay"></div>').css({opacity:.5});
2515    $('body').append(_overlay);
2516
2517    // hide popup by overlay clickin'
2518    $('#popup-overlay').click(function()
2519    {
2520        $(popupName).fadeOut(500);
2521        $('#popup-overlay').fadeOut(500);
2522        activePopup = false;
2523    });
2524
2525    //$('input.close', activePopup).live('click', function()
2526    $(document).on('click', 'input.close', function()
2527    {
2528        $(popupName).fadeOut(500);
2529        $('#popup-overlay').fadeOut(500);
2530        activePopup = false;
2531    });
2532}
2533
2534
2535function loadPopup(obj, div)
2536{
2537    if (!obj.attr('rel')) return false;
2538    
2539    $.ajax({
2540        url:obj.attr('rel'),
2541        
2542        success:function(data, textStatus)
2543        {
2544            $(div).html(data);          
2545        },
2546        
2547        beforeSend:function(XMLHttpRequest)
2548        {
2549        },
2550                
2551        complete:function(XMLHttpRequest, textStatus)
2552        {
2553            showPopup(div, true);
2554        },
2555    });
2556}
2557
2558
2559function showPopup(popupName, loaded)
2560{
2561    if (activePopup == '#notification-popup') return false;
2562    
2563    if (activePopup)
2564    {
2565        $(activePopup).fadeOut(500);
2566        activePopup = false;
2567    }
2568    
2569    $('html, body').animate({ scrollTop: 0 }, 0);
2570    
2571    activePopup = popupName;
2572    $('#popup-overlay').delay(100).fadeIn(500);
2573    $(popupName).delay(100).fadeIn(500);
2574}
2575
2576
2577// Fix for flash menu
2578function flashPopup(popupName)
2579{
2580    if ('#registration-popup' == popupName) showPopup('#registration-popup', true);
2581    if ('#feedback-popup' == popupName) loadPopup($('#header-feedback'), '#feedback-popup');
2582}
2583
2584
2585$(function()
2586{
2587    $(document).on('click', '.show-brands', function()
2588    {
2589        loadPopup($(this), '#brands-popup');
2590        return false;
2591    }); 
2592    
2593    
2594    $(document).on('click', '.show-subbrands', function()
2595    {
2596        loadPopup($(this), '#subbrands-popup');
2597        return false;
2598    });
2599    
2600    $(document).on('click', '.show-feedback', function()
2601    {
2602        loadPopup($(this), '#feedback-popup');
2603        return false;
2604    });
2605    
2606
2607
2608    $(document).on('click', '.show-registration', function()
2609    {
2610        showPopup('#registration-popup', true);
2611        return false;
2612    });
2613
2614    /*$(document).on('click', '.show-cart', function()
2615    {
2616        showPopup('#cart-product-popup', true);
2617        return false;
2618    });*/
2619    
2620    $(document).on('click', '.show-gift', function()
2621    {
2622        showPopup('#cart-gift-popup', true);
2623        return false;
2624    });
2625
2626    initPopup('div.popup');
2627});
2628function showNotification(message)
2629{
2630    $('#notification-message').html(message);
2631    showPopup('#notification-popup', true);
2632}
2633/*
2634 *
2635 */
2636function getFilterParams(param, value)
2637{
2638    if (param == "filter[in_stock]")
2639    {
2640        return ("undefined" == typeof($.QueryString[param])) ? false : true;
2641    }
2642
2643    if (param == "filter[is_allsex]")
2644    {
2645        return ("undefined" == typeof($.QueryString[param])) ? false : true;
2646    }    
2647    
2648    if (param == "filter[is_mens]")
2649    {
2650        return ("undefined" == typeof($.QueryString[param])) ? false : true;
2651    }
2652
2653    if (param == "filter[is_womens]")
2654    {
2655        return ("undefined" == typeof($.QueryString[param])) ? false : true;
2656    }
2657
2658    if (param == "filter[is_unisex]")
2659    {
2660        return ("undefined" == typeof($.QueryString[param])) ? false : true;
2661    }
2662
2663    return ("undefined" == typeof($.QueryString[param])) ? value : $.QueryString[param];
2664}
2665
2666/*
2667 *
2668 */
2669function getFilterDefaults(param)
2670{
2671    if ('filter[mechanism_type]' == param) return '';
2672    if ('filter[body_material]'  == param) return '';
2673    if ('filter[strap_bracelet]' == param) return '';
2674
2675    if ('filter[base_width]'     == param) return '';
2676    if ('filter[mounting_width]' == param) return '';
2677
2678    if ('filter[from_cost]'      == param) return '';
2679    if ('filter[to_cost]'        == param) return '';
2680
2681    if ('filter[in_stock]'       == param) return false;
2682
2683    if ('filter[is_allsex]'      == param) return true;
2684    if ('filter[is_mens]'        == param) return false;
2685    if ('filter[is_womens]'      == param) return false;
2686    if ('filter[is_unisex]'      == param) return false;
2687
2688    if ('sort[by]'               == param) return 'title';
2689    if ('page[per]'              == param) return 24;
2690}
2691
2692/*
2693 *
2694 */
2695function isFilterChanged()
2696{
2697    if (
2698        ($('#filter_mechanism_type').attr('value') != getFilterDefaults('filter[mechanism_type]')) ||
2699        ($('#filter_body_material').attr('value')  != getFilterDefaults('filter[body_material]')) ||
2700        ($('#filter_strap_bracelet').attr('value') != getFilterDefaults('filter[strap_bracelet]')) ||
2701
2702        ($('#filter_base_width').attr('value')     != getFilterDefaults('filter[base_width]')) ||
2703        ($('#filter_mounting_width').attr('value') != getFilterDefaults('filter[mounting_width]')) ||
2704
2705        ($('#filter_from_cost').attr('value')      != getFilterDefaults('filter[from_cost]')) ||
2706        ($('#filter_to_cost').attr('value')        != getFilterDefaults('filter[to_cost]')) ||
2707
2708        ($('#filter_in_stock').is(":checked")      != getFilterDefaults('filter[in_stock]')) ||
2709
2710        ($('#filter_is_allsex').is(":checked")     != getFilterDefaults('filter[is_allsex]')) ||
2711        ($('#filter_is_mens').is(":checked")       != getFilterDefaults('filter[is_mens]')) ||
2712        ($('#filter_is_womens').is(":checked")     != getFilterDefaults('filter[is_womens]')) ||
2713        ($('#filter_is_unisex').is(":checked")     != getFilterDefaults('filter[is_unisex]')) ||
2714
2715        ($('#sort_by').attr('value')               != getFilterDefaults('sort[by]')) ||
2716        ($('#page_per').attr('value')              != getFilterDefaults('page[per]'))
2717    )
2718    {
2719        return true;
2720    }
2721
2722    return false;
2723}
2724
2725/**
2726 *
2727 */
2728function isFilterApplied()
2729{
2730    if (
2731        ($('#filter_mechanism_type').attr('value') == getFilterParams('filter[mechanism_type]', getFilterDefaults('filter[mechanism_type]'))) &&
2732        ($('#filter_body_material').attr('value')  == getFilterParams('filter[body_material]', getFilterDefaults('filter[body_material]'))) &&
2733        ($('#filter_strap_bracelet').attr('value') == getFilterParams('filter[strap_bracelet]', getFilterDefaults('filter[strap_bracelet]'))) &&
2734
2735        ($('#filter_base_width').attr('value')     == getFilterParams('filter[base_width]', getFilterDefaults('filter[base_width]'))) &&
2736        ($('#filter_mounting_width').attr('value') == getFilterParams('filter[mounting_width]', getFilterDefaults('filter[mounting_width]'))) &&
2737
2738        ($('#filter_from_cost').attr('value')      == getFilterParams('filter[from_cost]', getFilterDefaults('filter[from_cost]'))) &&
2739        ($('#filter_to_cost').attr('value')        == getFilterParams('filter[to_cost]', getFilterDefaults('filter[to_cost]'))) &&
2740
2741        ($('#filter_in_stock').is(":checked")      == getFilterParams('filter[in_stock]', getFilterDefaults('filter[in_stock]'))) &&
2742
2743        ($('#filter_is_allsex').is(":checked")       == getFilterParams('filter[is_allsex]', getFilterDefaults('filter[is_allsex]'))) &&
2744        ($('#filter_is_mens').is(":checked")       == getFilterParams('filter[is_mens]', getFilterDefaults('filter[is_mens]'))) &&
2745        ($('#filter_is_womens').is(":checked")     == getFilterParams('filter[is_womens]', getFilterDefaults('filter[is_womens]'))) &&
2746        ($('#filter_is_unisex').is(":checked")     == getFilterParams('filter[is_unisex]', getFilterDefaults('filter[is_unisex]'))) &&
2747
2748        ($('#sort_by').attr('value')               == getFilterParams('sort[by]', getFilterDefaults('sort[by]'))) &&
2749        ($('#page_per').attr('value')              == getFilterParams('page[per]', getFilterDefaults('page[per]'))))
2750    {
2751        return true;
2752    }
2753
2754    return false;
2755}
2756
2757/**
2758 *
2759 */
2760function updateButtons(obj)
2761{
2762    if (isFilterChanged())
2763    {
2764        $("#filter-reset").removeClass("disabled").addClass("ok");
2765        $("#filter-reset").attr('onclick', '');
2766    } else {
2767        $("#filter-reset").removeClass("ok").addClass("disabled");
2768        $("#filter-reset").attr('onclick', 'return false');
2769    }
2770
2771    if (isFilterApplied())
2772    {
2773        $("#filter-submit").removeClass("apply").addClass("disabled");
2774        $("#filter-submit").attr('onclick', 'return false');
2775    } else {
2776        $("#filter-submit").removeClass("disabled").addClass("apply");
2777        $("#filter-submit").attr('onclick', '');
2778    }
2779}
2780
2781/**
2782 *
2783 */
2784$(function()
2785{
2786    $('#filter').change(function()
2787    {
2788        updateButtons($(this));
2789    });
2790
2791    $('#filter_from_cost').keyup(function()
2792    {
2793        updateButtons($(this));
2794    });
2795
2796    $('#filter_to_cost').keyup(function()
2797    {
2798        updateButtons($(this));
2799    });
2800
2801    $('#search-button').click(function() {
2802        $('#product_search').submit();
2803    });
2804
2805    updateButtons($(this));
2806});
2807function feedbackSent(obj)
2808{
2809    sentPostAJAX(
2810        $('#feedback'), 
2811        $('#feedback'), 
2812        $('#feedback-popup')
2813    );
2814}
2815
2816$(function()
2817{
2818    $(document).on('submit', '#feedback', function()
2819    {
2820        feedbackSent($(this));
2821        return false;
2822    });
2823    
2824});
2825angular.module('Cart.InputMaskDirective', []).directive('inputMask', function(){
2826  return {
2827    restrict: 'A',
2828    link: function(scope, el, attrs){
2829      el.inputmask(scope.$eval(attrs.inputMask));
2830      el.on('change', function(){
2831        scope.$eval(attrs.ngModel + "='" + el.val() + "'");
2832        // or scope[attrs.ngModel] = el.val() if your expression doesn't contain dot.
2833      });
2834    }
2835  };
2836});
2837angular.module('Cart.ngFocusDirective', []).directive('ngFocus', [function() {
2838  var FOCUS_CLASS = "ng-focused";
2839  return {
2840    restrict: 'A',
2841    require: 'ngModel',
2842    link: function(scope, element, attrs, ctrl) {
2843      ctrl.$focused = false;
2844      element.bind('focus', function(evt) {
2845        element.addClass(FOCUS_CLASS);
2846        scope.$apply(function() {ctrl.$focused = true;});
2847      }).bind('blur', function(evt) {
2848        element.removeClass(FOCUS_CLASS);
2849        scope.$apply(function() {ctrl.$focused = false;});
2850      });
2851    }
2852  }
2853}]);
2854angular.module('Cart.ngMatchDirective', []).directive("ngMatch", function() {
2855    return {
2856        require: "ngModel",
2857        link: function(scope, elem, attrs, ctrl) {
2858            var otherInput = elem.inheritedData("$formController")[attrs.ngMatch];
2859
2860            ctrl.$parsers.push(function(value) {
2861                if(value === otherInput.$viewValue) {
2862                    ctrl.$setValidity("nomatch", true);
2863                    return value;
2864                }
2865                ctrl.$setValidity("nomatch", false);
2866            });
2867
2868            otherInput.$parsers.push(function(value) {
2869                ctrl.$setValidity("nomatch", value === ctrl.$viewValue);
2870                return value;
2871            });
2872        }
2873    };
2874});
2875/**
2876 * Email unique validation
2877 */
2878angular.module('User.EmailUniqueDirective', []).directive('emailUnique', function($http, $timeout, UserProfileStorage) { // available
2879    //return false
2880
2881    return {
2882        require: 'ngModel',
2883        link: function(scope, elem, attr, ctrl) {
2884            // push the validator on so it runs last.
2885            ctrl.$parsers.push(function(viewValue) {
2886                // set it to true here, otherwise it will not 
2887                // clear out when previous validators fail.
2888                ctrl.$setValidity('emailUnique', true);
2889                if(ctrl.$valid) {
2890                  // set it to false here, because if we need to check 
2891                  // the validity of the email, it's invalid until the 
2892                  // AJAX responds.
2893                  //ctrl.$setValidity('checkingEmail', false);
2894
2895                  // now do your thing, chicken wing.
2896                  if(viewValue !== "" && typeof viewValue !== "undefined") {
2897                      $http.post('/user/email',{email:viewValue})
2898                          .success(function(data, status, headers, config) {
2899                              ctrl.$setValidity('emailUnique', false);
2900
2901                              if (data.status == 'unique') {
2902                                ctrl.$setValidity('emailUnique', true);
2903                              } else {
2904                                ctrl.$setValidity('emailUnique', false);
2905                              }
2906                          })
2907                          .error(function(data, status, headers, config) {
2908
2909                          });
2910                  } else {
2911                      ctrl.$setValidity('emailUnique', false);
2912                      //ctrl.$setValidity('checkingEmail', true);
2913                  }
2914                }
2915                return viewValue;
2916            });
2917
2918        }
2919    };
2920});
2921'use strict';
2922
2923/**
2924 * Fix for autofill forms
2925 */
2926angular.module('User.FormAutofillFixDirective', []).directive('formAutofillFix', function() {
2927  return function(scope, elem, attrs) {
2928    // Fixes Chrome bug: https://groups.google.com/forum/#!topic/angular/6NlucSskQjY
2929    elem.prop('method', 'POST');
2930
2931    // Fix autofill issues where Angular doesn't know about autofilled inputs
2932    if(attrs.ngSubmit) {
2933      setTimeout(function() {
2934        elem.unbind('submit').submit(function(e) {
2935          e.preventDefault();
2936          elem.find('input, textarea, select').trigger('input').trigger('change').trigger('keydown');
2937          scope.$apply(attrs.ngSubmit);
2938        });
2939      }, 0);
2940    }
2941  };
2942});
2943'use strict';
2944
2945/**
2946 * User profile storage
2947 */
2948angular.module('User.ProfileStorage', []).factory('UserProfileStorage', ['$rootScope', function($rootScope) {
2949  
2950    var service = {
2951        model: {}
2952    }
2953
2954    $rootScope.$on('saveState', function() {
2955        sessionStorage.profile = angular.toJson(service.model)
2956    })
2957
2958    service.model = (sessionStorage.profile) ? angular.fromJson(sessionStorage.profile) : {}
2959
2960    return service
2961}]);
2962'use strict';
2963
2964/**
2965 * Cart gifts storage
2966 */
2967angular.module('Cart.GiftsStorage', []).factory('CartGiftsStorage', ['$rootScope', function($rootScope) {
2968  
2969    var service = {
2970        model: []
2971    }
2972
2973    $rootScope.$on('saveState', function() {
2974        sessionStorage.gifts = angular.toJson(service.model)
2975    })
2976
2977    service.model = (sessionStorage.gifts) ? angular.fromJson(sessionStorage.gifts) : []
2978
2979    return service
2980}]);
2981'use strict';
2982
2983/**
2984 * Cart order storage
2985 */
2986angular.module('Cart.OrderStorage', []).factory('CartOrderStorage', ['$rootScope', function($rootScope) {
2987  
2988    var service = {
2989        model: {}
2990    }
2991
2992    $rootScope.$on('saveState', function() {
2993        sessionStorage.order = angular.toJson(service.model)
2994    })
2995
2996    service.model = (sessionStorage.order) ? angular.fromJson(sessionStorage.order) : {}
2997    
2998    return service
2999}]);
3000'use strict';
3001
3002/**
3003 * Cart products storage
3004 */
3005angular.module('Cart.ProductsStorage', []).factory('CartProductsStorage', ['$rootScope', function($rootScope) {
3006  
3007    var service = {
3008        model: []
3009    }
3010
3011    $rootScope.$on('saveState', function() {
3012        sessionStorage.products = angular.toJson(service.model)
3013    })
3014
3015    service.model = (sessionStorage.products) ? angular.fromJson(sessionStorage.products) : []
3016    
3017    return service
3018}]);
3019'use strict';
3020
3021/**
3022 * Cart total storage
3023 */
3024angular.module('Cart.TotalStorage', []).factory('CartTotalStorage', ['$rootScope', function($rootScope) {
3025  
3026    var service = {
3027        model: {}
3028    }
3029
3030    $rootScope.$on('saveState', function() {
3031        sessionStorage.total = angular.toJson(service.model)
3032    })  
3033    
3034    service.model = (sessionStorage.total) ? angular.fromJson(sessionStorage.total) : {}
3035    
3036    return service
3037}]);
3038'use strict';
3039
3040/**
3041 * Sign In Controller
3042 */
3043angular.module('User.SignInController', [
3044    'User.ProfileStorage'
3045]).controller('UserSignInController',  [
3046    '$scope', 
3047    '$http', 
3048    'UserProfileStorage',  
3049    function($scope, $http, UserProfileStorage) {
3050  
3051    /**
3052     * Init
3053     */
3054    $scope.user = UserProfileStorage;
3055
3056    /**
3057     * User sign in
3058     */
3059    $scope.signIn = function (auth) {
3060
3061        $http.post('/user/signin', auth)
3062            .success(function (data, status) {
3063                data.password = auth.password;
3064                data.password_again = auth.password;
3065                $scope.user.model = data;
3066            })
3067            .error(function (data, status) {
3068                if (status === 400) {
3069                    showNotification('<b>Опаньки!</b> Неверное значение электронной почты или пароля.');
3070                } else {
3071                    Bugsnag.notify("RequestError", "Ошибка запроса /user/signin.");
3072                    showNotification('<span style="color: red; font-weight: bold;">Ой, случилась неприятность.</span> <br /><br />Возникли какие-то проблемы, проверьте подключение к сети Интернет и повторите попытку.');
3073                }
3074                console.dir(data);
3075            });
3076    };
3077
3078    /**
3079     * User sign out
3080     */
3081    $scope.signOut = function (auth) {
3082
3083        $http.get('/user/signout', auth)
3084            .success(function (data, status) {
3085                $scope.user.model = null;
3086            })
3087            .error(function (data, status) {
3088                Bugsnag.notify("CartRequestError", "Ошибка с запросом '/user/signout'.");
3089                showNotification('<span style="color: red; font-weight: bold;">Ой, случилась неприятность.</span> <br /><br />Возникли какие-то проблемы, проверьте подключение к сети Интернет и повторите попытку.');
3090                console.dir(data);                
3091            });
3092    };
3093}]);
3094'use strict';
3095
3096/**
3097 * 
3098 */
3099angular.module('User.SignUpController', [
3100    'User.ProfileStorage'
3101]).controller('UserSignUpController',  [
3102    '$scope', 
3103    '$http', 
3104    'UserProfileStorage',  
3105    function($scope, $http, UserProfileStorage) {
3106 
3107    /**
3108     * Init
3109     */
3110    $scope.user = UserProfileStorage;
3111
3112    /**
3113     * User sign up
3114     */
3115    $scope.signUp = function (user) {
3116
3117        $http.post('/user/signup', user)
3118            .success(function (data, status) {
3119                showNotification('<b>Поздравляем!</b> Вы успешно зарегистрированы и авторизированы.');
3120                $scope.user.model = data;
3121            })
3122            .error(function (data, status) {
3123                Bugsnag.notify("RequestError", "Ошибка с запросом /user/signup.");
3124                showNotification('<span style="color: red; font-weight: bold;">Ой, случилась неприятность.</span> <br /><br />Возникли проблемы с регистрацией или авторизацией.<br /><br />Вероятнее всего, Вы ошиблись и указали несуществующую электронную почту.<br /><br /><b>Решение проблемы:</b><br /><br />1. Проверьте: все символы, дефисы и точки в электронной почте, которую Вы указали.<br />2. Или используйте другую почту.');
3125                console.dir(data);
3126            });
3127    };
3128}]);
3129'use strict';
3130
3131/**
3132 * 
3133 */
3134angular.module('User.ProfileController', [
3135    'Cart.OrderStorage', 
3136    'User.ProfileStorage'
3137]).controller('UserProfileController',  [
3138    '$scope', 
3139    '$rootScope',
3140    '$http', 
3141    'CartOrderStorage', 
3142    'UserProfileStorage', 
3143    function($scope, $rootScope, $http, CartOrderStorage, UserProfileStorage) {
3144  
3145    /**
3146     * Init
3147     */
3148    $scope.order = CartOrderStorage;
3149    $scope.user = UserProfileStorage;
3150
3151    /**
3152     * Save profile
3153     */
3154    $scope.saveUser = function(successCallback) {
3155
3156        $scope.form.$submitted = true;
3157
3158        if ($scope.form.$invalid) {
3159            return showNotification('<b>Внимание!</b> <br /><br />Вы указали неверные данные о себе или не заполнили поле(я) в <b>регистрационной форме</b>.<br /><br /> Поля с ошибками отмечены <span style="color: red; font-weight: bold;">красным цветом</span>.<br /><br />Пожалуйста, обратите внимание, что все поля отмеченные таким <b>*</b> знаком - нужно обязательно заполнить.');
3160        }
3161
3162        $http.put('/user/update', $scope.user.model)
3163            .success(function (data, status) {
3164                successCallback();
3165            })
3166            .error(function (data, status) {
3167                showNotification('<b>Что-то не так.</b> <br /><br />Вероятнее всего, Вы ошиблись и указали несуществующую электронную почту.<br /><br /><b>Решение проблемы:</b><br /><br />1. Проверьте: все символы, дефисы и точки в электронной почте, которую Вы указали.<br />2. Или используйте другую почту.');
3168                console.dir(data);
3169            });
3170    }
3171
3172    $rootScope.$on('saveUser', function(event, successCallback) {
3173        $scope.saveUser(successCallback);
3174    });
3175
3176}]);
3177'use strict';
3178
3179/**
3180 * Small cart controller
3181 */
3182angular.module('Cart.SmallController', [
3183    'Cart.ProductsStorage', 
3184    'Cart.GiftsStorage', 
3185    'Cart.OrderStorage',
3186    'Cart.TotalStorage'
3187]).controller('CartSmallController', [
3188    '$scope',
3189    '$http',
3190    'CartProductsStorage',
3191    'CartGiftsStorage', 
3192    'CartOrderStorage',
3193    'CartTotalStorage', 
3194    function($scope, $http, CartProductsStorage, CartGiftsStorage, CartOrderStorage, CartTotalStorage) {
3195  
3196    /**
3197     * Init
3198     */
3199    $scope.total = CartTotalStorage;
3200    $scope.products = CartProductsStorage;
3201    $scope.gifts = CartGiftsStorage;
3202    $scope.order = CartOrderStorage;
3203
3204    /**
3205     * Request total prices
3206     * @todo Объеденить с ProductDeliveryController
3207     */
3208    function requestTotal() {
3209        $http.post('/cart/total', {"products": CartProductsStorage.model, "gifts": CartGiftsStorage.model, "order": CartOrderStorage.model})
3210            .success(function (data, status) {
3211                $scope.total.model = data;
3212                console.dir(data);
3213            })
3214            .error(function (data, status) {
3215                Bugsnag.notify("CartRequestError", "Ошибка с корзиной 'опаньки'.");
3216                showNotification('<span style="color: red; font-weight: bold;">Ой, случилась неприятность.</span> <br /><br />Сервер расчета почтовой доставки не отвечает.<br/>Мы никак не можем повлиять на это.<br />Давайте попробуем ещё раз.');
3217                console.dir(data);
3218            });
3219    }
3220
3221    /**
3222     * Watch for products list changes
3223     */
3224    $scope.$watch('products', function() {
3225        requestTotal();
3226    }, true);
3227
3228    /**
3229     * Watch for order info changes
3230     */
3231    $scope.$watch('order', function() {
3232        requestTotal();
3233    }, true);
3234
3235}]);
3236'use strict';
3237
3238/**
3239 * Cart product controller
3240 */
3241angular.module('Cart.ProductController', [
3242    'Cart.ProductsStorage',
3243    'Cart.GiftsStorage',
3244    'Cart.OrderStorage',
3245    'Cart.TotalStorage'
3246]).controller('CartProductController', [
3247    '$scope',
3248    '$rootScope',
3249    'CartProductsStorage',
3250    'CartGiftsStorage',
3251    'CartOrderStorage',
3252    'CartTotalStorage',
3253    function($scope, $rootScope, CartProductsStorage, CartGiftsStorage, CartOrderStorage, CartTotalStorage) {
3254  
3255    /**
3256     * Init
3257     */
3258    $scope.products = CartProductsStorage;
3259    $scope.product = {};
3260    $scope.gifts = CartGiftsStorage;
3261    $scope.order = CartOrderStorage;
3262    $scope.total = CartTotalStorage;
3263  
3264    $scope.addProduct = function(product) {
3265        $scope.products.model.push(product);
3266        $rootScope.$broadcast('saveState');
3267        $(location).attr('href', '/cart/');
3268    };
3269
3270    $scope.addGift = function(gift) {
3271        $scope.gifts.model.push(gift);
3272        $rootScope.$broadcast('saveState');
3273        $(location).attr('href', '/cart/');
3274    }
3275  
3276    $scope.showProduct = function(product) {
3277        console.dir($scope.product);
3278    }
3279
3280    $scope.showGift = function(gift) {
3281        $scope.gift = gift;
3282    }
3283
3284}]);
3285'use strict';
3286
3287/**
3288 * Cart product controller
3289 */
3290angular.module('Cart.ProductListController', [
3291    'Cart.ProductsStorage'
3292]).controller('CartProductListController', [
3293    '$scope', 
3294    'CartProductsStorage', 
3295    function($scope, CartProductsStorage) {
3296  
3297    /**
3298     * Init
3299     */
3300    $scope.products = CartProductsStorage;
3301  
3302    /**
3303     * Delete product from cart
3304     */
3305    $scope.deleteProduct = function(product) {
3306        var index = $.inArray(product, $scope.products.model);
3307        $scope.products.model.splice(index, 1);
3308    
3309        return false;
3310  }
3311
3312}]);
3313'use strict';
3314
3315/**
3316 * Cart gifts controller
3317 */
3318angular.module('Cart.GiftListController', [
3319    'Cart.GiftsStorage',
3320    'Cart.OrderStorage',
3321    'Cart.TotalStorage'
3322]).controller('CartGiftListController', [
3323    '$scope', 
3324    'CartGiftsStorage',
3325    'CartOrderStorage',
3326    'CartTotalStorage',
3327    function($scope, CartGiftsStorage, CartOrderStorage, CartTotalStorage) {
3328  
3329    /**
3330     * Init
3331     */
3332    $scope.gifts = CartGiftsStorage;
3333    $scope.order = CartOrderStorage;
3334    $scope.total = CartTotalStorage;
3335
3336    /**
3337     * Delete gift from cart
3338     */
3339    $scope.deleteGift = function(gift) {
3340        var index = $.inArray(gift, $scope.gifts.model);
3341        $scope.gifts.model.splice(index, 1);
3342    
3343        return false;
3344    }
3345
3346}]);
3347'use strict';
3348
3349/**
3350 * Cart product controller
3351 */
3352angular.module('Cart.OrderController', [
3353    'Cart.ProductsStorage',
3354    'Cart.GiftsStorage', 
3355    'Cart.OrderStorage',
3356    'Cart.TotalStorage'
3357]).controller('CartOrderController', [
3358    '$scope', 
3359    '$rootScope',
3360    '$http', 
3361    'CartProductsStorage',
3362    'CartGiftsStorage', 
3363    'CartOrderStorage', 
3364    'CartTotalStorage',
3365    function($scope, $rootScope, $http, CartProductsStorage, CartGiftsStorage, CartOrderStorage, CartTotalStorage) {
3366  
3367    /**
3368     * Init
3369     */
3370    $scope.products = CartProductsStorage;
3371    $scope.gifts = CartGiftsStorage;
3372    $scope.order = CartOrderStorage;
3373    $scope.total = CartTotalStorage;
3374    $scope.productsWithoutEms = [];
3375
3376    $scope.deliveryMethods = [
3377        {"title": "-Выберите способ доставки-", "value": "select"},
3378		/*{"title": "самовывоз из пункта выдачи (в Москве)", "value": "самовывоз"},*/
3379        {"title": "Курьером (только по Москве в пределах МКАД)", "value": "курьером"},
3380        {"title": "Почтовая доставка", "value": "ems"}
3381    ];
3382
3383
3384    /**
3385     *  Load delivery method
3386     */
3387    $scope.deliveryMethod = getDeliveryMethod();
3388
3389    /**
3390     * Load EMS post locations
3391     * @todo  объеденить c ProductDeliveryController
3392     */
3393    $http({method: 'GET', url: '/api/cart/delivery/locations'}).
3394        success(function(data, status) {
3395            $scope.status = status;
3396            $scope.deliveryLocations = data;
3397
3398        var locationValue = ($scope.order.model.location) ? $scope.order.model.location : '-';
3399        var locationIndex = $.inArray(locationValue, $.map($scope.deliveryLocations, function(e) { return e.value; }));
3400        $scope.deliveryLocation = $scope.deliveryLocations[locationIndex];
3401
3402        /**
3403         * Save delivery location
3404         */
3405        $scope.$watch('deliveryLocation', function() {
3406        $scope.order.model.location = $scope.deliveryLocation.value;
3407    }, true);      
3408
3409    }).
3410    error(function(data, status) {
3411      $scope.deliveryLocations = data || "{}";
3412      $scope.status = status;
3413    });
3414
3415  /**
3416   * Returns payment methods
3417   */
3418  function getPaymentMethods(deliveryMethod) {
3419    if ('ems' === deliveryMethod) {
3420      return [
3421		{"title": "Оплата онлайн (100% предоплата)", "value": "yandex"}
3422      ]
3423    } else {
3424		if ('курьером' === deliveryMethod) {
3425			return [
3426			{"title": "-Выберите способ-", "value": "select"},
3427			{"title": "Наличные", "value": "наличные"},
3428			{"title": "Оплата онлайн (100% предоплата)", "value": "yandex"}
3429			]
3430		} else {
3431			if ('самовывоз' === deliveryMethod) {
3432				return [
3433				{"title": "-Выберите способ-", "value": "select"},
3434				{"title": "Наличные", "value": "наличные"},/*временно*/
3435				{"title": "Оплата онлайн (100% предоплата)", "value": "yandex"}
3436				]
3437			} else {
3438      return [
3439        {"title": "-Выберите способ-", "value": "select"},
3440		{"title": "Наличные", "value": "наличные"},
3441		{"title": "Банковская карта", "value": "банковская карта"},
3442		{"title": "Оплата онлайн (100% предоплата)", "value": "yandex"}
3443		]
3444			}
3445		}
3446	}
3447  }
3448
3449  /**
3450   *  
3451   */
3452  function getDeliveryMethod() {
3453    var deliveryValue = ($scope.order.model.delivery) ? $scope.order.model.delivery : 'select';
3454    var deliveryIndex = $.inArray(deliveryValue, $.map($scope.deliveryMethods, function(e) { return e.value; }));
3455
3456    // If value not found, then first
3457    if (deliveryIndex === -1) deliveryIndex = 0;
3458    return $scope.deliveryMethods[deliveryIndex];
3459  }
3460
3461  /**
3462   *  
3463   */
3464  function getPaymentMethod(deliveryMethod) {
3465    var paymentValue = ($scope.order.model.payment) ? $scope.order.model.payment : 'наличные';
3466    var paymentIndex = $.inArray(paymentValue, $.map($scope.paymentMethods, function(e) { return e.value; }));
3467
3468    // If value not found, then first
3469    if (paymentIndex === -1) paymentIndex = 0;
3470    return $scope.paymentMethods[paymentIndex];
3471  }
3472
3473  /**
3474   * Watch for delivery method
3475   */
3476  $scope.$watch('deliveryMethod', function() {
3477
3478    if ('ems' === $scope.deliveryMethod.value) {
3479      // If delivery change to ems
3480      if ('ems' !== $scope.order.model.delivery && 'yandex' !== $scope.order.model.payment) {
3481        //showPopup('#ems-popup', true); //временно отключено всплывающее окно (раскомментить)
3482			$scope.order.model.delivery = 'ems'; //временно отключено всплывающее окно (удалить строку)
3483			$scope.order.model.payment = 'yandex'; //временно отключено всплывающее окно (удалить строку)
3484		$scope.deliveryMethod = getDeliveryMethod();
3485			$scope.paymentMethod = getPaymentMethod($scope.deliveryMethod.value); //временно отключено всплывающее окно (удалить строку)
3486        //return; //временно отключено всплывающее окно (раскомментить)
3487      } 
3488
3489      $scope.showLocations = true;
3490    } else {
3491      $scope.showLocations = false;
3492    }
3493
3494    $scope.paymentMethods = getPaymentMethods($scope.deliveryMethod.value);
3495    $scope.paymentMethod = getPaymentMethod($scope.deliveryMethod.value);
3496    $scope.order.model.delivery = $scope.deliveryMethod.value;
3497  }, true);
3498
3499
3500  /**
3501   * Save payment method
3502   */
3503  $scope.$watch('paymentMethod', function() {
3504    $scope.order.model.payment = $scope.paymentMethod.value;
3505  }, true);
3506  
3507
3508  /**
3509   * Save payment method
3510   */
3511  $scope.$watch('products', function() {
3512    // clear on change
3513    $scope.productsWithoutEms = [];
3514
3515    $.each($scope.products.model, function(index, item) {
3516      if (!item.isEms) $scope.productsWithoutEms.push(item);
3517    });
3518  }, true);
3519
3520  /**
3521   * Confirm ems delivery
3522   */
3523  $scope.confirm = function() {
3524    $scope.order.model.delivery = 'ems';
3525    $scope.order.model.payment = 'yandex';
3526
3527    $scope.deliveryMethod = getDeliveryMethod();
3528    $scope.paymentMethod = getPaymentMethod($scope.deliveryMethod.value);
3529  }
3530
3531  /**
3532   * Cancel ems delilvery
3533   */
3534  $scope.cancel = function() {
3535    //$scope.deliveryMethod = getDeliveryMethod();
3536    //$scope.paymentMethod = getPaymentMethod(deliveryValue);
3537  }
3538
3539  /**
3540   * Save order
3541   */
3542  $scope.saveOrder = function() {
3543
3544    if ($scope.order.model.delivery == 'select') {
3545        showNotification('<span style="color: red; font-weight: bold;">Внимание!</span> <br /><br />Вы не выбрали способ доставки.<br />Выберите способ доставки внизу экрана.');
3546        return false;
3547    }
3548
3549    // Save user
3550    $rootScope.$emit('saveUser', function() {
3551        // Add note
3552        var order = $scope.order.model;
3553        order.note = $scope.note;
3554
3555        showNotification('<b>Пожалуйста ожидайте!</b> <br /><br /><br />Идет оформление заказа...');
3556
3557        // Save order when user saved
3558        $http.post('/cart/order', {'products': $scope.products.model, 'gifts': $scope.gifts.model, 'order': order})
3559            .success(function (data, status) {
3560                if ('ems' === order.delivery) {
3561                  showNotification('<b>Поздравляем!</b> Ваш заказ <b> №' + data + '</b><br /><br /><div style="background-color: #E0FFDD; width: 100%;">Проверьте свою электронную почту!</div><br />Вам на почту отправлено письмо с информацией о заказе.<br /><br /><span style="color: green; font-weight: bold; font-size: 14px;">Пожалуйста удостоверьтесь, что отправленное письмо не попало в папку СПАМ!!!</span><br /><br />');
3562                } else {
3563                  showNotification('<b>Поздравляем!</b> Ваш заказ <b> №' + data + '</b><br /><br /><div style="background-color: #E0FFDD; width: 100%;">Проверьте свою электронную почту!</div><br />Вам на почту отправлено письмо с информацией о заказе.<br /><br />В ближайшее время наш сотрудник свяжется с Вами по телефону <span style="color: green; font-weight: bold;">(в рабочее время магазина).<span><br /><br />');
3564                }
3565
3566                // Clear cart
3567                CartProductsStorage.model = [];
3568                CartGiftsStorage.model = [];
3569                CartOrderStorage.model = {"location":"-","delivery":"select","payment":"наличные"};
3570                // CartTotalStorage.model = {"giftPrice":0,"orderPrice":0,"discountPrice":0,"courierPrice":0,"emsPrice":0,"totalPrice":0};
3571            })
3572            .error(function (data, status) {
3573                Bugsnag.notify("CartRequestError", "Ошибка с корзиной 'опаньки' /cart/order.");
3574                showNotification('<span style="color: red; font-weight: bold;">Ой, случилась неприятность.</span> <br />Возникли проблемы с запросами сервера.');
3575                console.dir(data);
3576            });
3577    });
3578
3579
3580  }
3581
3582}]);
3583'use strict';
3584
3585/**
3586 * Product delivery controller
3587 */
3588angular.module('Cart.ProductDeliveryController', [
3589    'Cart.OrderStorage'
3590]).controller('CartProductDeliveryController', [
3591    '$scope',
3592    '$http',
3593    'CartOrderStorage',
3594    function($scope, $http, CartOrderStorage) {
3595  
3596    /**
3597     * Init
3598     */
3599    $scope.order = CartOrderStorage;
3600    $scope.product = {};
3601    $scope.total = {model: {'courierPrice': 'загружаю...', 'emsPrice': 'загружаю...'}};
3602
3603    /**
3604     * Load EMS post locations
3605     * @todo объеденить с OrderController
3606     */
3607    $http({method: 'GET', url: '/api/cart/delivery/locations'}).
3608    success(function(data, status) {
3609        $scope.status = status;
3610        $scope.deliveryLocations = data;
3611
3612        var locationValue = ($scope.order.model.location) ? $scope.order.model.location : '-';
3613        var locationIndex = $.inArray(locationValue, $.map($scope.deliveryLocations, function(e) { return e.value; }));
3614        $scope.deliveryLocation = $scope.deliveryLocations[locationIndex];
3615
3616        /**
3617         * Watch for changes
3618         */
3619        $scope.$watch('deliveryLocation', function() {
3620            // Save delivery location
3621            $scope.order.model.location = $scope.deliveryLocation.value;
3622
3623            /**
3624             * Request total prices
3625             * @todo объеденить с SmallController
3626             */
3627            $http.post('/cart/total', {'products': [$scope.product], 'gifts': [], 'order': {'location': $scope.deliveryLocation.value, 'delivery': 'ems'}})
3628                .success(function (data, status) {
3629                    $scope.total.model = data;
3630                    console.dir(data);
3631                })
3632                .error(function (data, status) {
3633                    Bugsnag.notify("CartRequestError", "Ошибка с корзиной 'опаньки'.");
3634                    showNotification('<span style="color: red; font-weight: bold;">Ой, случилась неприятность.</span> <br />Возникли проблемы с запросами сервера.');
3635                    console.dir(data);
3636                });            
3637        }, true);      
3638
3639    }).
3640    error(function(data, status) {
3641        $scope.deliveryLocations = data || "{}";
3642        $scope.status = status;
3643    });
3644
3645}]);
3646'use strict';
3647
3648
3649
3650
3651
3652
3653//
3654// // jQuery Deparam - v0.1.0 - 6/14/2011
3655// // http://benalman.com/
3656// // Copyright (c) 2011 Ben Alman; Licensed MIT, GPL
3657//
3658// (function($) {
3659//     // Creating an internal undef value is safer than using undefined, in case it
3660//     // was ever overwritten.
3661//     var undef;
3662//     // A handy reference.
3663//     var decode = decodeURIComponent;
3664//
3665//     // Document $.deparam.
3666//     var deparam = $.deparam = function(text, reviver) {
3667//         // The object to be returned.
3668//         var result = {};
3669//         // Iterate over all key=value pairs.
3670//         $.each(text.replace(/\+/g, ' ').split('&'), function(index, pair) {
3671//             // The key=value pair.
3672//             var kv = pair.split('=');
3673//             // The key, URI-decoded.
3674//             var key = decode(kv[0]);
3675//             // Abort if there's no key.
3676//             if ( !key ) { return; }
3677//             // The value, URI-decoded. If value is missing, use empty string.
3678//             var value = decode(kv[1] || '');
3679//             // If key is more complex than 'foo', like 'a[]' or 'a[b][c]', split it
3680//             // into its component parts.
3681//             var keys = key.split('][');
3682//             var last = keys.length - 1;
3683//             // Used when key is complex.
3684//             var i = 0;
3685//             var current = result;
3686//
3687//             // If the first keys part contains [ and the last ends with ], then []
3688//             // are correctly balanced.
3689//             if ( keys[0].indexOf('[') >= 0 && /\]$/.test(keys[last]) ) {
3690//                 // Remove the trailing ] from the last keys part.
3691//                 keys[last] = keys[last].replace(/\]$/, '');
3692//                 // Split first keys part into two parts on the [ and add them back onto
3693//                 // the beginning of the keys array.
3694//                 keys = keys.shift().split('[').concat(keys);
3695//                 // Since a key part was added, increment last.
3696//                 last++;
3697//             } else {
3698//                 // Basic 'foo' style key.
3699//                 last = 0;
3700//             }
3701//
3702//             if ( $.isFunction(reviver) ) {
3703//                 // If a reviver function was passed, use that function.
3704//                 value = reviver(key, value);
3705//             } else if ( reviver ) {
3706//                 // If true was passed, use the built-in $.deparam.reviver function.
3707//                 value = deparam.reviver(key, value);
3708//             }
3709//
3710//             if ( last ) {
3711//                 // Complex key, like 'a[]' or 'a[b][c]'. At this point, the keys array
3712//                 // might look like ['a', ''] (array) or ['a', 'b', 'c'] (object).
3713//                 for ( ; i <= last; i++ ) {
3714//                     // If the current key part was specified, use that value as the array
3715//                     // index or object key. If omitted, assume an array and use the
3716//                     // array's length (effectively an array push).
3717//                     key = keys[i] !== '' ? keys[i] : current.length;
3718//                     if ( i < last ) {
3719//                         // If not the last key part, update the reference to the current
3720//                         // object/array, creating it if it doesn't already exist AND there's
3721//                         // a next key. If the next key is non-numeric and not empty string,
3722//                         // create an object, otherwise create an array.
3723//                         current = current[key] = current[key] || (isNaN(keys[i + 1]) ? {} : []);
3724//                     } else {
3725//                         // If the last key part, set the value.
3726//                         current[key] = value;
3727//                     }
3728//                 }
3729//             } else {
3730//                 // Simple key.
3731//                 if ( $.isArray(result[key]) ) {
3732//                     // If the key already exists, and is an array, push the new value onto
3733//                     // the array.
3734//                     result[key].push(value);
3735//                 } else if ( key in result ) {
3736//                     // If the key already exists, and is NOT an array, turn it into an
3737//                     // array, pushing the new value onto it.
3738//                     result[key] = [result[key], value];
3739//                 } else {
3740//                     // Otherwise, just set the value.
3741//                     result[key] = value;
3742//                 }
3743//             }
3744//         });
3745//
3746//         return result;
3747//     };
3748//
3749//     // Default reviver function, used when true is passed as the second argument
3750//     // to $.deparam. Don't like it? Pass your own!
3751//     deparam.reviver = function(key, value) {
3752//         var specials = {
3753//             'true': true,
3754//             'false': false,
3755//             'null': null,
3756//             'undefined': undef
3757//         };
3758//
3759//         return (+value + '') === value ? +value // Number
3760//             : value in specials ? specials[value] // true, false, null, undefined
3761//                 : value; // String
3762//     };
3763//
3764// }(jQuery));
3765
3766
3767/**
3768 * Product delivery controller
3769 */
3770angular.module('Products.FilterFormController', [
3771]).controller('ProductsFilterFormController', [
3772    '$scope',
3773    '$http',
3774    '$location',
3775    function($scope, $http, $location) {
3776
3777        /**
3778         *
3779         */
3780        var loadProducts = function() {
3781
3782            $.ajax({
3783                type: 'get',
3784                url: location.pathname + location.search,
3785                beforeSend: function () {
3786                    $('#products').hide();
3787                    $('#products-preloader').show();
3788                },
3789                success: function (data) {
3790                    $('#products-preloader').hide();
3791                    $('#products').show();
3792                    $('#products').html(data);
3793                }
3794            });
3795
3796        }
3797
3798        /**
3799         *
3800         */
3801        $('.ajax').live('click', function(e) {
3802            e.preventDefault();
3803            window.history.pushState({url: $(this).attr('href')}, null, $(this).attr('href'));
3804
3805            loadProducts();
3806            window.scrollTo(0, 0);
3807        });
3808
3809        /**
3810         *
3811         */
3812        $(window).on("popstate", function(event) {
3813            //if (event.originalEvent.state !== null) {
3814            //    console.dir(event.originalEvent.state);
3815                loadProducts();
3816
3817                // Parses GET parameter values.
3818                var search = location.search.substring(1);
3819                if (search) {
3820                    var params = JSON.parse('{"' + decodeURI(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g,'":"').replace(/\+/g, ' ') + '"}');
3821                } else {
3822                    var params = {};
3823                }
3824
3825                // Sets the param values in the form.
3826                for (var key in params) {
3827                    if ($("[name='" + key + "']")[0].type === 'checkbox') {
3828                        //$("[name='" + key + "']").attr('disabled', false);
3829                        $("[name='" + key + "']").attr('checked', 'checked');
3830                        updateButtonTitles($("[name='" + key + "']"));
3831
3832                        if (key === 'filter[is_mens]') {
3833                            $('#filter_is_womens').attr('checked', false);
3834                        } else if (key === 'filter[is_womens]') {
3835                            $('#filter_is_mens').attr('checked', false);
3836                        }
3837                    } else {
3838                        $("[name='" + key + "']").val(params[key]);
3839                    }
3840                }
3841
3842                // Resets field value if the parameter is not present in the list of GET params.
3843                $("#filter :input").each(function() {
3844                    if (params[this.name] === undefined) {
3845                        if (this.type === 'checkbox') {
3846                            $(this).attr('checked', false);
3847
3848                            //if (!$('#filter_is_mens').is(":checked")) $('#filter_is_womens').attr('disabled', false);
3849                            //if (!$('#filter_is_womens').is(":checked")) $('#filter_is_mens').attr('disabled', false);
3850                        } else {
3851                            if (this.name === 'sort[by]') {
3852                                this.value = 'title';
3853                            } else if (this.name === 'page[per]') {
3854                                this.value = '24';
3855                            } else {
3856                                this.value = "";
3857                            }
3858                        }
3859                    }
3860                });
3861                
3862                if (!$('#filter_is_mens').is(':checked') && !$('#filter_is_womens').is(':checked') && !$('#filter_is_unisex').is(':checked')) {
3863                    $('#filter_is_allsex').attr('checked', 'checked');
3864                    $("#filter_is_unisex").next("span").text('Выбрать УНИСЕКС');
3865                    $('#filter_is_mens').next("span").text('Выбрать МУЖСКИЕ');
3866                    $('#filter_is_womens').next("span").text('Выбрать ЖЕНСКИЕ');
3867                    $('#filter_is_unisex').next("span").text('Выбрать УНИСЕКС');
3868                }
3869
3870                updateButtons();
3871           // }
3872        });
3873
3874        /**
3875         *
3876         */
3877        var sendForm = function() {
3878            var newDecodedParams = decodeURIComponent(
3879                $("#filter :input").filter(
3880                    function(index, element) {
3881                        if (element.name == 'requires_cleaning') return false;
3882                        return $(element).val() != "";
3883                    }
3884                ).serialize()
3885            );
3886            var newURL = window.location.pathname + '?' + newDecodedParams;
3887            //$location.url(newURL);
3888            //console.log(newDecodedParams);
3889            var state = { url: newURL }  //window.location.href
3890            window.history.pushState(state, newURL, newURL);
3891
3892            loadProducts();
3893        }
3894
3895        /**
3896         *
3897         */
3898        $('#filter').submit(function(event){
3899            event.preventDefault();
3900            sendForm();
3901        });
3902
3903        /**
3904         *
3905         */
3906        $('#filter').on('change', "input[name='filter[in_stock]'], select", function(event) {
3907            sendForm();
3908        });
3909
3910        /**
3911         *
3912         * @type {null}
3913         */
3914        var timeout = null;
3915        $('#filter').on('input', "input[type='text'], textarea", function(event) {
3916            clearTimeout(timeout);
3917            timeout = setTimeout(sendForm, 1000);
3918        });
3919
3920        // Set the initial state of the fields.
3921        if (!$('#filter_is_mens').is(':checked') && !$('#filter_is_womens').is(':checked') && !$('#filter_is_unisex').is(':checked')) {
3922            $('#filter_is_allsex').attr('checked', 'checked');
3923        }
3924
3925
3926        updateButtonTitles($("#filter-sex").find("input[type='checkbox']:checked"));
3927        //
3928        function updateButtonTitles(button) {
3929            if (button.attr('name') === 'filter[is_mens]') {
3930                $('#filter_is_womens').attr('checked', false);
3931                $('#filter_is_unisex').attr('checked', false);
3932                $('#filter_is_allsex').attr('checked', false);
3933                $("#filter_is_mens").next("span").text('Только МУЖСКИЕ');
3934                $('#filter_is_womens').next("span").text('Выбрать ЖЕНСКИЕ');
3935                $('#filter_is_unisex').next("span").text('Выбрать УНИСЕКС');
3936                $('#filter_is_allsex').next("span").text('ВСЕ-Муж/Жен/Уни');
3937            } else if (button.attr('name') === 'filter[is_womens]') {
3938                $('#filter_is_mens').attr('checked', false);
3939                $('#filter_is_unisex').attr('checked', false);
3940                $('#filter_is_allsex').attr('checked', false);
3941                $("#filter_is_womens").next("span").text('Только ЖЕНСКИЕ');
3942                $('#filter_is_mens').next("span").text('Выбрать МУЖСКИЕ');
3943                $('#filter_is_unisex').next("span").text('Выбрать УНИСЕКС');
3944                $('#filter_is_allsex').next("span").text('ВСЕ-Муж/Жен/Уни');
3945            } else if (button.attr('name') === 'filter[is_unisex]') {
3946                $('#filter_is_mens').attr('checked', false);
3947                $('#filter_is_womens').attr('checked', false);
3948                $('#filter_is_allsex').attr('checked', false);
3949                $("#filter_is_unisex").next("span").text('Только УНИСЕКС');
3950                $('#filter_is_mens').next("span").text('Выбрать МУЖСКИЕ');
3951                $('#filter_is_womens').next("span").text('Выбрать ЖЕНСКИЕ');
3952                $('#filter_is_allsex').next("span").text('ВСЕ-Муж/Жен/Уни');
3953            } else if (button.attr('name') === 'filter[is_allsex]') {
3954                $('#filter_is_mens').attr('checked', false);
3955                $('#filter_is_womens').attr('checked', false);
3956                $('#filter_is_unisex').attr('checked', false);
3957                $("#filter_is_unisex").next("span").text('Выбрать УНИСЕКС');
3958                $('#filter_is_mens').next("span").text('Выбрать МУЖСКИЕ');
3959                $('#filter_is_womens').next("span").text('Выбрать ЖЕНСКИЕ');
3960                $('#filter_is_unisex').next("span").text('Выбрать УНИСЕКС');
3961                $('#filter_is_allsex').next("span").text('ВСЕ-Муж/Жен/Уни');
3962            }
3963        }
3964
3965        //
3966        $('#filter').on('click', "input[type='checkbox']", function(event) {
3967            if ($(this).is(":checked")) {
3968                updateButtonTitles($(this));
3969                sendForm();
3970            } else {
3971                if (this.name !== 'filter[in_stock]') {
3972                    return event.preventDefault();
3973                }
3974            }
3975        });
3976    }]);
3977'use strict';
3978
3979/**
3980 * Application init
3981 */
3982var App = angular.module('chasmag', [
3983    'Cart.InputMaskDirective',
3984    'Cart.ngFocusDirective',
3985    'Cart.ngMatchDirective',
3986    'User.EmailUniqueDirective',
3987    'User.FormAutofillFixDirective',
3988  
3989    'User.SignInController',
3990    'User.SignUpController',
3991    'User.ProfileController',
3992    'Cart.SmallController',
3993    'Cart.ProductController',
3994    'Cart.ProductListController',
3995    'Cart.GiftListController',
3996    'Cart.OrderController',
3997    'Cart.ProductDeliveryController',
3998
3999    'Products.FilterFormController'
4000]);
4001
4002/**
4003 * Fix for IE (placeholder & $dirt)
4004 */
4005App.config(['$provide', function($provide) {
4006    $provide.decorator('$sniffer', ['$delegate', function($sniffer) {
4007        var msie = parseInt((/msie (\d+)/.exec(angular.lowercase(navigator.userAgent)) || [])[1], 10);
4008        var msie11 = !!navigator.userAgent.match(/Trident\/7\./);
4009        // only for IE10
4010        if (10 === msie || msie11) {
4011            var _hasEvent = $sniffer.hasEvent;
4012            $sniffer.hasEvent = function(event) {
4013                if (event === 'input') {
4014                 return false;
4015                }
4016                _hasEvent.call(this, event);
4017            }
4018        }
4019
4020        return $sniffer;
4021    }]);
4022
4023    /**
4024     * Disabled all URL manipulation (otherwhise pushState doesn't work correctly).
4025     */
4026    $provide.decorator('$browser', ['$delegate', function ($delegate) {
4027        $delegate.onUrlChange = function () {};
4028        $delegate.url = function () { return ""};
4029        return $delegate;
4030    }]);
4031}]);
4032
4033/**
4034 * Auto send message to save values
4035 */
4036App.run(['$rootScope', function($rootScope) {
4037
4038    window.onbeforeunload = function(e) {
4039        //$rootScope.$broadcast('saveState');
4040        //console.log('OK');
4041    };
4042
4043    // Fix for Opera 12 onbeforeunload
4044    setInterval(function() {
4045        $rootScope.$broadcast('saveState');
4046    }, 1000);
4047
4048
4049    /**
4050     * If this is Android (Disable input-mask for android and etc.)
4051     */
4052     var uagent = navigator.userAgent.toLowerCase();
4053     if (uagent.search("android") > -1) {
4054        $rootScope.android = true;
4055     }
4056
4057
4058    // $rootScope.$on('$locationChangeSuccess', function(next, current) {
4059    //     console.dir(next);
4060    //     console.log(window.location.href);
4061    // });
4062}]);
4063
4064
4065/**
4066 * Fix placeholders for IE9
4067 */
4068$(function() {
4069    setTimeout(function() {
4070        $('input, textarea').placeholder();
4071    }, 2000);
4072});
4073
4074
4075/**
4076 * Scroll to #down in cart
4077 */
4078$(function() {
4079    var anchor = document.getElementById('down');
4080    if (anchor) anchor.scrollIntoView();
4081});
4082
4083/**
4084 * кнопка хочу скидку
4085 */
4086$(function(){
4087	$('#butdiscount').click(function () {
4088		$(this).addClass('hidden'); $('.costgreenup').toggleClass('lineblue');
4089	});
4090});
4091
4092/**
4093 * SLIDER
4094 */
4095$(window).load(function() {
4096    $('#slider').nivoSlider({
4097    	effect : 'sliceDownLeft',
4098		animSpeed: 500,
4099    	pauseTime : 3000,
4100    	pauseOnHover : true,
4101    	controlNav : true,
4102    	prevText: ' ',
4103    	nextText: ' '
4104    });
4105});
4106/**
4107 * Активное верхнее меню
4108 */
4109$(function () { 
4110    $('.wrapper-black a').each(function () {
4111        var location = window.location.href;
4112        var link = this.href; 
4113        if(location == link) {
4114            $(this).addClass('active');
4115        }
4116    });
4117});

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.