﻿// ALFramework js

/* Namespace for all Creditland js script */
if (!window.ALF) { window.ALF = {}; }

// Type utilities
ALF.getString = function(value) {
    return "" + value;
};
ALF.getInt = function(value) {
    return value * 1;
};
ALF.getDouble = function(value) {
    return value.replace(/\,/g, ".") * 1.0;
};
ALF.isInt = function(value) {
    return !isNaN(this.getInt(value));
};
ALF.isDouble = function(value) {
    return !isNaN(this.getDouble(value));
};

// String utilities
String.prototype._replace = function(str1, str2) {
    return this.replace(new RegExp("" + str1 + "", "g"), str2);
};
String.prototype._trim = function() {
    return this.replace(/^\s+/g, '').replace(/\s+$/g, '');
};
String.prototype._trimChar = function(c) {
    return this.trimCharRight(c).trimCharLeft(c);
};
String.prototype._trimCharLeft = function(c) {
    reg = new RegExp("^(" + c + ")+", "g");
    return this.replace(reg, '');
};
String.prototype._trimCharRight = function(c) {
    reg = new RegExp("(" + c + ")+$", "g");
    return this.replace(reg, '');
};
String.prototype._removeAccents = function() {
    var str = this;
    str = str.replace(/[ÀÁÂÃÄÅ]/g, "A");
    str = str.replace(/[àáâãäå]/g, "a");
    str = str.replace(/[ÒÓÔÕÖØ]/g, "O");
    str = str.replace(/[òóôõöø]/g, "o");
    str = str.replace(/[ÈÉÊË]/g, "E");
    str = str.replace(/[èéêë]/g, "e");
    str = str.replace(/[ÌÍÎÏ]/g, "I");
    str = str.replace(/[ìíîï]/g, "i");
    str = str.replace(/[ÙÚÛÜ]/g, "U");
    str = str.replace(/[ùúûü]/g, "u");
    str = str.replace(/[Ÿ]/g, "Y");
    str = str.replace(/[ÿ]/g, "y");
    str = str.replace(/[Ñ]/g, "N");
    str = str.replace(/[ñ]/g, "n");
    str = str.replace(/[Ç]/g, "C");
    str = str.replace(/[ç]/g, "c");
    return str;
};

String.prototype._getUrlFromUri = function() {
    if (this.search('http://') != -1) {
        return this.replace("http://" + location.host, "");
    }
    else if (this.search('https://') != -1) {
        return this.replace("https://" + location.host, "");
    }
    else {
        return this.replace(location.host, "");
    }
}

// Date utilities
Date._now = function() {
    return new Date();
};
Date._today = function() {
    var d = Date._now();
    return new Date(d.getFullYear(), d.getMonth(), d.getDate());
};
Date._year = function() {
    return Date._now().getFullYear();
};
Date._todayFirstDayMonth = function() {
    var d = Date._now();
    return new Date(d.getFullYear(), d.getMonth(), 1);
};
Date.prototype._getDay = function() {
    return this.getDate();
};
Date.prototype._getYear = function() {
    return this.getFullYear();
};
Date.prototype._addDays = function(n) {
    this.setDate(this._getDay() + n)
    return this;
};
Date.prototype._addMonths = function(n) {
    this.setMonth(this.getMonth() + n);
    return this;
};
Date.prototype._addYears = function(n) {
    this.setYear(this.getFullYear() + n);
    return this;
};
Date._formatDate = function(format) {
    // Use jQuery datepicker utilities
    // TODO : refactor to avoid jQuery ?
    return $.datepicker.formatDate(format, this);
};
Date.prototype._formatPubDateHTML5 = function() {
    var day = this.getDate();
    var month = this.getMonth() + 1;
    var min = this.getMinutes();
    var hours = this.getHours();
    if (day.toString().length == 1)
        day = '0' + day;
    if (month.toString().length == 1)
        month = '0' + month;
    if (min.toString().length == 1)
        min = '0' + min;
    if (hours.toString().length == 1)
        hours = '0' + hours;
    return this.getFullYear() + '-' + month + '-' + day + 'T' + hours + ':' + min;
};
Date.prototype._formatDateddMMyyyy = function(separator) {
    if (separator == undefined )
        separator = '/';
    var day = this.getDate();
    var month = this.getMonth() + 1;
    if (day.toString().length == 1)
        day = '0' + day;
    if (month.toString().length == 1)
        month = '0' + month;
    return day + separator + month + separator + this.getFullYear();
}
Date.prototype._formatDateHHmm = function(separator) {
    if (separator == undefined)
        separator = ':';
    var min = this.getMinutes();
    var hours = this.getHours();
    if (min.toString().length == 1)
        min = '0' + min;
    if (hours.toString().length == 1)
        hours = '0' + hours;
    return hours + separator + min;
}
Date._parseDate = function(format, d) {
    // Use jQuery datepicker utilities
    // TODO : refactor to avoid jQuery ?
    return $.datepicker.parseDate(format, d);
};
Date._tryParseDate = function(format, d) {
    try {
        return Date._parseDate(format, d);
    } catch (ex) {
        return null;
    }
};
ALF.getAge = function(birthday,dateRef,useDayDiff) {
    var today;
    var useJustMonth;    
    if(dateRef)
        today=dateRef;
    else
       today=new Date();
    if (useDayDiff)
       useJustMonth=false;
    else
       useJustMonth=true;
    var age=today.getFullYear()-birthday.getFullYear();
    if(today.getMonth()<birthday.getMonth() || (!useJustMonth && today.getMonth()==birthday.getMonth() && today.getDate()<birthday.getDate())){age--;}
    return age;
};



// Constants
ALF.PATTERN_EMAIL = /^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$/;
ALF.PATTERN_TEL = /^[0-9]{10}$/;

// Misc
ALF.show = function(eltId) { $('#' + eltId).show(); };
ALF.hide = function(eltId) { $('#' + eltId).hide(); };

ALF.goToURL = function(url, parent) {
    /*window.location.href = url;*/
    /* location.href don't send HTTP_REFERER in request header on IE */
    if (typeof parent == 'undefined') parent = false;
    var w = (parent ? window.parent : window);
    if($.browser.msie) {
        var fakeLink = w.document.createElement("a");
        fakeLink.href = url;
        w.document.body.appendChild(fakeLink);
        fakeLink.click(); // click() method defined in IE only
    } else {
        w.location.href = url; // sends referrer in FF, not in IE
    }
};

ALF.objToString = function(obj,separator) {
    var str = '';
    for (var p in obj) {
        if (obj.hasOwnProperty(p)) {
            str += obj[p] + separator;
        }
    }
    // remove last separator
    return str.substring(0,str.length-2);
}

// Input utilities
ALF.getSelectionStart = function(o) {
    if (o.createTextRange) {
        var r = document.selection.createRange().duplicate();
        r.moveEnd('character', o.value.length);
        if (r.text == '') return o.value.length;
        return o.value.lastIndexOf(r.text);
    } else return o.selectionStart;
};

ALF.getSelectionEnd = function(o) {
    if (o.createTextRange) {
        var r = document.selection.createRange().duplicate();
        r.moveStart('character', -o.value.length);
        return r.text.length;
    } else return o.selectionEnd;
};

// ALFramework extenders

var ALF_ValidatorExtenderLiwio_p1 = null;
var ALF_ValidatorExtenderLiwio_p2 = null;
/* Override this method in your script if required */
function ALF_ValidatorExtenderLiwio(val, valid) {
    if (ALF_ValidatorExtenderLiwio_p1 != null && ALF_ValidatorExtenderLiwio_p2 != null) {
        if (!valid)
            ALF.Liwio.event(ALF_ValidatorExtenderLiwio_p1, ALF_ValidatorExtenderLiwio_p2, val.controltovalidate._replace("ctl00_ContentPlaceHolder[0-9]*_", ""));
    }
}

// Add animation on ASP.NET validator
function ALF_ValidatorAnimationExtenderEvaluationFunction(val) {
    // Update message visibility (empty message required)
    document.getElementById(val.id).innerHTML = "";
    val.isvalid = true;
    ValidatorUpdateDisplay(val);
    // Add animation
    var extId = val.id + "_valAnimExt";
    document.getElementById(extId).innerHTML = "<img src='/images/px.gif' alt='Chargement ...' class='alf_validatorImg alf_validatorLoading' />"
    // Evaluate validator
    var valid = val.alf_targetevaluationfunction(val);
    var script = "";
    var msg = val.alf_targeterrormessage;
    if (valid == true)
        script = "document.getElementById('" + extId + "').innerHTML = \"<img src='/images/px.gif' alt='Ok' class='alf_validatorImg alf_validatorOk' />\";";
    else {
        script = "document.getElementById('" + extId + "').innerHTML = \"<img src='/images/px.gif' alt='Erreur' class='alf_validatorImg alf_validatorError' />\";";
        // Get error message (could have been changed by custom validator)
        if (val.alf_targeterrormessage == '') {
            msg = document.getElementById(val.id).innerHTML;
            document.getElementById(val.id).innerHTML = "";
        }
    }
    script += "document.getElementById('" + val.id + "').innerHTML = '" + msg._replace("'", "\\'") + "';ValidatorUpdateDisplay(document.getElementById('" + val.id + "'));";
    setTimeout(script, 400);
    if (ALF_ValidatorExtenderLiwio) ALF_ValidatorExtenderLiwio(val, valid);
    return valid;
}
function ALF_ValidatorAnimationExtenderEnable(val, b) {
    var extId = val.id + "_valAnimExt";
    if (document.getElementById(extId) != null) {
        if (b) {
            document.getElementById(extId).style.display = "inline";
        } else {
            document.getElementById(extId).style.display = "none";
            document.getElementById(extId).innerHTML = "";
        }
    }
}

// Add picto on ASP.NET validator
function ALF_ValidatorPictoExtenderEvaluationFunction(val) {
    var valid = val.alf_targetevaluationfunction(val);
    if (val.isvalid) {
        $("#" + val.id + "_valPictoExt").fadeOut();
    }
    if (valid) {//no error
        ALF_ValidatorPictoExtenderEvaluationFunctionValid(val)
    }
    else {//error
        ALF_ValidatorPictoExtenderEvaluationFunctionError(val);
    }
    if (ALF_ValidatorExtenderLiwio) ALF_ValidatorExtenderLiwio(val, valid);
    return valid;
}
function ALF_ValidatorPictoExtenderEvaluationFunctionValid(val) {
    $("#" + val.id + "_valPictoExt").fadeOut();
    $("#" + val.controltovalidate).removeClass("alf_error");
}
function ALF_ValidatorPictoExtenderEvaluationFunctionError(val) {
    $("#" + val.id + "_valPictoExt").attr("title", val.errormessage._replace("<br/>",""));
    $("#" + val.id + "_valPictoExt").fadeIn();
    $("#" + val.controltovalidate).addClass("alf_error");
}
function ALF_ValidatorPictoExtenderEnable(val, b) {
    var extId = val.id + "_valPictoExt";
    if (document.getElementById(extId) != null) {
        if (b) {
            /* Do nothing */
        } else {
            ALF_ValidatorPictoExtenderEvaluationFunctionValid(val);
        }
    }
}

// Validar effect display
function ALF_ValidatorEffectExtenderEvaluationFunction(val) {
    // Update message visibility (empty message required)
    if (val.isvalid) {
        $('#' + val.id).fadeOut();
    }
    document.getElementById(val.id).innerHTML = "";
    // Evaluate validator
    var valid = val.alf_targetevaluationfunction(val);
    var script = "";
    var msg = val.alf_targeterrormessage;
    if (valid == false) {
        // Get error message (could have been changed by custom validator)
        if (val.alf_targeterrormessage == '') {
            msg = document.getElementById(val.id).innerHTML;
            document.getElementById(val.id).innerHTML = "";
        }
        $('#' + val.id).hide().html(msg).fadeIn();
    }
    if (ALF_ValidatorExtenderLiwio) ALF_ValidatorExtenderLiwio(val, valid);
    return valid;
}

// ALFramework liwio tracking wrapper
ALF.Liwio = {}
ALF.Liwio.enabled = false;
ALF.Liwio.debug = false;
ALF.Liwio.call = function(f, p1, p2, p3) {
    try {
        if (this.enabled) {
            if (p1 != null) p1 = this.clean(p1);
            if (p2 != null) p2 = this.clean(p2);
            if (p3 != null) p3 = this.clean(p3);
            if (this.debug)
                alert("Lw." + f + "('" + p1 + "'" + (p2 != null ? ",'" + p2 + "'" : "") + (p3 != null ? ",'" + p3 + "'" : "") + ")");
            if (p3 != null && p2 != null && p1 != null)
                eval("Lw." + f + "('" + p1 + "', '" + p2 + "', '" + p3 + "')");
            else if (p2 != null && p1 != null)
                eval("Lw." + f + "('" + p1 + "', '" + p2 + "')");
            else if (p1 != null)
                eval("Lw." + f + "('" + p1 + "')");
        }
    } catch (ex) {
        if (this.enabled && this.debug) alert(ex);
    }
};
ALF.Liwio.clean = function(str) {
    return str._removeAccents()._replace("'","\\'")._trim();
};
ALF.Liwio.event = function(p1, p2, p3) {
    this.call("event", p1, p2, p3);
};
ALF.Liwio.trans = function(p1, p2, p3) {
    this.call("trans", p1, p2, p3);
};
ALF.Liwio.tpv = function(p1, p2, p3) {
    this.call("tpv", p1, p2, p3);
};
ALF.Liwio.tpvUrl = function(p1) {
    try {
        var url = document.location.href;
        var p = url.substring(url.indexOf("/", 7), url.length);
        if (p1 != null && p1 != "") {
            p += "#" + p1.replace(/^\s+/g, '').replace(/\s+$/g, '').replace(/\s/g, "-");
        }
        this.tpv(p);
    } catch (ex) {
        if (this.enabled) alert(ex);
    }
};

// ALFramework jQuery plugins

// Update insee code dropdownlist by zip code textbox
(function($) {
    $.fn.zipcodeTextBox = function(ddlId, ddlValidator, ALF_ValidatorExtenderEnable, fctCallBack, validateDllOnLoad, textOptionNull) {
        return this.each(function() {
       
        if (!ddlId) {
                throw 'ddlId argument missing';
            }
            if ($(this).val().length < 5) {
                $("#" + ddlId).hide();
                if (ddlValidator != null) {
                    
                    ValidatorEnable(ddlValidator, false);
                    if (ALF_ValidatorExtenderEnable != null) ALF_ValidatorExtenderEnable(ddlValidator, false);
                }
                if (fctCallBack != null) { fctCallBack($("#" + ddlId).get(0), false, ddlValidator); }
            }
            $(this).keyup(function(event) {
                if ($(this).val().length == 5) {
                    $("#" + ddlId).show();
                    $("#" + ddlId).get(0).options.length = 0;

                    // Feed dropdownlist (json)
                    // Failed when .asmx is embeded in ALFramework library ...

                    // Feed dropdownlist (XML)
                    $.ajax(
                    {
                        type: "GET",
                        url: "/ALFramework/Ws/ZipCodeLocationWs.asmx/GetLocationByZipCode",
                        data: { zipcode: $(this).val() },
                        dataType: "xml",
                        success: function(result) {
                            var ddl = $("#" + ddlId).get(0);
                            ddl.options.length = 0;
                            var j = 0;
                            var nodes = $(result).find('ZipCodeLocation');
                            if (nodes.length > 1) {
                                if (textOptionNull == null)
                                    ddl.options[j++] = new Option("-- Sélectionnez --", "");
                                else
                                    ddl.options[j++] = new Option(textOptionNull, "");
                            }
                            for (var i = 0; i < nodes.length; i++) {
                                ddl.options[j++] = new Option($(nodes[i]).find('Location').text(), $(nodes[i]).find('InseeCode').text());
                            }
                            if (ddlValidator != null) {
                                if (validateDllOnLoad) {
                                    ValidatorEnable(ddlValidator, true);
                                } else {
                                    ddlValidator.enabled = true;
                                    ddlValidator.isvalid = true;
                                }
                                if (ALF_ValidatorExtenderEnable != null) ALF_ValidatorExtenderEnable(ddlValidator, true);
                            }
                            if (fctCallBack != null) { fctCallBack($("#" + ddlId).get(0), true, ddlValidator); }
                        }
                    });
                } else {
                    $("#" + ddlId).hide();
                    if (ddlValidator != null) {
                        ValidatorEnable(ddlValidator, false);
                        if (ALF_ValidatorExtenderEnable != null) ALF_ValidatorExtenderEnable(ddlValidator, false);
                    }
                    if (fctCallBack != null) { fctCallBack($("#" + ddlId).get(0), false, ddlValidator); }
                }
            });
        });
    };
})(jQuery);

// Regular expression input filter
(function($) {
    $.fn.regexFilter = function(regex) {
        return this.each(function() {
            if (!regex) {
                throw 'regex argument missing';
            } else if (regex == 'float-ptbr') {
                regex = /^((\d{1,3}(\.\d{3})*(((\.\d{0,2}))|((\,\d*)?)))|(\d+(\,\d*)?))$/;
            } else if (regex == 'float-enus') {
                regex = /^((\d{1,3}(\,\d{3})*(((\,\d{0,2}))|((\.\d*)?)))|(\d+(\.\d*)?))$/;
            } else {
                try {
                    regex.test("");
                } catch (e) {
                    throw 'regex need to support test method';
                }
            }
            $(this).keypress(function(event) {
                if (event.which == null)
                    key = String.fromCharCode(event.keyCode); // IE
                else if (event.which != 0 && event.charCode != 0)
                    key = String.fromCharCode(event.which); // All others
                else
                    return true;
                var part1 = this.value.substring(0, ALF.getSelectionStart(this));
                var part2 = this.value.substring(ALF.getSelectionEnd(this), this.value.length);
                return regex.test(part1 + key + part2);
            });
        });
    };
})(jQuery);

// Toggle css class on focus/blur event
(function($) {
    $.fn.fieldfocus = function(cssclass) {
        return this.each(function() {
            if (!cssclass) {
                throw 'cssclass argument missing';
            }
            var f = function(event) { $(this).addClass(cssclass); };
            if ($.browser.msie)
                $(this).focusin(f);
            else
                $(this).focus(f);
            $(this).blur(function() { $(this).removeClass(cssclass); });
        });
    };
})(jQuery);

// Mutual exclusion on checkbox list
(function($) {
    $.fn.cbMutualExclusion = function() {
        return this.each(function() {
            var $cbl = $(this);
            $(this).find("input[type='checkbox']").change(function() {
                var l = $cbl.find("input[type='checkbox']");
                for (var i = 0; i < l.length; i++) {
                    if(l[i].id != this.id)
                        $(l[i]).attr('checked', false);
                }
            });
        });
    };
})(jQuery);

// Multiple text input characters counter
(function($) {
    $.fn.charactersCounter = function(inputs) {
        return this.each(function() {
            if (!inputs || inputs.length == 0) {
                throw 'inputs argument missing';
            }
            var $span = $(this);
            var count1 = 0;
            for (var i = 0; i < inputs.length; i++) {
                count1 += $("#" + inputs[i]).val()._trim().length;
                $("#" + inputs[i]).keyup(function() {
                    var count2 = 0;
                    for (var j = 0; j < inputs.length; j++) {
                        count2 += $("#" + inputs[j]).val()._trim().length;
                    }
                    $span.html(count2 + " caractère(s)");
                });
            }
            // Default value
            $span.html(count1 + " caractère(s)");
        });
    };
})(jQuery);

// /!\ Probably not to the state of jquery art 
// (use radio button or select for HTML ? use existing plugins ?)
// Stack level selector
(function($) {
    $.fn.stackLevel = function(readonly, enabledLabels, labels) {
        return this.each(function() {
            var $parent = $(this);
            var $items = $(this).find(".alf_item");
            var $hf = $(this).find("input[type='hidden']")
            var $lbl = $(this).find(".alf_label");

            if (!readonly) {
                $(this).find(".alf_item:first").click(function() {
                    if ($hf.val() == 1) {
                        // Update value
                        $hf.val(0);
                        // Update state
                        $(this).attr('class', "alf_item alf_next");
                        // Update label
                        if (enabledLabels) $lbl.html(labels[0]);
                    } else {
                        // Update value
                        $hf.val(1);
                    }
                });
                $(this).find(".alf_item:gt(0)").click(function() {
                    // Update value
                    $hf.val($(this).attr("value"));
                    // Update state and label in mouseover event
                });
                $items.mouseover(function() {
                    // Update item state
                    $(this).attr('class', "alf_item alf_current");
                    $(this).prevAll(".alf_item").attr('class', "alf_item alf_previous");
                    $(this).nextAll(".alf_item").attr('class', "alf_item alf_next");
                    // Update label
                    if (enabledLabels) $lbl.html(labels[$(this).attr('value')]);
                });
                $items.mouseout(function() {
                    var v = $hf.val();
                    // Update item state
                    for (var i = 0; i < $items.length; i++) {
                        if ($($items[i]).attr("value") > v)
                            $($items[i]).attr('class', "alf_item alf_next");
                        else if ($($items[i]).attr("value") < v)
                            $($items[i]).attr('class', "alf_item alf_previous");
                        else
                            $($items[i]).attr('class', "alf_item alf_current");
                    }
                    // Update label
                    if (enabledLabels) $lbl.html(labels[$hf.val()]);
                });
            }

            // Default value
            var i = $hf.val() - 1;
            if (i >= 0) {
                $(this).find(".alf_item:lt(" + i + ")").attr('class', "alf_item alf_previous");
                $(this).find(".alf_item:gt(" + i + ")").attr('class', "alf_item alf_next");
                $(this).find(".alf_item:eq(" + i + ")").attr('class', "alf_item alf_current");
            } else {
                $(this).find(".alf_item").attr('class', "alf_item alf_next");
            }
            // Update label
            if (enabledLabels && !readonly) $lbl.html(labels[$hf.val()]);
        });
    };
})(jQuery);

// Ajax image loading
(function($) {
    $.fn.ajaxImg = function(url) {
        return this.each(function() {
            if (!url) {
                throw 'url argument missing';
            }
            var $that = $(this);
            var img = new Image();
            $(img).load(function() {
                var f = function() {
                    $that.fadeOut(function() {
                        $that.removeClass("alf_ajaxImg").attr("src", url).fadeIn();
                    })
                }
                setTimeout(f, 1000);
            }).error(function() {
                // notify the user that the image could not be loaded
            }).attr("src", url);
        });
    };
})(jQuery);

// Box HyperLink
(function($) {
    $.fn.boxHyperLink = function() {
        return this.each(function() {
            var target = $(this).attr("target");
            var href = $(this).attr("href");
            var click = $(this).get(0).onclick;
            var $parent = $(this).parents(".alf_box:first");
            $parent.click(
                function() {
                    if (click != null && click() === false)
                        return false;
                    if (target == "_blank") {
                        // Conflit with link action
                        // call event.stopPropagation() after call onclick event ?
                        //window.open(href);
                    } else {
                        ALF.goToURL(href);
                    }
                }
            );
            $(this).get(0).onclick = null;
        });
    };
})(jQuery);

// Box LinkButton
(function($) {
    $.fn.boxLinkButton = function() {
        return this.each(function() {
            var postback = $(this).attr("href")._trim("javascript:");
            var click = $(this).get(0).onclick;
            var $parent = $(this).parents(".alf_box:first");
            $parent.click(
                function() {
                    if (click != null && click() === false)
                        return false;
                    eval(postback);
                }
            );
            $(this).removeAttr("href");
            $(this).get(0).onclick = null;
        });
    };
})(jQuery);
/*
Masked Input plugin for jQuery
Copyright (c) 2007-2009 Josh Bush (digitalbush.com)
Licensed under the MIT license (http://digitalbush.com/projects/masked-input-plugin/#license) 
Version: 1.2.2 (03/09/2009 22:39:06)
*/
(function(a) { var c = (a.browser.msie ? "paste" : "input") + ".mask"; var b = (window.orientation != undefined); a.mask = { definitions: { "9": "[0-9]", a: "[A-Za-z]", "*": "[A-Za-z0-9]"} }; a.fn.extend({ caret: function(e, f) { if (this.length == 0) { return } if (typeof e == "number") { f = (typeof f == "number") ? f : e; return this.each(function() { if (this.setSelectionRange) { this.focus(); this.setSelectionRange(e, f) } else { if (this.createTextRange) { var g = this.createTextRange(); g.collapse(true); g.moveEnd("character", f); g.moveStart("character", e); g.select() } } }) } else { if (this[0].setSelectionRange) { e = this[0].selectionStart; f = this[0].selectionEnd } else { if (document.selection && document.selection.createRange) { var d = document.selection.createRange(); e = 0 - d.duplicate().moveStart("character", -100000); f = e + d.text.length } } return { begin: e, end: f} } }, unmask: function() { return this.trigger("unmask") }, mask: function(j, d) { if (!j && this.length > 0) { var f = a(this[0]); var g = f.data("tests"); return a.map(f.data("buffer"), function(l, m) { return g[m] ? l : null }).join("") } d = a.extend({ placeholder: "_", completed: null }, d); var k = a.mask.definitions; var g = []; var e = j.length; var i = null; var h = j.length; a.each(j.split(""), function(m, l) { if (l == "?") { h--; e = m } else { if (k[l]) { g.push(new RegExp(k[l])); if (i == null) { i = g.length - 1 } } else { g.push(null) } } }); return this.each(function() { var r = a(this); var m = a.map(j.split(""), function(x, y) { if (x != "?") { return k[x] ? d.placeholder : x } }); var n = false; var q = r.val(); r.data("buffer", m).data("tests", g); function v(x) { while (++x <= h && !g[x]) { } return x } function t(x) { while (!g[x] && --x >= 0) { } for (var y = x; y < h; y++) { if (g[y]) { m[y] = d.placeholder; var z = v(y); if (z < h && g[y].test(m[z])) { m[y] = m[z] } else { break } } } s(); r.caret(Math.max(i, x)) } function u(y) { for (var A = y, z = d.placeholder; A < h; A++) { if (g[A]) { var B = v(A); var x = m[A]; m[A] = z; if (B < h && g[B].test(x)) { z = x } else { break } } } } function l(y) { var x = a(this).caret(); var z = y.keyCode; n = (z < 16 || (z > 16 && z < 32) || (z > 32 && z < 41)); if ((x.begin - x.end) != 0 && (!n || z == 8 || z == 46)) { w(x.begin, x.end) } if (z == 8 || z == 46 || (b && z == 127)) { t(x.begin + (z == 46 ? 0 : -1)); return false } else { if (z == 27) { r.val(q); r.caret(0, p()); return false } } } function o(B) { if (n) { n = false; return (B.keyCode == 8) ? false : null } B = B || window.event; var C = B.charCode || B.keyCode || B.which; var z = a(this).caret(); if (B.ctrlKey || B.altKey || B.metaKey) { return true } else { if ((C >= 32 && C <= 125) || C > 186) { var x = v(z.begin - 1); if (x < h) { var A = String.fromCharCode(C); if (g[x].test(A)) { u(x); m[x] = A; s(); var y = v(x); a(this).caret(y); if (d.completed && y == h) { d.completed.call(r) } } } } } return false } function w(x, y) { for (var z = x; z < y && z < h; z++) { if (g[z]) { m[z] = d.placeholder } } } function s() { return r.val(m.join("")).val() } function p(y) { var z = r.val(); var C = -1; for (var B = 0, x = 0; B < h; B++) { if (g[B]) { m[B] = d.placeholder; while (x++ < z.length) { var A = z.charAt(x - 1); if (g[B].test(A)) { m[B] = A; C = B; break } } if (x > z.length) { break } } else { if (m[B] == z[x] && B != e) { x++; C = B } } } if (!y && C + 1 < e) { r.val(""); w(0, h) } else { if (y || C + 1 >= e) { s(); if (!y) { r.val(r.val().substring(0, C + 1)) } } } return (e ? B : i) } if (!r.attr("readonly")) { r.one("unmask", function() { r.unbind(".mask").removeData("buffer").removeData("tests") }).bind("focus.mask", function() { q = r.val(); var x = p(); s(); setTimeout(function() { if (x == j.length) { r.caret(0, x) } else { r.caret(x) } }, 0) }).bind("blur.mask", function() { p(); if (r.val() != q) { r.change() } }).bind("keydown.mask", l).bind("keypress.mask", o).bind(c, function() { setTimeout(function() { r.caret(p(true)) }, 0) }) } p() }) } }) })(jQuery);

/*
* jQuery outside events - v1.1 - 3/16/2010
* http://benalman.com/projects/jquery-outside-events-plugin/
* 
* Copyright (c) 2010 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
(function($, c, b) { $.map("click dblclick mousemove mousedown mouseup mouseover mouseout change select submit keydown keypress keyup".split(" "), function(d) { a(d) }); a("focusin", "focus" + b); a("focusout", "blur" + b); $.addOutsideEvent = a; function a(g, e) { e = e || g + b; var d = $(), h = g + "." + e + "-special-event"; $.event.special[e] = { setup: function() { d = d.add(this); if (d.length === 1) { $(c).bind(h, f) } }, teardown: function() { d = d.not(this); if (d.length === 0) { $(c).unbind(h) } }, add: function(i) { var j = i.handler; i.handler = function(l, k) { l.target = k; j.apply(this, arguments) } } }; function f(i) { $(d).each(function() { var j = $(this); if (this !== i.target && !j.has(i.target).length) { j.triggerHandler(e, [i.target]) } }) } } })(jQuery, document, "outside");
