accounting.settings = {
    currency: {
        symbol: "R$",   // default currency symbol is '$'
        format: "%s%v", // controls output: %s = symbol, %v = value/number (can be object: see below)
        decimal: ",",  // decimal point separator
        thousand: ".",  // thousands separator
        precision: 2   // decimal places
    },
    number: {
        precision: 2,  // default precision on numbers is 0
        thousand: ".",
        decimal: ","
    }
};

(function ($) {
    var defaultOptions = {
        errorClass: 'erro',
    };

    $.validator.setDefaults(defaultOptions);

    $.validator.unobtrusive.options = {
        errorClass: defaultOptions.errorClass,
        invalidHandler: function (event, validator) {
            var errors = validator.numberOfInvalids();

            if (errors) {

                var summary = '';

                $.each(validator.errorList, function () { summary += ' * ' + this.message + '<br>'; });

                global.showErrorMessage(summary);
            }

        }
    };
})(jQuery);

$.fn.getXPath = function (rootNodeName) {
    //other nodes may have the same XPath but because this function is used to determine the corresponding input name of a data node, index is not included 
    var position,
        $node = this.first(),
        nodeName = $node.prop('nodeName'),
        $sibSameNameAndSelf = $node.siblings(nodeName).addBack(),
        steps = [],
        $parent = $node.parent(),
        parentName = $parent.prop('nodeName');

    position = ($sibSameNameAndSelf.length > 1) ? '[' + ($sibSameNameAndSelf.index($node) + 1) + ']' : '';
    steps.push(nodeName + position);

    while ($parent.length == 1 && parentName !== rootNodeName && parentName !== '#document') {
        $sibSameNameAndSelf = $parent.siblings(parentName).addBack();
        position = ($sibSameNameAndSelf.length > 1) ? '[' + ($sibSameNameAndSelf.index($parent) + 1) + ']' : '';
        steps.push(parentName + position);
        $parent = $parent.parent();
        parentName = $parent.prop('nodeName');
    }
    return '/' + steps.reverse().join('/');
};


var global = {

    
    getBrowserData: function() {

        var data = {};

        if (navigator.userAgent.match(/Trident\/7/)) {
            data.browser = 'MSIE';
            data.version = '11';
        }

        if (navigator.userAgent.match(/Trident\/6/)) {
            data.browser = 'MSIE';
            data.version = '10';
        }

        if (navigator.userAgent.match(/Trident\/5/)) {
            data.browser = 'MSIE';
            data.version = '9';
        }

        if (navigator.userAgent.match(/Trident\/4/)) {
            data.browser = 'MSIE';
            data.version = '8';
        }

        if (navigator.userAgent.match(/Chrome/)) {
            data.browser = 'Chrome';
        }

        if (navigator.userAgent.match(/Firefox/)) {
            data.browser = 'Firefox';
        }

        return data;
    },

    showLoading: function (el) {
        $.blockUI.defaults.baseZ = 10000;
        if (el) {
            $(el).block({ message: '<span id="block-message">Aguarde</span>' });

        } else {
            $.blockUI({ message: '<span id="block-message">Aguarde</span>', fadeIn: 0 });
        }

        this.startBlockMessageAnimation();
    },

    hideLoading: function (el) {
        if (el) {
            $(el).unblock();
        } else {
            $.unblockUI();
        }

        this.stopBlockMessageAnimation();
    },

    startBlockMessageAnimation: function () {
        this.stopBlockMessageAnimation();
        this.dots = 0;
        this.blockMessageAnimation = setInterval(this.animateBlockMessageAnimation, 400);
    },

    animateBlockMessageAnimation: function () {
        if (!global.dots)
            global.dots = 0;

        $("#block-message").html('Aguarde' + Array((++global.dots % 4) + 1).join("."));
        if (global.dots === 3) {
            global.dots = 0;
        }
    },

    stopBlockMessageAnimation: function () {
        if (this.blockMessageAnimation) {
            clearInterval(this.blockMessageAnimation);
        }
    },

    getElementFontSize: function (context) {
        return parseFloat(getComputedStyle(context || document.documentElement).fontSize);
    },

    convertRem: function (value) {
        return this.convertEm(value);
    },

    convertEm: function (value, context) {
        return value * this.getElementFontSize(context);
    },

    formatJsonDate: function (date, format) {
        moment.locale('pt-br');

        if (!format) {
            format = 'DD/MM/YYYY';
        }

        var formatDate = moment(date.replace('\\', ''));
        return formatDate.format(format);
    },

    toDate: function (date, format) {
        moment.locale('pt-br');
        var formatDate = format ? moment(date.replace('\\', ''), format) : moment(date.replace('\\', ''));
        return moment(formatDate).toDate();

    },

    formatExtensionDate: function (date) {
        moment.locale('pt-br');
        var formatDate = moment(date.replace('\\', ''));
        return formatDate.format('DD MMM YYYY');
    },

    formatDate: function (date, format, fromFormat) {

        if (!date) {
            return null;
        }

        moment.locale('pt-br');
        if (!format) {
            format = 'DD/MM/YYYY';
        }

        if (this.isAspNetJsonDate(date)) {
            return this.formatJsonDate(date, format);
        }

        if (date instanceof Date) {
            var formatDate = moment(date);
            return formatDate.format(format);
        } else {

            var formatDate = fromFormat ? moment(date, fromFormat) : moment(date);
            return formatDate.isValid() ? formatDate.format(format) : null;
        }
    },

    formatHourMinute: function (date) {
        moment.locale('pt-br');
        var formatDate = moment(date.replace('\\', ''));
        return formatDate.format('HH:mm');
    },

    addValidators: function () {

        this.addTimeValidator();
        this.addDateGreaterThanValidator();
        this.addDateValidator();
        this.addDateGreaterOrEqualThanActualDateValidator();
        this.addMinValueValidator();

    },

    addDateValidator: function () {
        $.validator.addMethod('validateDate', function (value, element) {

            if (!value) {
                return true;
            }

            return global.validateDate(value);
        });
    },

    addDateGreaterOrEqualThanActualDateValidator: function () {
        $.validator.addMethod('dateGreaterOrEqualThanActualDate', function (value, element) {

            if (!value) {
                return true;
            }

            return global.dateGreaterOrEqualThanActualDate(value);
        });
    },
    
    validateNumberMaxValue: function(type, value) {
        
        if (!type || !value) {
            return true;
        }
        
        var valid = false;

        $.ajax({
            url: "/Comum/ValidateNumberMaxValue",
            async: false,
            cache: false,
            method: "POST",
            data: {
                type: type,
                value: value
            },

            success: function (data) {
                valid = data == "1";
            }
        });

        return valid;

    },
    
    addNumberMaxValueValidator: function () {
        $.validator.addMethod("numberMaxValue",
            function (value, element, params) {
                return global.validateNumberMaxValue(params, value);
            });
    },

    validateDate: function(date) {
        if (!date) {
            return false;
        }

        var valid = false;

        $.ajax({
            url: "/Comum/ValidateDate",
            async: false,
            cache: false,
            method: "POST",
            data: {
                date: date
            },

            success: function (data) {
                valid = data == "1";
            }
        });

        return valid;
    },

    dateGreaterOrEqualThanActualDate: function(date) {
        if (!date) {
            return false;
        }

        var valid = false;

        $.ajax({
            url: "/Comum/DateGreaterOrEqualThanActualDate",
            async: false,
            cache: false,
            method: "POST",
            data: {
                date: date
            },

            success: function (data) {
                valid = data == "1";
            }
        });

        return valid;
    },

    addTimeValidator: function () {

        $.validator.addMethod('validateTime', function (value, element) {
            return /^(([0-1]?[0-9])|([2][0-3])):([0-5]?[0-9])(:([0-5]?[0-9]))?$/i.test(value);
        });

    },

    addDateGreaterThanValidator: function () {
        $.validator.addMethod("greaterThan",
            function (value, element, params) {

                if (!/Invalid|NaN/.test(new Date(value))) {
                    return new Date(value) >= new Date($(params).val());
                }

                return isNaN(value) && isNaN($(params).val())
                    || (Number(value) >= Number($(params).val()));
            });
    },

    addMinValueValidator: function () {

        $.validator.addMethod('minValue', function (value, element, params) {
            return parseFloat(value) > params;
        });

    },

    convertFormToJSON: function (options) {

        var form = options.selector ? $(options.selector) : options.element;
        var mapper = options.mapper;

        var disabled = form.find(':input:disabled').removeAttr('disabled');

        var array = form.serializeArray();

        disabled.attr('disabled', 'disabled');

        var json = {};

        $.each(array, function () {
            var value = this.value || '';

            var map = mapper && mapper[this.name] ? mapper[this.name] : this.name;

            if (json[map]) {
                if (!$.isArray(json[map])) {
                    var previousValue = json[map];
                    json[map] = new Array();
                    json[map].push(previousValue);
                }
                json[map].push(value);

            } else {
                json[map] = value;
            }
        });

        return json;
    },

    getRandomColor: function () {
        var letters = '0123456789ABCDEF'.split('');
        var color = '#';
        for (var i = 0; i < 6; i++) {
            color += letters[Math.floor(Math.random() * 16)];
        }
        return color;
    },

    clearFormFields: function (options) {
        this.clearFields(options);
    },

    escapeRegExp: function (string) {
        return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
    },

    replaceAll: function (string, find, replace) {
        return string.replace(new RegExp(this.escapeRegExp(find), 'g'), replace);
    },

    validateEmail: function (email) {
        var filter = /^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/;
        if (filter.test(email)) {
            return true;
        } else {
            return false;
        }
    },

    confirm: function(messages, callback) {
      
        var message = '';

        if (typeof messages != 'string') {
            $.each(messages, function () {
                message += this + '<br>';
            });
        } else {
            message = messages;
        }

        return confirm(message);
    },

    showMessage: function (messages, title, css) {

        var message = '';

        if (typeof messages != 'string') {
            $.each(messages, function () {
                message += this + '<br>';
            });
        } else {
            message = messages;
        }

        toastr.options = {
            "closeButton": true,
            "debug": false,
            "positionClass": "toast-top-center",
            "onclick": null,
            "showDuration": "500",
            "hideDuration": "1000",
            "extendedTimeOut": "1000",
            "showEasing": "swing",
            "hideEasing": "linear",
            "showMethod": "fadeIn",
            "hideMethod": "fadeOut"
        };

        if (css === 'success') {
            title = title === undefined ? "Sucesso!" : title;

            toastr.success(message, title);
        } else if (css === "warn") {
            title = title === undefined ? "Aviso!" : title;

            toastr.warning(message, title);
        } else {
            title = title === undefined ? "Erro!" : title;

            toastr.error(message, title);
        }

    },

    showErrorMessage: function (messages) {
        this.showMessage(messages, null, 'error');
    },

    showWarnMessage: function (messages) {
        this.showMessage(messages, null, 'warn');
    },

    showSuccessMessage: function (messages) {
        this.showMessage(messages, null, 'success');
    },

    showDefaultErrorMessage: function () {
        this.showErrorMessage('Ocorreu um problema com a requisição, por favor tente novamente.');
    },

    sortSelect: function (select) {

        var options = $(select + ' option');

        var arr = options.map(function (_, o) {
            return {
                t: $(o).text(),
                v: o.value
            };
        }).get();
        arr.sort(function (o1, o2) {
            return o1.t > o2.t ? 1 : o1.t < o2.t ? -1 : 0;
        });
        options.each(function (i, o) {
            console.log(i);
            o.value = arr[i].v;
            $(o).text(arr[i].t);
        });

    },

    numeric: function (options) {

        var $el = options.selector ? $(options.selector) : options.element;

        if (!$el || $el.length == 0) {
            return;
        }

        $el.numeric();

        $el.bind('mouseenter', function (e) {
            var val = $(this).val();
            if (val != '0') {
                val = val.replace(/[^0-9]+/g, "");
                $(this).val(val);
            }
        });

        $el.bind("paste", function (e) {
            e.preventDefault();
        });

    },

    isFormValid: function (formSelector) {
        var validator = $.data($(formSelector)[0], 'validator');
        return validator.form();
    },

    bindJSONToForm: function (formSelector, json) {

        var $form = $(formSelector);

        $.each(json, function (key, value) {
            $form.find("[name='" + key + "']").val(value);
        });
    },

    updateJSONData: function (jsonFrom, jsonTo) {
        $.each(jsonFrom, function (key, value) {
            jsonTo[key] = value;
        });
    },

    applyMasks: function () {
        $('[mask-data]').inputmask({
            mask: '99/99/9999'
        });

        $('[calendar]').datetimepicker({
            locale: 'pt-br'
        }).on("dp.change", function (e) {
            $('input', $(e.target)).trigger('change');
        });
        

        $('[mask-telefone]').inputmask('(99) 9999[9]-9999');
        $('[mask-hora]').inputmask('99:99');
        $('[mask-cpf]').inputmask('999.999.999-99');
        $('[mask-cep]').inputmask('99.999-999');
        $('[mask-cnpj]').inputmask('99.999.999/9999-99');

        $('[mask-numero]').inputmask('9999999999');


        $('[mask-decimal]').inputmask({
            alias: "numeric",
            radixPoint: ',',
            groupSeparator: ".",
            autoGroup: true,
            autoUnmask: true,
            digits: 2,
            digitsOptional: true,
            rightAlign: false,
            showMaskOnFocus: true,
            showMaskOnHover: false,
            greedy: false,
            placeholder: ""
        });


        //$('[mask-decimal]').inputmask('decimal', { radixPoint: ",", autoGroup: true, groupSeparator: ".", groupSize: 3 });

        $('[mask]').each(function () {
            var el = $(this);
            el.inputmask(el.attr('mask'));
        });

    },

    intersects: function (r1start, r1end, r2start, r2end) {
        return (r1start == r2start) || (r1start > r2start ? r1start <= r2end : r2start <= r1end);
    },

    fromDateToArray: function (date) {
        moment.locale('pt-br');
        return moment(date).toArray();
    },

    applyDateTimePicker: function (options) {

        var $el = options.selector ? $(options.selector) : options.element;

        var minView = 0;
        var maxView = 4;

        if (options.format === 'dd/mm/yyyy') {
            minView = 2;
        } else if (options.format === 'hh:mm:ss') {
            minView = 0;
            maxView = 1;
        }


        return $el.datetimepicker({
            language: 'pt-BR',
            todayBtn: true,
            todayHighlight: true,
            format: options.format,
            autoclose: true,
            minView: minView,
            maxView: maxView
        });
    },

    configForm: function (options) {


        var $form = $(options.selector);

        var validationOptions = {
            errorClass: 'erro',
            onkeyup: false,
            errorPlacement: function (error, element) {
                return true;
            },
            focusInvalid: typeof options.focusInvalid != 'undefined' ? options.focusInvalid : false,
            invalidHandler: function (event, validator) {

                var errors = validator.numberOfInvalids();

                if (errors) {
                    var messages = new Array();

                    $.each(validator.errorList, function () {
                        messages.push(this.message);
                    });

                    global.showErrorMessage(messages);

                    return false;
                }
            },
            rules: options.rules,
            messages: options.messages
        };

        if (options.ignore) {
            validationOptions.ignore = options.ignore;
        }

        $form.validate(validationOptions);

    },

    ajax: function (args) {

        if (typeof args.blockUI == 'undefined' || args.blockUI) {
            this.blockUI();
        }

        var successCallback = typeof args.success != 'undefined' ? args.success : null;
        var errorCallback = typeof args.error != 'undefined' ? args.error : null;

        var ajaxData = args;

        ajaxData.success = $.proxy(function (options, data) {

            data = global.tratarRetorno(data);

            if (successCallback)
                successCallback(data);

            if (typeof options.blockUI == 'undefined' || options.blockUI) {
                global.unblockUI();
            }
            
        }, this, args);

        ajaxData.error = $.proxy(function (options, jqXHR, textStatus, errorThrown) {

            var blockUI = typeof options.blockUI == 'undefined' || options.blockUI;

            if (jqXHR.status == '200' && successCallback) {
                successCallback();
                if (blockUI) {
                    global.unblockUI();
                }
                return;
            }
            else if (errorCallback) {
                errorCallback(jqXHR, textStatus, errorThrown);
                if (blockUI) {
                    global.unblockUI();
                }
            } else {
                if (blockUI) {
                    global.unblockUI();
                }
            }
            
            if (typeof ajaxData.showDefaultErrorMessage == 'undefined' || ajaxData.showDefaultErrorMessage) {
                global.showDefaultErrorMessage();
            }
        }, this, args);

        $.ajax(ajaxData);
    },

    autocomplete: function (options) {

        var $el = options.selector ? $(options.selector) : options.element;

        var $select2 = $el.select2({
            placeHolder: options.placeHolder,
            minimumInputLength: options.minChar,
            maximumSelectionSize: options.maxSelection,
            allowClear: true,
            multiple: options.multiple,
            width: options.width,
            initSelection: options.initSelection,
            ajax: {
                cache: true,
                allowClear: true,
                dataType: "json",
                quietMillis: 500,
                type: "POST",
                url: options.url,
                data: options.ajaxData ? options.ajaxData :
                    function (term, id) {
                        var data = {};
                        data['term'] = term;
                        return data;
                    },
                results: function (data) {
                    return { results: data };
                }
            },
        });

        if (options.change) {
            $select2.on('change', options.change);
        }

        if (options.val) {
            $el.select2('val', options.val);
        }

    },

    clearFields: function (options) {
        var $el = options.selector ? $(options.selector) : options.element;

        $(':input', $el)
            .not(':button, :submit, :reset, :hidden')
            .val('')
            .removeAttr('checked')
            .removeAttr('selected');
    },

    isAspNetJsonDate: function (input) {
        return /^\/?Date\((\-?\d+)/i.exec(input) !== null;
    },

    formatNumber: function (number, precision) {
        return accounting.formatNumber(number, precision);
    },

    formatMoney: function (number, precision) {
        return accounting.formatMoney(number, precision);
    },

    validateUrl: function (url) {
        return /^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/|www\.)[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/.test(url);
    },

    blockUI: function (options) {

        var el = options ? options.el : null;

        var blockOptions = {
            css: {
                border: '1px solid darkgray',
                padding: '15px',
                '-webkit-border-radius': '10px',
                '-moz-border-radius': '10px',
                width: '15%',
                zIndex: 99999
            },
            overlayCSS: {
                opacity: 0.1,
            },
            message: options ? $(options.message) : null,
            baseZ: 99999
        };


        if (!el) {
            $.blockUI(blockOptions);
        } else {
            $(el).block(blockOptions);
        }
    },

    unblockUI: function (options) {

        var el = options ? options.el : null;

        if (el) {
            $(el).unblock();
        } else {
            $.unblockUI();
        }

    },

    activateMenu: function (options) {

        if (options.renderViewOptions) {
            this.renderView(options.renderViewOptions);
        }

        $('.open.active,.start.active').removeClass('open').removeClass('active');

        var parents = $(options.el).parents('[data-menu]');

        $(options.el).closest('li').addClass('open active');

        $(parents).each(function () {
            $(this).addClass('open active');
        });



    },

    renderView: function (options) {

        this.blockUI();

        var self = this;

        $.ajax({
            url: options.url,
            type: options.type,
            data: options.data,
            cache: options.cache ? options.cache : false,
            success: function (data) {
                $(options.renderTo).html(data);
                $(document).scrollTop(0);

                self.unblockUI();

            }
        });

    },

    tratarRetorno: function (data) {

        if (!data) {
            return null;
        }

        if (data.UserMessage) {
            this.showWarnMessage(data.UserMessage);
        }

        if (data.Error) {

            switch (data.ErrorType) {
                case 'DomainLayerException':
                case 'AccessDenied':
                    this.showErrorMessage(data.Error);
                    break;
                case 'SessionExpired':
                case 'SessionExpiredException':
                    this.showErrorMessage(data.Error);
                    $(window).attr('permitirSairView', true);
                    setTimeout($.proxy(this.redirectToLoginPage, this), 500);
                    break;
                case 'VendedorSessionExpired':
                    $(window).attr('permitirSairView', true);
                    setTimeout($.proxy(this.redirect, this, data.RedirectUrl), 500);
                    break;
                default:
                    this.showErrorMessage('O sistema está temporariamente indisponível. Aguarde alguns minutos e tente novamente. Se o problema persistir entre em contato com nossa Central de Suporte através do número (31)2126-4422.');
            }

            return null;

        } else {
            return data;
        }
    },

    where: function (list, args) {
        return _.where(list, args);
    },

    redirectToAction: function (actionName, controllerName) {

        var url = this.getUrl(actionName, controllerName);
        this.redirect(url);
    },

    redirect: function (url) {

        if (!url) {
            return;
        }

        window.location.href = url;
    },

    redirectToLoginPage: function () {
        var url = this.getRouteUrl('autenticar');
        if (url) {
            this.redirect(url);
        }
    },

    getUrl: function (actionName, controllerName) {
        var url = null;
        $.ajax({
            url: '/Comum/GetUrl',
            async: false,
            method: "POST",
            data: {
                actionName: actionName,
                controllerName: controllerName
            },
            success: function (d) {
                url = d;
            }
        });

        return url;
    },

    getRouteUrl: function (routeName) {
        var url = null;
        $.ajax({
            url: '/Comum/GetRouteUrl',
            async: false,
            method: "POST",
            data: {
                routeName: routeName
            },
            success: function (d) {
                url = d;
            }
        });

        return url;
    },

    applyConditionalMask: function (args) {

        if (!args) {
            return;
        }

        var $el = $(args.triggerElement);

        if ((typeof args.initialMask != 'undefined' && args.initialMask) && (typeof args.masks != 'undefined' && args.masks && args.masks.length > 0)) {

            $.each(args.masks, function () {

                if (this.name == args.initialMask) {
                    $el.inputmask(this.mask, args.options);
                    $el.attr('mask-applied', this.name);
                    return false;
                }
            });
        }

        $el.on(args.triggerEvent, function (e) {

            if (typeof args.masks != 'undefined' && args.masks && args.masks.length > 0) {
                $.each(args.masks, function () {
                    if (this.name != $el.attr('mask-applied') && typeof this.condition != 'undefined' && this.condition && this.condition(e)) {
                        $el.inputmask(this.mask, args.options);
                        $el.attr('mask-applied', this.name);
                        return false;
                    }
                });
            }

        });


    },

    logError: function(message, url, line, col, error) {


        var data = {
            error: message,
            url: url,
            line: line,
            col: col,
            stack: error && typeof error.stack != 'undefined' && error.stack ? error.stack : error
        };

        $.ajax({
            url: '/Comum/LogJavaScriptError',
            type: "POST",
            contentType: 'application/json',
            data: JSON.stringify({
                errorData: data
            })
        }
        );

    },

    resolveDates: function (data) {

        if (!data) {
            return;
        }

        for (var key in data) {
            var value = data[key];

            if (Array.isArray(value)) {
                for (var item in value) {
                    global.resolveDates(value[item]);
                }

            }

            if (typeof value == 'string' && value.indexOf('Date(') > -1) {
                data[key] = moment(value).toDate();
            }
        }
    },

    isInArray: function(item, array, property) {
        
        if (!item || !array || array.length == 0) {
            return false;
        }

        var exists = false;

        $.each(array, function () {

            var value = this;

            if (property) {
                value = this[property];
            }

            if (item == value) {
                exists = true;
                return false;
            }
        });

        return exists;
    },

    rgb2hex: function(rgb) {
        rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
        return (rgb && rgb.length === 4) ? "#" +
        ("0" + parseInt(rgb[1], 10).toString(16)).slice(-2) +
        ("0" + parseInt(rgb[2], 10).toString(16)).slice(-2) +
        ("0" + parseInt(rgb[3], 10).toString(16)).slice(-2) : '';
    },

    sum: function(list, property) {
        
        if (!list || list.length == 0) {
            return 0;
        }

        var value = 0;

        $.each(list, function () {

            var item = this;

            if (item.toJSON) {
                item = item.toJSON();
            }

            value += item[property];
        });

        return value;
    }

};


window.onerror = global.logError;

$(document).ready(function () {
    //throw 'teste de exceção de javascript';
    global.applyMasks();
    global.addValidators();
});

(function (jQuery) {
    jQuery.fn.hasAttr = function (name) {
        for (var i = 0, l = this.length; i < l; i++) {
            if (!!(this.attr(name) !== undefined)) {
                return true;
            }
        }
        return false;
    };
})(jQuery);