{"version":3,"sources":["webpack://aspnetValidation/webpack/universalModuleDefinition","webpack://aspnetValidation/webpack/bootstrap","webpack://aspnetValidation/./src/index.ts"],"names":["root","factory","exports","module","define","amd","window","installedModules","__webpack_require__","moduleId","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","getRelativeFormElement","elementName","selector","realSelector","substr","dotLocation","lastIndexOf","relativeElementName","relativeElement","document","getElementsByName","MvcValidationProviders","this","required","element","params","Boolean","stringLength","min","parseInt","length","max","compare","other","otherElement","range","val","parseFloat","isNaN","regex","pattern","RegExp","test","email","creditcard","cDigit","nCheck","nDigit","bEven","replace","charAt","url","phone","remote","fieldSelectors","additionalfields","split","fields","_i","fieldSelectors_1","fieldSelector","fieldName","fieldElement","encodedParams","encodedParam","encodeURIComponent","push","payload","join","Promise","ok","reject","request","XMLHttpRequest","type","postData","FormData","append","open","setRequestHeader","send","onload","e","status","data","JSON","parse","responseText","statusText","onerror","ValidationService","providers","messageFor","elementUIDs","elementByUID","formInputs","validators","elementEvents","summary","debounce","addProvider","callback","addMvcProviders","mvc","scanMessages","validationMessageElements","querySelectorAll","name_1","getAttribute","parseDirectives","attributes","directives","validationAtributes","cut","a","indexOf","parameters","keys","filter","Q","directive","error","pcut","pvalue","pkey","guid4","Math","random","toString","getElementUID","node","x","uid","getFormValidationTask","formUID","formInputUIDs","formValidators","inputUID","tasks","map","all","then","result","every","trackFormInput","form","_this","cb","validate","preventDefault","success","submit","catch","console","log","addEventListener","uids_1","input","classList","remove","spans","innerHTML","renderSummary","addInput","createValidator","delay","clearTimeout","setTimeout","tagName","toLowerCase","scanInputs","inputs","createSummaryDOM","ul","createElement","li","appendChild","summaryElements","shadow","stringify","sort","renderedSummaryJSON","className","cloneNode","addError","message","add","removeError","__awaiter","provider","valid","resolution","_c","sent","bootstrap","event"],"mappings":"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","file":"aspnet-validation.min.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"aspnetValidation\"] = factory();\n\telse\n\t\troot[\"aspnetValidation\"] = factory();\n})(window, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","/**\r\n * A simple IDictionary<string, string>\r\n */\r\nexport interface StringKeyValuePair {\r\n    [key: string]: string\r\n}\r\n\r\n/**\r\n * A duplex key-value pair for an element, by GUID or its DOM object reference.\r\n */\r\ninterface ElementUID {\r\n    node: Element,\r\n    uid: string;\r\n}\r\n\r\n/**\r\n * Parameters passed into validation providers from the element attributes.\r\n * error property is read from data-val-[Provider Name] attribute.\r\n * params property is populated from data-val-[Provider Name]-[Parameter Name] attributes.\r\n */\r\nexport interface ValidationDirectiveBindings {\r\n    error: string,\r\n    params: StringKeyValuePair\r\n}\r\n\r\n/**\r\n * A key-value pair describing what validations to enforce to an input element, with respective parameters.\r\n */\r\nexport type ValidationDirective = {\r\n    [key: string]: ValidationDirectiveBindings\r\n};\r\n\r\n/**\r\n * Validation plugin signature with multitype return.\r\n * Boolean return signifies the validation result, which uses the default validation error message read from the element attribute.\r\n * String return signifies failed validation, which then will be used as the validation error message.\r\n * Promise return signifies asynchronous plugin behavior, with same behavior as Boolean or String.\r\n */\r\nexport type ValidationProvider = (value: string, element: HTMLInputElement, params: StringKeyValuePair) => boolean | string | Promise<boolean | string>;\r\n\r\n/**\r\n * A callback method signature that kickstarts a new validation task for an input element, as a Boolean Promise.\r\n */\r\ntype Validator = () => Promise<boolean>;\r\n\r\n/**\r\n * Resolves and returns the element referred by original element using ASP.NET selector logic.\r\n * @param elementName \r\n */\r\nfunction getRelativeFormElement(elementName: string, selector: string) {\r\n    // example elementName: Form.PasswordConfirm, Form.Email\r\n    // example selector (dafuq): *.Password, *.__RequestVerificationToken\r\n    // example result element name: Form.Password, __RequestVerificationToken\r\n\r\n    let realSelector = selector.substr(2); // Password, __RequestVerificationToken\r\n    let objectName = '';\r\n\r\n    let dotLocation = elementName.lastIndexOf('.');\r\n    if (dotLocation > -1) {\r\n        // Form\r\n        objectName = elementName.substr(0, dotLocation);\r\n\r\n        // Form.Password\r\n        let relativeElementName = objectName + '.' + realSelector;\r\n        let relativeElement = document.getElementsByName(relativeElementName)[0];\r\n        if (relativeElement) {\r\n            return relativeElement;\r\n        }\r\n    }\r\n\r\n    // __RequestVerificationToken\r\n    return document.getElementsByName(realSelector)[0];\r\n}\r\n\r\n/**\r\n * Contains default implementations for ASP.NET Core MVC validation attributes.\r\n */\r\nexport class MvcValidationProviders {\r\n    /**\r\n     * Validates whether the input has a value.\r\n     */\r\n    required: ValidationProvider = (value, element, params) => {\r\n        return Boolean(value);\r\n    }\r\n\r\n    /**\r\n     * Validates whether the input value satisfies the length contstraint.\r\n     */\r\n    stringLength: ValidationProvider = (value, element, params) => {\r\n        if (!value) {\r\n            return true;\r\n        }\r\n\r\n        if (params.min) {\r\n            let min = parseInt(params.min);\r\n            if (value.length < min) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        if (params.max) {\r\n            let max = parseInt(params.max);\r\n            if (value.length > max) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Validates whether the input value is equal to another input value.\r\n     */\r\n    compare: ValidationProvider = (value, element, params) => {\r\n        if (!params.other) {\r\n            return true;\r\n        }\r\n\r\n        let otherElement = getRelativeFormElement(element.name, params.other) as HTMLInputElement;\r\n        if (!otherElement) {\r\n            return true;\r\n        }\r\n\r\n        return (otherElement.value === value);\r\n    }\r\n\r\n    /**\r\n     * Validates whether the input value is a number within a given range.\r\n     */\r\n    range: ValidationProvider = (value, element, params) => {\r\n        if (!value) {\r\n            return true;\r\n        }\r\n\r\n        let val = parseFloat(value);\r\n        if (isNaN(val)) {\r\n            return false;\r\n        }\r\n\r\n        if (params.min) {\r\n            let min = parseFloat(params.min);\r\n            if (val < min) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        if (params.max) {\r\n            let max = parseFloat(params.max);\r\n            if (val > max) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * Validates whether the input value satisfies a regular expression pattern.\r\n     */\r\n    regex: ValidationProvider = (value, element, params) => {\r\n        if (!value || !params.pattern) {\r\n            return true;\r\n        }\r\n\r\n        let r = new RegExp(params.pattern);\r\n        return r.test(value);\r\n    }\r\n\r\n    /**\r\n     * Validates whether the input value is an email in accordance to RFC822 specification, with a top level domain.\r\n     */\r\n    email: ValidationProvider = (value, element, params) => {\r\n        if (!value) {\r\n            return true;\r\n        }\r\n\r\n        // RFC822 email address with .TLD validation\r\n        // (c) Richard Willis, Chris Ferdinandi, MIT Licensed\r\n        // https://gist.github.com/badsyntax/719800\r\n        // https://gist.github.com/cferdinandi/d04aad4ce064b8da3edf21e26f8944c4\r\n\r\n        let r = /^([^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+|\\x22([^\\x0d\\x22\\x5c\\x80-\\xff]|\\x5c[\\x00-\\x7f])*\\x22)(\\x2e([^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+|\\x22([^\\x0d\\x22\\x5c\\x80-\\xff]|\\x5c[\\x00-\\x7f])*\\x22))*\\x40([^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+|\\x5b([^\\x0d\\x5b-\\x5d\\x80-\\xff]|\\x5c[\\x00-\\x7f])*\\x5d)(\\x2e([^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+|\\x5b([^\\x0d\\x5b-\\x5d\\x80-\\xff]|\\x5c[\\x00-\\x7f])*\\x5d))*(\\.\\w{2,})+$/;\r\n        return r.test(value);\r\n    }\r\n\r\n    /**\r\n     * Validates whether the input value is a credit card number, with Luhn's Algorithm.\r\n     */\r\n    creditcard: ValidationProvider = (value, element, params) => {\r\n        if (!value) {\r\n            return true;\r\n        }\r\n\r\n        // (c) jquery-validation, MIT Licensed\r\n        // https://github.com/jquery-validation/jquery-validation/blob/master/src/additional/creditcard.js\r\n        // based on https://en.wikipedia.org/wiki/Luhn_algorithm\r\n\r\n        // Accept only spaces, digits and dashes\r\n        if (/[^0-9 \\-]+/.test(value)) {\r\n            return false;\r\n        }\r\n\r\n        var nCheck = 0,\r\n            nDigit = 0,\r\n            bEven = false,\r\n            n, cDigit;\r\n\r\n        value = value.replace(/\\D/g, \"\");\r\n\r\n        // Basing min and max length on https://developer.ean.com/general_info/Valid_Credit_Card_Types\r\n        if (value.length < 13 || value.length > 19) {\r\n            return false;\r\n        }\r\n\r\n        for (n = value.length - 1; n >= 0; n--) {\r\n            cDigit = value.charAt(n);\r\n            nDigit = parseInt(cDigit, 10);\r\n            if (bEven) {\r\n                if ((nDigit *= 2) > 9) {\r\n                    nDigit -= 9;\r\n                }\r\n            }\r\n\r\n            nCheck += nDigit;\r\n            bEven = !bEven;\r\n        }\r\n\r\n        return (nCheck % 10) === 0;\r\n    }\r\n\r\n    /**\r\n     * Validates whether the input value is a URL.\r\n     */\r\n    url: ValidationProvider = (value, element, params) => {\r\n        if (!value) {\r\n            return true;\r\n        }\r\n\r\n        // (c) Diego Perini, MIT Licensed\r\n        // https://gist.github.com/dperini/729294\r\n\r\n        var r = new RegExp(\r\n            \"^\" +\r\n            // protocol identifier\r\n            \"(?:(?:https?|ftp)://)\" +\r\n            // user:pass authentication\r\n            \"(?:\\\\S+(?::\\\\S*)?@)?\" +\r\n            \"(?:\" +\r\n            // IP address exclusion\r\n            // private & local networks\r\n            \"(?!(?:10|127)(?:\\\\.\\\\d{1,3}){3})\" +\r\n            \"(?!(?:169\\\\.254|192\\\\.168)(?:\\\\.\\\\d{1,3}){2})\" +\r\n            \"(?!172\\\\.(?:1[6-9]|2\\\\d|3[0-1])(?:\\\\.\\\\d{1,3}){2})\" +\r\n            // IP address dotted notation octets\r\n            // excludes loopback network 0.0.0.0\r\n            // excludes reserved space >= 224.0.0.0\r\n            // excludes network & broacast addresses\r\n            // (first & last IP address of each class)\r\n            \"(?:[1-9]\\\\d?|1\\\\d\\\\d|2[01]\\\\d|22[0-3])\" +\r\n            \"(?:\\\\.(?:1?\\\\d{1,2}|2[0-4]\\\\d|25[0-5])){2}\" +\r\n            \"(?:\\\\.(?:[1-9]\\\\d?|1\\\\d\\\\d|2[0-4]\\\\d|25[0-4]))\" +\r\n            \"|\" +\r\n            // host name\r\n            \"(?:(?:[a-z\\\\u00a1-\\\\uffff0-9]-*)*[a-z\\\\u00a1-\\\\uffff0-9]+)\" +\r\n            // domain name\r\n            \"(?:\\\\.(?:[a-z\\\\u00a1-\\\\uffff0-9]-*)*[a-z\\\\u00a1-\\\\uffff0-9]+)*\" +\r\n            // TLD identifier\r\n            \"(?:\\\\.(?:[a-z\\\\u00a1-\\\\uffff]{2,}))\" +\r\n            // TLD may end with dot\r\n            \"\\\\.?\" +\r\n            \")\" +\r\n            // port number\r\n            \"(?::\\\\d{2,5})?\" +\r\n            // resource path\r\n            \"(?:[/?#]\\\\S*)?\" +\r\n            \"$\", \"i\"\r\n        );\r\n\r\n        return r.test(value);\r\n    }\r\n\r\n    /**\r\n     * Validates whether the input value is a phone number.\r\n     */\r\n    phone: ValidationProvider = (value, element, params) => {\r\n        if (!value) {\r\n            return true;\r\n        }\r\n\r\n        // Allows whitespace or dash as number separator because some people like to do that...\r\n        let consecutiveSeparator = /[\\+\\-\\s][\\-\\s]/g;\r\n        if (consecutiveSeparator.test(value)) {\r\n            return false;\r\n        }\r\n\r\n        let r = /^\\+?[0-9\\-\\s]+$/;\r\n        return r.test(value);\r\n    }\r\n\r\n    /**\r\n     * Asynchronously validates the input value to a JSON GET API endpoint. \r\n     */\r\n    remote: ValidationProvider = (value, element, params) => {\r\n        if (!value) {\r\n            return true;\r\n        }\r\n\r\n        // params.additionalfields: *.Email,*.Username\r\n        let fieldSelectors: string[] = (params.additionalfields as string).split(',');\r\n        let fields: StringKeyValuePair = {};\r\n\r\n        for (let fieldSelector of fieldSelectors) {\r\n            let fieldName = fieldSelector.substr(2);\r\n            let fieldElement = getRelativeFormElement(element.name, fieldSelector) as HTMLInputElement;\r\n\r\n            let hasValue = Boolean(fieldElement && fieldElement.value);\r\n            if (!hasValue) {\r\n                continue;\r\n            }\r\n\r\n            fields[fieldName] = fieldElement.value;\r\n        }\r\n\r\n        let url: string = params['url'];\r\n        // console.log(fields);\r\n\r\n        let encodedParams: string[] = [];\r\n        for (let fieldName in fields) {\r\n            let encodedParam = encodeURIComponent(fieldName) + '=' + encodeURIComponent(fields[fieldName]);\r\n            encodedParams.push(encodedParam);\r\n        }\r\n        let payload = encodedParams.join('&');\r\n        // console.log(payload);\r\n\r\n        return new Promise((ok, reject) => {\r\n            let request = new XMLHttpRequest();\r\n\r\n            if (params.type === 'Post') {\r\n                let postData = new FormData();\r\n                for (let fieldName in fields) {\r\n                    postData.append(fieldName, fields[fieldName]);\r\n                }\r\n                request.open('post', url);\r\n                request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');\r\n                request.send(payload);\r\n            } else {\r\n                request.open('get', url + '?' + payload);\r\n                request.send();\r\n            }\r\n\r\n            request.onload = e => {\r\n                if (request.status >= 200 && request.status < 300) {\r\n                    let data = JSON.parse(request.responseText);\r\n                    ok(data);\r\n                } else {\r\n                    reject({\r\n                        status: request.status,\r\n                        statusText: request.statusText,\r\n                        data: request.responseText\r\n                    });\r\n                }\r\n            };\r\n\r\n            request.onerror = e => {\r\n                reject({\r\n                    status: request.status,\r\n                    statusText: request.statusText,\r\n                    data: request.responseText\r\n                });\r\n            };\r\n        });\r\n    }\r\n}\r\n\r\n/**\r\n * Responsibles for managing the DOM elements and running the validation providers.\r\n */\r\nexport class ValidationService {\r\n    /**\r\n     * A key-value collection of loaded validation plugins. \r\n     */\r\n    private providers: { [name: string]: ValidationProvider } = {};\r\n\r\n    /**\r\n     * A key-value collection of <span> elements for displaying validation messages for an input (by DOM ID).\r\n     */\r\n    private messageFor: { [id: string]: Element[] } = {};\r\n\r\n    /**\r\n     * A list of managed elements, each having a randomly assigned unique identifier (UID).\r\n     */\r\n    private elementUIDs: ElementUID[] = [];\r\n\r\n    /**\r\n     * A key-value collection of UID to Element for quick lookup. \r\n     */\r\n    private elementByUID: { [uid: string]: Element } = {};\r\n\r\n    /**\r\n     * A key-value collection of input UIDs for a <form> UID.\r\n     */\r\n    private formInputs: { [formUID: string]: string[] } = {};\r\n\r\n    /**\r\n     * A key-value map for input UID to its validator factory.\r\n     */\r\n    private validators: { [inputUID: string]: Validator } = {};\r\n\r\n    /**\r\n     * A key-value map for element UID to its trigger element (submit event for <form>, input event for <textarea> and <input>).\r\n     */\r\n    private elementEvents: { [id: string]: (Event) => any } = {};\r\n\r\n    /**\r\n     * A key-value map of input UID to its validation error message.\r\n     */\r\n    private summary: StringKeyValuePair = {};\r\n\r\n    /**\r\n     * A serialized representation of the validation error message summary rendered to the user.\r\n     */\r\n    private renderedSummaryJSON: string;\r\n\r\n    /**\r\n     * In milliseconds, the rate of fire of the input validation.\r\n     */\r\n    debounce = 300;\r\n\r\n    /**\r\n     * Registers a new validation plugin of the given name, if not registered yet.\r\n     * Registered plugin validates inputs with data-val-[name] attribute, used as error message.\r\n     * @param name \r\n     * @param callback \r\n     */\r\n    addProvider(name: string, callback: ValidationProvider) {\r\n        if (this.providers[name]) {\r\n            // First-Come-First-Serve validation plugin design.\r\n            // Allows developers to override the default MVC Providers by adding custom providers BEFORE bootstrap() is called!\r\n            return;\r\n        }\r\n        this.providers[name] = callback;\r\n    }\r\n\r\n    /**\r\n     * Registers the default providers for enabling ASP.NET Core MVC client-side validation. \r\n     */\r\n    private addMvcProviders() {\r\n        let mvc = new MvcValidationProviders();\r\n\r\n        // [Required]\r\n        this.addProvider('required', mvc.required);\r\n        // [StringLength], [MinLength], [MaxLength]\r\n        this.addProvider('length', mvc.stringLength);\r\n        this.addProvider('maxlength', mvc.stringLength);\r\n        this.addProvider('minlength', mvc.stringLength);\r\n        // [Compare]\r\n        this.addProvider('equalto', mvc.compare);\r\n        // [Range]\r\n        this.addProvider('range', mvc.range);\r\n        // [RegularExpression]\r\n        this.addProvider('regex', mvc.regex);\r\n        // [CreditCard]\r\n        this.addProvider('creditcard', mvc.creditcard);\r\n        // [EmailAddress]\r\n        this.addProvider('email', mvc.email);\r\n        // [Url]\r\n        this.addProvider('url', mvc.url);\r\n        // [Phone]\r\n        this.addProvider('phone', mvc.phone);\r\n        // [Remote]\r\n        this.addProvider('remote', mvc.remote);\r\n    }\r\n\r\n    /**\r\n     * Scans document for all validation message <span> generated by ASP.NET Core MVC, then tracks them.\r\n     */\r\n    private scanMessages() {\r\n        let validationMessageElements = document.querySelectorAll('[data-valmsg-for]');\r\n\r\n        for (let i = 0; i < validationMessageElements.length; i++) {\r\n            let e = validationMessageElements[i];\r\n            let name = e.getAttribute('data-valmsg-for');\r\n\r\n            if (!this.messageFor[name]) {\r\n                this.messageFor[name] = [];\r\n            }\r\n\r\n            this.messageFor[name].push(e);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Given attribute map for an HTML input, returns the validation directives to be executed. \r\n     * @param attributes \r\n     */\r\n    parseDirectives(attributes: NamedNodeMap) {\r\n        let directives: ValidationDirective = {};\r\n        let validationAtributes: StringKeyValuePair = {};\r\n\r\n        let cut = 'data-val-'.length;\r\n        for (let i = 0; i < attributes.length; i++) {\r\n            let a = attributes[i];\r\n            if (a.name.indexOf('data-val-') === 0) {\r\n                let key = a.name.substr(cut);\r\n                validationAtributes[key] = a.value;\r\n            }\r\n        }\r\n\r\n        for (let key in validationAtributes) {\r\n            if (key.indexOf('-') === -1) {\r\n                let parameters = Object.keys(validationAtributes).filter(Q => {\r\n                    return (Q !== key) && (Q.indexOf(key) === 0);\r\n                });\r\n\r\n                let directive: ValidationDirectiveBindings = {\r\n                    error: validationAtributes[key],\r\n                    params: {}\r\n                };\r\n\r\n                let pcut = (key + '-').length;\r\n                for (let i = 0; i < parameters.length; i++) {\r\n                    let pvalue = validationAtributes[parameters[i]];\r\n                    let pkey = parameters[i].substr(pcut);\r\n\r\n                    directive.params[pkey] = pvalue;\r\n                }\r\n\r\n                directives[key] = directive;\r\n            }\r\n        }\r\n\r\n        // console.log(directives);\r\n        return directives;\r\n    }\r\n\r\n    /**\r\n     *  Returns an RFC4122 version 4 compliant GUID.\r\n     */\r\n    private guid4() {\r\n        // (c) broofa, MIT Licensed\r\n        // https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript/2117523#2117523\r\n\r\n        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\r\n            var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);\r\n            return v.toString(16);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Gets a UID for an DOM element.\r\n     * @param node \r\n     */\r\n    private getElementUID(node: Element) {\r\n        let x = this.elementUIDs.filter(e => {\r\n            return e.node === node;\r\n        })[0];\r\n\r\n        if (x) {\r\n            return x.uid;\r\n        }\r\n\r\n        let uid = this.guid4();\r\n        this.elementUIDs.push({\r\n            node: node,\r\n            uid: uid\r\n        });\r\n        this.elementByUID[uid] = node;\r\n        return uid;\r\n    }\r\n\r\n    /**\r\n     * Returns a Promise that returns validation result for each and every inputs within the form.\r\n     * @param formUID \r\n     */\r\n    private getFormValidationTask(formUID: string) {\r\n        let formInputUIDs = this.formInputs[formUID];\r\n        if (!formInputUIDs || formInputUIDs.length === 0) {\r\n            return null;\r\n        }\r\n\r\n        let formValidators: Validator[] = [];\r\n\r\n        for (let i = 0; i < formInputUIDs.length; i++) {\r\n            let inputUID = formInputUIDs[i];\r\n            formValidators.push(this.validators[inputUID]);\r\n        }\r\n\r\n        let tasks = formValidators.map(factory => factory());\r\n        return Promise.all(tasks).then(result => result.every(e => e));\r\n    }\r\n\r\n    /**\r\n     * Tracks a <form> element as parent of an input UID. When the form is submitted, attempts to validate the said input asynchronously.\r\n     * @param form \r\n     * @param inputUID \r\n     */\r\n    private trackFormInput(form: HTMLFormElement, inputUID: string) {\r\n        let formUID = this.getElementUID(form);\r\n        if (!this.formInputs[formUID]) {\r\n            this.formInputs[formUID] = [];\r\n        }\r\n        let add = (this.formInputs[formUID].indexOf(inputUID) === -1);\r\n        if (add) {\r\n            this.formInputs[formUID].push(inputUID);\r\n        }\r\n\r\n        if (this.elementEvents[formUID]) {\r\n            return;\r\n        }\r\n\r\n        let cb = e => {\r\n            let validate = this.getFormValidationTask(formUID);\r\n            if (!validate) {\r\n                return;\r\n            }\r\n\r\n            e.preventDefault();\r\n            validate.then(success => {\r\n                if (success) {\r\n                    form.submit();\r\n                }\r\n            }).catch(error => {\r\n                console.log(error);\r\n            });\r\n        };\r\n\r\n        form.addEventListener('submit', cb);\r\n        form.addEventListener('reset', e => {\r\n            let uids = this.formInputs[formUID];\r\n\r\n            for (let uid of uids) {\r\n                let input = this.elementByUID[uid] as HTMLInputElement;\r\n                input.classList.remove('input-validation-error');\r\n                input.classList.remove('input-validation-valid');\r\n\r\n                let spans = this.messageFor[input.name];\r\n                if (spans) {\r\n                    for (let i = 0; i < spans.length; i++) {\r\n                        spans[i].innerHTML = '';\r\n                    }\r\n                }\r\n\r\n                delete this.summary[uid];\r\n            }\r\n            this.renderSummary();\r\n        });\r\n        this.elementEvents[formUID] = cb;\r\n    }\r\n\r\n    /**\r\n     * Adds an input element to be managed and validated by the service.\r\n     * Triggers a debounced live validation when input value changes.\r\n     * @param input \r\n     */\r\n    addInput(input: HTMLInputElement) {\r\n        let uid = this.getElementUID(input);\r\n\r\n        let directives = this.parseDirectives(input.attributes);\r\n        let validate = this.createValidator(input, directives);\r\n\r\n        this.validators[uid] = validate;\r\n        if (input.form) {\r\n            this.trackFormInput(input.form, uid);\r\n        }\r\n\r\n        if (this.elementEvents[uid]) {\r\n            return;\r\n        }\r\n\r\n        let delay;\r\n        let cb = e => {\r\n            let validate = this.validators[uid];\r\n            clearTimeout(delay);\r\n            delay = setTimeout(validate, this.debounce);\r\n        };\r\n\r\n        let isDropdown = input.tagName.toLowerCase() === 'select';\r\n        if (isDropdown) {\r\n            input.addEventListener('change', cb);\r\n        } else {\r\n            input.addEventListener('input', cb);\r\n        }\r\n\r\n        this.elementEvents[uid] = cb;\r\n    }\r\n\r\n    /**\r\n     * Scans the entire document for input elements to be validated.\r\n     */\r\n    private scanInputs() {\r\n        let inputs = document.querySelectorAll('[data-val=\"true\"]');\r\n\r\n        for (let i = 0; i < inputs.length; i++) {\r\n            let input = inputs[i] as HTMLInputElement;\r\n            this.addInput(input);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Returns a <ul> element as a validation errors summary.\r\n     */\r\n    createSummaryDOM() {\r\n        if (!Object.keys(this.summary).length) {\r\n            return null;\r\n        }\r\n\r\n        let ul = document.createElement('ul');\r\n        for (let key in this.summary) {\r\n            let li = document.createElement('li');\r\n            li.innerHTML = this.summary[key];\r\n            ul.appendChild(li);\r\n        }\r\n        return ul;\r\n    }\r\n\r\n    /**\r\n     * Displays validation summary to ASP.NET Core MVC designated elements, when it actually gets updated.\r\n     */\r\n    private renderSummary() {\r\n        let summaryElements = document.querySelectorAll('[data-valmsg-summary=\"true\"]');\r\n        if (!summaryElements.length) {\r\n            return;\r\n        }\r\n\r\n        // Using JSON.stringify for quick and painless deep compare of simple KVP. You need to sort the keys first, tho...\r\n        let shadow = JSON.stringify(this.summary, Object.keys(this.summary).sort());\r\n        if (shadow === this.renderedSummaryJSON) {\r\n            return;\r\n        }\r\n\r\n        // Prevents wasteful re-rendering of summary list element with identical items!\r\n        // console.log('RENDERING VALIDATION SUMMARY');\r\n        this.renderedSummaryJSON = shadow;\r\n        let ul = this.createSummaryDOM();\r\n\r\n        for (let i = 0; i < summaryElements.length; i++) {\r\n            let e = summaryElements[i];\r\n            e.innerHTML = '';\r\n            if (ul) {\r\n                e.className = 'validation-summary-errors';\r\n                e.appendChild(ul.cloneNode(true));\r\n            } else {\r\n                e.className = 'validation-summary-valid';\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds an error message to an input element, which also updates the validation message elements and validation summary elements.\r\n     * @param input \r\n     * @param message \r\n     */\r\n    addError(input: HTMLInputElement, message: string) {\r\n        let spans = this.messageFor[input.name];\r\n        if (spans) {\r\n            for (let i = 0; i < spans.length; i++) {\r\n                spans[i].innerHTML = message;\r\n                spans[i].className = 'field-validation-error';\r\n            }\r\n        }\r\n\r\n        input.classList.remove('input-validation-valid');\r\n        input.classList.add('input-validation-error');\r\n\r\n        let uid = this.getElementUID(input);\r\n        this.summary[uid] = message;\r\n        this.renderSummary();\r\n    }\r\n\r\n    /**\r\n     * Removes an error message from an input element, which also updates the validation message elements and validation summary elements.\r\n     * @param input \r\n     */\r\n    removeError(input: HTMLInputElement) {\r\n        let spans = this.messageFor[input.name];\r\n        if (spans) {\r\n            for (let i = 0; i < spans.length; i++) {\r\n                spans[i].innerHTML = '';\r\n                spans[i].className = 'field-validation-valid';\r\n            }\r\n        }\r\n\r\n        input.classList.remove('input-validation-error');\r\n        input.classList.add('input-validation-valid');\r\n\r\n        let uid = this.getElementUID(input);\r\n        delete this.summary[uid];\r\n        this.renderSummary();\r\n    }\r\n\r\n    /**\r\n     * Returns a validation Promise factory for an input element, using given validation directives.  \r\n     * @param input \r\n     * @param directives \r\n     */\r\n    createValidator(input: HTMLInputElement, directives: ValidationDirective) {\r\n        return async () => {\r\n            for (let key in directives) {\r\n                let directive = directives[key];\r\n                let provider = this.providers[key];\r\n\r\n                if (!provider) {\r\n                    console.log('aspnet-validation provider not implemented: ' + key);\r\n                    continue;\r\n                }\r\n\r\n                let result = provider(input.value, input, directive.params);\r\n                let valid = false;\r\n                let error = directive.error;\r\n\r\n                if (typeof result === 'boolean') {\r\n                    valid = result;\r\n                } else if (typeof result === 'string') {\r\n                    valid = false;\r\n                    error = result;\r\n                } else {\r\n                    let resolution = await result;\r\n                    if (typeof resolution === 'boolean') {\r\n                        valid = resolution;\r\n                    } else {\r\n                        valid = false;\r\n                        error = resolution;\r\n                    }\r\n                }\r\n\r\n                if (!valid) {\r\n                    this.addError(input, error);\r\n                    return false;\r\n                }\r\n            }\r\n\r\n            this.removeError(input);\r\n            return true;\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Load default validation providers and scans the entire document when ready.\r\n     */\r\n    bootstrap() {\r\n        this.addMvcProviders();\r\n\r\n        window.addEventListener('load', event => {\r\n            this.scanMessages();\r\n            this.scanInputs();\r\n        });\r\n    }\r\n}\r\n"],"sourceRoot":""}